Raise IndexDefect when deleting element at out of bounds index (#17821)
Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> Co-authored-by: Heiko Nickerl <mail@hnicke.de> Co-authored-by: Heiko Nickerl <heiko.nickerl@flipapp.de>
This commit is contained in:
parent
eb0b323f45
commit
92cb765714
5 changed files with 70 additions and 36 deletions
|
|
@ -28,6 +28,9 @@
|
||||||
- `math.round` now is rounded "away from zero" in JS backend which is consistent
|
- `math.round` now is rounded "away from zero" in JS backend which is consistent
|
||||||
with other backends. See #9125. Use `-d:nimLegacyJsRound` for previous behavior.
|
with other backends. See #9125. Use `-d:nimLegacyJsRound` for previous behavior.
|
||||||
|
|
||||||
|
- Instead of deleting the element at the last index,
|
||||||
|
`system.delete()` now raises `IndexDefect` when given index is out of bounds.
|
||||||
|
|
||||||
- Changed the behavior of `uri.decodeQuery` when there are unencoded `=`
|
- Changed the behavior of `uri.decodeQuery` when there are unencoded `=`
|
||||||
characters in the decoded values. Prior versions would raise an error. This is
|
characters in the decoded values. Prior versions would raise an error. This is
|
||||||
no longer the case to comply with the HTML spec and other languages
|
no longer the case to comply with the HTML spec and other languages
|
||||||
|
|
|
||||||
|
|
@ -1325,30 +1325,6 @@ proc del*[T](x: var seq[T], i: Natural) {.noSideEffect.} =
|
||||||
movingCopy(x[i], x[xl])
|
movingCopy(x[i], x[xl])
|
||||||
setLen(x, xl)
|
setLen(x, xl)
|
||||||
|
|
||||||
proc delete*[T](x: var seq[T], i: Natural) {.noSideEffect.} =
|
|
||||||
## Deletes the item at index `i` by moving all `x[i+1..]` items by one position.
|
|
||||||
##
|
|
||||||
## This is an `O(n)` operation.
|
|
||||||
##
|
|
||||||
## See also:
|
|
||||||
## * `del <#del,seq[T],Natural>`_ for O(1) operation
|
|
||||||
##
|
|
||||||
## .. code-block:: Nim
|
|
||||||
## var i = @[1, 2, 3, 4, 5]
|
|
||||||
## i.delete(2) # => @[1, 2, 4, 5]
|
|
||||||
template defaultImpl =
|
|
||||||
let xl = x.len
|
|
||||||
for j in i.int..xl-2: movingCopy(x[j], x[j+1])
|
|
||||||
setLen(x, xl-1)
|
|
||||||
|
|
||||||
when nimvm:
|
|
||||||
defaultImpl()
|
|
||||||
else:
|
|
||||||
when defined(js):
|
|
||||||
{.emit: "`x`.splice(`i`, 1);".}
|
|
||||||
else:
|
|
||||||
defaultImpl()
|
|
||||||
|
|
||||||
proc insert*[T](x: var seq[T], item: sink T, i = 0.Natural) {.noSideEffect.} =
|
proc insert*[T](x: var seq[T], item: sink T, i = 0.Natural) {.noSideEffect.} =
|
||||||
## Inserts `item` into `x` at position `i`.
|
## Inserts `item` into `x` at position `i`.
|
||||||
##
|
##
|
||||||
|
|
@ -2154,6 +2130,40 @@ const
|
||||||
import system/dollars
|
import system/dollars
|
||||||
export dollars
|
export dollars
|
||||||
|
|
||||||
|
proc delete*[T](x: var seq[T], i: Natural) {.noSideEffect.} =
|
||||||
|
## Deletes the item at index `i` by moving all `x[i+1..^1]` items by one position.
|
||||||
|
##
|
||||||
|
## This is an `O(n)` operation.
|
||||||
|
##
|
||||||
|
## See also:
|
||||||
|
## * `del <#del,seq[T],Natural>`_ for O(1) operation
|
||||||
|
##
|
||||||
|
runnableExamples:
|
||||||
|
var s = @[1, 2, 3, 4, 5]
|
||||||
|
s.delete(2)
|
||||||
|
doAssert s == @[1, 2, 4, 5]
|
||||||
|
|
||||||
|
doAssertRaises(IndexDefect):
|
||||||
|
s.delete(4)
|
||||||
|
|
||||||
|
if i > high(x):
|
||||||
|
# xxx this should call `raiseIndexError2(i, high(x))` after some refactoring
|
||||||
|
raise (ref IndexDefect)(msg: "index out of bounds: '" & $i & "' < '" & $x.len & "' failed")
|
||||||
|
|
||||||
|
template defaultImpl =
|
||||||
|
let xl = x.len
|
||||||
|
for j in i.int..xl-2: movingCopy(x[j], x[j+1])
|
||||||
|
setLen(x, xl-1)
|
||||||
|
|
||||||
|
when nimvm:
|
||||||
|
defaultImpl()
|
||||||
|
else:
|
||||||
|
when defined(js):
|
||||||
|
{.emit: "`x`.splice(`i`, 1);".}
|
||||||
|
else:
|
||||||
|
defaultImpl()
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch
|
NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch
|
||||||
## is the version of Nim as a string.
|
## is the version of Nim as a string.
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,10 @@ for i in 0..1024:
|
||||||
s.add(obj)
|
s.add(obj)
|
||||||
|
|
||||||
proc limit*[t](a: var seq[t]) =
|
proc limit*[t](a: var seq[t]) =
|
||||||
var loop = s.len() - 512
|
while s.len > 0:
|
||||||
for i in 0..loop:
|
|
||||||
#echo i
|
|
||||||
#GC_fullCollect()
|
|
||||||
if getOccupiedMem() > 3000_000: quit("still a leak!")
|
if getOccupiedMem() > 3000_000: quit("still a leak!")
|
||||||
s.delete(i)
|
s.delete(0)
|
||||||
|
|
||||||
s.limit()
|
s.limit()
|
||||||
|
|
||||||
echo "no leak: ", getOccupiedMem()
|
echo "no leak: ", getOccupiedMem()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,10 @@ discard """
|
||||||
targets: "c cpp js"
|
targets: "c cpp js"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import stdtest/testutils
|
||||||
|
|
||||||
# TODO: in future work move existing `system` tests here, where they belong
|
# TODO: in future work move existing `system` tests here, where they belong
|
||||||
|
|
||||||
import stdtest/testutils
|
|
||||||
|
|
||||||
template main =
|
template main =
|
||||||
block: # closure
|
block: # closure
|
||||||
|
|
@ -42,5 +43,34 @@ template main =
|
||||||
# doAssert rawEnv(inner3) != rawEnv(inner1) # because `a` vs `b` # this doesn't hold
|
# doAssert rawEnv(inner3) != rawEnv(inner1) # because `a` vs `b` # this doesn't hold
|
||||||
outer()
|
outer()
|
||||||
|
|
||||||
|
block: # system.delete
|
||||||
|
block:
|
||||||
|
var s = @[1]
|
||||||
|
s.delete(0)
|
||||||
|
doAssert s == @[]
|
||||||
|
|
||||||
|
block:
|
||||||
|
var s = @["foo", "bar"]
|
||||||
|
s.delete(1)
|
||||||
|
doAssert s == @["foo"]
|
||||||
|
|
||||||
|
block:
|
||||||
|
var s: seq[string]
|
||||||
|
doAssertRaises(IndexDefect):
|
||||||
|
s.delete(0)
|
||||||
|
|
||||||
|
block:
|
||||||
|
doAssert not compiles(@["foo"].delete(-1))
|
||||||
|
|
||||||
|
block: # bug #6710
|
||||||
|
var s = @["foo"]
|
||||||
|
s.delete(0)
|
||||||
|
doAssert s == @[]
|
||||||
|
|
||||||
|
block: # bug #16544: deleting out of bounds index should raise
|
||||||
|
var s = @["foo"]
|
||||||
|
doAssertRaises(IndexDefect):
|
||||||
|
s.delete(1)
|
||||||
|
|
||||||
static: main()
|
static: main()
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -59,11 +59,6 @@ doAssert high(float) > low(float)
|
||||||
doAssert high(float32) > low(float32)
|
doAssert high(float32) > low(float32)
|
||||||
doAssert high(float64) > low(float64)
|
doAssert high(float64) > low(float64)
|
||||||
|
|
||||||
# bug #6710
|
|
||||||
var s = @[1]
|
|
||||||
s.delete(0)
|
|
||||||
|
|
||||||
|
|
||||||
proc foo(a: openArray[int]) =
|
proc foo(a: openArray[int]) =
|
||||||
for x in a: echo x
|
for x in a: echo x
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue