From d8d914332d1ebe1f6d427790a44cdd9713ce202a Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Thu, 10 Dec 2020 12:05:22 +0100 Subject: [PATCH] random helpers (#64) * random helpers * arrayops as a home for small array/openArray utilities * assign2 - a replacement for genericAssign and assignment operators in general which in nim are very slow * use assign2 in a few places to speed things up * fixes * fixes --- README.md | 4 ++ stew/arrayops.nim | 80 ++++++++++++++++++++++++++++++++++++++++ stew/assign2.nim | 58 +++++++++++++++++++++++++++++ stew/byteutils.nim | 32 +++------------- stew/sequtils2.nim | 22 +++++++++++ tests/all_tests.nim | 9 +++-- tests/test_arrayops.nim | 26 +++++++++++++ tests/test_assign2.nim | 29 +++++++++++++++ tests/test_byteutils.nim | 5 ++- tests/test_sequtils2.nim | 39 ++++++++++++++++++++ 10 files changed, 273 insertions(+), 31 deletions(-) create mode 100644 stew/arrayops.nim create mode 100644 stew/assign2.nim create mode 100644 stew/sequtils2.nim create mode 100644 tests/test_arrayops.nim create mode 100644 tests/test_assign2.nim create mode 100644 tests/test_sequtils2.nim diff --git a/README.md b/README.md index 812230d..923d92c 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ broken out into separate repositories. Libraries are documented either in-module or on a separate README in their respective folders +- `arrayops` - small helpers and operations on `array`/`openArray` +- `assign2` - fast assignments (unlike the `=` operator in nim which is very slow) - `bitops2` - an updated version of `bitops.nim`, filling in gaps in original code - `byteutils` - utilities that make working with the Nim `byte` type convenient - `endians2` - utilities for converting to and from little / big endian integers @@ -28,6 +30,8 @@ respective folders - `ptrops` - pointer arithmetic utilities - `result` - friendly, exception-free value-or-error returns, similar to `Option[T]`, from [nim-result](https://github.com/arnetheduck/nim-result/) - `shims` - backports of nim `devel` code to the stable version that Status is using +- `sequtils2` - extensions to the `sequtils` module for working conveniently with `seq` +- `varints` - helpers for working with variable length integers ## Layout diff --git a/stew/arrayops.nim b/stew/arrayops.nim new file mode 100644 index 0000000..8b8d055 --- /dev/null +++ b/stew/arrayops.nim @@ -0,0 +1,80 @@ +# Copyright (c) 2020 Status Research & Development GmbH +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +{.push raises: [Defect].} + +## Operations on array and openArray + +import + ./assign2 + +export assign2 + +template eachElement(x, res, op: untyped) = + for i in 0.. 0: + copyMem(addr tgt[0], unsafeAddr src[0], sizeof(tgt[0]) * tgt.len) + else: + for i in 0.. 0: + let start = s.len + s.setLen(start + v.len) + when supportsCopyMem(T): # shortcut + copyMem(addr s[start], unsafeAddr v[0], v.len * sizeof(T)) + else: + assign(s.toOpenArray(start, s.high), v) diff --git a/tests/all_tests.nim b/tests/all_tests.nim index 7b4f42c..35e7923 100644 --- a/tests/all_tests.nim +++ b/tests/all_tests.nim @@ -9,18 +9,21 @@ import ranges/all, + test_assign2, + test_arrayops, test_base32, test_base58, test_base64, test_bitops2, test_bitseqs, test_byteutils, + test_ctops, test_endians2, + test_io2, test_macros, test_objects, test_ptrops, + test_sequtils2, test_results, test_varints, - test_ctops, - test_io2, - test_winacl \ No newline at end of file + test_winacl diff --git a/tests/test_arrayops.nim b/tests/test_arrayops.nim new file mode 100644 index 0000000..da04265 --- /dev/null +++ b/tests/test_arrayops.nim @@ -0,0 +1,26 @@ +# stew +# Copyright 2018-2019 Status Research & Development GmbH +# Licensed under either of +# +# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) +# +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +{.used.} + +import + std/unittest, + ../stew/arrayops + +suite "arrayops": + test "basic": + let + a = [byte 0, 1] + b = [byte 4, 5] + + check: + (a and b) == [a[0] and b[0], a[1] and b[1]] + (a or b) == [a[0] or b[0], a[1] or b[1]] + (a xor b) == [a[0] xor b[0], a[1] xor b[1]] + (not a) == [not a[0], not a[1]] diff --git a/tests/test_assign2.nim b/tests/test_assign2.nim new file mode 100644 index 0000000..dddbe13 --- /dev/null +++ b/tests/test_assign2.nim @@ -0,0 +1,29 @@ +import + std/unittest, + ../stew/assign2 + +suite "assign2": + test "basic": + type X = distinct int + var + a = 5 + b = [2, 3] + c = @[5, 6] + + assign(c, b) + check: c == b + assign(b, [4, 5]) + check: b == [4, 5] + + assign(a, 6) + check: a == 6 + + assign(c.toOpenArray(0, 1), [2, 2]) + check: c == [2, 2] + + var + dis = X(53) + + assign(dis, X(55)) + + check: int(dis) == 55 diff --git a/tests/test_byteutils.nim b/tests/test_byteutils.nim index cf171d1..ccad076 100644 --- a/tests/test_byteutils.nim +++ b/tests/test_byteutils.nim @@ -5,8 +5,9 @@ # * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). # at your option. This file may not be copied, modified, or distributed except according to those terms. -import unittest, - ../stew/byteutils +import + std/unittest, + ../stew/byteutils proc compilationTest {.exportc: "compilationTest".} = var bytes = @[1.byte, 2, 3, 4] diff --git a/tests/test_sequtils2.nim b/tests/test_sequtils2.nim new file mode 100644 index 0000000..3c52f10 --- /dev/null +++ b/tests/test_sequtils2.nim @@ -0,0 +1,39 @@ +# byteutils +# Copyright (c) 2018 Status Research & Development GmbH +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + std/unittest, + ../stew/sequtils2 + +suite "sequtils2": + test "write": + block: + var a: seq[int] + + a.write([0, 1, 2, 3]) + + check: + a == @[0, 1, 2, 3] + + a.write([]) + a.write([4]) + + check: + a == @[0, 1, 2, 3, 4] + block: + var a: seq[byte] + + a.write([byte 0, 1, 2, 3]) + + check: + a == [byte 0, 1, 2, 3] + + a.write([]) + a.write([byte 4]) + + check: + a == [byte 0, 1, 2, 3, 4]