Implemented outplace differently (#12599)

* implemented sugar.outplace; refs #12550
* Different approach, allows for chaining
This commit is contained in:
Clyybber
2019-11-09 12:52:31 +01:00
committed by Andreas Rumpf
parent 6958248efe
commit 144ad36974
2 changed files with 50 additions and 0 deletions

View File

@@ -36,6 +36,11 @@
`CountTable.take`
- Added `sugar.outplace` for turning in-place algorithms like `sort` and `shuffle` into
operations that work on a copy of the data and return the mutated copy. As the existing
`sorted` does.
## Library changes
- `asyncdispatch.drain` now properly takes into account `selector.hasPendingOperations`

View File

@@ -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