Range Redesign: Copy Semantics

Alexandru Ermicioi alexandru.ermicioi at gmail.com
Sun Jan 21 13:22:26 UTC 2024


On Sunday, 21 January 2024 at 05:00:31 UTC, Jonathan M Davis 
wrote:
>
> 1. The range is a value type, so copying it results in two 
> completely indepedent copies. Iterating through one has no 
> effect on the other.
>
> 2. The range is a reference type, so copying it results in two 
> completely dependent copies. They both share all of their 
> state, so iterating through one iterates through the other, and 
> they both always have the same state.
>
> 3. The range is a pseudo-reference type, and it has value 
> semantics for its iteration state but reference semantics for 
> some portion of the rest of its state. This means that if you 
> iterate through a copy of the range, it has no effect on the 
> original, so the range is a value type in that respect, but the 
> rest of its state may or may not be copied by value (often - 
> though not always - this means that the iteration state is 
> directly within the range type, but the elements themselves are 
> referred to via pointer, so mutating the actual elements would 
> affect all copies of that range, but each range can be iterated 
> independently). Dynamic arrays are the most common example of 
> this sort of range.
>
> 4. The range is a pseudo-reference type, but it does not have 
> value semantics with regards to its iteration state. So, when 
> copying the range, some portion of its state is copied by 
> value, but you don't end up with indendepent copies - and in 
> fact, you don't get dependent copies either, since some of the 
> state is copied by value. A common example of this sort of 
> range which would be one which contains most of its state via a 
> pointer or reference but which caches its front as a member 
> variable within the struct. The result of this is that once 
> you've mutated a copy of the range, you can no longer use the 
> original, because mutating the copy only partially mutates the 
> state of the original, leaving it in an inconsistent / invalid 
> state.

For all these cases there is `.save` method which seems to be 
ignored in most of the code and compiler, when it should not be. 
It explicitly defines that range is copied irrelevant of the type 
of range you've mntioned. Since `.save` is defined on forward 
range, this means that pure input range must never be copyable, 
i.e. copy and post constructors must be disabled.

If this rule is followed, issues with copying would dissappear.

Even more drastic measure would be to disable copying on all 
types of ranges, and allow copying only through `.save` method, 
i.e. do explicit copying when it is intended to.

Best regards,
Alexandru.


More information about the Digitalmars-d mailing list