Difference between range `save` and copy constructor

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sat Feb 15 14:45:12 UTC 2020


On Saturday, February 15, 2020 7:34:42 AM MST Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 2/15/20 5:53 AM, uranuz wrote:
> > I am interested in current circumstances when we have new copy
> > constructor feature what is the purpose of having range `save`
> > primitive? For me they look like doing basicaly the same thing. And when
> > looking in some source code of `range` module the most common thing that
> > `save` does is that it use constructor typeof(this) to create a new
> > instance and use `save` on the source range:
> > https://github.com/dlang/phobos/blob/v2.090.1/std/range/package.d
> >
> > So what is conceptual difference between `save` and copy contructor of
> > range?
>
> Nothing. IMO, any time you are doing anything in save other than `return
> this;`, you shouldn't have implemented it.
>
> The original impetus for the save requirement was so that forward ranges
> could have a tangible checkable thing that allows introspection (does
> the range have a save method?).
>
> I'm not entirely sure if disabled postblit was even available at the time.
>
> The correct way to do it would be to treat ranges that can be copied
> (regardless of whether they have a copy constructor) as forward ranges,
> and treat ones that cannot be copied as input ranges.
>
> But it's hard to redo ranges like this with all existing code out there.

Actually, as I understand it, the main reason that save was introduced was
so that classes could be forward ranges. While it would be possible to use
the postblit constructor or copy constructor with structs, that obviously
won't work for classes - hence when save is required.

Personally, I think that we'd be better of simply requiring that forward
rangse be copyable and force classes that want to be forward ranges to be
wrapped by structs, but that would require reworking the range API, and it's
far from a trivial change.

In practice though, classes should almost never be used as forward ranges,
because calling save on them would requires allocating a now object, and
that gets expensive fast. As part of testing dxml, I tested it with forward
ranges that were classes in order to make sure that they were handled
correctly, and their performance was absolutely terrible in comparison to
ranges that were structs or strings.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list