mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 22:50:38 +03:00
Merge pull request #6144 from wilzbach/traits-is-same-min-max
Use __traits(isSame) for min,maxElement merged-on-behalf-of: Jack Stouffer <jack@jackstouffer.com>
This commit is contained in:
commit
7ac39eff7a
1 changed files with 54 additions and 83 deletions
|
@ -1314,33 +1314,64 @@ if (isInputRange!Range && !isInfinite!Range &&
|
||||||
alias CommonElement = CommonType!(Element, RangeElementType);
|
alias CommonElement = CommonType!(Element, RangeElementType);
|
||||||
Unqual!CommonElement extremeElement = seedElement;
|
Unqual!CommonElement extremeElement = seedElement;
|
||||||
|
|
||||||
alias MapType = Unqual!(typeof(mapFun(CommonElement.init)));
|
|
||||||
MapType extremeElementMapped = mapFun(extremeElement);
|
|
||||||
|
|
||||||
// direct access via a random access range is faster
|
// if we only have one statement in the loop, it can be optimized a lot better
|
||||||
static if (isRandomAccessRange!Range)
|
static if (__traits(isSame, map, a => a))
|
||||||
{
|
{
|
||||||
foreach (const i; 0 .. r.length)
|
|
||||||
|
// direct access via a random access range is faster
|
||||||
|
static if (isRandomAccessRange!Range)
|
||||||
{
|
{
|
||||||
MapType mapElement = mapFun(r[i]);
|
foreach (const i; 0 .. r.length)
|
||||||
if (selectorFun(mapElement, extremeElementMapped))
|
|
||||||
{
|
{
|
||||||
extremeElement = r[i];
|
if (selectorFun(r[i], extremeElement))
|
||||||
extremeElementMapped = mapElement;
|
{
|
||||||
|
extremeElement = r[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (!r.empty)
|
||||||
|
{
|
||||||
|
if (selectorFun(r.front, extremeElement))
|
||||||
|
{
|
||||||
|
extremeElement = r.front;
|
||||||
|
}
|
||||||
|
r.popFront();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (!r.empty)
|
alias MapType = Unqual!(typeof(mapFun(CommonElement.init)));
|
||||||
|
MapType extremeElementMapped = mapFun(extremeElement);
|
||||||
|
|
||||||
|
// direct access via a random access range is faster
|
||||||
|
static if (isRandomAccessRange!Range)
|
||||||
{
|
{
|
||||||
MapType mapElement = mapFun(r.front);
|
foreach (const i; 0 .. r.length)
|
||||||
if (selectorFun(mapElement, extremeElementMapped))
|
|
||||||
{
|
{
|
||||||
extremeElement = r.front;
|
MapType mapElement = mapFun(r[i]);
|
||||||
extremeElementMapped = mapElement;
|
if (selectorFun(mapElement, extremeElementMapped))
|
||||||
|
{
|
||||||
|
extremeElement = r[i];
|
||||||
|
extremeElementMapped = mapElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (!r.empty)
|
||||||
|
{
|
||||||
|
MapType mapElement = mapFun(r.front);
|
||||||
|
if (selectorFun(mapElement, extremeElementMapped))
|
||||||
|
{
|
||||||
|
extremeElement = r.front;
|
||||||
|
extremeElementMapped = mapElement;
|
||||||
|
}
|
||||||
|
r.popFront();
|
||||||
}
|
}
|
||||||
r.popFront();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return extremeElement;
|
return extremeElement;
|
||||||
|
@ -1350,10 +1381,7 @@ private auto extremum(alias selector = "a < b", Range)(Range r)
|
||||||
if (isInputRange!Range && !isInfinite!Range &&
|
if (isInputRange!Range && !isInfinite!Range &&
|
||||||
!is(typeof(unaryFun!selector(ElementType!(Range).init))))
|
!is(typeof(unaryFun!selector(ElementType!(Range).init))))
|
||||||
{
|
{
|
||||||
alias Element = ElementType!Range;
|
return extremum!(a => a, selector)(r);
|
||||||
Unqual!Element seed = r.front;
|
|
||||||
r.popFront();
|
|
||||||
return extremum!selector(r, seed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we only have one statement in the loop it can be optimized a lot better
|
// if we only have one statement in the loop it can be optimized a lot better
|
||||||
|
@ -1364,34 +1392,7 @@ private auto extremum(alias selector = "a < b", Range,
|
||||||
!is(CommonType!(ElementType!Range, RangeElementType) == void) &&
|
!is(CommonType!(ElementType!Range, RangeElementType) == void) &&
|
||||||
!is(typeof(unaryFun!selector(ElementType!(Range).init))))
|
!is(typeof(unaryFun!selector(ElementType!(Range).init))))
|
||||||
{
|
{
|
||||||
alias Element = ElementType!Range;
|
return extremum!(a => a, selector)(r, seedElement);
|
||||||
alias CommonElement = CommonType!(Element, RangeElementType);
|
|
||||||
Unqual!CommonElement extremeElement = seedElement;
|
|
||||||
alias selectorFun = binaryFun!selector;
|
|
||||||
|
|
||||||
// direct access via a random access range is faster
|
|
||||||
static if (isRandomAccessRange!Range)
|
|
||||||
{
|
|
||||||
foreach (const i; 0 .. r.length)
|
|
||||||
{
|
|
||||||
if (selectorFun(r[i], extremeElement))
|
|
||||||
{
|
|
||||||
extremeElement = r[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (!r.empty)
|
|
||||||
{
|
|
||||||
if (selectorFun(r.front, extremeElement))
|
|
||||||
{
|
|
||||||
extremeElement = r.front;
|
|
||||||
}
|
|
||||||
r.popFront();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return extremeElement;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@safe pure unittest
|
@safe pure unittest
|
||||||
|
@ -3374,21 +3375,14 @@ See_Also:
|
||||||
$(LREF maxElement), $(REF min, std,algorithm,comparison), $(LREF minCount),
|
$(LREF maxElement), $(REF min, std,algorithm,comparison), $(LREF minCount),
|
||||||
$(LREF minIndex), $(LREF minPos)
|
$(LREF minIndex), $(LREF minPos)
|
||||||
*/
|
*/
|
||||||
auto minElement(alias map, Range)(Range r)
|
auto minElement(alias map = (a => a), Range)(Range r)
|
||||||
if (isInputRange!Range && !isInfinite!Range)
|
if (isInputRange!Range && !isInfinite!Range)
|
||||||
{
|
{
|
||||||
return extremum!map(r);
|
return extremum!map(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
auto minElement(Range)(Range r)
|
auto minElement(alias map = (a => a), Range, RangeElementType = ElementType!Range)
|
||||||
if (isInputRange!Range && !isInfinite!Range)
|
|
||||||
{
|
|
||||||
return extremum(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ditto
|
|
||||||
auto minElement(alias map, Range, RangeElementType = ElementType!Range)
|
|
||||||
(Range r, RangeElementType seed)
|
(Range r, RangeElementType seed)
|
||||||
if (isInputRange!Range && !isInfinite!Range &&
|
if (isInputRange!Range && !isInfinite!Range &&
|
||||||
!is(CommonType!(ElementType!Range, RangeElementType) == void))
|
!is(CommonType!(ElementType!Range, RangeElementType) == void))
|
||||||
|
@ -3396,15 +3390,6 @@ if (isInputRange!Range && !isInfinite!Range &&
|
||||||
return extremum!map(r, seed);
|
return extremum!map(r, seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ditto
|
|
||||||
auto minElement(Range, RangeElementType = ElementType!Range)
|
|
||||||
(Range r, RangeElementType seed)
|
|
||||||
if (isInputRange!Range && !isInfinite!Range &&
|
|
||||||
!is(CommonType!(ElementType!Range, RangeElementType) == void))
|
|
||||||
{
|
|
||||||
return extremum(r, seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
@safe pure unittest
|
@safe pure unittest
|
||||||
{
|
{
|
||||||
|
@ -3453,6 +3438,7 @@ auto minElement(Range, RangeElementType = ElementType!Range)
|
||||||
DummyType d;
|
DummyType d;
|
||||||
assert(d.minElement == 1);
|
assert(d.minElement == 1);
|
||||||
assert(d.minElement!(a => a) == 1);
|
assert(d.minElement!(a => a) == 1);
|
||||||
|
assert(d.minElement!(a => -a) == 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// with empty, but seeded ranges
|
// with empty, but seeded ranges
|
||||||
|
@ -3491,21 +3477,14 @@ See_Also:
|
||||||
$(LREF minElement), $(REF max, std,algorithm,comparison), $(LREF maxCount),
|
$(LREF minElement), $(REF max, std,algorithm,comparison), $(LREF maxCount),
|
||||||
$(LREF maxIndex), $(LREF maxPos)
|
$(LREF maxIndex), $(LREF maxPos)
|
||||||
*/
|
*/
|
||||||
auto maxElement(alias map, Range)(Range r)
|
auto maxElement(alias map = (a => a), Range)(Range r)
|
||||||
if (isInputRange!Range && !isInfinite!Range)
|
if (isInputRange!Range && !isInfinite!Range)
|
||||||
{
|
{
|
||||||
return extremum!(map, "a > b")(r);
|
return extremum!(map, "a > b")(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
auto maxElement(Range)(Range r)
|
auto maxElement(alias map = (a => a), Range, RangeElementType = ElementType!Range)
|
||||||
if (isInputRange!Range && !isInfinite!Range)
|
|
||||||
{
|
|
||||||
return extremum!`a > b`(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ditto
|
|
||||||
auto maxElement(alias map, Range, RangeElementType = ElementType!Range)
|
|
||||||
(Range r, RangeElementType seed)
|
(Range r, RangeElementType seed)
|
||||||
if (isInputRange!Range && !isInfinite!Range &&
|
if (isInputRange!Range && !isInfinite!Range &&
|
||||||
!is(CommonType!(ElementType!Range, RangeElementType) == void))
|
!is(CommonType!(ElementType!Range, RangeElementType) == void))
|
||||||
|
@ -3513,15 +3492,6 @@ if (isInputRange!Range && !isInfinite!Range &&
|
||||||
return extremum!(map, "a > b")(r, seed);
|
return extremum!(map, "a > b")(r, seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ditto
|
|
||||||
auto maxElement(Range, RangeElementType = ElementType!Range)
|
|
||||||
(Range r, RangeElementType seed)
|
|
||||||
if (isInputRange!Range && !isInfinite!Range &&
|
|
||||||
!is(CommonType!(ElementType!Range, RangeElementType) == void))
|
|
||||||
{
|
|
||||||
return extremum!`a > b`(r, seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
@safe pure unittest
|
@safe pure unittest
|
||||||
{
|
{
|
||||||
|
@ -3571,6 +3541,7 @@ if (isInputRange!Range && !isInfinite!Range &&
|
||||||
DummyType d;
|
DummyType d;
|
||||||
assert(d.maxElement == 10);
|
assert(d.maxElement == 10);
|
||||||
assert(d.maxElement!(a => a) == 10);
|
assert(d.maxElement!(a => a) == 10);
|
||||||
|
assert(d.maxElement!(a => -a) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// with empty, but seeded ranges
|
// with empty, but seeded ranges
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue