Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 1702

Show
Ignore:
Timestamp:
07/01/10 02:24:58 (14 years ago)
Author:
dsimcha
Message:

Bug 3872: std.algorithm.filter could become bidirectional if its input range is bidir

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/docsrc/changelog.dd

    r1698 r1702  
    1616    $(LI $(BUGZILLA 978): std.utf's toUTF* functions accept some invalid and reject some valid UTF) 
    1717    $(LI $(BUGZILLA 996): Error in doc on implicit conversion between pointer and array) 
    1818    $(LI $(BUGZILLA 2275): std.utf.toUTF16z() should return const(wchar)*) 
    1919    $(LI $(BUGZILLA 2872): Length, opIndex for Map) 
    2020    $(LI $(BUGZILLA 3202): std.math.pow cause dead loop) 
    2121    $(LI $(BUGZILLA 3355): std.string.cmp works incorrectly for mixed-type and different-length strings) 
    2222    $(LI $(BUGZILLA 3386): to!bool(string) is not implemented) 
    2323    $(LI $(BUGZILLA 3436): std.functional.compose with only one function) 
    2424    $(LI $(BUGZILLA 3439): std.range.Sequence.opIndex not consistent after calling popFront().) 
    2525    $(LI $(BUGZILLA 3447): std.file uses unconventional file permissions) 
     26    $(LI $(BUGZILLA 3872): std.algorithm.filter could become bidirectional if its input range is bidir) 
    2627    $(LI $(BUGZILLA 3874): std.range.stride assumes a bidirectional input range) 
    2728    $(LI $(BUGZILLA 3937): os.path.dirname fails on absolute path) 
    2829    $(LI $(BUGZILLA 3961): Error with to!(somestruct)) 
    2930    $(LI $(BUGZILLA 4109): (reopened) writeln doesn't work with empty static array) 
    3031    $(LI $(BUGZILLA 4171): std.random.uniform does not work for a range of characters) 
    3132    $(LI $(BUGZILLA 4260): windows & basename) 
    3233    $(LI $(BUGZILLA 4305): Take, Chain on top of ranges w/o moveFront() ) 
    3334    $(LI $(BUGZILLA 4327): std.container.Array.Range.~this() tries to call free(T[])) 
    3435    $(LI $(BUGZILLA 4362): std.range.repeat and cycle do not have a .save() method) 
    3536    $(LI $(BUGZILLA 4363): std.algorithm.Until is not a forward range) 
  • trunk/phobos/std/algorithm.d

    r1698 r1702  
    558558} 
    559559 
    560560struct Filter(alias pred, Range) if (isInputRange!(Range)) 
    561561{ 
    562562    Range _input; 
    563563 
    564564    this(Range r) 
    565565    { 
    566566        _input = r; 
    567567        while (!_input.empty && !pred(_input.front)) _input.popFront; 
     568        static if (isBidirectionalRange!Range) { 
     569            while (!_input.empty && !pred(_input.back)) _input.popBack; 
     570        } 
     571 
    568572    } 
    569573 
    570574    ref Filter opSlice() 
    571575    { 
    572576        return this; 
    573577    } 
    574578 
    575579    static if(isInfinite!Range) { 
    576580        enum bool empty = false; 
    577581    } else { 
     
    584588        { 
    585589            _input.popFront; 
    586590        } while (!_input.empty && !pred(_input.front)); 
    587591    } 
    588592 
    589593    ElementType!(Range) front() 
    590594    { 
    591595        return _input.front; 
    592596    } 
    593597 
     598    static if (isBidirectionalRange!Range) { 
     599        void popBack() 
     600        { 
     601            do 
     602            { 
     603                _input.popBack; 
     604            } while (!_input.empty && !pred(_input.back)); 
     605        } 
     606 
     607        ElementType!(Range) back() { return _input.back;} 
     608    } 
     609 
     610 
    594611    static if(isForwardRange!Range) 
    595612    { 
    596613        @property typeof(this) save() 
    597614        { 
    598615            return typeof(this)(_input.save); 
    599616        } 
    600617    } 
    601618} 
    602619 
    603620unittest 
     
    609626 
    610627    a = [ 1, 22, 3, 42, 5 ]; 
    611628    auto under10 = filter!("a < 10")(a); 
    612629    assert(equal(under10, [1, 3, 5][])); 
    613630    static assert(isForwardRange!(typeof(under10))); 
    614631 
    615632    auto infinite = filter!"a > 2"(repeat(3)); 
    616633    static assert(isInfinite!(typeof(infinite))); 
    617634    static assert(isForwardRange!(typeof(infinite))); 
    618635 
     636    auto nums = [0,1,2,3,4]; 
     637    auto forward = filter!"a % 2 == 0"(nums); 
     638    assert(equal(retro(forward), [4,2,0][])); // f is a bidirectional range 
     639 
     640 
    619641    foreach(DummyType; AllDummyRanges) { 
    620642        DummyType d; 
    621643        auto f = filter!"a & 1"(d); 
    622644        assert(equal(f, [1,3,5,7,9])); 
     645 
     646        static if(isForwardRange!DummyType) { 
     647            static assert(isForwardRange!(typeof(f))); 
     648        } 
     649 
     650        static if(isBidirectionalRange!DummyType) { 
     651            static assert(isBidirectionalRange!(typeof(f))); 
     652            assert(equal(retro(f), [9,7,5,3,1])); 
     653        } 
    623654    } 
    624655} 
    625656 
    626657// move 
    627658/** 
    628659Moves $(D source) into $(D target) via a destructive 
    629660copy. Specifically: $(UL $(LI If $(D hasAliasing!T) is true (see 
    630661$(XREF traits, hasAliasing)), then the representation of $(D source) 
    631662is bitwise copied into $(D target) and then $(D source = T.init) is 
    632663evaluated.)  $(LI Otherwise, $(D target = source) is evaluated.)) See