deprecate sequtils.delete and add an overload with saner semantics consistent with system.delete (#18487)

* deprecate sequtils.delete and add an overload with saner semantics
* AssertionDefect => IndexDefect
* improve tsequtils
* add tests; use splice in js for optimization
This commit is contained in:
Timothee Cour 2021-07-15 11:54:07 -07:00 • committed by GitHub
commit 1d6863a789
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 144 additions and 48 deletions

View file

@ -509,12 +509,51 @@ proc keepIf*[T](s: var seq[T], pred: proc(x: T): bool {.closure.})
inc(pos)
setLen(s, pos)
func delete*[T](s: var seq[T]; first, last: Natural) =
func delete*[T](s: var seq[T]; slice: Slice[int]) =
## Deletes the items `s[slice]`, raising `IndexDefect` if the slice contains
## elements out of range.
##
## This operation moves all elements after `s[slice]` in linear time.
runnableExamples:
var a = @[10, 11, 12, 13, 14]
doAssertRaises(IndexDefect): a.delete(4..5)
assert a == @[10, 11, 12, 13, 14]
a.delete(4..4)
assert a == @[10, 11, 12, 13]
a.delete(1..2)
assert a == @[10, 13]
a.delete(1..<1) # empty slice
assert a == @[10, 13]
when compileOption("boundChecks"):
if not (slice.a < s.len and slice.a >= 0 and slice.b < s.len):
raise newException(IndexDefect, $(slice: slice, len: s.len))
if slice.b >= slice.a:
template defaultImpl =
var i = slice.a
var j = slice.b + 1
var newLen = s.len - j + i
while i < newLen:
when defined(gcDestructors):
s[i] = move(s[j])
else:
s[i].shallowCopy(s[j])
inc(i)
inc(j)
setLen(s, newLen)
when nimvm: defaultImpl()
else:
when defined(js):
let n = slice.b - slice.a + 1
let first = slice.a
{.emit: "`s`.splice(`first`, `n`);".}
else:
defaultImpl()
func delete*[T](s: var seq[T]; first, last: Natural) {.deprecated: "use `delete(s, first..last)`".} =
## Deletes the items of a sequence `s` at positions `first..last`
## (including both ends of the range).
## This modifies `s` itself, it does not return a copy.
##
runnableExamples:
runnableExamples("--warning:deprecated:off"):
let outcome = @[1, 1, 1, 1, 1, 1, 1, 1]
var dest = @[1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1]
dest.delete(3, 8)