Re: fibers and ranges: what's wrong here?

2014-12-13 Thread Tobias Pankrath via Digitalmars-d-learn

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?

2014-12-13 Thread zeljkog via Digitalmars-d-learn

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?

2014-12-13 Thread Tobias Pankrath via Digitalmars-d-learn
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?

2014-12-13 Thread zeljkog via Digitalmars-d-learn

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?