On Thu, 19 May 2011 18:09:09 -0400, Lars Tandle Kyllingstad
<[email protected]> wrote:
On Thu, 2011-05-19 at 14:24 -0400, Robert Jacques wrote:
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.
It definitely needs to be fleshed out a bit, yes. Right now it's
sufficient for my uses, however, so I just thought I'd gauge the
interest before making any improvements.
I can't really see any elegant way to implement save() for such a range,
though, and without save() it doesn't qualify as a forward range, a
bidirectional range or a random-access range -- at least not as defined
by isForwardRange & co. Is there then any point in implementing the
remaining primitives?
-Lars
Well, any routine which uses byRef internally, like I do, won't
necessarily care about save, but might use indexing/slicing if available.
Besides, what's wrong with something like:
static if(/*...*/)
ByRef save()
{
auto ptr = new Range;
*ptr = (*_range).save;
return byRef(ptr);
}
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos