On Friday, 1 September 2017 at 00:09:16 UTC, H. S. Teoh wrote:
Consider the case where .front returns a subrange. As you
state above, copying this subrange does not have defined
behaviour. One reason is the difference in semantics between
reference types and value types: the assignment operator `=`
means different things for each kind of type. `x=y;` for a
value type makes a new copy of the value in x, but `x=y;` for a
reference type only copies the reference, not the value.
Absolutely, in particular, InputRange shouldn't be assumed
copyable.
joiner saves whatever was passed to it, in this particular case,
result of
files.map!(a => a.byLine) which is range itself and is evaluated
lazily. This makes every call of .front() to re-evaluate (a =>
a.byLine) and to call the constructor again, skipping first line
every time.
The partial solution is simple, force joiner to make immediate
evaluation instead of lazy one:
return joiner(array(files.map!(a => a.byLine)));
here, the array is saved in joiner and no lazy constructor call
is performed. However, in general I have a feeling that something
is wrong here with design. Copying of InputRanges should be
disabled possibly, or lazy range evaluation should be under
control. Can't say what is wrong exactly, but something
definitely is.