mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 17:34:43 +00:00
172 lines
4.7 KiB
Nim
172 lines
4.7 KiB
Nim
when sizeof(int) <= 2:
|
||
type IntLikeForCount = int|int8|int16|char|bool|uint8|enum
|
||
else:
|
||
type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16|enum
|
||
|
||
iterator countdown*[T](a, b: T, step: Positive = 1): T {.inline.} =
|
||
## Counts from ordinal value `a` down to `b` (inclusive) with the given
|
||
## step count.
|
||
##
|
||
## `T` may be any ordinal type, `step` may only be positive.
|
||
##
|
||
## **Note**: This fails to count to `low(int)` if T = int for
|
||
## efficiency reasons.
|
||
runnableExamples:
|
||
import std/sugar
|
||
let x = collect(newSeq):
|
||
for i in countdown(7, 3):
|
||
i
|
||
|
||
assert x == @[7, 6, 5, 4, 3]
|
||
|
||
let y = collect(newseq):
|
||
for i in countdown(9, 2, 3):
|
||
i
|
||
assert y == @[9, 6, 3]
|
||
when T is (uint|uint64):
|
||
var res = a
|
||
while res >= b:
|
||
yield res
|
||
if res == b: break
|
||
dec(res, step)
|
||
elif T is IntLikeForCount and T is Ordinal:
|
||
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)
|
||
|
||
iterator countup*[T](a, b: T, step: Positive = 1): T {.inline.} =
|
||
## Counts from ordinal value `a` to `b` (inclusive) with the given
|
||
## step count.
|
||
##
|
||
## `T` may be any ordinal type, `step` may only be positive.
|
||
##
|
||
## **Note**: This fails to count to `high(int)` if T = int for
|
||
## efficiency reasons.
|
||
runnableExamples:
|
||
import std/sugar
|
||
let x = collect(newSeq):
|
||
for i in countup(3, 7):
|
||
i
|
||
|
||
assert x == @[3, 4, 5, 6, 7]
|
||
|
||
let y = collect(newseq):
|
||
for i in countup(2, 9, 3):
|
||
i
|
||
assert y == @[2, 5, 8]
|
||
mixin inc
|
||
when T is IntLikeForCount and T is Ordinal:
|
||
var res = int(a)
|
||
while res <= int(b):
|
||
yield T(res)
|
||
inc(res, step)
|
||
else:
|
||
var res = a
|
||
while res <= b:
|
||
yield res
|
||
inc(res, step)
|
||
|
||
iterator `..`*[T](a, b: T): T {.inline.} =
|
||
## An alias for `countup(a, b, 1)`.
|
||
##
|
||
## See also:
|
||
## * [..<](#..<.i,T,T)
|
||
runnableExamples:
|
||
import std/sugar
|
||
|
||
let x = collect(newSeq):
|
||
for i in 3 .. 7:
|
||
i
|
||
|
||
assert x == @[3, 4, 5, 6, 7]
|
||
mixin inc
|
||
when T is IntLikeForCount and T is Ordinal:
|
||
var res = int(a)
|
||
while res <= int(b):
|
||
yield T(res)
|
||
inc(res)
|
||
else:
|
||
var res = a
|
||
while res <= b:
|
||
yield res
|
||
inc(res)
|
||
|
||
template dotdotImpl(t) {.dirty.} =
|
||
iterator `..`*(a, b: t): t {.inline.} =
|
||
## A type specialized version of `..` for convenience so that
|
||
## mixing integer types works better.
|
||
##
|
||
## See also:
|
||
## * [..<](#..<.i,T,T)
|
||
var res = a
|
||
while res <= b:
|
||
yield res
|
||
inc(res)
|
||
|
||
dotdotImpl(int64)
|
||
dotdotImpl(int32)
|
||
dotdotImpl(uint64)
|
||
dotdotImpl(uint32)
|
||
|
||
iterator `..<`*[T](a, b: T): T {.inline.} =
|
||
mixin inc
|
||
var i = a
|
||
while i < b:
|
||
yield i
|
||
inc i
|
||
|
||
template dotdotLessImpl(t) {.dirty.} =
|
||
iterator `..<`*(a, b: t): t {.inline.} =
|
||
## A type specialized version of `..<` for convenience so that
|
||
## mixing integer types works better.
|
||
var res = a
|
||
while res < b:
|
||
yield res
|
||
inc(res)
|
||
|
||
dotdotLessImpl(int64)
|
||
dotdotLessImpl(int32)
|
||
dotdotLessImpl(uint64)
|
||
dotdotLessImpl(uint32)
|
||
|
||
iterator `||`*[S, T](a: S, b: T, annotation: static string = "parallel for"): T {.
|
||
inline, magic: "OmpParFor", sideEffect.} =
|
||
## OpenMP parallel loop iterator. Same as `..` but the loop may run in parallel.
|
||
##
|
||
## `annotation` is an additional annotation for the code generator to use.
|
||
## The default annotation is `parallel for`.
|
||
## Please refer to the `OpenMP Syntax Reference
|
||
## <https://www.openmp.org/wp-content/uploads/OpenMP-4.5-1115-CPP-web.pdf>`_
|
||
## for further information.
|
||
##
|
||
## Note that the compiler maps that to
|
||
## the `#pragma omp parallel for` construct of `OpenMP`:idx: and as
|
||
## such isn't aware of the parallelism in your code! Be careful! Later
|
||
## versions of `||` will get proper support by Nim's code generator
|
||
## and GC.
|
||
discard
|
||
|
||
iterator `||`*[S, T](a: S, b: T, step: Positive, annotation: static string = "parallel for"): T {.
|
||
inline, magic: "OmpParFor", sideEffect.} =
|
||
## OpenMP parallel loop iterator with stepping.
|
||
## Same as `countup` but the loop may run in parallel.
|
||
##
|
||
## `annotation` is an additional annotation for the code generator to use.
|
||
## The default annotation is `parallel for`.
|
||
## Please refer to the `OpenMP Syntax Reference
|
||
## <https://www.openmp.org/wp-content/uploads/OpenMP-4.5-1115-CPP-web.pdf>`_
|
||
## for further information.
|
||
##
|
||
## Note that the compiler maps that to
|
||
## the `#pragma omp parallel for` construct of `OpenMP`:idx: and as
|
||
## such isn't aware of the parallelism in your code! Be careful! Later
|
||
## versions of `||` will get proper support by Nim's code generator
|
||
## and GC.
|
||
discard
|