From c23f4ddf1bd31b0d17dff09ff7a2132854c5f46e Mon Sep 17 00:00:00 2001 From: andri lim Date: Thu, 7 Jun 2018 22:26:08 +0700 Subject: [PATCH 1/3] add concat operation --- ranges/typedranges.nim | 16 ++++++++++++++++ tests/ttypedranges.nim | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/ranges/typedranges.nim b/ranges/typedranges.nim index 0ff8651..9943b69 100644 --- a/ranges/typedranges.nim +++ b/ranges/typedranges.nim @@ -145,3 +145,19 @@ proc `[]=`*[T, U, V](r: MutRange[T], s: HSlice[U, V], v: Range[T]) {.inline.} = r[s] = toOpenArray(v) proc baseAddr*[T](r: Range[T]): ptr T {.inline.} = r.start + +template toRange*[T](a: Range[T]): Range[T] = a + +proc concat*[T](v: varargs[Range[T], toRange]): seq[T] = + var len = 0 + for c in v: inc(len, c.len) + result = newSeq[T](len) + len = 0 + for c in v: + copyMem(result[len].addr, c.start, sizeof(T) * c.len) + inc(len, c.len) + +proc `&`*[T](a, b: Range[T]): seq[T] = + result = newSeq[T](a.len + b.len) + copyMem(result[0].addr, a.start, sizeof(T) * a.len) + copyMem(result[a.len].addr, b.start, sizeof(T) * b.len) diff --git a/tests/ttypedranges.nim b/tests/ttypedranges.nim index 3a49424..3fac19c 100644 --- a/tests/ttypedranges.nim +++ b/tests/ttypedranges.nim @@ -26,3 +26,20 @@ suite "Typed ranges": var z = toRange(@[1, 2, 3, 4]) check y == z check x != z + + test "concat operation": + var a = toRange(@[1,2,3]) + var b = toRange(@[4,5,6]) + var c = toRange(@[7,8,9]) + var d = @[1,2,3,4,5,6,7,8,9] + var e = @[1,2,3,4,5,6] + var f = @[4,5,6,7,8,9] + var x = concat(a, b, c) + var y = a & b + check x == d + check y == e + var z = concat(b, @[7,8,9]) + check z == f + + + From 39f0a3cd03990cf7ce30ed4607ad73eff4d22fb3 Mon Sep 17 00:00:00 2001 From: andri lim Date: Fri, 8 Jun 2018 10:07:47 +0700 Subject: [PATCH 2/3] fix concat operation --- ranges/typedranges.nim | 20 ++++++++++++++++---- tests/ttypedranges.nim | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/ranges/typedranges.nim b/ranges/typedranges.nim index 9943b69..b33cae4 100644 --- a/ranges/typedranges.nim +++ b/ranges/typedranges.nim @@ -1,4 +1,4 @@ -import ./ptr_arith +import ./ptr_arith, typetraits const rangesGCHoldEnabled = not defined(rangesDisableGCHold) const unsafeAPIEnabled = defined(rangesEnableUnsafeAPI) @@ -148,16 +148,28 @@ proc baseAddr*[T](r: Range[T]): ptr T {.inline.} = r.start template toRange*[T](a: Range[T]): Range[T] = a +# this preferred syntax doesn't work +# see https://github.com/nim-lang/Nim/issues/7995 +#template copyRange[T](dest: seq[T], destOffset: int, src: Range[T]) = +# when supportsCopyMem(T): + +template copyRange[T](E: typedesc, dest: seq[T], destOffset: int, src: Range[T]) = + when supportsCopyMem(E): + copyMem(dest[destOffset].unsafeAddr, src.start, sizeof(T) * src.len) + else: + for i in 0.. Date: Tue, 12 Jun 2018 16:00:45 +0700 Subject: [PATCH 3/3] fix zero length concat --- ranges/typedranges.nim | 3 ++- tests/ttypedranges.nim | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ranges/typedranges.nim b/ranges/typedranges.nim index b33cae4..4d2eb7c 100644 --- a/ranges/typedranges.nim +++ b/ranges/typedranges.nim @@ -155,7 +155,8 @@ template toRange*[T](a: Range[T]): Range[T] = a template copyRange[T](E: typedesc, dest: seq[T], destOffset: int, src: Range[T]) = when supportsCopyMem(E): - copyMem(dest[destOffset].unsafeAddr, src.start, sizeof(T) * src.len) + if dest.len != 0 and src.len != 0: + copyMem(dest[destOffset].unsafeAddr, src.start, sizeof(T) * src.len) else: for i in 0..