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:
The Dlang Bot 2018-03-16 16:54:04 +01:00 committed by GitHub
commit 7ac39eff7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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