countUntil's constraints

Steven Schveighoffer schveiguy at gmail.com
Wed Aug 8 14:23:29 UTC 2018


On 8/7/18 10:28 PM, Nicholas Wilson wrote:
> On Wednesday, 8 August 2018 at 01:33:26 UTC, Steven Schveighoffer wrote:
>> 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
> 
> 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.
> 

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.

-Steve


More information about the Digitalmars-d-learn mailing list