Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[std.range.chain] Use static assert instead of complex constraint #8821

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions std/range/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -928,9 +928,17 @@ 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)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to have this anySatisfy constraint here but not on chooseAmong?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added this constraint to chooseAmong now for consistency. The only reason was I thought that was a less likely name to have a collision (see my next comment).

{
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 assert(!is(RvalueElementType == void),
"No common element type for ranges `", Ranges, "`");

static if (Ranges.length == 1)
{
return rs[0];
Expand All @@ -940,8 +948,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);
Expand Down Expand Up @@ -1722,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);
}
Expand Down Expand Up @@ -2170,11 +2178,18 @@ 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 &&
anySatisfy!(isInputRange, staticMap!(Unqual, Ranges)))
{
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);
}

///
Expand Down