Forward ranges in Phobos v2

Paul Backus snarwin at gmail.com
Thu Nov 4 03:25:12 UTC 2021


On Wednesday, 3 November 2021 at 17:41:10 UTC, Andrei 
Alexandrescu wrote:
> On 2021-11-03 12:18, Paul Backus wrote:
>> On Wednesday, 3 November 2021 at 15:40:41 UTC, Andrei 
>> Alexandrescu wrote:
>>> On 2021-11-02 20:38, Paul Backus wrote:
>>>>
>>>> auto next(R)(ref R r)
>>>>      if (isForwardRangeV2!R && isMutable!R)
>>>> {
>>>>      alias E = ElementType!R;
>>>>      if (r.empty)
>>>>          return none!E();
>>>>      else
>>>>      {
>>>>          auto result = some(r.head);
>>>>          r = r.tail;
>>>>          return result;
>>>>      }
>>>> }
>>>
>>> OK, so the signature of next for all ranges is:
>>>
>>> Option!(ElementType!R) next(Range)(ref Range);
>>>
>>> Is that correct?
>> 
>> More precisely, to use the Phobos convention: 
>> `is(ReturnType!((Range r) => r.next) == 
>> Option!(ElementType!R))`.
>> 
>> So, `next` could be a function, a @property, or a member 
>> variable, and it does not necessarily require an lvalue to 
>> call (just like `front` today).
>
> We've considered this way back when. I'm talking like 2006. It 
> was like this:
>
> T next(Range)(ref Range r, ref bool done);
>
> The main problem is that iterating such a forward range would 
> entail a copy of each element of the range. This is not 
> scalable in general.
>
> This is a showstopper.

If we want to avoid copying, we can have `next` return a `Ref!T` 
in the case where the forward range has lvalue elements:

struct Ref(T)
{
     T* ptr;

     ref inout(T) deref() inout
     {
         return *ptr;
     }
     alias deref this;
}

I've tested some simple uses of this wrapper on run.dlang.io, and 
it seems like DIP 1000 is good enough to make it work in @safe 
code.

If "returns either `T` or `Ref!T`" sounds like a suspect design 
for an API, consider that it is basically the same thing as an 
`auto ref` return value--just with the distinction between ref 
and non-ref brought inside the type system.


More information about the Digitalmars-d mailing list