diff --git a/std/range.d b/std/range.d index 88db6c9aa..0a5029a24 100644 --- a/std/range.d +++ b/std/range.d @@ -4277,20 +4277,19 @@ struct Cycle(R) this(R input, size_t index = 0) { _original = input; - _index = index; + _index = index % _original.length; } @property auto ref front() { - return _original[_index % _original.length]; + return _original[_index]; } - static if (is(typeof((cast(const R)_original)[0])) && - is(typeof((cast(const R)_original).length))) + static if (is(typeof((cast(const R)_original)[_index]))) { @property auto ref front() const { - return _original[_index % _original.length]; + return _original[_index]; } } @@ -4298,7 +4297,7 @@ struct Cycle(R) { @property auto front(ElementType!R val) { - _original[_index % _original.length] = val; + _original[_index] = val; } } @@ -4307,6 +4306,8 @@ struct Cycle(R) void popFront() { ++_index; + if (_index >= _original.length) + _index = 0; } auto ref opIndex(size_t n) @@ -4314,7 +4315,7 @@ struct Cycle(R) return _original[(n + _index) % _original.length]; } - static if (is(typeof((cast(const R)_original)[0])) && + static if (is(typeof((cast(const R)_original)[_index])) && is(typeof((cast(const R)_original).length))) { auto ref opIndex(size_t n) const @@ -4393,7 +4394,8 @@ struct Cycle(R) void popFront() { _current.popFront(); - if (_current.empty) _current = _original; + if (_current.empty) + _current = _original.save; } @property Cycle save() @@ -4424,12 +4426,12 @@ nothrow: this(ref R input, size_t index = 0) { _ptr = input.ptr; - _index = index; + _index = index % R.length; } @property ref inout(ElementType) front() inout { - return _ptr[_index % R.length]; + return _ptr[_index]; } enum bool empty = false; @@ -4437,6 +4439,8 @@ nothrow: void popFront() { ++_index; + if (_index >= R.length) + _index = 0; } ref inout(ElementType) opIndex(size_t n) inout @@ -4589,6 +4593,43 @@ unittest // For infinite ranges assert (c == i); } +unittest +{ + int[5] arr = [0, 1, 2, 3, 4]; + auto cleS = cycle(arr); //Static + auto cleD = cycle(arr[]); //Dynamic + assert(equal(cleS[5 .. 10], arr[])); + assert(equal(cleD[5 .. 10], arr[])); + + //n is a multiple of 5 worth about 3/4 of size_t.max + auto n = size_t.max/4 + size_t.max/2; + n -= n % 5; + + //Test index overflow + foreach (_ ; 0 .. 10) + { + cleS = cleS[n .. $]; + cleD = cleD[n .. $]; + assert(equal(cleS[5 .. 10], arr[])); + assert(equal(cleD[5 .. 10], arr[])); + } +} + +unittest +{ + int[1] arr = [0]; + auto cleS = cycle(arr); + cleS = cleS[10 .. $]; + assert(equal(cleS[5 .. 10], 0.repeat(5))); + assert(cleS.front == 0); +} + +unittest //10845 +{ + auto a = inputRangeObject(iota(3).filter!"true"); + assert(equal(cycle(a).take(10), [0, 1, 2, 0, 1, 2, 0, 1, 2, 0])); +} + private template lengthType(R) { alias typeof((inout int = 0){ R r = void; return r.length; }()) lengthType; } /**