-
-
Notifications
You must be signed in to change notification settings - Fork 740
Fix issue 10773. #1456
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
Fix issue 10773. #1456
Conversation
As well as require bidirectional separator with length before assuming retro(separator) and separator.length will work. Without these additional constraints, splitter will cause unhelpful compile errors about being unable instantiate find, when the separator is a non-forward input range, or when it doesn't have length, or when it's non-bidirectional. In the latter case, splitter should still work, just that it won't export a bidirectional interface.
foreach (e; s) { | ||
assert(e.equal(expected.front)); | ||
expected.popFront(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Y u no use equal
?
unittest // Issue 10773
{
equal(splitter("abc", ""), ["a", "b", "c"]);
}
Ditto for below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
O right, I just saw you were using equal
for the individual elements.
TIP: If the default ==
doesn't work to compare elements, you can parameterize equal to have a comp arg to correctly do the comparison, which includes simply using equal itself:
equal!equal(myRoR1, myRoR2);
I think that single line of code is one of my favorite examples of D's template mechanics' power and expessiveness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoa! That's cool! I've never thought to do that. :) Yeah you're right, this is a fine example of the power of D's templates. :)
I wonder, can that trick be used recursively? I.e. if I have a range of ranges of ranges, of unequal but comparable types, could I write equal!(equal!equal)(roror) or something to that effect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, there is a limit :)
equal!(equal!equal)
won't work, as when you pass equal!equal
as an comparison argument, the compiler doesn't find the template, because of the partial specification.
So currently, you have to do something along the lines of:
int[][][] b;
equal!(equal!(equal, int[][], int[][]))(b, b);
Yuk!
That said, I think that if we made equal a template, eg:
template equal(Comp)
{
bool equal(R1, R2)
{
//...
}
}
Then it should be possible to make it work. I'll keep this enhancement in mind, maybe I'll implement it in a near future.
I wrote it that way 'cos if the subrange is a distinct type from the original range, equal won't compare them properly (compiler will complain about == not being defined). But in this case, it does work, so I rewrote it to use equal() directly.
Merged. Thanks. |
If the separator is empty, should split into single-element subranges, rather than get stuck in an infinite loop of empty subranges.