Re: fibers and ranges: what's wrong here?
On Saturday, 13 December 2014 at 12:26:49 UTC, zeljkog wrote: On 13.12.14 13:01, zeljkog wrote: void main() { auto tt = Tree(5, [Tree(7,[Tree(11), Tree(4)]), Tree(10)]); auto tr1 = TreeRange(tt); foreach(v; tr1){ writef("%2d, ", v); } writeln(); for(auto r = TreeRange(tt); !r.empty; r.popFront()) writef("%2d, ", r.front); writeln(); } Sorry, this works: void main() { auto tt = Tree(5, [Tree(7,[Tree(11), Tree(4)]), Tree(10)]); foreach(v; TreeRange(tt)){ writef("%2d, ", v); } writeln(); for(auto r = TreeRange(tt); !r.empty; r.popFront()) writef("%2d, ", r.front); writeln(); } I needed this: struct TreeRange{ this (this){ throw new Exception("TreeRange is noncopyable!"); } ... } Or use class :) Have a look at @disable.
Re: fibers and ranges: what's wrong here?
On 13.12.14 13:01, zeljkog wrote: void main() { auto tt = Tree(5, [Tree(7,[Tree(11), Tree(4)]), Tree(10)]); auto tr1 = TreeRange(tt); foreach(v; tr1){ writef("%2d, ", v); } writeln(); for(auto r = TreeRange(tt); !r.empty; r.popFront()) writef("%2d, ", r.front); writeln(); } Sorry, this works: void main() { auto tt = Tree(5, [Tree(7,[Tree(11), Tree(4)]), Tree(10)]); foreach(v; TreeRange(tt)){ writef("%2d, ", v); } writeln(); for(auto r = TreeRange(tt); !r.empty; r.popFront()) writef("%2d, ", r.front); writeln(); } I needed this: struct TreeRange{ this (this){ throw new Exception("TreeRange is noncopyable!"); } ... } Or use class :)
Re: fibers and ranges: what's wrong here?
When you assigning the worker in TreeRange, you create a delegate that captures the current TreeRange or 'this'. --- worker = new Fiber(&fiberFunc); --- foreach is defined as (http://dlang.org/statement.html#ForeachStatement): --- for (auto __r = range; !__r.empty; __r.popFront()) { auto e = __r.front; ... } --- __r is a copy of your range that still refers to the original worker which in turn refers to your original range. So when you popFront, the worker will advance the original range and if you call front you get the element from __r - unadvanced. That's my best guess.
fibers and ranges: what's wrong here?
import std.stdio, core.thread; struct Tree{ int val; Tree[] tree; } struct TreeRange{ Tree curtree; bool empty; Fiber worker; this(Tree t){ worker = new Fiber(&fiberFunc); curtree = t; popFront(); } void fiberFunc(){ Tree t = curtree; Fiber.yield(); foreach(child; t.tree){ curtree = child; fiberFunc(); } } int front(){ return curtree.val; }; void popFront() { worker.call(); empty = worker.state == Fiber.State.TERM; } } void main() { auto tt = Tree(5, [Tree(7,[Tree(11), Tree(4)]), Tree(10)]); auto tr1 = TreeRange(tt); foreach(v; tr1){ writef("%2d, ", v); } writeln(); for(auto r = TreeRange(tt); !r.empty; r.popFront()) writef("%2d, ", r.front); writeln(); } output: 5, 5, 5, 5, 5, 5, 7, 11, 4, 10, Is it supposed to work?