On Thu, 19 May 2011 10:14:58 -0400, Lars Tandle Kyllingstad <[email protected]> wrote:
Below is a simple implementation of a range which iterates another
(input) range by reference, for those cases when using an
InputRangeObject is overkill.  I've used it quite a bit and I find it
immensely useful.

It is sort of the opposite of save().  Where save() ensures that you are
only consuming a copy of the original range, byRef() ensures that you
are consuming the original range.

Would this be useful for Phobos?  I guess it is a tad unsafe, since it
stores the address of the range, which may well be stored on the stack.


/** Range that iterates another range by reference. */
auto byRef(Range)(ref Range range) if (isInputRange!Range)
{
    static struct ByRef
    {
        private Range* _range;

        static if (isInfinite!Range)
        {
            enum empty = false;
        }
        else
        {
            @property bool empty() { return (*_range).empty; }
        }

        @property ElementType!Range front()
        {
            return (*_range).front;
        }

        void popFront()
        {
            (*_range).popFront();
        }
    }

    return ByRef(&range);
}

unittest
{
    auto a = [1, 2, 3, 4];
    auto b = take(byRef(a), 2);

    assert (equal(b, [1, 2]));
    assert (equal(a, [3, 4]));
}

I've wrote version of this for my Json library, so yes, I think it's useful. I'd recommend a few things. First, if the Range is a reference type, then you don't need the extra level of indirection. Second, you may wish to include the rest of the range primitives, plus length/slicing, if the base type supports them.
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

Reply via email to