diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-09-29 00:08:31 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-28 18:08:31 +0200 |
commit | 285cbcb6aa36147e9b9c024ceed78e46526dd1ea (patch) | |
tree | f42ae1f52f808579b5ab6efa7125d9ca6134e639 | |
parent | 4bf0f846df3bdeeeeff288f1d28688ee4852bc71 (diff) | |
download | Nim-285cbcb6aa36147e9b9c024ceed78e46526dd1ea.tar.gz |
ref #19727; implement `setLenUninit` for seqsv2 (#22767)
ref #19727
-rw-r--r-- | changelog.md | 2 | ||||
-rw-r--r-- | lib/system/seqs_v2.nim | 24 |
2 files changed, 26 insertions, 0 deletions
diff --git a/changelog.md b/changelog.md index b661226be..e0eb34470 100644 --- a/changelog.md +++ b/changelog.md @@ -12,6 +12,8 @@ [//]: # "Additions:" - Added `newStringUninit` to system, which creates a new string of length `len` like `newString` but with uninitialized content. +- Added `setLenUninit` to system, which doesn't initalize +slots when enlarging a sequence. - Added `hasDefaultValue` to `std/typetraits` to check if a type has a valid default value. - Added Viewport API for the JavaScript targets in the `dom` module. diff --git a/lib/system/seqs_v2.nim b/lib/system/seqs_v2.nim index c4e3e3e6b..7ce8de054 100644 --- a/lib/system/seqs_v2.nim +++ b/lib/system/seqs_v2.nim @@ -195,5 +195,29 @@ func capacity*[T](self: seq[T]): int {.inline.} = let sek = cast[ptr NimSeqV2[T]](unsafeAddr self) result = if sek.p != nil: sek.p.cap and not strlitFlag else: 0 +func setLenUninit*[T](s: var seq[T], newlen: Natural) {.nodestroy.} = + ## Sets the length of seq `s` to `newlen`. `T` may be any sequence type. + ## New slots will not be initialized. + ## + ## If the current length is greater than the new length, + ## `s` will be truncated. + ## ```nim + ## var x = @[10, 20] + ## x.setLenUninit(5) + ## x[4] = 50 + ## assert x[4] == 50 + ## x.setLenUninit(1) + ## assert x == @[10] + ## ``` + {.noSideEffect.}: + if newlen < s.len: + shrink(s, newlen) + else: + let oldLen = s.len + if newlen <= oldLen: return + var xu = cast[ptr NimSeqV2[T]](addr s) + if xu.p == nil or (xu.p.cap and not strlitFlag) < newlen: + xu.p = cast[typeof(xu.p)](prepareSeqAddUninit(oldLen, xu.p, newlen - oldLen, sizeof(T), alignof(T))) + xu.len = newlen {.pop.} # See https://github.com/nim-lang/Nim/issues/21401 |