diff options
-rw-r--r-- | lib/system.nim | 47 | ||||
-rw-r--r-- | tests/stdlib/tcount.nim | 29 |
2 files changed, 63 insertions, 13 deletions
diff --git a/lib/system.nim b/lib/system.nim index 4180f24f9..ea35bd54a 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1556,30 +1556,51 @@ when not defined(nimrodVM) and hostOS != "standalone": ## returns the number of bytes on the shared heap that are owned by the ## process. This is only available when threads are enabled. +when sizeof(int) <= 2: + type IntLikeForCount = int|int8|int16|char|bool|uint8 +else: + type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16 + iterator countdown*[T](a, b: T, step = 1): T {.inline.} = ## Counts from ordinal value `a` down to `b` with the given ## step count. `T` may be any ordinal type, `step` may only - ## be positive. - var res = a - while res >= b: - yield res - dec(res, step) + ## be positive. **Note**: This fails to count to ``low(int)`` if T = int for + ## efficiency reasons. + when T is IntLikeForCount: + var res = int(a) + while res >= int(b): + yield T(res) + dec(res, step) + else: + var res = a + while res >= b: + yield res + dec(res, step) + +template countupImpl(incr: stmt) {.immediate, dirty.} = + when T is IntLikeForCount: + var res = int(a) + while res <= int(b): + yield T(res) + incr + else: + var res: T = T(a) + while res <= b: + yield res + incr iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} = ## Counts from ordinal value `a` up to `b` with the given ## step count. `S`, `T` may be any ordinal type, `step` may only - ## be positive. - var res: T = T(a) - while res <= b: - yield res + ## be positive. **Note**: This fails to count to ``high(int)`` if T = int for + ## efficiency reasons. + countupImpl: inc(res, step) iterator `..`*[S, T](a: S, b: T): T {.inline.} = ## An alias for `countup`. - var res: T = T(a) - while res <= b: - yield res - inc res + countupImpl: + inc(res) iterator `||`*[S, T](a: S, b: T, annotation=""): T {. inline, magic: "OmpParFor", sideEffect.} = diff --git a/tests/stdlib/tcount.nim b/tests/stdlib/tcount.nim new file mode 100644 index 000000000..ce1d14b6c --- /dev/null +++ b/tests/stdlib/tcount.nim @@ -0,0 +1,29 @@ +discard """ + output: '''1 +2 +3 +4 +5 +done''' +""" + +# bug #1845, #2224 + +var arr = [3,2,1,5,4] + +# bubble sort +for i in low(arr)..high(arr): + for j in i+1..high(arr): # Error: unhandled exception: value out of range: 5 [RangeError] + if arr[i] > arr[j]: + let tmp = arr[i] + arr[i] = arr[j] + arr[j] = tmp + +for i in low(arr)..high(arr): + echo arr[i] + +# check this terminates: +for x in countdown('\255', '\0'): + discard + +echo "done" |