@@ -3868,45 +3868,89 @@ if (isInputRange!Range && !isInfinite!Range &&
38683868 */
38693869// TODO alias map = a => a
38703870ElementType! Range [2 ] extrema (Range )(Range r)
3871- if (isRandomAccessRange ! Range && hasLength ! Range )
3871+ if (isInputRange ! Range && ! isInfinite ! Range )
38723872in (! r.empty)
38733873{
3874- if (r.length == 1 )
3875- return [r[0 ], r[0 ]];
3876-
3877- typeof (return ) result;
3878- size_t i;
3879- if (r.length & 1 ) // odd
3880- {
3881- result = [r[0 ], r[0 ]];
3882- i = 1 ;
3883- }
3884- else
3885- {
3886- result = (r[0 ] < r[1 ]) ? [r[0 ], r[1 ]] : [r[1 ], r[0 ]];
3887- i = 2 ;
3888- }
3889- // iterate pairs
3890- const imax = r.length;
3891- for (; i != imax; i += 2 )
3874+ static if (isRandomAccessRange! Range && hasLength! Range )
38923875 {
3893- // save work
3894- if (r[i] < r[i+ 1 ])
3876+ if (r.length == 1 )
3877+ return [r[0 ], r[0 ]];
3878+
3879+ typeof (return ) result;
3880+ size_t i;
3881+ if (r.length & 1 ) // odd
38953882 {
3896- if (r[i] < result[0 ])
3897- result[0 ] = r[i];
3898- if (r[i+ 1 ] > result[1 ])
3899- result[1 ] = r[i+ 1 ];
3883+ result = [r[0 ], r[0 ]];
3884+ i = 1 ;
39003885 }
39013886 else
39023887 {
3903- if (r[i+ 1 ] < result[0 ])
3904- result[0 ] = r[i+ 1 ];
3905- if (r[i] > result[1 ])
3906- result[1 ] = r[i];
3888+ result = (r[0 ] < r[1 ]) ? [r[0 ], r[1 ]] : [r[1 ], r[0 ]];
3889+ i = 2 ;
3890+ }
3891+ // iterate pairs
3892+ const imax = r.length;
3893+ for (; i != imax; i += 2 )
3894+ {
3895+ // save work
3896+ if (r[i] < r[i+ 1 ])
3897+ {
3898+ if (r[i] < result[0 ])
3899+ result[0 ] = r[i];
3900+ if (r[i+ 1 ] > result[1 ])
3901+ result[1 ] = r[i+ 1 ];
3902+ }
3903+ else
3904+ {
3905+ if (r[i+ 1 ] < result[0 ])
3906+ result[0 ] = r[i+ 1 ];
3907+ if (r[i] > result[1 ])
3908+ result[1 ] = r[i];
3909+ }
3910+ }
3911+ return result;
3912+ }
3913+ else
3914+ {
3915+ auto first = r.front;
3916+ r.popFront;
3917+ if (r.empty)
3918+ return [first, first];
3919+
3920+ typeof (return ) result = (first < r.front) ? [first, r.front] : [r.front, first];
3921+ // iterate pairs
3922+ while (true )
3923+ {
3924+ r.popFront;
3925+ if (r.empty)
3926+ return result;
3927+ first = r.front;
3928+ r.popFront;
3929+ if (r.empty)
3930+ {
3931+ if (first < result[0 ])
3932+ result[0 ] = first;
3933+ else if (first > result[1 ])
3934+ result[1 ] = first;
3935+ return result;
3936+ }
3937+ // save work
3938+ if (first < r.front)
3939+ {
3940+ if (first < result[0 ])
3941+ result[0 ] = first;
3942+ if (r.front > result[1 ])
3943+ result[1 ] = r.front;
3944+ }
3945+ else
3946+ {
3947+ if (r.front < result[0 ])
3948+ result[0 ] = r.front;
3949+ if (first > result[1 ])
3950+ result[1 ] = first;
3951+ }
39073952 }
39083953 }
3909- return result;
39103954}
39113955
39123956// /
@@ -3921,6 +3965,10 @@ in (!r.empty)
39213965 assert (extrema([1 ,5 ,3 ,2 ]) == [1 , 5 ]);
39223966 assert (extrema([2 ,3 ,3 ,2 ]) == [2 , 3 ]);
39233967
3968+ import std.internal.test.dummyrange ;
3969+ DummyRange! (ReturnBy.Reference, Length.No, RangeType.Input) r;
3970+ assert (r.extrema == [1u , 10u ]);
3971+
39243972 version (StdRandomTests)
39253973 foreach (i; 0 .. 1000 )
39263974 {
0 commit comments