Bug 4305 – Take, Chain on top of ranges w/o moveFront()
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2010-06-13T11:51:00Z
Last change time
2010-06-24T20:07:48Z
Assigned to
andrei
Creator
dsimcha
Comments
Comment #0 by dsimcha — 2010-06-13T11:51:14Z
import std.range;
struct CountRange {
uint num;
uint front() {
return num;
}
void popFront() {
num++;
}
bool empty() @property {
return num == uint.max;
}
typeof(this) save() @property {
return this;
}
}
void main() {
CountRange cr;
auto t = take(cr, 100);
}
This produces a compile time error:
d:\dmd2\windows\bin\..\..\src\phobos\std\range.d(1289): Error: template std.range.moveFront(R) if (is(typeof(&r.front()) == ElementType!(R)*)) does not match any function template declaration
d:\dmd2\windows\bin\..\..\src\phobos\std\range.d(1289): Error: template std.range.moveFront(R) if (is(typeof(&r.front()) == ElementType!(R)*)) cannot deduce template function from argument types !()(CountRange)
Similar results occur when the main block looks like this instead:
void main() {
CountRange cr1;
CountRange cr2;
auto c = chain(cr1, cr2);
}
I guess the correct fix is to just stick moveFront() in a static if block and disable it for ranges that don't have lvalue elements. However, I'd like to get some comments in case I'm misunderstanding the issue here.
Comment #1 by andrei — 2010-06-13T20:54:52Z
The intent is to allow manipulation of ranges that contain types arbitrarily expensive to copy. The current design requires either front() to yield a ref, or the range to define moveFront().
I think a better design is to define the module-level std.range.moveFront() to issue a simple copy when the type being copied does not define this(this). I'll do so soon. Thanks!