[Issue 14478] New: isInputRange failed to recognize some ranges
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Tue Apr 21 11:35:21 PDT 2015
https://issues.dlang.org/show_bug.cgi?id=14478
Issue ID: 14478
Summary: isInputRange failed to recognize some ranges
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: major
Priority: P1
Component: Phobos
Assignee: nobody at puremagic.com
Reporter: ketmar at ketmar.no-ip.org
assume we have this code:
import std.range;
import std.stdio;
struct S {
int n;
@disable this (this);
}
void main () {
S[2] s0, s1;
foreach (ref el; chain(s0[], s1[])) writeln(el.n);
}
if we try to compile it, we got error:
(12): Error: template std.range.chain cannot deduce function from argument
types
yet if we will remove `@disable this (this);`, everything is working fine.
the bug is in `isInputRange` template:
template isInputRange(R)
{
enum bool isInputRange = is(typeof(
(inout int = 0)
{
R r = R.init; // can define a range object
if (r.empty) {} // can test for empty
r.popFront(); // can invoke popFront()
auto h = r.front; // can get the front of the range (HERE!)
}));
}
line `auto h = r.front;` causes the bug. althru `front` returning ref here, we
can't declare ref variables, so `h` looses `ref` and thus requires copying. yet
we explicitly disabled copying for our struct, so `isInputRange` is failing.
here is the proposed fix:
template isInputRange(R)
{
enum bool isInputRange = is(typeof(
(inout int = 0)
{
R r = R.init; // can define a range object
if (r.empty) {} // can test for empty
r.popFront(); // can invoke popFront()
static void testfront(T) (auto ref T n) {} testfront(r.front);
}));
}
here we using nested function with `auto ref` to not loose `ref` from `front`.
it would be good to check if some other templates requires such fix too.
p.s. with the proposed fix sample code works like a charm.
--
More information about the Digitalmars-d-bugs
mailing list