From dde77ece73513ecb01f6cb54f3ef1cfe5d857f79 Mon Sep 17 00:00:00 2001 From: monarchdodra Date: Sun, 12 Jan 2014 11:47:00 +0100 Subject: [PATCH 1/3] Tweak Cycle indexing --- std/range.d | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/std/range.d b/std/range.d index f70a0f73f..49ba6e5d4 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 @@ -4424,12 +4425,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 +4438,8 @@ nothrow: void popFront() { ++_index; + if (_index >= R.length) + _index = 0; } ref inout(ElementType) opIndex(size_t n) inout From 25f123687cca76ba4a4db6408ba2231ced54030e Mon Sep 17 00:00:00 2001 From: monarchdodra Date: Sun, 12 Jan 2014 11:53:29 +0100 Subject: [PATCH 2/3] Fix issue 10845 --- std/range.d | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/std/range.d b/std/range.d index 49ba6e5d4..77179b7ca 100644 --- a/std/range.d +++ b/std/range.d @@ -4394,7 +4394,8 @@ struct Cycle(R) void popFront() { _current.popFront(); - if (_current.empty) _current = _original; + if (_current.empty) + _current = _original.save; } @property Cycle save() From 63535371bc2f2c50d1328c05a49d626e556a122d Mon Sep 17 00:00:00 2001 From: monarchdodra Date: Sun, 12 Jan 2014 11:52:52 +0100 Subject: [PATCH 3/3] Cycle unittests --- std/range.d | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/std/range.d b/std/range.d index 77179b7ca..442912f0d 100644 --- a/std/range.d +++ b/std/range.d @@ -4593,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; } /**