Range Redesign: Copy Semantics

Steven Schveighoffer schveiguy at gmail.com
Sun Jan 21 19:24:20 UTC 2024


On Sunday, 21 January 2024 at 05:00:31 UTC, Jonathan M Davis 
wrote:
> Ultimately, I'm inclined to argue that we should give basic 
> input ranges a new API - not just because it would allow them 
> to use reference counting, but also because the current input 
> range API tends to force basic input ranges to cache the value 
> of front (which if anything, encourages basic input ranges to 
> be pseudo-reference types and could result in an extra layer of 
> indirection in some cases if they're forced to be reference 
> types). It would be annoying in some cases to require that 
> different functions be used for basic input ranges and forward 
> ranges (though overloading could obviously be used to avoid 
> needing different names), but it's already often the case that 
> code isn't really designed to work with both, and overloading 
> on the category of range being used is already fairly common, 
> since different range capabilities allow for different 
> implementations. So, given that it would prevent whole classes 
> of copying bugs as well as potentially remove the requirement 
> to cache front for basic input ranges, I think that a separate 
> API for basic input ranges is warranted. What I would propose 
> for that would be a single function
>
>     auto next();
>
> where next returns a nullable type where the value returned is 
> the next element in the range, with a null value being returned 
> if the range is empty. The return type would then need to 
> emulate a pointer - specifically, when casting it to bool, it 
> would be true if it's non-null and false if it's null, and 
> dereferencing it would give you the actual value if it's 
> non-null (with it being undefined behavior if you dereference 
> null). So, a basic input range of ints might define next as
>
>     int* next();

While I agree with most of what you wrote, there is one very big 
problem with this. Namely, current input ranges are suddenly 
considered to be forward ranges. Changing the semantics of what 
it means to only define `front`, `popFront`, and `empty` changes 
the semantics of existing code.

And this is not something you can solve with some kind of 
versioning. The only way I can think of is to alter the name of 
one or more primitives to prevent accidental usage.

-Steve


More information about the Digitalmars-d mailing list