The constructor of the result of std.range.chain copies it's input tuple
and then has to check which of the input-ranges in the first non-empty
one. The member function empty is not guaranteed to be const, filter is
probably the most prominent function that has to be "primed". On the
first call to empty(), filter will try to advance all it's input ranges
to the first element that matches the predicate.
For ranges with full value semantics, using the old input object instead
of the new internal buffer means that the work of priming is done twice.
If any ranges have reference semantics, the references gets advances,
but the value-semantic parts of the range-composition gets reset.
This fixes#10561 and #9877
In an attempt make it so that non-copyable types worked with some of the
functions in std/range/package.d, they were made to use moves instead of
assignment, which broke the code for types which work with assignment
but not moves (which affected the folks at Weka).
The code checked for assignment but not whether move could be used, and
that didn't change when the code was changed to use move, meaning that
the checks didn't match what the code was actually doing.
So, to support both the non-copyable types and the ones that can be
assigned to but not moved to, this changes the code to use
core.lifetime.forward which will move the argument if it can and assign
otherwise. So ,the code that worked previously should work again, and
the newer functionality of being able to use non-copyable types with
this code should continue to work.
Discussion here: https://github.com/dlang/phobos/pull/8721
Since the compiler is treating the auto-generated copy-constructor for
OnlyResult as private (thus rendering it useless outside of
std.range.package), this commit adds an explicit one and makes it
public. Once the dmd bug has been fixed, the explicit copy constructor
should be removed.
This allows the ranges returned by only to be used in algorithms that
require assignable elements, such as reverse, sort, and transposed.
Fixes bugzilla issue 24382.
Previously, roundRobin would always attempt to fetch its first element
from the first range passed to it, even if that range was empty.
Fixes bugzilla issue 24384.
The requirement for opSlice on an infinite range to return the result of
take or takeExactly was removed in commit c828a08b64, which was included
in Phobos 2.067.0, released in March 2015. However, the documentation
was never updated to take this change into account.
This change updates the documentation and adds a unit test for the "new"
behavior.
Fixes bugzilla issue 24348.
This replaces the bespoke type comparison that was previously used. All
conversions allowed by the previous version are still allowed after this
change.
Rebindable2 is a simplified version of std.typecons.Rebindable that clears up every special case: classes, arrays and structs now have the same struct.
Whichever type you instantiate `Rebindable2` with, you always get the same type out by calling `value.get` on the resulting container.
Also use this type to simplify the parts of Phobos we previously used `Rebindable` for.
`only` is a range that may be *mutable*, but not *assignable*. `chain` falls over here because it assumes it can make a struct with ranges, and reassign them with new values, which isn't necessarily the case even if the ranges are not `const`.
Solved by creating a separate tuple of `Rebindable` ranges for this case.
* Optimised std.range.chain
Chain now remembers which subrange has the first and the last elements,
eliminating needless work on each usage.
* Style fix.
* No longer needless `.empty` calls in the constructor.
* Improvements based on Razvans observations.