iterators_1.nim 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. when sizeof(int) <= 2:
  2. type IntLikeForCount = int|int8|int16|char|bool|uint8|enum
  3. else:
  4. type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16|enum
  5. iterator countdown*[T](a, b: T, step: Positive = 1): T {.inline.} =
  6. ## Counts from ordinal value `a` down to `b` (inclusive) with the given
  7. ## step count.
  8. ##
  9. ## `T` may be any ordinal type, `step` may only be positive.
  10. ##
  11. ## **Note**: This fails to count to ``low(int)`` if T = int for
  12. ## efficiency reasons.
  13. ##
  14. ## .. code-block:: Nim
  15. ## for i in countdown(7, 3):
  16. ## echo i # => 7; 6; 5; 4; 3
  17. ##
  18. ## for i in countdown(9, 2, 3):
  19. ## echo i # => 9; 6; 3
  20. when T is (uint|uint64):
  21. var res = a
  22. while res >= b:
  23. yield res
  24. if res == b: break
  25. dec(res, step)
  26. elif T is IntLikeForCount and T is Ordinal:
  27. var res = int(a)
  28. while res >= int(b):
  29. yield T(res)
  30. dec(res, step)
  31. else:
  32. var res = a
  33. while res >= b:
  34. yield res
  35. dec(res, step)
  36. when defined(nimNewRoof):
  37. iterator countup*[T](a, b: T, step: Positive = 1): T {.inline.} =
  38. ## Counts from ordinal value `a` to `b` (inclusive) with the given
  39. ## step count.
  40. ##
  41. ## `T` may be any ordinal type, `step` may only be positive.
  42. ##
  43. ## **Note**: This fails to count to ``high(int)`` if T = int for
  44. ## efficiency reasons.
  45. ##
  46. ## .. code-block:: Nim
  47. ## for i in countup(3, 7):
  48. ## echo i # => 3; 4; 5; 6; 7
  49. ##
  50. ## for i in countup(2, 9, 3):
  51. ## echo i # => 2; 5; 8
  52. mixin inc
  53. when T is IntLikeForCount and T is Ordinal:
  54. var res = int(a)
  55. while res <= int(b):
  56. yield T(res)
  57. inc(res, step)
  58. else:
  59. var res = a
  60. while res <= b:
  61. yield res
  62. inc(res, step)
  63. iterator `..`*[T](a, b: T): T {.inline.} =
  64. ## An alias for `countup(a, b, 1)`.
  65. ##
  66. ## See also:
  67. ## * [..<](#..<.i,T,T)
  68. ##
  69. ## .. code-block:: Nim
  70. ## for i in 3 .. 7:
  71. ## echo i # => 3; 4; 5; 6; 7
  72. mixin inc
  73. when T is IntLikeForCount and T is Ordinal:
  74. var res = int(a)
  75. while res <= int(b):
  76. yield T(res)
  77. inc(res)
  78. else:
  79. var res = a
  80. while res <= b:
  81. yield res
  82. inc(res)
  83. template dotdotImpl(t) {.dirty.} =
  84. iterator `..`*(a, b: t): t {.inline.} =
  85. ## A type specialized version of ``..`` for convenience so that
  86. ## mixing integer types works better.
  87. ##
  88. ## See also:
  89. ## * [..<](#..<.i,T,T)
  90. var res = a
  91. while res <= b:
  92. yield res
  93. inc(res)
  94. dotdotImpl(int64)
  95. dotdotImpl(int32)
  96. dotdotImpl(uint64)
  97. dotdotImpl(uint32)
  98. iterator `..<`*[T](a, b: T): T {.inline.} =
  99. mixin inc
  100. var i = a
  101. while i < b:
  102. yield i
  103. inc i
  104. template dotdotLessImpl(t) {.dirty.} =
  105. iterator `..<`*(a, b: t): t {.inline.} =
  106. ## A type specialized version of ``..<`` for convenience so that
  107. ## mixing integer types works better.
  108. var res = a
  109. while res < b:
  110. yield res
  111. inc(res)
  112. dotdotLessImpl(int64)
  113. dotdotLessImpl(int32)
  114. dotdotLessImpl(uint64)
  115. dotdotLessImpl(uint32)
  116. else: # not defined(nimNewRoof)
  117. iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} =
  118. ## Counts from ordinal value `a` up to `b` (inclusive) with the given
  119. ## step count.
  120. ##
  121. ## `S`, `T` may be any ordinal type, `step` may only be positive.
  122. ##
  123. ## **Note**: This fails to count to ``high(int)`` if T = int for
  124. ## efficiency reasons.
  125. ##
  126. ## .. code-block:: Nim
  127. ## for i in countup(3, 7):
  128. ## echo i # => 3; 4; 5; 6; 7
  129. ##
  130. ## for i in countup(2, 9, 3):
  131. ## echo i # => 2; 5; 8
  132. when T is IntLikeForCount and T is Ordinal:
  133. var res = int(a)
  134. while res <= int(b):
  135. yield T(res)
  136. inc(res, step)
  137. else:
  138. var res = T(a)
  139. while res <= b:
  140. yield res
  141. inc(res, step)
  142. iterator `..`*[S, T](a: S, b: T): T {.inline.} =
  143. ## An alias for `countup(a, b, 1)`.
  144. ##
  145. ## See also:
  146. ## * [..<](#..<.i,T,T)
  147. ##
  148. ## .. code-block:: Nim
  149. ## for i in 3 .. 7:
  150. ## echo i # => 3; 4; 5; 6; 7
  151. mixin inc
  152. when T is IntLikeForCount and T is Ordinal:
  153. var res = int(a)
  154. while res <= int(b):
  155. yield T(res)
  156. inc(res)
  157. else:
  158. var res = T(a)
  159. while res <= b:
  160. yield res
  161. inc(res)
  162. iterator `..<`*[S, T](a: S, b: T): T {.inline.} =
  163. mixin inc
  164. var i = T(a)
  165. while i < b:
  166. yield i
  167. inc i
  168. iterator `||`*[S, T](a: S, b: T, annotation: static string = "parallel for"): T {.
  169. inline, magic: "OmpParFor", sideEffect.} =
  170. ## OpenMP parallel loop iterator. Same as `..` but the loop may run in parallel.
  171. ##
  172. ## `annotation` is an additional annotation for the code generator to use.
  173. ## The default annotation is `parallel for`.
  174. ## Please refer to the `OpenMP Syntax Reference
  175. ## <https://www.openmp.org/wp-content/uploads/OpenMP-4.5-1115-CPP-web.pdf>`_
  176. ## for further information.
  177. ##
  178. ## Note that the compiler maps that to
  179. ## the ``#pragma omp parallel for`` construct of `OpenMP`:idx: and as
  180. ## such isn't aware of the parallelism in your code! Be careful! Later
  181. ## versions of ``||`` will get proper support by Nim's code generator
  182. ## and GC.
  183. discard
  184. iterator `||`*[S, T](a: S, b: T, step: Positive, annotation: static string = "parallel for"): T {.
  185. inline, magic: "OmpParFor", sideEffect.} =
  186. ## OpenMP parallel loop iterator with stepping.
  187. ## Same as `countup` but the loop may run in parallel.
  188. ##
  189. ## `annotation` is an additional annotation for the code generator to use.
  190. ## The default annotation is `parallel for`.
  191. ## Please refer to the `OpenMP Syntax Reference
  192. ## <https://www.openmp.org/wp-content/uploads/OpenMP-4.5-1115-CPP-web.pdf>`_
  193. ## for further information.
  194. ##
  195. ## Note that the compiler maps that to
  196. ## the ``#pragma omp parallel for`` construct of `OpenMP`:idx: and as
  197. ## such isn't aware of the parallelism in your code! Be careful! Later
  198. ## versions of ``||`` will get proper support by Nim's code generator
  199. ## and GC.
  200. discard