On Saturday, 3 December 2016 at 16:37:21 UTC, Jerry wrote:
On Saturday, 3 December 2016 at 11:52:00 UTC, rumbu wrote:
import std.range.primitives: isInputRange;

void test(R)(ref R range) if (isInputRange!R)
{
auto c = r.front; //Error: no property 'front' for type 'string'
}

[...]

import std.range.primitives: isInputRange, ElementType;
import std.traits: isSomeChar;

void foo(C)(const(C)[] array) if (isSomeChar!C)
{
    //this will be never called 
}

void foo(R)(ref R range) if (isInputRange!R && isSomeChar!(ElementType!R))
{
    //this will be always called
//any call to range.front, range.empty and so on will result in error
}

foo(somestring)

I expect foo!string to be called instead of foo!Range, because in my context isInputRange!string should return false. Instead, my context is hijacked by the definitions spread along std.range.primitives module.

The workaround I found is to define the second overload like this:

void foo(R)(ref R range) if (isInputRange!R && !isSomeString!R && isSomeChar!(ElementType!R))

Is that the exact code? isInputRange checks to see if the type has "front" defined.


https://github.com/dlang/phobos/blob/v2.072.0/std/range/primitives.d#L162

Also "string" is just an alias of an array, "immutable(char)[]". So an array should have "front" defined. Can you post more code?

No, an array should not have "front" defined according to D language specification. "front" for arrays is defined in std.range.primitives. That's the problem, I cannot have two specialized functions (one taking arrays and one taking ranges), because std.range.primitives hijacks any char array and transforms it in a range). front, empty, popFront must not be defined for arrays in the same module as isInputRange.

Exact code is irrelevant, but you're welcome:

string constructor: https://github.com/rumbu13/numerics/blob/master/src/numerics/fixed.d#L978

range constructor
https://github.com/rumbu13/numerics/blob/master/src/numerics/fixed.d#L1104


Reply via email to