Wolfgang Thallergcc 15.1.0ada185d1 year agoHistory
565 lines · 13.5 KB · D
RawDownload
/**For testing only.Used with the dummy ranges for testing higher order ranges.*/module std.internal.test.dummyrange; import std.meta;import std.range.primitives;import std.typecons; enum RangeType{    Input,    Forward,    Bidirectional,    Random} enum Length{    Yes,    No} enum ReturnBy{    Reference,    Value} import std.traits : isArray; // Range that's useful for testing other higher order ranges,// can be parametrized with attributes.  It just dumbs down an array of// numbers 1 .. 10.struct DummyRange(ReturnBy _r, Length _l, RangeType _rt, T = uint[])if (isArray!T){    private static immutable uinttestData =        [1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U];    // These enums are so that the template params are visible outside    // this instantiation.    enum r = _r;    enum l = _l;    enum rt = _rt;     static if (is(T == uint[]))    {        T arr = uinttestData;    }    else    {        T arr;    }     alias RetType = ElementType!(T);    alias RetTypeNoAutoDecoding = ElementEncodingType!(T);     void reinit()    {        // Workaround for DMD bug 4378        static if (is(T == uint[]))        {            arr = uinttestData.dup;        }    }     void popFront()    {        arr = arr[1..$];    }     @property bool empty() const    {        return arr.length == 0;    }     static if (r == ReturnBy.Reference)    {        @property ref inout(RetType) front() inout        {            return arr[0];        }    }    else    {        @property RetType front() const        {            return arr[0];        }         @property void front(RetTypeNoAutoDecoding val)        {            arr[0] = val;        }    }     static if (rt >= RangeType.Forward)    {        @property typeof(this) save()        {            return this;        }    }     static if (rt >= RangeType.Bidirectional)    {        void popBack()        {            arr = arr[0..$ - 1];        }         static if (r == ReturnBy.Reference)        {            @property ref inout(RetType) back() inout            {                return arr[$ - 1];            }        }        else        {            @property RetType back() const            {                return arr[$ - 1];            }             @property void back(RetTypeNoAutoDecoding val)            {                arr[$ - 1] = val;            }        }    }     static if (rt >= RangeType.Random)    {        static if (r == ReturnBy.Reference)        {            ref inout(RetType) opIndex(size_t index) inout            {                return arr[index];            }        }        else        {            RetType opIndex(size_t index) const            {                return arr[index];            }             RetType opIndexAssign(RetTypeNoAutoDecoding val, size_t index)            {                return arr[index] = val;            }             RetType opIndexOpAssign(string op)(RetTypeNoAutoDecoding value, size_t index)            {                mixin("return arr[index] " ~ op ~ "= value;");            }             RetType opIndexUnary(string op)(size_t index)            {                mixin("return " ~ op ~ "arr[index];");            }        }         typeof(this) opSlice(size_t lower, size_t upper)        {            auto ret = this;            ret.arr = arr[lower .. upper];            return ret;        }         typeof(this) opSlice()        {            return this;        }    }     static if (l == Length.Yes)    {        @property size_t length() const        {            return arr.length;        }         alias opDollar = length;    }} enum dummyLength = 10; alias AllDummyRanges = AliasSeq!(    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Forward),    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Bidirectional),    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random),    DummyRange!(ReturnBy.Reference, Length.No, RangeType.Forward),    DummyRange!(ReturnBy.Reference, Length.No, RangeType.Bidirectional),    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Input),    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Forward),    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Bidirectional),    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random),    DummyRange!(ReturnBy.Value, Length.No, RangeType.Input),    DummyRange!(ReturnBy.Value, Length.No, RangeType.Forward),    DummyRange!(ReturnBy.Value, Length.No, RangeType.Bidirectional)); template AllDummyRangesType(T){    alias AllDummyRangesType = AliasSeq!(        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Forward, T),        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Bidirectional, T),        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random, T),        DummyRange!(ReturnBy.Reference, Length.No, RangeType.Forward, T),        DummyRange!(ReturnBy.Reference, Length.No, RangeType.Bidirectional, T),        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Input, T),        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Forward, T),        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Bidirectional, T),        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random, T),        DummyRange!(ReturnBy.Value, Length.No, RangeType.Input, T),        DummyRange!(ReturnBy.Value, Length.No, RangeType.Forward, T),        DummyRange!(ReturnBy.Value, Length.No, RangeType.Bidirectional, T)    );} /**Tests whether forward, bidirectional and random access properties arepropagated properly from the base range(s) R to the higher order rangeH.  Useful in combination with DummyRange for testing several higherorder ranges.*/template propagatesRangeType(H, R...){    static if (allSatisfy!(isRandomAccessRange, R))        enum bool propagatesRangeType = isRandomAccessRange!H;    else static if (allSatisfy!(isBidirectionalRange, R))        enum bool propagatesRangeType = isBidirectionalRange!H;    else static if (allSatisfy!(isForwardRange, R))        enum bool propagatesRangeType = isForwardRange!H;    else        enum bool propagatesRangeType = isInputRange!H;} template propagatesLength(H, R...){    static if (allSatisfy!(hasLength, R))        enum bool propagatesLength = hasLength!H;    else        enum bool propagatesLength = !hasLength!H;} /**Reference type input range*/class ReferenceInputRange(T){    import std.array : array;     this(Range)(Range r)    if (isInputRange!Range) {_payload = array(r);}    final @property ref T front() {return _payload.front;}    final void popFront() {_payload.popFront();}    final @property bool empty() {return _payload.empty;}    protected T[] _payload;} /**Infinite input range*/class ReferenceInfiniteInputRange(T){    this(T first = T.init) {_val = first;}    final @property T front() {return _val;}    final void popFront() {++_val;}    enum bool empty = false;    protected T _val;} /**Reference forward range*/class ReferenceForwardRange(T) : ReferenceInputRange!T{    this(Range)(Range r)    if (isInputRange!Range) {super(r);}    final @property auto save(this This)() {return new This( _payload);}} /**Infinite forward range*/class ReferenceInfiniteForwardRange(T) : ReferenceInfiniteInputRange!T{    this(T first = T.init) {super(first);}    final @property ReferenceInfiniteForwardRange save()    {return new ReferenceInfiniteForwardRange!T(_val);}} /**Reference bidirectional range*/class ReferenceBidirectionalRange(T) : ReferenceForwardRange!T{    this(Range)(Range r)    if (isInputRange!Range) {super(r);}    final @property ref T back() {return _payload.back;}    final void popBack() {_payload.popBack();}} @safe unittest{    static assert(isInputRange!(ReferenceInputRange!int));    static assert(isInputRange!(ReferenceInfiniteInputRange!int));     static assert(isForwardRange!(ReferenceForwardRange!int));    static assert(isForwardRange!(ReferenceInfiniteForwardRange!int));     static assert(isBidirectionalRange!(ReferenceBidirectionalRange!int));} private: pure struct Cmp(T)if (is(T == uint)){    static auto iota(size_t low = 1, size_t high = 11)    {        import std.range : iota;        return iota(cast(uint) low, cast(uint) high);    }     static void initialize(ref uint[] arr)    {        import std.array : array;        arr = iota().array;    }     static bool function(uint,uint) cmp = function(uint a, uint b) { return a == b; };     enum dummyValue = 1337U;    enum dummyValueRslt = 1337U * 2;} pure struct Cmp(T)if (is(T == double)){    import std.math.operations : isClose;     static auto iota(size_t low = 1, size_t high = 11)    {        import std.range : iota;        return iota(cast(double) low, cast(double) high, 1.0);    }     static void initialize(ref double[] arr)    {        import std.array : array;        arr = iota().array;    }     alias cmp = isClose!(double,double,double);     enum dummyValue = 1337.0;    enum dummyValueRslt = 1337.0 * 2.0;} struct TestFoo{    int a;     bool opEquals(const ref TestFoo other) const    {        return this.a == other.a;    }     TestFoo opBinary(string op)(TestFoo other)    {        TestFoo ret = this;        mixin("ret.a " ~ op ~ "= other.a;");        return ret;    }     TestFoo opOpAssign(string op)(TestFoo other)    {        mixin("this.a " ~ op ~ "= other.a;");        return this;    }} pure struct Cmp(T)if (is(T == TestFoo)){    static auto iota(size_t low = 1, size_t high = 11)    {        import std.algorithm.iteration : map;        import std.range : iota;        return iota(cast(int) low, cast(int) high).map!(a => TestFoo(a));    }     static void initialize(ref TestFoo[] arr)    {        import std.array : array;        arr = iota().array;    }     static bool function(TestFoo,TestFoo) cmp = function(TestFoo a, TestFoo b)    {        return a.a == b.a;    };     @property static TestFoo dummyValue()    {        return TestFoo(1337);    }     @property static TestFoo dummyValueRslt()    {        return TestFoo(1337 * 2);    }} @system unittest{    import std.algorithm.comparison : equal;    import std.range : iota, retro, repeat;     static void testInputRange(T,Cmp)()    {        T it;        Cmp.initialize(it.arr);        for (size_t numRuns = 0; numRuns < 2; ++numRuns)        {            if (numRuns == 1)            {                static if (is(immutable ElementType!(T) == immutable uint))                {                    it.reinit();                }                 Cmp.initialize(it.arr);            }             assert(equal!(Cmp.cmp)(it, Cmp.iota(1, 11)));             static if (hasLength!T)            {                assert(it.length == 10);            }             assert(!Cmp.cmp(it.front, Cmp.dummyValue));            auto s = it.front;            it.front = Cmp.dummyValue;            assert(Cmp.cmp(it.front, Cmp.dummyValue));            it.front = s;             auto cmp = Cmp.iota(1,11);             size_t jdx = 0;            while (!it.empty && !cmp.empty)            {                static if (hasLength!T)                {                    assert(it.length == 10 - jdx);                }                 assert(Cmp.cmp(it.front, cmp.front));                it.popFront();                cmp.popFront();                 ++jdx;            }             assert(it.empty);            assert(cmp.empty);        }     }     static void testForwardRange(T,Cmp)()    {        T it;        Cmp.initialize(it.arr);        auto s = it.save();        s.popFront();        assert(!Cmp.cmp(s.front, it.front));    }     static void testBidirectionalRange(T,Cmp)()    {        T it;        Cmp.initialize(it.arr);        assert(equal!(Cmp.cmp)(it.retro, Cmp.iota().retro));         auto s = it.back;        assert(!Cmp.cmp(s, Cmp.dummyValue));        it.back = Cmp.dummyValue;        assert( Cmp.cmp(it.back, Cmp.dummyValue));        it.back = s;    }     static void testRandomAccessRange(T,Cmp)()

Lines 1–500 of 565.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t