@@ -116,6 +116,11 @@ macro evalOnceAs(expAlias, exp: untyped,
116116 newProc (name = genSym (nskTemplate, $ expAlias), params = [getType (untyped )],
117117 body = val, procType = nnkTemplateDef))
118118
119+ template unCheckedInc (x) =
120+ {.push overflowChecks : off .}
121+ inc (x)
122+ {.pop .}
123+
119124func concat * [T](seqs: varargs [seq [T]]): seq [T] =
120125 # # Takes several sequences' items and returns them inside a new sequence.
121126 # # All sequences must be of the same type.
@@ -139,7 +144,7 @@ func concat*[T](seqs: varargs[seq[T]]): seq[T] =
139144 for s in items (seqs):
140145 for itm in items (s):
141146 result [i] = itm
142- inc (i)
147+ unCheckedInc (i)
143148
144149func addUnique * [T](s: var seq [T], x: sink T) =
145150 # # Adds `x` to the container `s` if it is not already present.
@@ -170,7 +175,7 @@ func count*[T](s: openArray[T], x: T): int =
170175 result = 0
171176 for itm in items (s):
172177 if itm == x:
173- inc result
178+ unCheckedInc result
174179
175180func cycle * [T](s: openArray [T], n: Natural ): seq [T] =
176181 # # Returns a new sequence with the items of the container `s` repeated
@@ -188,7 +193,7 @@ func cycle*[T](s: openArray[T], n: Natural): seq[T] =
188193 for x in 0 ..< n:
189194 for e in s:
190195 result [o] = e
191- inc o
196+ unCheckedInc o
192197
193198proc repeat * [T](x: T, n: Natural ): seq [T] =
194199 # # Returns a new sequence with the item `x` repeated `n` times.
@@ -321,6 +326,26 @@ func minmax*[T](x: openArray[T], cmp: proc(a, b: T): int): (T, T) {.effectsOf: c
321326 elif cmp (result [1 ], x[i]) < 0 : result [1 ] = x[i]
322327
323328
329+ template findIt * (s, predicate: untyped ): int =
330+ # # Iterates through a container and returns the index of the first item that
331+ # # fulfills the predicate, or -1
332+ # #
333+ # # Unlike the `find`, the predicate needs to be an expression using
334+ # # the `it` variable for testing, like: `findIt([3, 2, 1], it == 2)`.
335+ var
336+ res = - 1
337+ i = 0
338+
339+ # We must use items here since both `find` and `anyIt` are defined in terms
340+ # of `items`
341+ # (and not `pairs`)
342+ for it {.inject .} in items (s):
343+ if predicate:
344+ res = i
345+ break
346+ unCheckedInc (i)
347+ res
348+
324349template zipImpl (s1, s2, retType: untyped ): untyped =
325350 proc zip * [S, T](s1: openArray [S], s2: openArray [T]): retType =
326351 # # Returns a new sequence with a combination of the two input containers.
@@ -417,7 +442,7 @@ func distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] =
417442
418443 if extra == 0 or spread == false :
419444 # Use an algorithm which overcounts the stride and minimizes reading limits.
420- if extra > 0 : inc (stride)
445+ if extra > 0 : unCheckedInc (stride)
421446 for i in 0 ..< num:
422447 result [i] = newSeq [T]()
423448 for g in first ..< min (s.len, first + stride):
@@ -429,7 +454,7 @@ func distribute*[T](s: seq[T], num: Positive, spread = true): seq[seq[T]] =
429454 last = first + stride
430455 if extra > 0 :
431456 extra -= 1
432- inc (last)
457+ unCheckedInc (last)
433458 result [i] = newSeq [T]()
434459 for g in first ..< last:
435460 result [i].add (s[g])
@@ -586,7 +611,7 @@ proc keepIf*[T](s: var seq[T], pred: proc(x: T): bool {.closure.})
586611 s[pos] = move (s[i])
587612 else :
588613 shallowCopy (s[pos], s[i])
589- inc (pos)
614+ unCheckedInc (pos)
590615 setLen (s, pos)
591616
592617func delete * [T](s: var seq [T]; slice: Slice [int ]) =
@@ -617,8 +642,8 @@ func delete*[T](s: var seq[T]; slice: Slice[int]) =
617642 s[i] = move (s[j])
618643 else :
619644 s[i].shallowCopy (s[j])
620- inc (i)
621- inc (j)
645+ unCheckedInc (i)
646+ unCheckedInc (j)
622647 setLen (s, newLen)
623648 when nimvm : defaultImpl ()
624649 else :
@@ -649,8 +674,8 @@ func delete*[T](s: var seq[T]; first, last: Natural) {.deprecated: "use `delete(
649674 s[i] = move (s[j])
650675 else :
651676 s[i].shallowCopy (s[j])
652- inc (i)
653- inc (j)
677+ unCheckedInc (i)
678+ unCheckedInc (j)
654679 setLen (s, newLen)
655680
656681func insert * [T](dest: var seq [T], src: openArray [T], pos = 0 ) =
@@ -681,10 +706,10 @@ func insert*[T](dest: var seq[T], src: openArray[T], pos = 0) =
681706 dec (i)
682707 dec (j)
683708 # Insert items from `dest` into `dest` at `pos`
684- inc (j)
709+ unCheckedInc (j)
685710 for item in src:
686711 dest[j] = item
687- inc (j)
712+ unCheckedInc (j)
688713
689714
690715template filterIt * (s, pred: untyped ): untyped =
@@ -715,7 +740,7 @@ template filterIt*(s, pred: untyped): untyped =
715740 var result = newSeq [typeof (s [0 ])]()
716741 for it {.inject .} in items (s):
717742 if pred: result .add (it)
718- result
743+ move result
719744
720745template keepItIf * (varSeq: seq , pred: untyped ) =
721746 # # Keeps the items in the passed sequence (must be declared as a `var`)
@@ -743,7 +768,7 @@ template keepItIf*(varSeq: seq, pred: untyped) =
743768 varSeq[pos] = move (varSeq[i])
744769 else :
745770 shallowCopy (varSeq[pos], varSeq[i])
746- inc (pos)
771+ unCheckedInc (pos)
747772 setLen (varSeq, pos)
748773
749774since (1 , 1 ):
@@ -842,12 +867,7 @@ template anyIt*(s, pred: untyped): bool =
842867 assert numbers.anyIt (it > 8 ) == true
843868 assert numbers.anyIt (it > 9 ) == false
844869
845- var result = false
846- for it {.inject .} in items (s):
847- if pred:
848- result = true
849- break
850- result
870+ findIt (s, pred) != - 1
851871
852872template toSeq1 (s: not iterator ): untyped =
853873 # overload for typed but not iterator
@@ -875,7 +895,7 @@ template toSeq2(iter: iterator): untyped =
875895 var result = newSeq [typeof (iter2)](iter2.len)
876896 for x in iter2:
877897 result [i] = x
878- inc i
898+ unCheckedInc i
879899 result
880900 else :
881901 type OutType = typeof (iter2 ())
@@ -920,7 +940,7 @@ template toSeq*(iter: untyped): untyped =
920940 var i = 0
921941 for x in iter2:
922942 result [i] = x
923- inc i
943+ unCheckedInc i
924944 result
925945 else :
926946 var result : seq [typeof (iter)] = @ []
0 commit comments