On 9/29/10 9:52 PDT, dsimcha wrote:
== Quote from Andrei Alexandrescu ([email protected])'s article
On 9/29/10 6:22 PDT, Steven Schveighoffer wrote:
std.algorithm.sort seems to require lvalue access to elements of a
range, presumably so it can call swap on two elements during sorting. So
while a range can technically allow changing of data, it cannot be
passed to swap.
e.g.
struct myrange
{
@property T front() {...}
@property T front(T t) {...}
void popFront() {...}
@property bool empty() {...}
myrange opSlice(size_t low, size_t hi) {...}
@property size_t length() {...}
}
Good news - you should be able to use sort on sealed ranges if they
define moveFront, moveBack, and moveAt. Look e.g. at Zip, it's also
sealed yet you can sort Zips no problem.
This is a relatively new addition.
Andrei
Actually, this gives me the opportunity to bring up a point I've been meaning to
bring up. moveFront() and friends don't even need to be explicitly defined.
The
module level function moveFront() in std.range defines default behavior in the
following cases:
1. If the range's elements don't have elaborate copy construction, moveFront
just
forwards to front.
2. If the range's elements are lvalues, std.algorithm.move(range.front) can
give
the proper behavior.
Of course, these are just defaults and can be overridden by explicitly defining
moveFront() even where they apply. If range.moveFront() is explicitly defined,
the module level function always forwards to it no matter what.
The situation has gradually evolved into this state due to discussions on
Bugzilla
and the Phobos list and the impracticality of forcing explicit moveFront() on
all
ranges. Unless it's still subject to change, it should probably be documented
somewhere.
Yah. I've been with a foot in the air regarding this until Walter
figures out what to do about the rule a.f(b) -> f(a, b).
Andrei