From ec7a5edc798bf45463964319392fc4e0c43dc48a Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Fri, 22 Sep 2023 14:23:58 +0100 Subject: [PATCH 1/4] [std.range.chain] Use static assert instead of complex constraint We can give more precise errors then. I've included a constraint that at least one argument is an input range. This is to reduce the chance of breaking code that uses an overload of chain defined elsewhere. --- std/range/package.d | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/std/range/package.d b/std/range/package.d index 1b4f233d94a..65907de8a74 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -928,9 +928,18 @@ See_Also: $(LREF only) to chain values to a range */ auto chain(Ranges...)(Ranges rs) if (Ranges.length > 0 && - allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) && - !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, Ranges))) == void)) + anySatisfy!(isInputRange, staticMap!(Unqual, Ranges))) { + alias R = staticMap!(Unqual, Ranges); + static foreach (T; R) + { + static assert(isInputRange!T, "`", T, "` is not an input range"); + } + alias RvalueElementType = CommonType!(staticMap!(ElementType, R)); + static if (is(RvalueElementType == void)) + { + static assert(0, "No common element type for ranges `", Ranges, "`"); + } static if (Ranges.length == 1) { return rs[0]; @@ -940,8 +949,6 @@ if (Ranges.length > 0 && static struct Result { private: - alias R = staticMap!(Unqual, Ranges); - alias RvalueElementType = CommonType!(staticMap!(.ElementType, R)); template sameET(A) { enum sameET = is(.ElementType!A == RvalueElementType); From 53afc4510d69075163f818d89074a9f3fd411287 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Fri, 22 Sep 2023 17:29:59 +0100 Subject: [PATCH 2/4] Avoid `static if` --- std/range/package.d | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/std/range/package.d b/std/range/package.d index 65907de8a74..43bffab3c61 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -936,10 +936,9 @@ if (Ranges.length > 0 && static assert(isInputRange!T, "`", T, "` is not an input range"); } alias RvalueElementType = CommonType!(staticMap!(ElementType, R)); - static if (is(RvalueElementType == void)) - { - static assert(0, "No common element type for ranges `", Ranges, "`"); - } + static assert(!is(RvalueElementType == void), + "No common element type for ranges `", Ranges, "`"); + static if (Ranges.length == 1) { return rs[0]; From 5934c380c5e4202420a2b77867ecf39a0654b63f Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Fri, 22 Sep 2023 17:45:35 +0100 Subject: [PATCH 3/4] Similar for choose and chooseAmong --- std/range/package.d | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/std/range/package.d b/std/range/package.d index 43bffab3c61..caa9b15f119 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -1728,9 +1728,11 @@ Returns: A range type dependent on `R1` and `R2`. */ auto choose(R1, R2)(bool condition, return scope R1 r1, return scope R2 r2) -if (isInputRange!(Unqual!R1) && isInputRange!(Unqual!R2) && - !is(CommonType!(ElementType!(Unqual!R1), ElementType!(Unqual!R2)) == void)) +if (isInputRange!(Unqual!R1) && isInputRange!(Unqual!R2)) { + static assert(!is(CommonType!(ElementType!(Unqual!R1), ElementType!(Unqual!R2)) == void), + "No common element type for `", R1, "` and `", R2, "`"); + size_t choice = condition? 0: 1; return ChooseResult!(R1, R2)(choice, r1, r2); } @@ -2176,11 +2178,17 @@ Returns: alias of that range's type. */ auto chooseAmong(Ranges...)(size_t index, return scope Ranges rs) -if (Ranges.length >= 2 - && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) - && !is(CommonType!(staticMap!(ElementType, Ranges)) == void)) +if (Ranges.length >= 2) { - return ChooseResult!Ranges(index, rs); + alias URs = staticMap!(Unqual, Ranges); + static foreach (T; URs) + { + static assert(isInputRange!T, "`", T, "` is not an input range"); + } + static assert(!is(CommonType!(staticMap!(ElementType, URs)) == void), + "No common element type for `", Ranges, "`"); + + return ChooseResult!Ranges(index, rs); } /// From f75118b0a67e3d7ab6b1f18c53608adf1b1be0ee Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Mon, 6 Nov 2023 17:54:25 +0000 Subject: [PATCH 4/4] Require >=1 input range in constraint for consistency --- std/range/package.d | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/std/range/package.d b/std/range/package.d index caa9b15f119..fb1f976097c 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -2178,7 +2178,8 @@ Returns: alias of that range's type. */ auto chooseAmong(Ranges...)(size_t index, return scope Ranges rs) -if (Ranges.length >= 2) +if (Ranges.length >= 2 && + anySatisfy!(isInputRange, staticMap!(Unqual, Ranges))) { alias URs = staticMap!(Unqual, Ranges); static foreach (T; URs)