From 5c8d160ceaf149a98c1286e6a857904e1eabecc8 Mon Sep 17 00:00:00 2001 From: Nimaoth Date: Tue, 19 Mar 2024 22:52:38 +0100 Subject: [PATCH] added tests for smallseq --- src/misc/smallseq.nim | 20 +++--- tests/unit/tsmallseq.nim | 139 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 10 deletions(-) create mode 100644 tests/unit/tsmallseq.nim diff --git a/src/misc/smallseq.nim b/src/misc/smallseq.nim index 2a3d732e..17c7f580 100644 --- a/src/misc/smallseq.nim +++ b/src/misc/smallseq.nim @@ -43,7 +43,7 @@ func getInlineData[T; Count: static int](s: ptr SmallSeq[T, Count]): ptr Uncheck else: return cast[ptr UncheckedArray[T]](s.data.inline.arr.addr) -func isInline[T; Count: static int](s: SmallSeq[T, Count]): bool {.inline, raises: [].} = +func isInline*[T; Count: static int](s: SmallSeq[T, Count]): bool {.inline, raises: [].} = ## Returns true if the sequence is stored inline let tag = cast[ptr uint8](s.addr)[] return (tag and 1) == 0 @@ -76,7 +76,7 @@ func `high`*[T; Count: static int](s: SmallSeq[T, Count]): int {.inline, raises: ## Returns the highest valid index of the sequence, or -1 if the sequence is empty s.len - 1 -func `len=`[T; Count: static int](s: var SmallSeq[T, Count], len: int) {.inline, raises: [].} = +func `len=`*[T; Count: static int](s: var SmallSeq[T, Count], len: int) {.inline, raises: [].} = ## Internal: set the length of the sequence if s.isInline: when sizeof(T) == 1 and Count <= MAX_COUNT8: @@ -174,13 +174,13 @@ proc moveToHeap[T; Count: static int](s: var SmallSeq[T, Count], slack: int) {.r s.data.heap.arr = heapArr s.data.heap.capacity = capacity -proc shrink[T; Count: static int](s: var SmallSeq[T, Count], slack: int = 0) {.raises: [].} = +proc shrink*[T; Count: static int](s: var SmallSeq[T, Count], slack: int = 0) {.raises: [].} = ## Try to shrink the capacity of the sequence to fit the current length + `slack` if s.isInline: return - let len = s.len - let newCapacity = len + slack + let oldLen = s.len + let newCapacity = oldLen + slack let capacity = s.data.heap.capacity if newCapacity <= inlineCapacity(T, Count): @@ -188,15 +188,15 @@ proc shrink[T; Count: static int](s: var SmallSeq[T, Count], slack: int = 0) {.r let arr = s.data.heap.arr s.setInline true - s.len = len + s.len = oldLen let inlineArr = s.addr.getInlineData - for i in 0..= 0 if s.isInline: - s.shiftLeft(slice.a, reduction) + s.shiftLeft(slice.b + 1, reduction) s.len = newLen elif shrink and newLen <= inlineCapacity(T, Count): @@ -333,7 +333,7 @@ proc delete*[T; Count: static int](s: var SmallSeq[T, Count], slice: Slice[int], s.len = newLen else: - s.shiftLeft(slice.a, reduction) + s.shiftLeft(slice.b + 1, reduction) s.len = newLen if shrink: s.shrink() diff --git a/tests/unit/tsmallseq.nim b/tests/unit/tsmallseq.nim new file mode 100644 index 00000000..35c6b681 --- /dev/null +++ b/tests/unit/tsmallseq.nim @@ -0,0 +1,139 @@ +discard """ + action: "run" + cmd: "nim $target --nimblePath:./nimbleDir/simplePkgs $options $file" + timeout: 60 + targets: "c" + matrix: "" +""" + +import std/[tables, unittest, strformat] +import input + +import misc/smallseq + + +suite "SmallSeq": + + proc testAdd[T]() = + var s = initSmallSeq(T, 23) + + assert s.isInline + assert s.len == 0 + + s.add 0 + + assert s.isInline + assert s.len == 1 + + for i in 1..22: + s.add i.T + + assert s.isInline + + assert s.len == 23 + assert @(s[0..<23]) == @[0.T, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22] + + s.add 23 + + assert not s.isInline + assert s.len == 24 + + for i in 0..<24: + assert s[i] == i.T + + assert @(s[0..<24]) == @[0.T, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] + + for i in 24..256: + s.add i.T + assert s[i] == i.T + + test "add int8": + testAdd[uint8]() + + test "add int32": + testAdd[int32]() + + test "inline capacity": + assert initSmallSeq(int8, 10).capacity == 23 + assert initSmallSeq(int32, 10).capacity == 10 + assert initSmallSeq(int8, 23).capacity == 23 + assert initSmallSeq(int32, 23).capacity == 23 + assert initSmallSeq(int8, 24).capacity == 24 + assert initSmallSeq(int32, 24).capacity == 24 + + proc testShrink[T]() = + var s = initSmallSeq(T, 30) + for i in 0..<40: + s.add i.T + + assert not s.isInline + assert s.len == 40 + assert s.capacity == 60 + + s.shrink(1) + + assert not s.isInline + assert s.len == 40 + assert s.capacity == 41 + + s.delete(0..<15, shrink=true) + + assert s.isInline + assert s.len == 25 + assert s.capacity == 30 + + test "shrink int8": + testShrink[int8]() + + test "shrink int32": + testShrink[int32]() + + proc testDelete[T]() = + var s = initSmallSeq(T, 30) + for i in 0..<50: + s.add i.T + + assert s.len == 50 + + for i in 0..s.high: + assert s[i] == i.T + + s.delete 10..<15 + assert s.len == 45 + assert not s.isInline + + for i in 0..<10: + assert s[i] == i.T + + for i in 10..<45: + assert s[i] == i.T + 5 + + s.delete 25..<44 + assert s.len == 26 + assert s.isInline + + for i in 0..<10: + assert s[i] == i.T + + for i in 10..<25: + assert s[i] == i.T + 5 + + for i in 25..