bearophile <bearophileh...@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

Reply via email to