Thread overview | ||||||
---|---|---|---|---|---|---|
|
December 13, 2014 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? |
December 13, 2014 Re: fibers and ranges: what's wrong here? | ||||
---|---|---|---|---|
| ||||
Posted in reply to zeljkog | 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. |
December 13, 2014 Re: fibers and ranges: what's wrong here? | ||||
---|---|---|---|---|
| ||||
Posted in reply to zeljkog | 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 :)
|
December 13, 2014 Re: fibers and ranges: what's wrong here? | ||||
---|---|---|---|---|
| ||||
Posted in reply to zeljkog | 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.
|
Copyright © 1999-2021 by the D Language Foundation