Merge pull request #1851 from monarchdodra/cycleMod

Fixes in Cycle
This commit is contained in:
Hara Kenji 2014-01-25 14:15:35 -08:00
commit 8e302d0114

View file

@ -4277,20 +4277,19 @@ struct Cycle(R)
this(R input, size_t index = 0) this(R input, size_t index = 0)
{ {
_original = input; _original = input;
_index = index; _index = index % _original.length;
} }
@property auto ref front() @property auto ref front()
{ {
return _original[_index % _original.length]; return _original[_index];
} }
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)))
{ {
@property auto ref front() const @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) @property auto front(ElementType!R val)
{ {
_original[_index % _original.length] = val; _original[_index] = val;
} }
} }
@ -4307,6 +4306,8 @@ struct Cycle(R)
void popFront() void popFront()
{ {
++_index; ++_index;
if (_index >= _original.length)
_index = 0;
} }
auto ref opIndex(size_t n) auto ref opIndex(size_t n)
@ -4314,7 +4315,7 @@ struct Cycle(R)
return _original[(n + _index) % _original.length]; 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))) is(typeof((cast(const R)_original).length)))
{ {
auto ref opIndex(size_t n) const auto ref opIndex(size_t n) const
@ -4393,7 +4394,8 @@ struct Cycle(R)
void popFront() void popFront()
{ {
_current.popFront(); _current.popFront();
if (_current.empty) _current = _original; if (_current.empty)
_current = _original.save;
} }
@property Cycle save() @property Cycle save()
@ -4424,12 +4426,12 @@ nothrow:
this(ref R input, size_t index = 0) this(ref R input, size_t index = 0)
{ {
_ptr = input.ptr; _ptr = input.ptr;
_index = index; _index = index % R.length;
} }
@property ref inout(ElementType) front() inout @property ref inout(ElementType) front() inout
{ {
return _ptr[_index % R.length]; return _ptr[_index];
} }
enum bool empty = false; enum bool empty = false;
@ -4437,6 +4439,8 @@ nothrow:
void popFront() void popFront()
{ {
++_index; ++_index;
if (_index >= R.length)
_index = 0;
} }
ref inout(ElementType) opIndex(size_t n) inout ref inout(ElementType) opIndex(size_t n) inout
@ -4589,6 +4593,43 @@ unittest // For infinite ranges
assert (c == i); 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; } private template lengthType(R) { alias typeof((inout int = 0){ R r = void; return r.length; }()) lengthType; }
/** /**