std.algorithm.filter returns a forward range. This could become a bidirectional range if its input range is also a bidirectional range. That way, filter can fed to more algorithms. Obviously, it cannot in general become a random-access range or define a length... Too bad. Possible code follow: struct Filter(alias pred, Range) if (isInputRange!(Range)) { Range _input; this(Range r) { _input = r; while (!_input.empty && !pred(_input.front)) _input.popFront; static if (isBidirectionalRange!Range) while (!_input.empty && !pred(_input.back)) _input.popBack; } ref Filter opSlice() { return this; } bool empty() { return _input.empty; } void popFront() { do { _input.popFront; } while (!_input.empty && !pred(_input.front)); } ElementType!(Range) front() { return _input.front;} static if (isBidirectionalRange!Range) { void popBack() { do { _input.popBack; } while (!_input.empty && !pred(_input.back)); } ElementType!(Range) back() { return _input.back;} } } unittest { auto r = [0,1,2,3,4]; auto f = filter!"a%2==0"(r); assert(equal(retro(f), [4,2,0][])); // f is a bidirectional range }
Fixed SVN.
Got unfixed at some point: ``` import std.algorithm : filter; import std.range : only; void main() { int[] a = [2, 3]; assert(only(2, 3).back == 3); assert(a.filter!"a == 2".back == 2); } ``` => onlineapp.d(7): Error: no property `back` for `filter(a)` of type `std.algorithm.iteration.FilterResult!(unaryFun, int[])` Apparently there's `filterBidirectional`. I am violently opposed to that function and all it represents. `filter` should support bidirectional iteration by default, with maybe `filterUnidirectional` or `forceForwardRange` if you want to *disable* it. Since when do we sacrifice functionality for speed by default?
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/9883 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB