Another task

Simen kjaeraas simen.kjaras at gmail.com
Wed Jan 19 18:31:37 PST 2011


bearophile <bearophileHUGS at lycos.com> wrote:

> D AAs have byKey and byValue that return a lazy iterator. So if we add a  
> "byItem" or "byPair" or "byKeyValue" you are able to read pairs lazily  
> :-)

byKey is essentially an opApply. You have to wrap it in a fiber to make it
work with the range interface:


import std.algorithm;
import std.range;
import std.stdio;
import std.typecons;
import core.thread;

class opApplyRange( T ) {
     alias int delegate( int delegate( ref T ) ) dgType;
     Fiber fib;
     T value;
     dgType dg;

     void fibFun( ) {
         dg( ( ref T t ){ value = t; Fiber.yield(); return 0; } );
     }

     this( dgType _dg ) {
         dg = _dg;
         fib = new Fiber( &fibFun );
         popFront( );
     }

     @property T front( ) {
         return value;
     }

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

     void popFront( ) {
         if ( !empty ) {
             fib.call( );
         }
     }
}

opApplyRange!T toRange( T )( int delegate( int delegate( ref T ) ) dg ) {
     return new opApplyRange!T( dg );
}

void main( ) {
     auto aa = [1:"a", 2:"b", 3:"c"];

     auto o = map!((a){return tuple(a*10,aa[a]~aa[a]);})( toRange(  
aa.byKey() ) );
     writeln(typeof(o).stringof);
     writeln(array(o));
}

Ugly, but it works.

-- 
Simen


More information about the Digitalmars-d mailing list