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:
parent
a9701f6531
commit
1d6863a789
3 changed files with 144 additions and 48 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue