digitalmars.D.learn - countUntil's constraints
- Nicholas Wilson (13/13) Aug 07 2018 the first overload is
- Steven Schveighoffer (6/20) Aug 07 2018 No, not exactly the same.
- Nicholas Wilson (5/26) Aug 07 2018 But forward ranges are a superset of input ranges so
- Nicholas Wilson (20/41) Aug 07 2018 Ahhh, Rs[0] is not necessarily a range, consider:
- Steven Schveighoffer (6/50) Aug 08 2018 Ah, but there is a third overload which just takes a haystack and a
the first overload is ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles) if (isForwardRange!R && Rs.length > 0 && isForwardRange!(Rs[0]) == isInputRange!(Rs[0]) && is(typeof(startsWith!pred(haystack, needles[0]))) && (Rs.length == 1 || is(typeof(countUntil!pred(haystack, needles[1 .. $]))))) What does `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` mean here? Is it just the same as `isForwardRange!(Rs[0])`? Why is it written like that?
Aug 07 2018
On 8/7/18 9:20 PM, Nicholas Wilson wrote:the first overload is ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles) if (isForwardRange!R && Rs.length > 0 && isForwardRange!(Rs[0]) == isInputRange!(Rs[0]) && is(typeof(startsWith!pred(haystack, needles[0]))) && (Rs.length == 1 || is(typeof(countUntil!pred(haystack, needles[1 .. $]))))) What does `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` mean here? Is it just the same as `isForwardRange!(Rs[0])`? Why is it written like that?No, not exactly the same. Superficially, this rejects elements that are input ranges but NOT forward ranges. Other than that, I can't tell you the reason why it's that way. -Steve
Aug 07 2018
On Wednesday, 8 August 2018 at 01:33:26 UTC, Steven Schveighoffer wrote:On 8/7/18 9:20 PM, Nicholas Wilson wrote:But forward ranges are a superset of input ranges so `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` <=> `isForwardRange!(Rs[0])`, right?the first overload is ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles) if (isForwardRange!R && Rs.length > 0 && isForwardRange!(Rs[0]) == isInputRange!(Rs[0]) && is(typeof(startsWith!pred(haystack, needles[0]))) && (Rs.length == 1 || is(typeof(countUntil!pred(haystack, needles[1 .. $]))))) What does `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` mean here? Is it just the same as `isForwardRange!(Rs[0])`? Why is it written like that?No, not exactly the same. Superficially, this rejects elements that are input ranges but NOT forward ranges. Other than that, I can't tell you the reason why it's that way. -Steve
Aug 07 2018
On Wednesday, 8 August 2018 at 01:33:26 UTC, Steven Schveighoffer wrote:On 8/7/18 9:20 PM, Nicholas Wilson wrote:Ahhh, Rs[0] is not necessarily a range, consider: `assert(countUntil("hello world", 'r') == 8);` so that means `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` if Rs[0] is a range it must be a forward range. The second overload looks as though it will never be a viable candidate ptrdiff_t countUntil(alias pred = "a == b", R, N)(R haystack, N needle) if (isInputRange!R && is(typeof(binaryFun!pred(haystack.front, needle)) : bool)) { bool pred2(ElementType!R a) { return binaryFun!pred(a, needle); } return countUntil!pred2(haystack); // <--- } because the marked line can't recurse be cause there is only one arg, so it tries to call the first overload, which fails due to Rs.length > 0.the first overload is ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles) if (isForwardRange!R && Rs.length > 0 && isForwardRange!(Rs[0]) == isInputRange!(Rs[0]) && is(typeof(startsWith!pred(haystack, needles[0]))) && (Rs.length == 1 || is(typeof(countUntil!pred(haystack, needles[1 .. $]))))) What does `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` mean here? Is it just the same as `isForwardRange!(Rs[0])`? Why is it written like that?No, not exactly the same. Superficially, this rejects elements that are input ranges but NOT forward ranges. Other than that, I can't tell you the reason why it's that way. -Steve
Aug 07 2018
On 8/7/18 10:28 PM, Nicholas Wilson wrote:On Wednesday, 8 August 2018 at 01:33:26 UTC, Steven Schveighoffer wrote:Ah, but there is a third overload which just takes a haystack and a predicate. What is a bit more confusing to me is why there isn't an ambiguity error when the needle parameter is one element that is not a range. -SteveOn 8/7/18 9:20 PM, Nicholas Wilson wrote:Ahhh, Rs[0] is not necessarily a range, consider: `assert(countUntil("hello world", 'r') == 8);` so that means `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` if Rs[0] is a range it must be a forward range. The second overload looks as though it will never be a viable candidate ptrdiff_t countUntil(alias pred = "a == b", R, N)(R haystack, N needle) if (isInputRange!R && is(typeof(binaryFun!pred(haystack.front, needle)) : bool)) { bool pred2(ElementType!R a) { return binaryFun!pred(a, needle); } return countUntil!pred2(haystack); // <--- } because the marked line can't recurse be cause there is only one arg, so it tries to call the first overload, which fails due to Rs.length > 0.the first overload is ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles) if (isForwardRange!R && Rs.length > 0 && isForwardRange!(Rs[0]) == isInputRange!(Rs[0]) && is(typeof(startsWith!pred(haystack, needles[0]))) && (Rs.length == 1 || is(typeof(countUntil!pred(haystack, needles[1 .. $]))))) What does `isForwardRange!(Rs[0]) == isInputRange!(Rs[0]` mean here? Is it just the same as `isForwardRange!(Rs[0])`? Why is it written like that?No, not exactly the same. Superficially, this rejects elements that are input ranges but NOT forward ranges. Other than that, I can't tell you the reason why it's that way. -Steve
Aug 08 2018