From 028699fe6ca3defa598fef65ffd287e7e3626f72 Mon Sep 17 00:00:00 2001 From: Brad Anderson Date: Thu, 19 Apr 2012 19:57:45 -0600 Subject: [PATCH 1/2] fix Issue 7944 - std.range.iota.popFront() cycles when the range is empty Added !empty assertions to front, popFront, back, and popBack to the integer iota like some other ranges do. Also added the one that was missing to the floating point iota. --- std/range.d | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/std/range.d b/std/range.d index b565e0bca62..85e1ffa826d 100644 --- a/std/range.d +++ b/std/range.d @@ -4352,12 +4352,12 @@ if ((isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E))) } } @property bool empty() const { return current == pastLast; } - @property Value front() { return current; } + @property Value front() { assert(!empty); return current; } alias front moveFront; - void popFront() { current += step; } - @property Value back() { return pastLast - step; } + void popFront() { assert(!empty); current += step; } + @property Value back() { assert(!empty); return pastLast - step; } alias back moveBack; - void popBack() { pastLast -= step; } + void popBack() { assert(!empty); pastLast -= step; } @property auto save() { return this; } Value opIndex(ulong n) { @@ -4418,12 +4418,12 @@ if (isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E))) } } @property bool empty() const { return current == pastLast; } - @property Value front() { return current; } + @property Value front() { assert(!empty); return current; } alias front moveFront; - void popFront() { ++current; } - @property Value back() { return pastLast - 1; } + void popFront() { assert(!empty); ++current; } + @property Value back() { assert(!empty); return pastLast - 1; } alias back moveBack; - void popBack() { --pastLast; } + void popBack() { assert(!empty); --pastLast; } @property auto save() { return this; } Value opIndex(ulong n) { @@ -4489,7 +4489,7 @@ if (isFloatingPoint!(CommonType!(B, E, S))) } } @property bool empty() const { return index == count; } - @property Value front() { return start + step * index; } + @property Value front() { assert(!empty); return start + step * index; } alias front moveFront; void popFront() { From 23bfcd766f71f2f6c0fb007b7b74a29417afc3a8 Mon Sep 17 00:00:00 2001 From: Brad Anderson Date: Fri, 20 Apr 2012 21:12:09 -0600 Subject: [PATCH 2/2] Add index < length assert to iota.opIndex --- std/range.d | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/std/range.d b/std/range.d index 85e1ffa826d..0616ab6fa5e 100644 --- a/std/range.d +++ b/std/range.d @@ -4361,6 +4361,8 @@ if ((isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E))) @property auto save() { return this; } Value opIndex(ulong n) { + assert(n < this.length); + // Just cast to Value here because doing so gives overflow behavior // consistent with calling popFront() n times. return cast(Value) (current + step * n); @@ -4427,6 +4429,8 @@ if (isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E))) @property auto save() { return this; } Value opIndex(ulong n) { + assert(n < this.length); + // Just cast to Value here because doing so gives overflow behavior // consistent with calling popFront() n times. return cast(Value) (current + n);