mirror of
https://github.com/dlang/phobos.git
synced 2025-05-08 12:07:15 +03:00
Fix issue 22786 (immutable element in maxElement) by always using Rebindable.
This commit is contained in:
parent
656ae7905e
commit
b818901e63
1 changed files with 34 additions and 16 deletions
|
@ -1292,17 +1292,6 @@ if (isInputRange!R &&
|
||||||
|
|
||||||
private enum bool hasConstEmptyMember(T) = is(typeof(((const T* a) => (*a).empty)(null)) : bool);
|
private enum bool hasConstEmptyMember(T) = is(typeof(((const T* a) => (*a).empty)(null)) : bool);
|
||||||
|
|
||||||
// Rebindable doesn't work with structs
|
|
||||||
// see: https://github.com/dlang/phobos/pull/6136
|
|
||||||
private template RebindableOrUnqual(T)
|
|
||||||
{
|
|
||||||
import std.typecons : Rebindable;
|
|
||||||
static if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)
|
|
||||||
alias RebindableOrUnqual = Rebindable!T;
|
|
||||||
else
|
|
||||||
alias RebindableOrUnqual = Unqual!T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Iterates the passed range and selects the extreme element with `less`.
|
Iterates the passed range and selects the extreme element with `less`.
|
||||||
If the extreme element occurs multiple time, the first occurrence will be
|
If the extreme element occurs multiple time, the first occurrence will be
|
||||||
|
@ -1326,10 +1315,19 @@ in
|
||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
import std.typecons : Rebindable;
|
||||||
|
|
||||||
alias Element = ElementType!Range;
|
alias Element = ElementType!Range;
|
||||||
RebindableOrUnqual!Element seed = r.front;
|
Rebindable!Element seed = r.front;
|
||||||
r.popFront();
|
r.popFront();
|
||||||
return extremum!(map, selector)(r, seed);
|
static if (is(Rebindable!Element == T[], T))
|
||||||
|
{
|
||||||
|
return extremum!(map, selector)(r, seed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return extremum!(map, selector)(r, seed.get);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private auto extremum(alias map, alias selector = "a < b", Range,
|
private auto extremum(alias map, alias selector = "a < b", Range,
|
||||||
|
@ -1339,13 +1337,14 @@ if (isInputRange!Range && !isInfinite!Range &&
|
||||||
!is(CommonType!(ElementType!Range, RangeElementType) == void) &&
|
!is(CommonType!(ElementType!Range, RangeElementType) == void) &&
|
||||||
is(typeof(unaryFun!map(ElementType!(Range).init))))
|
is(typeof(unaryFun!map(ElementType!(Range).init))))
|
||||||
{
|
{
|
||||||
|
import std.typecons : Rebindable;
|
||||||
|
|
||||||
alias mapFun = unaryFun!map;
|
alias mapFun = unaryFun!map;
|
||||||
alias selectorFun = binaryFun!selector;
|
alias selectorFun = binaryFun!selector;
|
||||||
|
|
||||||
alias Element = ElementType!Range;
|
alias Element = ElementType!Range;
|
||||||
alias CommonElement = CommonType!(Element, RangeElementType);
|
alias CommonElement = CommonType!(Element, RangeElementType);
|
||||||
RebindableOrUnqual!CommonElement extremeElement = seedElement;
|
Rebindable!CommonElement extremeElement = seedElement;
|
||||||
|
|
||||||
|
|
||||||
// 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
|
||||||
static if (__traits(isSame, map, a => a))
|
static if (__traits(isSame, map, a => a))
|
||||||
|
@ -1406,7 +1405,15 @@ if (isInputRange!Range && !isInfinite!Range &&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return extremeElement;
|
// Rebindable is an alias to T for arrays
|
||||||
|
static if (is(typeof(extremeElement) == T[], T))
|
||||||
|
{
|
||||||
|
return extremeElement;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return extremeElement.get;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private auto extremum(alias selector = "a < b", Range)(Range r)
|
private auto extremum(alias selector = "a < b", Range)(Range r)
|
||||||
|
@ -1522,6 +1529,17 @@ if (isInputRange!Range && !isInfinite!Range &&
|
||||||
assert(arr.extremum!"a.val".val == 0);
|
assert(arr.extremum!"a.val".val == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://issues.dlang.org/show_bug.cgi?id=22786
|
||||||
|
@nogc @safe nothrow pure unittest
|
||||||
|
{
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
immutable int value;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert([S(5), S(6)].extremum!"a.value" == S(5));
|
||||||
|
}
|
||||||
|
|
||||||
// find
|
// find
|
||||||
/**
|
/**
|
||||||
Finds an individual element in an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).
|
Finds an individual element in an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue