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