Skip to content

Commit 3d2892c

Browse files
committed
Only require input range
1 parent e282bec commit 3d2892c

File tree

1 file changed

+78
-30
lines changed

1 file changed

+78
-30
lines changed

std/algorithm/searching.d

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3868,45 +3868,89 @@ if (isInputRange!Range && !isInfinite!Range &&
38683868
*/
38693869
// TODO alias map = a => a
38703870
ElementType!Range[2] extrema(Range)(Range r)
3871-
if (isRandomAccessRange!Range && hasLength!Range)
3871+
if (isInputRange!Range && !isInfinite!Range)
38723872
in (!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

Comments
 (0)