Plan for InputRange?

Dukc ajieskola at gmail.com
Tue Sep 28 15:07:59 UTC 2021


Yesterday, I came across [this 
bug](https://issues.dlang.org/show_bug.cgi?id=19544) that is 
caused by design of std.range.interfaces. The problem is that 
`InputRange` has an abstract member function `moveFront()`.

Why is this a problem, you could ask - if I'm able to get a 
`front` of a range by copy, surely I can get it when I don't even 
require a copy? This is all good and true with most types. But 
`moveFront()` from `std.range.primitives`, just like 
`core.lifetime.move`, will require the element to be a LValue. 
`moveFront()` is smart enough to use copy with RValues if there 
are no copy constructors or postblits, but with them a reference 
access to `front` is required. It follows that the dynamic range 
interfaces will not work at for ranges with RValue elements with 
copy constructors:

```D
import std;

struct HasCC
{   inout this(ref inout typeof(this)){}
}

void main()
{   // will not compile
     auto dynamicRange = repeat(HasCC.init).inputRangeObject;
}
```

What should we do about this? One could argue that `moveFront` 
belongs to `InputAssignable` as opposed to `InputRange`, but I 
think it would be too much breakage to change it like that 
anymore.

Another option might be to say that `moveFront` should behave 
just like `front` when `front` is a RValue. Either just in 
`std.range.interfaces` or also in `std.range.primitives`. Perhaps 
even `move` could behave like that? But maybe there is some 
reason I'm missing why they do not act like that already?

We could also leave it just as is, documenting the limitation in 
`std.range.interfaces`. It would not necessarily mean a permanent 
defeat, because of possibility to fix it in Phobos V2 (Timeline 
estimates on that, anyone?).


More information about the Digitalmars-d mailing list