On Friday, 5 September 2014 at 19:55:50 UTC, Nick Sabalausky
wrote:
One issue with struct-based input ranges: Saving the state of
an input range is not supported (by definition of input range),
and yet, you can trivially and accidentally do so with a simple
assignment or passing into a function. The results may or may
not blow up depending on the exact situation.
And if the input range happens to hit a poorly-implemented
algorithm which *should* be statically requiring a ForwardRange
and using ".save()" to duplicate state, but instead accepts any
range and (accidentally?) saves state by simple struct
copy...which will work fine for most struct-based forward
ranges and therefore could go completely unnoticed...Then once
again, your input range touches it and BOOM.
This *could* be addressed by making the input range a class,
but that seems a bit overkill in many cases.
So I'm tempted to give my struct-bassed input ranges a
@disable'd postblit. That would solve the problem, right? Would
there be any reason NOT to do this?
Ref semantics is one option, yes. Either by class, or by struct.
For example, most IO ranges implemented ref-counted reference
semantics.
IMO, disabling postblit is overkill, as almost anything that does
anything with ranges will pass them by value at one point or
another.
That said, most of the functions that do operate (and modify) a
range either take it by reference, or return the modified copy.
This means you can "boomrang" your range in and then back out. EG:
r = doIt(r);
For example, copy, find etc... do this.
*Ideally*, these functions would do a move-return, and you'd
pass-by-move, so you'd be able to effectively disable postblit,
but still pass by move-value. Unfortunately, we aren't quite
there yet...
My 0.02$