[phobos] Would you find a ByRef range useful?

Robert Jacques sandford at jhu.edu
Thu May 19 15:28:05 PDT 2011


On Thu, 19 May 2011 18:09:09 -0400, Lars Tandle Kyllingstad  
<lars at kyllingen.net> 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
>> <lars at kyllingen.net> 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);
}


More information about the phobos mailing list