@@ -119,12 +119,9 @@ template all(alias pred = "a")
119
119
Performs (at most) $(BIGOH range.length) evaluations of `pred`.
120
120
+/
121
121
bool all (Range )(Range range)
122
- if (isInputRange! Range )
122
+ if (isInputRange! Range &&
123
+ (__traits(isTemplate, pred) || is (typeof (unaryFun! pred(range.front)))))
123
124
{
124
- static assert (is (typeof (unaryFun! pred(range.front))),
125
- " `" ~ (isSomeString! (typeof (pred))
126
- ? pred.stringof[1 .. $- 1 ] : pred.stringof)
127
- ~ " ` isn't a unary predicate function for range.front" );
128
125
import std.functional : not;
129
126
130
127
return find! (not! (unaryFun! pred))(range).empty;
@@ -172,7 +169,8 @@ template any(alias pred = "a")
172
169
Performs (at most) $(BIGOH range.length) evaluations of `pred`.
173
170
+/
174
171
bool any (Range )(Range range)
175
- if (isInputRange! Range && is (typeof (unaryFun! pred(range.front))))
172
+ if (isInputRange! Range &&
173
+ (__traits(isTemplate, pred) || is (typeof (unaryFun! pred(range.front)))))
176
174
{
177
175
return ! find! pred(range).empty;
178
176
}
@@ -1294,17 +1292,6 @@ if (isInputRange!R &&
1294
1292
1295
1293
private enum bool hasConstEmptyMember(T) = is (typeof (((const T* a) => (* a).empty)(null )) : bool );
1296
1294
1297
- // Rebindable doesn't work with structs
1298
- // see: https://github.com/dlang/phobos/pull/6136
1299
- private template RebindableOrUnqual (T)
1300
- {
1301
- import std.typecons : Rebindable;
1302
- static if (is (T == class ) || is (T == interface ) || isDynamicArray! T || isAssociativeArray! T)
1303
- alias RebindableOrUnqual = Rebindable! T;
1304
- else
1305
- alias RebindableOrUnqual = Unqual! T;
1306
- }
1307
-
1308
1295
/**
1309
1296
Iterates the passed range and selects the extreme element with `less`.
1310
1297
If the extreme element occurs multiple time, the first occurrence will be
@@ -1313,8 +1300,8 @@ returned.
1313
1300
Params:
1314
1301
map = custom accessor for the comparison key
1315
1302
selector = custom mapping for the extrema selection
1316
- seed = custom seed to use as initial element
1317
1303
r = Range from which the extreme value will be selected
1304
+ seedElement = custom seed to use as initial element
1318
1305
1319
1306
Returns:
1320
1307
The extreme value according to `map` and `selector` of the passed-in values.
@@ -1328,10 +1315,19 @@ in
1328
1315
}
1329
1316
do
1330
1317
{
1318
+ import std.typecons : Rebindable;
1319
+
1331
1320
alias Element = ElementType! Range ;
1332
- RebindableOrUnqual ! Element seed = r.front;
1321
+ Rebindable ! Element seed = r.front;
1333
1322
r.popFront();
1334
- return extremum! (map, selector)(r, seed);
1323
+ static if (is (Rebindable! Element == T[], T))
1324
+ {
1325
+ return extremum! (map, selector)(r, seed);
1326
+ }
1327
+ else
1328
+ {
1329
+ return extremum! (map, selector)(r, seed.get );
1330
+ }
1335
1331
}
1336
1332
1337
1333
private auto extremum (alias map, alias selector = " a < b" , Range ,
@@ -1341,13 +1337,14 @@ if (isInputRange!Range && !isInfinite!Range &&
1341
1337
! is (CommonType! (ElementType! Range , RangeElementType) == void ) &&
1342
1338
is (typeof (unaryFun! map(ElementType! (Range ).init))))
1343
1339
{
1340
+ import std.typecons : Rebindable;
1341
+
1344
1342
alias mapFun = unaryFun! map;
1345
1343
alias selectorFun = binaryFun! selector;
1346
1344
1347
1345
alias Element = ElementType! Range ;
1348
1346
alias CommonElement = CommonType! (Element, RangeElementType);
1349
- RebindableOrUnqual! CommonElement extremeElement = seedElement;
1350
-
1347
+ Rebindable! CommonElement extremeElement = seedElement;
1351
1348
1352
1349
// if we only have one statement in the loop, it can be optimized a lot better
1353
1350
static if (__traits(isSame, map, a => a))
@@ -1408,7 +1405,15 @@ if (isInputRange!Range && !isInfinite!Range &&
1408
1405
}
1409
1406
}
1410
1407
}
1411
- return extremeElement;
1408
+ // Rebindable is an alias to T for arrays
1409
+ static if (is (typeof (extremeElement) == T[], T))
1410
+ {
1411
+ return extremeElement;
1412
+ }
1413
+ else
1414
+ {
1415
+ return extremeElement.get ;
1416
+ }
1412
1417
}
1413
1418
1414
1419
private auto extremum (alias selector = " a < b" , Range )(Range r)
@@ -1493,6 +1498,10 @@ if (isInputRange!Range && !isInfinite!Range &&
1493
1498
assert (d.extremum! ` a > b` == 10 );
1494
1499
assert (d.extremum! (a => a, ` a > b` ) == 10 );
1495
1500
}
1501
+
1502
+ // compiletime
1503
+ enum ctExtremum = iota(1 , 5 ).extremum;
1504
+ assert (ctExtremum == 1 );
1496
1505
}
1497
1506
1498
1507
@nogc @safe nothrow pure unittest
@@ -1524,6 +1533,17 @@ if (isInputRange!Range && !isInfinite!Range &&
1524
1533
assert (arr.extremum! " a.val" .val == 0 );
1525
1534
}
1526
1535
1536
+ // https://issues.dlang.org/show_bug.cgi?id=22786
1537
+ @nogc @safe nothrow pure unittest
1538
+ {
1539
+ struct S
1540
+ {
1541
+ immutable int value;
1542
+ }
1543
+
1544
+ assert ([S(5 ), S(6 )].extremum! " a.value" == S(5 ));
1545
+ }
1546
+
1527
1547
// find
1528
1548
/**
1529
1549
Finds an individual element in an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).
@@ -1552,7 +1572,7 @@ Complexity:
1552
1572
`find` performs $(BIGOH walkLength(haystack)) evaluations of `pred`.
1553
1573
There are specializations that improve performance by taking
1554
1574
advantage of $(REF_ALTTEXT bidirectional, isBidirectionalRange, std,range,primitives)
1555
- or $(REF_ALTTEXT random access, isRandomAccess , std,range,primitives)
1575
+ or $(REF_ALTTEXT random access, isRandomAccessRange , std,range,primitives)
1556
1576
ranges (where possible).
1557
1577
1558
1578
Params:
0 commit comments