aboutsummaryrefslogtreecommitdiff
path: root/libphobos/src/std/algorithm
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-07-09 22:08:36 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2023-07-09 22:08:36 +0200
commit3b007164b3ef114c3c86c42ca2455f8f2696fb0d (patch)
tree340037c67d4a2a57774103d54fa103390611f6e5 /libphobos/src/std/algorithm
parentd6c1d7c4009bfe759719675ce3bc03ca503b9bf4 (diff)
downloadgcc-3b007164b3ef114c3c86c42ca2455f8f2696fb0d.zip
gcc-3b007164b3ef114c3c86c42ca2455f8f2696fb0d.tar.gz
gcc-3b007164b3ef114c3c86c42ca2455f8f2696fb0d.tar.bz2
d: Merge upstream dmd, druntime 28a3b24c2e, phobos 8ab95ded5.
D front-end changes: - Import dmd v2.104.0-beta.1. - Better error message when attribute inference fails down the call stack. - Using `;' as an empty statement has been turned into an error. - Using `in' parameters with non- `extern(D)' or `extern(C++)' functions is deprecated. - `in ref' on parameters has been deprecated in favor of `-preview=in'. - Throwing `immutable', `const', `inout', and `shared' qualified objects is now deprecated. - User Defined Attributes now parse Template Arguments. D runtime changes: - Import druntime v2.104.0-beta.1. Phobos changes: - Import phobos v2.104.0-beta.1. - Better static assert messages when instantiating `std.algorithm.comparison.clamp' with wrong inputs. - `std.typecons.Rebindable' now supports all types. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 28a3b24c2e. * dmd/VERSION: Bump version to v2.104.0-beta.1. * d-codegen.cc (build_bounds_slice_condition): Update for new front-end interface. * d-lang.cc (d_init_options): Likewise. (d_handle_option): Likewise. (d_post_options): Initialize global.compileEnv. * expr.cc (ExprVisitor::visit (CatExp *)): Replace code generation with new front-end lowering. (ExprVisitor::visit (LoweredAssignExp *)): New method. (ExprVisitor::visit (StructLiteralExp *)): Don't generate static initializer symbols for structs defined in C sources. * runtime.def (ARRAYCATT): Remove. (ARRAYCATNTX): Remove. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 28a3b24c2e. * src/MERGE: Merge upstream phobos 8ab95ded5. gcc/testsuite/ChangeLog: * gdc.dg/rtti1.d: Move array concat testcase to ... * gdc.dg/nogc1.d: ... here. New test.
Diffstat (limited to 'libphobos/src/std/algorithm')
-rw-r--r--libphobos/src/std/algorithm/comparison.d23
-rw-r--r--libphobos/src/std/algorithm/iteration.d28
-rw-r--r--libphobos/src/std/algorithm/searching.d68
3 files changed, 81 insertions, 38 deletions
diff --git a/libphobos/src/std/algorithm/comparison.d b/libphobos/src/std/algorithm/comparison.d
index 5ecb4f6..5c70960 100644
--- a/libphobos/src/std/algorithm/comparison.d
+++ b/libphobos/src/std/algorithm/comparison.d
@@ -577,19 +577,20 @@ Returns:
and `T3` are different.
*/
T1 clamp(T1, T2, T3)(T1 val, T2 lower, T3 upper)
-if (is(typeof(val.lessThan(lower) ? lower : val.greaterThan(upper) ? upper : val))
- && (is(T2 : T1) && is(T3 : T1)))
-// cannot use :
-// `if (is(typeof(val.lessThan(lower) ? lower : val.greaterThan(upper) ? upper : val) : T1))
-// because of https://issues.dlang.org/show_bug.cgi?id=16235.
-// Once that is fixed, we can simply use the ternary in both the template constraint
-// and the template body
-in
{
+ static assert(is(T2 : T1), "T2 of type '", T2.stringof
+ , "' must be implicitly convertible to type of T1 '"
+ , T1.stringof, "'");
+ static assert(is(T3 : T1), "T3 of type '", T3.stringof
+ , "' must be implicitly convertible to type of T1 '"
+ , T1.stringof, "'");
+
assert(!lower.greaterThan(upper), "Lower can't be greater than upper.");
-}
-do
-{
+
+ // `if (is(typeof(val.lessThan(lower) ? lower : val.greaterThan(upper) ? upper : val) : T1))
+ // because of https://issues.dlang.org/show_bug.cgi?id=16235.
+ // Once that is fixed, we can simply use the ternary in both the template constraint
+ // and the template body
if (val.lessThan(lower))
return lower;
else if (val.greaterThan(upper))
diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d
index 8236076..9f5a6ac 100644
--- a/libphobos/src/std/algorithm/iteration.d
+++ b/libphobos/src/std/algorithm/iteration.d
@@ -3632,18 +3632,18 @@ auto joiner(RoR, Separator)(RoR r, Separator sep)
/// Ditto
auto joiner(RoR)(RoR r)
-if (isInputRange!RoR && isInputRange!(ElementType!RoR))
+if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)))
{
static struct Result
{
private:
RoR _items;
- ElementType!RoR _current;
+ Unqual!(ElementType!RoR) _current;
enum isBidirectional = isForwardRange!RoR && isForwardRange!(ElementType!RoR) &&
isBidirectionalRange!RoR && isBidirectionalRange!(ElementType!RoR);
static if (isBidirectional)
{
- ElementType!RoR _currentBack;
+ Unqual!(ElementType!RoR) _currentBack;
bool reachedFinalElement;
}
@@ -4293,6 +4293,28 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
assert([only(S(null))].joiner.front == S(null));
}
+// https://issues.dlang.org/show_bug.cgi?id=22785
+@safe unittest
+{
+
+ import std.algorithm.iteration : joiner, map;
+ import std.array : array;
+
+ static immutable struct S
+ {
+ int value;
+ }
+
+ static immutable struct T
+ {
+ S[] arr;
+ }
+
+ auto range = [T([S(3)]), T([S(4), S(5)])];
+
+ assert(range.map!"a.arr".joiner.array == [S(3), S(4), S(5)]);
+}
+
/++
Implements the homonym function (also known as `accumulate`, $(D
compress), `inject`, or `foldl`) present in various programming
diff --git a/libphobos/src/std/algorithm/searching.d b/libphobos/src/std/algorithm/searching.d
index 15f7ca9..ee318c8 100644
--- a/libphobos/src/std/algorithm/searching.d
+++ b/libphobos/src/std/algorithm/searching.d
@@ -119,12 +119,9 @@ template all(alias pred = "a")
Performs (at most) $(BIGOH range.length) evaluations of `pred`.
+/
bool all(Range)(Range range)
- if (isInputRange!Range)
+ if (isInputRange!Range &&
+ (__traits(isTemplate, pred) || is(typeof(unaryFun!pred(range.front)))))
{
- static assert(is(typeof(unaryFun!pred(range.front))),
- "`" ~ (isSomeString!(typeof(pred))
- ? pred.stringof[1..$-1] : pred.stringof)
- ~ "` isn't a unary predicate function for range.front");
import std.functional : not;
return find!(not!(unaryFun!pred))(range).empty;
@@ -172,7 +169,8 @@ template any(alias pred = "a")
Performs (at most) $(BIGOH range.length) evaluations of `pred`.
+/
bool any(Range)(Range range)
- if (isInputRange!Range && is(typeof(unaryFun!pred(range.front))))
+ if (isInputRange!Range &&
+ (__traits(isTemplate, pred) || is(typeof(unaryFun!pred(range.front)))))
{
return !find!pred(range).empty;
}
@@ -1294,17 +1292,6 @@ if (isInputRange!R &&
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`.
If the extreme element occurs multiple time, the first occurrence will be
@@ -1313,8 +1300,8 @@ returned.
Params:
map = custom accessor for the comparison key
selector = custom mapping for the extrema selection
- seed = custom seed to use as initial element
r = Range from which the extreme value will be selected
+ seedElement = custom seed to use as initial element
Returns:
The extreme value according to `map` and `selector` of the passed-in values.
@@ -1328,10 +1315,19 @@ in
}
do
{
+ import std.typecons : Rebindable;
+
alias Element = ElementType!Range;
- RebindableOrUnqual!Element seed = r.front;
+ Rebindable!Element seed = r.front;
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,
@@ -1341,13 +1337,14 @@ if (isInputRange!Range && !isInfinite!Range &&
!is(CommonType!(ElementType!Range, RangeElementType) == void) &&
is(typeof(unaryFun!map(ElementType!(Range).init))))
{
+ import std.typecons : Rebindable;
+
alias mapFun = unaryFun!map;
alias selectorFun = binaryFun!selector;
alias Element = ElementType!Range;
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
static if (__traits(isSame, map, a => a))
@@ -1408,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)
@@ -1493,6 +1498,10 @@ if (isInputRange!Range && !isInfinite!Range &&
assert(d.extremum!`a > b` == 10);
assert(d.extremum!(a => a, `a > b`) == 10);
}
+
+ // compiletime
+ enum ctExtremum = iota(1, 5).extremum;
+ assert(ctExtremum == 1);
}
@nogc @safe nothrow pure unittest
@@ -1524,6 +1533,17 @@ if (isInputRange!Range && !isInfinite!Range &&
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
/**
Finds an individual element in an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).
@@ -1552,7 +1572,7 @@ Complexity:
`find` performs $(BIGOH walkLength(haystack)) evaluations of `pred`.
There are specializations that improve performance by taking
advantage of $(REF_ALTTEXT bidirectional, isBidirectionalRange, std,range,primitives)
- or $(REF_ALTTEXT random access, isRandomAccess, std,range,primitives)
+ or $(REF_ALTTEXT random access, isRandomAccessRange, std,range,primitives)
ranges (where possible).
Params: