Combine Coroutines and Input Ranges for Dead-Simple D Iteration

Robert Clipsham robert at octarineparrot.com
Tue May 1 05:26:48 PDT 2012


On 01/05/2012 09:27, Nick Sabalausky wrote:
> A little write-up I just did on something I thought was pretty cool:
>
> Combine Coroutines and Input Ranges for Dead-Simple D Iteration
> https://www.semitwist.com/articles/article/view/combine-coroutines-and-input-ranges-for-dead-simple-d-iteration
>
>

This got me thinking, so I tried to do something a little similar 
myself, the result is below.

If you only have one type to iterate over, you can make the user code 
look even cleaner! I can't help but feel it can become even cleaner too.

(Scroll to the "User code" comment to miss out the implementation).

The code:
----
import core.thread;

class VFiber(Elem) : Fiber
{
     Elem elem;
     this(void delegate() dg)
     {
         super(dg);
     }
}

auto visitor(T, Elem = T.visitType)(T t)
{
     static struct Visitor
     {
         T t;
         VFiber!Elem f;
         @disable this();
         @disable this(this);
         this(T t)
         {
             this.t = t;
             f = new VFiber!Elem(&t.visit);
             f.call();
         }

         Elem front() @property
         {
             return f.elem;
         }

         void popFront()
         {
             f.call();
         }

         bool empty() @property
         {
             return f.state == Fiber.State.TERM;
         }
     }
     return Visitor(t);
}

void yield(Elem)(Elem el)
{
     auto f = cast(VFiber!Elem)cast(void*)Fiber.getThis();
     if (f is null) throw new FiberException("Cannot yield a value from 
outside the visit() method");
     f.elem = el;
     Fiber.yield();
}

// User code starts here
struct Iterable
{
     string[] strs = ["hello", "world"];
     alias string visitType;

     void visit()
     {
         foreach(str; strs)
             yield(str);
     }
}

void main()
{
     import std.stdio;
     Iterable i;
     foreach(el; i.visitor)
     {
         writefln("%s", el);
     }
}
----

-- 
Robert
http://octarineparrot.com/


More information about the Digitalmars-d-announce mailing list