Ok, so to sum it up:
rfind should return the same type as provided.
Its direction (popFront()) should be the same.
auto rfing( Range, E )( Range r, E e ) if (blablabla) {
auto original = r.save; //This is to remember the end of the
orginal range.
r.reverse; //Reverse it. The range keeps track of its direction.
auto found = find( r, e ); //Now front() shall give us e, and
popFront() moves toward original's beginning.
auto res = Range.merge( found, original ); //Take the start of
found, which is on e and take the end of original, which has not
moved.
//Where does popFront() goes now? Depends: either expect merge
to decide for us or make sure its just dumb.
//If it is dumb, then the assumption we make about the
direction of the returned range is that popFront() goes in the
not reversed direction (reversed returns false). Therefore, we
have start on e and end where we want it, we only need to move in
the proper direction, which is the one of the original.
if( original.reversed ) { res.reverse; }
return res;
}
struct DListRange {
Node * _start;
Node * _end; //Initialized to the lists'end.
bool _reversed = false;
bool empty() { return _start is null || _end is null; } //The
user has seen it all.
void popBack() {
if( _reversed ) {
_start = _start.next;
} else {
_end = _end.previous;
}
}
...
@property bool reversed() { return _reversed; }
void reverse() { _reversed = !_reversed; }
//Dumb version.
static typeof( this ) merge( typeof( this ) sr, typeof( this )
er ) {
return typeof( this )( sr._start, er._end );
}
}