summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorClyybber <darkmine956@gmail.com>2019-11-09 12:52:31 +0100
committerAndreas Rumpf <rumpf_a@web.de>2019-11-09 12:52:31 +0100
commit144ad36974b061f8e723d78d5ab6819627b1877d (patch)
tree047f4b4d0cdfb89cc42ad2ff84cadd52216bba4f /lib
parent6958248efe22a7be45eede4d59ba3f7f8bcf7c01 (diff)
downloadNim-144ad36974b061f8e723d78d5ab6819627b1877d.tar.gz
Implemented outplace differently (#12599)
* implemented sugar.outplace; refs #12550
* Different approach, allows for chaining
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/sugar.nim45
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim
index 21ea4387e..264f3749c 100644
--- a/lib/pure/sugar.nim
+++ b/lib/pure/sugar.nim
@@ -237,3 +237,48 @@ macro distinctBase*(T: typedesc): untyped =
   while typeSym.typeKind == ntyDistinct:
     typeSym = getTypeImpl(typeSym)[0]
   typeSym.freshIdentNodes
+
+when (NimMajor, NimMinor) >= (1, 1):
+  macro outplace*[T](arg: T, call: untyped; inplaceArgPosition: static[int] = 1): T =
+    ## Turns an `in-place`:idx: algorithm into one that works on
+    ## a copy and returns this copy. The second parameter is the
+    ## index of the calling expression that is replaced by a copy
+    ## of this expression.
+    ## **Since**: Version 1.2.
+    runnableExamples:
+      import algorithm
+
+      var a = @[1, 2, 3, 4, 5, 6, 7, 8, 9]
+      doAssert a.outplace(sort()) == sorted(a)
+      #Chaining:
+      var aCopy = a
+      aCopy.insert(10)
+
+      doAssert a.outplace(insert(10)).outplace(sort()) == sorted(aCopy)
+
+    expectKind call, nnkCallKinds
+    let tmp = gensym(nskVar, "outplaceResult")
+    var callsons = call[0..^1]
+    callsons.insert(tmp, inplaceArgPosition)
+    result = newTree(nnkStmtListExpr,
+      newVarStmt(tmp, arg),
+      copyNimNode(call).add callsons,
+      tmp)
+
+  when isMainModule:
+    import algorithm
+
+    var a = @[1, 2, 3, 4, 5, 6, 7, 8, 9]
+    doAssert outplace(a, sort()) == sorted(a)
+    doAssert a.outplace(sort()) == sorted(a)
+    #Chaining:
+    var aCopy = a
+    aCopy.insert(10)
+    doAssert a.outplace(insert(10)).outplace(sort()) == sorted(aCopy)
+
+    import random
+
+    const b = @[0, 1, 2]
+    let c = b.outplace shuffle()
+    doAssert c[0] == 1
+    doAssert c[1] == 0