Fix #10440 Use right template constraint for each (#10689)

The current contraints have been implemented in #3837 to make `each`
behave more like `foreach` and automatically destructure tuples.

I haven't publically documented this behavior because it is probably
better these days to use `bind` for that.
This commit is contained in:
Inkrementator 2025-03-19 00:14:17 +01:00 committed by GitHub
parent 56f8c64df4
commit c79914db2d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -865,8 +865,8 @@ See_Also: $(REF tee, std,range)
template each(alias fun = "a") template each(alias fun = "a")
{ {
import std.meta : AliasSeq; import std.meta : AliasSeq;
import std.traits : Parameters; import std.traits : Parameters, isInstanceOf;
import std.typecons : Flag, Yes, No; import std.typecons : Flag, Yes, No, Tuple;
private: private:
alias BinaryArgs = AliasSeq!(fun, "i", "a"); alias BinaryArgs = AliasSeq!(fun, "i", "a");
@ -912,7 +912,8 @@ public:
Flag!"each" each(Range)(Range r) Flag!"each" each(Range)(Range r)
if (!isForeachIterable!Range && ( if (!isForeachIterable!Range && (
isRangeIterable!Range || isRangeIterable!Range ||
__traits(compiles, typeof(r.front).length))) // Tuples get automatically expanded if function takes right number of args
(isInputRange!Range && isInstanceOf!(Tuple, typeof(r.front)))))
{ {
static if (isRangeIterable!Range) static if (isRangeIterable!Range)
{ {
@ -953,7 +954,11 @@ public:
} }
else else
{ {
// range interface with >2 parameters. /* Range over Tuples, fun must have correct number of args
* If number of args of fun is <= 2, calling fun(tuple) or fun(idx, tuple)
* will have precendence over fun(tuple.expand).
* Provide types to delegate params to control this.
*/
for (auto range = r; !range.empty; range.popFront()) for (auto range = r; !range.empty; range.popFront())
{ {
static if (!is(typeof(fun(r.front.expand)) == Flag!"each")) static if (!is(typeof(fun(r.front.expand)) == Flag!"each"))