Lazy Literal Range: Stooid late-nite idea?

Lutger Blijdestijn lutger.blijdestijn at gmail.com
Sun Oct 9 04:43:52 PDT 2011


Jacob Carlborg wrote:

> On 2011-10-09 08:33, Vladimir Panteleev wrote:
>> On Sun, 09 Oct 2011 06:06:21 +0300, Nick Sabalausky <a at a.a> wrote:
>>
>>> Great, right? But what about this?:
>>>
>>> auto x = [runtimeExpressionA, runtimeExprB, runtimeExprC,
>>> etc].find(blah);
>>
>> With the anonymous delegate literal syntax suggested by Andrei a while
>> ago, you should be able to write this as:
>>
>> auto x = [() => runtimeExpressionA, () => runtimeExprB, () =>
>> runtimeExprC, () => etc].find(blah);
>>
>> I guess it looks quirky with an empty parameter list, but it's shorter
>> than writing {return runtimeExpressionA;}, {return runtimeExpressionB;}
>> etc.
>>
> 
> Or wrap it in a function taking a list of lazy parameters:
> http://www.d-programming-language.org/function.html#parameters
> 
> auto x = lazyRange(runtimeExpressionA, runtimeExprB, runtimeExprC);
> 

typesafe variadics with delegates also allow for this syntax, though not 
with type inference. I hacked this together:

struct LazyRange(T)
{
    import std.array;

    this(T delegate()[] input...)
    {
        _input = input;
    }

    @property
    bool empty() const
    {
        return std.array.empty(_input);
    }

    void popFront()
    {
        std.array.popFront(_input);
        _isCached = false;
    }

    @property
    T front()
    {
        if (_isCached)
            return _front;
        _front = std.array.front(_input)();
        _isCached = true;
        return _front;
    }

private:
    T _front;
    bool _isCached = false;
    T delegate()[] _input;
}

unittest
{
    import std.algorithm;
    auto stuff = LazyRange!string("foo",
                                  "foo" ~ "bar",
                                  { assert(false); return "bat"; }(),
                                  "meow");
    assert(find(stuff,"foobar").front == "foobar");
}


More information about the Digitalmars-d mailing list