[other] prettify collections (#11695)
This commit is contained in:
parent
55e8aefbea
commit
2255d8795b
14 changed files with 209 additions and 186 deletions
|
|
@ -64,29 +64,29 @@ type
|
||||||
|
|
||||||
EntryArr = ptr array[0..10_000_000, Entry]
|
EntryArr = ptr array[0..10_000_000, Entry]
|
||||||
|
|
||||||
PConcTable[K,V] = ptr object {.pure.}
|
PConcTable[K, V] = ptr object {.pure.}
|
||||||
len: int
|
len: int
|
||||||
used: int
|
used: int
|
||||||
active: int
|
active: int
|
||||||
copyIdx: int
|
copyIdx: int
|
||||||
copyDone: int
|
copyDone: int
|
||||||
next: PConcTable[K,V]
|
next: PConcTable[K, V]
|
||||||
data: EntryArr
|
data: EntryArr
|
||||||
|
|
||||||
proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int,
|
proc setVal[K, V](table: var PConcTable[K, V], key: int, val: int,
|
||||||
expVal: int, match: bool): int
|
expVal: int, match: bool): int
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
# Create a new table
|
# Create a new table
|
||||||
proc newLFTable*[K,V](size: int = minTableSize): PConcTable[K,V] =
|
proc newLFTable*[K, V](size: int = minTableSize): PConcTable[K, V] =
|
||||||
let
|
let
|
||||||
dataLen = max(nextPowerOfTwo(size), minTableSize)
|
dataLen = max(nextPowerOfTwo(size), minTableSize)
|
||||||
dataSize = dataLen*sizeof(Entry)
|
dataSize = dataLen*sizeof(Entry)
|
||||||
dataMem = allocShared0(dataSize)
|
dataMem = allocShared0(dataSize)
|
||||||
tableSize = 7 * intSize
|
tableSize = 7 * intSize
|
||||||
tableMem = allocShared0(tableSize)
|
tableMem = allocShared0(tableSize)
|
||||||
table = cast[PConcTable[K,V]](tableMem)
|
table = cast[PConcTable[K, V]](tableMem)
|
||||||
table.len = dataLen
|
table.len = dataLen
|
||||||
table.used = 0
|
table.used = 0
|
||||||
table.active = 0
|
table.active = 0
|
||||||
|
|
@ -99,13 +99,13 @@ proc newLFTable*[K,V](size: int = minTableSize): PConcTable[K,V] =
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
# Delete a table
|
# Delete a table
|
||||||
proc deleteConcTable[K,V](tbl: PConcTable[K,V]) =
|
proc deleteConcTable[K, V](tbl: PConcTable[K, V]) =
|
||||||
deallocShared(tbl.data)
|
deallocShared(tbl.data)
|
||||||
deallocShared(tbl)
|
deallocShared(tbl)
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc `[]`[K,V](table: var PConcTable[K,V], i: int): var Entry {.inline.} =
|
proc `[]`[K, V](table: var PConcTable[K, V], i: int): var Entry {.inline.} =
|
||||||
table.data[i]
|
table.data[i]
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
@ -154,7 +154,7 @@ proc setPrime(x: int): int {.inline.} =
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
##This is for i32 only need to override for i64
|
##This is for i32 only need to override for i64
|
||||||
proc hashInt(x: int):int {.inline.} =
|
proc hashInt(x: int): int {.inline.} =
|
||||||
var h = uint32(x) #shr 2'u32
|
var h = uint32(x) #shr 2'u32
|
||||||
h = h xor (h shr 16'u32)
|
h = h xor (h shr 16'u32)
|
||||||
h *= 0x85ebca6b'u32
|
h *= 0x85ebca6b'u32
|
||||||
|
|
@ -165,7 +165,7 @@ proc hashInt(x: int):int {.inline.} =
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc resize[K,V](self: PConcTable[K,V]): PConcTable[K,V] =
|
proc resize[K, V](self: PConcTable[K, V]): PConcTable[K, V] =
|
||||||
var next = atomic_load_n(self.next.addr, ATOMIC_RELAXED)
|
var next = atomic_load_n(self.next.addr, ATOMIC_RELAXED)
|
||||||
#echo("next = " & $cast[int](next))
|
#echo("next = " & $cast[int](next))
|
||||||
if next != nil:
|
if next != nil:
|
||||||
|
|
@ -173,11 +173,12 @@ proc resize[K,V](self: PConcTable[K,V]): PConcTable[K,V] =
|
||||||
return next
|
return next
|
||||||
var
|
var
|
||||||
oldLen = atomic_load_n(self.len.addr, ATOMIC_RELAXED)
|
oldLen = atomic_load_n(self.len.addr, ATOMIC_RELAXED)
|
||||||
newTable = newLFTable[K,V](oldLen*2)
|
newTable = newLFTable[K, V](oldLen*2)
|
||||||
success = atomic_compare_exchange_n(self.next.addr, next.addr, newTable,
|
success = atomic_compare_exchange_n(self.next.addr, next.addr, newTable,
|
||||||
false, ATOMIC_RELAXED, ATOMIC_RELAXED)
|
false, ATOMIC_RELAXED, ATOMIC_RELAXED)
|
||||||
if not success:
|
if not success:
|
||||||
echo("someone beat us to it! delete table we just created and return his " & $cast[int](next))
|
echo("someone beat us to it! delete table we just created and return his " &
|
||||||
|
$cast[int](next))
|
||||||
deleteConcTable(newTable)
|
deleteConcTable(newTable)
|
||||||
return next
|
return next
|
||||||
else:
|
else:
|
||||||
|
|
@ -209,7 +210,8 @@ proc keyEQ[K](key1: int, key2: int): bool {.inline.} =
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc copySlot[K,V](idx: int, oldTbl: var PConcTable[K,V], newTbl: var PConcTable[K,V]): bool =
|
proc copySlot[K, V](idx: int, oldTbl: var PConcTable[K, V],
|
||||||
|
newTbl: var PConcTable[K, V]): bool =
|
||||||
#echo("Copy idx " & $idx)
|
#echo("Copy idx " & $idx)
|
||||||
var
|
var
|
||||||
oldVal = 0
|
oldVal = 0
|
||||||
|
|
@ -224,7 +226,7 @@ proc copySlot[K,V](idx: int, oldTbl: var PConcTable[K,V], newTbl: var PConcTable
|
||||||
#Prevent new values from appearing in the old table by priming
|
#Prevent new values from appearing in the old table by priming
|
||||||
oldVal = atomic_load_n(oldTbl[idx].value.addr, ATOMIC_RELAXED)
|
oldVal = atomic_load_n(oldTbl[idx].value.addr, ATOMIC_RELAXED)
|
||||||
while not isPrime(oldVal):
|
while not isPrime(oldVal):
|
||||||
var box = if oldVal == 0 or isTomb(oldVal) : oldVal.setTomb.setPrime
|
var box = if oldVal == 0 or isTomb(oldVal): oldVal.setTomb.setPrime
|
||||||
else: oldVal.setPrime
|
else: oldVal.setPrime
|
||||||
if atomic_compare_exchange_n(oldTbl[idx].value.addr, oldVal.addr,
|
if atomic_compare_exchange_n(oldTbl[idx].value.addr, oldVal.addr,
|
||||||
box, false, ATOMIC_RELAXED, ATOMIC_RELAXED):
|
box, false, ATOMIC_RELAXED, ATOMIC_RELAXED):
|
||||||
|
|
@ -248,13 +250,13 @@ proc copySlot[K,V](idx: int, oldTbl: var PConcTable[K,V], newTbl: var PConcTable
|
||||||
# Our copy is done so we disable the old slot
|
# Our copy is done so we disable the old slot
|
||||||
while not ok:
|
while not ok:
|
||||||
ok = atomic_compare_exchange_n(oldTbl[idx].value.addr, oldVal.addr,
|
ok = atomic_compare_exchange_n(oldTbl[idx].value.addr, oldVal.addr,
|
||||||
oldVal.setTomb.setPrime , false, ATOMIC_RELAXED, ATOMIC_RELAXED)
|
oldVal.setTomb.setPrime, false, ATOMIC_RELAXED, ATOMIC_RELAXED)
|
||||||
#echo("disabled old slot")
|
#echo("disabled old slot")
|
||||||
#echo"---------------------"
|
#echo"---------------------"
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc promote[K,V](table: var PConcTable[K,V]) =
|
proc promote[K, V](table: var PConcTable[K, V]) =
|
||||||
var
|
var
|
||||||
newData = atomic_load_n(table.next.data.addr, ATOMIC_RELAXED)
|
newData = atomic_load_n(table.next.data.addr, ATOMIC_RELAXED)
|
||||||
newLen = atomic_load_n(table.next.len.addr, ATOMIC_RELAXED)
|
newLen = atomic_load_n(table.next.len.addr, ATOMIC_RELAXED)
|
||||||
|
|
@ -272,7 +274,7 @@ proc promote[K,V](table: var PConcTable[K,V]) =
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc checkAndPromote[K,V](table: var PConcTable[K,V], workDone: int): bool =
|
proc checkAndPromote[K, V](table: var PConcTable[K, V], workDone: int): bool =
|
||||||
var
|
var
|
||||||
oldLen = atomic_load_n(table.len.addr, ATOMIC_RELAXED)
|
oldLen = atomic_load_n(table.len.addr, ATOMIC_RELAXED)
|
||||||
copyDone = atomic_load_n(table.copyDone.addr, ATOMIC_RELAXED)
|
copyDone = atomic_load_n(table.copyDone.addr, ATOMIC_RELAXED)
|
||||||
|
|
@ -294,10 +296,11 @@ proc checkAndPromote[K,V](table: var PConcTable[K,V], workDone: int): bool =
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc copySlotAndCheck[K,V](table: var PConcTable[K,V], idx: int):
|
proc copySlotAndCheck[K, V](table: var PConcTable[K, V], idx: int):
|
||||||
PConcTable[K,V] =
|
PConcTable[K, V] =
|
||||||
var
|
var
|
||||||
newTable = cast[PConcTable[K,V]](atomic_load_n(table.next.addr, ATOMIC_RELAXED))
|
newTable = cast[PConcTable[K, V]](atomic_load_n(table.next.addr,
|
||||||
|
ATOMIC_RELAXED))
|
||||||
result = newTable
|
result = newTable
|
||||||
if newTable != nil and copySlot(idx, table, newTable):
|
if newTable != nil and copySlot(idx, table, newTable):
|
||||||
#echo("copied a single slot, idx = " & $idx)
|
#echo("copied a single slot, idx = " & $idx)
|
||||||
|
|
@ -306,9 +309,10 @@ proc copySlotAndCheck[K,V](table: var PConcTable[K,V], idx: int):
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc helpCopy[K,V](table: var PConcTable[K,V]): PConcTable[K,V] =
|
proc helpCopy[K, V](table: var PConcTable[K, V]): PConcTable[K, V] =
|
||||||
var
|
var
|
||||||
newTable = cast[PConcTable[K,V]](atomic_load_n(table.next.addr, ATOMIC_RELAXED))
|
newTable = cast[PConcTable[K, V]](atomic_load_n(table.next.addr,
|
||||||
|
ATOMIC_RELAXED))
|
||||||
result = newTable
|
result = newTable
|
||||||
if newTable != nil:
|
if newTable != nil:
|
||||||
var
|
var
|
||||||
|
|
@ -338,7 +342,7 @@ proc helpCopy[K,V](table: var PConcTable[K,V]): PConcTable[K,V] =
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int,
|
proc setVal[K, V](table: var PConcTable[K, V], key: int, val: int,
|
||||||
expVal: int, match: bool): int =
|
expVal: int, match: bool): int =
|
||||||
#echo("-try set- in table ", " key = ", (popPtr[K](key)[]), " val = ", val)
|
#echo("-try set- in table ", " key = ", (popPtr[K](key)[]), " val = ", val)
|
||||||
when K is Raw:
|
when K is Raw:
|
||||||
|
|
@ -346,7 +350,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int,
|
||||||
else:
|
else:
|
||||||
var idx = popPtr[K](key)[].hash
|
var idx = popPtr[K](key)[].hash
|
||||||
var
|
var
|
||||||
nextTable: PConcTable[K,V]
|
nextTable: PConcTable[K, V]
|
||||||
probes = 1
|
probes = 1
|
||||||
# spin until we find a key slot or build and jump to next table
|
# spin until we find a key slot or build and jump to next table
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -400,7 +404,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int,
|
||||||
nextTable = resize(table)
|
nextTable = resize(table)
|
||||||
if nextTable != nil:
|
if nextTable != nil:
|
||||||
#echo("tomb old slot then set in new table")
|
#echo("tomb old slot then set in new table")
|
||||||
nextTable = copySlotAndCheck(table,idx)
|
nextTable = copySlotAndCheck(table, idx)
|
||||||
return setVal(nextTable, key, val, expVal, match)
|
return setVal(nextTable, key, val, expVal, match)
|
||||||
# Finally ready to add new val to table
|
# Finally ready to add new val to table
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -424,7 +428,7 @@ proc setVal[K,V](table: var PConcTable[K,V], key: int, val: int,
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc getVal[K,V](table: var PConcTable[K,V], key: int): int =
|
proc getVal[K, V](table: var PConcTable[K, V], key: int): int =
|
||||||
#echo("-try get- key = " & $key)
|
#echo("-try get- key = " & $key)
|
||||||
when K is Raw:
|
when K is Raw:
|
||||||
var idx = hashInt(key)
|
var idx = hashInt(key)
|
||||||
|
|
@ -437,7 +441,7 @@ proc getVal[K,V](table: var PConcTable[K,V], key: int): int =
|
||||||
while true:
|
while true:
|
||||||
idx = idx and (table.len - 1)
|
idx = idx and (table.len - 1)
|
||||||
var
|
var
|
||||||
newTable: PConcTable[K,V] # = atomic_load_n(table.next.addr, ATOMIC_ACQUIRE)
|
newTable: PConcTable[K, V] # = atomic_load_n(table.next.addr, ATOMIC_ACQUIRE)
|
||||||
probedKey = atomic_load_n(table[idx].key.addr, ATOMIC_SEQ_CST)
|
probedKey = atomic_load_n(table[idx].key.addr, ATOMIC_SEQ_CST)
|
||||||
if keyEQ[K](probedKey, key):
|
if keyEQ[K](probedKey, key):
|
||||||
#echo("found key after ", probes+1)
|
#echo("found key after ", probes+1)
|
||||||
|
|
@ -472,7 +476,7 @@ proc getVal[K,V](table: var PConcTable[K,V], key: int): int =
|
||||||
#proc set*[V](table: var PConcTable[Raw,V], key: Raw, val: ptr V) =
|
#proc set*[V](table: var PConcTable[Raw,V], key: Raw, val: ptr V) =
|
||||||
# discard setVal(table, pack(key), cast[int](val), 0, false)
|
# discard setVal(table, pack(key), cast[int](val), 0, false)
|
||||||
|
|
||||||
proc set*[K,V](table: var PConcTable[K,V], key: var K, val: var V) =
|
proc set*[K, V](table: var PConcTable[K, V], key: var K, val: var V) =
|
||||||
when not (K is Raw):
|
when not (K is Raw):
|
||||||
var newKey = cast[int](copyShared(key))
|
var newKey = cast[int](copyShared(key))
|
||||||
else:
|
else:
|
||||||
|
|
@ -489,7 +493,7 @@ proc set*[K,V](table: var PConcTable[K,V], key: var K, val: var V) =
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proc get*[K,V](table: var PConcTable[K,V], key: var K): V =
|
proc get*[K, V](table: var PConcTable[K, V], key: var K): V =
|
||||||
when not (V is Raw):
|
when not (V is Raw):
|
||||||
when not (K is Raw):
|
when not (K is Raw):
|
||||||
return popPtr[V](getVal(table, cast[int](key.addr)))[]
|
return popPtr[V](getVal(table, cast[int](key.addr)))[]
|
||||||
|
|
@ -538,14 +542,14 @@ when not defined(testing) and isMainModule:
|
||||||
f0: int
|
f0: int
|
||||||
f1: int
|
f1: int
|
||||||
|
|
||||||
Data = tuple[k: string,v: TestObj]
|
Data = tuple[k: string, v: TestObj]
|
||||||
PDataArr = array[0..numTests-1, Data]
|
PDataArr = array[0..numTests-1, Data]
|
||||||
Dict = PConcTable[string,TestObj]
|
Dict = PConcTable[string, TestObj]
|
||||||
|
|
||||||
var
|
var
|
||||||
thr: array[0..numThreads-1, Thread[Dict]]
|
thr: array[0..numThreads-1, Thread[Dict]]
|
||||||
|
|
||||||
table = newLFTable[string,TestObj](8)
|
table = newLFTable[string, TestObj](8)
|
||||||
rand = newMersenneTwister(2525)
|
rand = newMersenneTwister(2525)
|
||||||
|
|
||||||
proc createSampleData(len: int): PDataArr =
|
proc createSampleData(len: int): PDataArr =
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ proc rawInsert[T](c: var CritBitTree[T], key: string): Node[T] =
|
||||||
wherep[] = inner
|
wherep[] = inner
|
||||||
inc c.count
|
inc c.count
|
||||||
|
|
||||||
proc exclImpl[T](c: var CritBitTree[T], key: string) : int =
|
proc exclImpl[T](c: var CritBitTree[T], key: string): int =
|
||||||
var p = c.root
|
var p = c.root
|
||||||
var wherep = addr(c.root)
|
var wherep = addr(c.root)
|
||||||
var whereq: ptr Node[T] = nil
|
var whereq: ptr Node[T] = nil
|
||||||
|
|
@ -237,7 +237,8 @@ iterator mpairs*[T](c: var CritBitTree[T]): tuple[key: string, val: var T] =
|
||||||
## yields all (key, value)-pairs of `c`. The yielded values can be modified.
|
## yields all (key, value)-pairs of `c`. The yielded values can be modified.
|
||||||
for x in leaves(c.root): yield (x.key, x.val)
|
for x in leaves(c.root): yield (x.key, x.val)
|
||||||
|
|
||||||
proc allprefixedAux[T](c: CritBitTree[T], key: string; longestMatch: bool): Node[T] =
|
proc allprefixedAux[T](c: CritBitTree[T], key: string;
|
||||||
|
longestMatch: bool): Node[T] =
|
||||||
var p = c.root
|
var p = c.root
|
||||||
var top = p
|
var top = p
|
||||||
if p != nil:
|
if p != nil:
|
||||||
|
|
@ -253,27 +254,27 @@ proc allprefixedAux[T](c: CritBitTree[T], key: string; longestMatch: bool): Node
|
||||||
result = top
|
result = top
|
||||||
|
|
||||||
iterator itemsWithPrefix*[T](c: CritBitTree[T], prefix: string;
|
iterator itemsWithPrefix*[T](c: CritBitTree[T], prefix: string;
|
||||||
longestMatch=false): string =
|
longestMatch = false): string =
|
||||||
## yields all keys starting with `prefix`. If `longestMatch` is true,
|
## yields all keys starting with `prefix`. If `longestMatch` is true,
|
||||||
## the longest match is returned, it doesn't have to be a complete match then.
|
## the longest match is returned, it doesn't have to be a complete match then.
|
||||||
let top = allprefixedAux(c, prefix, longestMatch)
|
let top = allprefixedAux(c, prefix, longestMatch)
|
||||||
for x in leaves(top): yield x.key
|
for x in leaves(top): yield x.key
|
||||||
|
|
||||||
iterator keysWithPrefix*[T](c: CritBitTree[T], prefix: string;
|
iterator keysWithPrefix*[T](c: CritBitTree[T], prefix: string;
|
||||||
longestMatch=false): string =
|
longestMatch = false): string =
|
||||||
## yields all keys starting with `prefix`.
|
## yields all keys starting with `prefix`.
|
||||||
let top = allprefixedAux(c, prefix, longestMatch)
|
let top = allprefixedAux(c, prefix, longestMatch)
|
||||||
for x in leaves(top): yield x.key
|
for x in leaves(top): yield x.key
|
||||||
|
|
||||||
iterator valuesWithPrefix*[T](c: CritBitTree[T], prefix: string;
|
iterator valuesWithPrefix*[T](c: CritBitTree[T], prefix: string;
|
||||||
longestMatch=false): T =
|
longestMatch = false): T =
|
||||||
## yields all values of `c` starting with `prefix` of the
|
## yields all values of `c` starting with `prefix` of the
|
||||||
## corresponding keys.
|
## corresponding keys.
|
||||||
let top = allprefixedAux(c, prefix, longestMatch)
|
let top = allprefixedAux(c, prefix, longestMatch)
|
||||||
for x in leaves(top): yield x.val
|
for x in leaves(top): yield x.val
|
||||||
|
|
||||||
iterator mvaluesWithPrefix*[T](c: var CritBitTree[T], prefix: string;
|
iterator mvaluesWithPrefix*[T](c: var CritBitTree[T], prefix: string;
|
||||||
longestMatch=false): var T =
|
longestMatch = false): var T =
|
||||||
## yields all values of `c` starting with `prefix` of the
|
## yields all values of `c` starting with `prefix` of the
|
||||||
## corresponding keys. The values can be modified.
|
## corresponding keys. The values can be modified.
|
||||||
let top = allprefixedAux(c, prefix, longestMatch)
|
let top = allprefixedAux(c, prefix, longestMatch)
|
||||||
|
|
@ -281,14 +282,14 @@ iterator mvaluesWithPrefix*[T](c: var CritBitTree[T], prefix: string;
|
||||||
|
|
||||||
iterator pairsWithPrefix*[T](c: CritBitTree[T],
|
iterator pairsWithPrefix*[T](c: CritBitTree[T],
|
||||||
prefix: string;
|
prefix: string;
|
||||||
longestMatch=false): tuple[key: string, val: T] =
|
longestMatch = false): tuple[key: string, val: T] =
|
||||||
## yields all (key, value)-pairs of `c` starting with `prefix`.
|
## yields all (key, value)-pairs of `c` starting with `prefix`.
|
||||||
let top = allprefixedAux(c, prefix, longestMatch)
|
let top = allprefixedAux(c, prefix, longestMatch)
|
||||||
for x in leaves(top): yield (x.key, x.val)
|
for x in leaves(top): yield (x.key, x.val)
|
||||||
|
|
||||||
iterator mpairsWithPrefix*[T](c: var CritBitTree[T],
|
iterator mpairsWithPrefix*[T](c: var CritBitTree[T],
|
||||||
prefix: string;
|
prefix: string;
|
||||||
longestMatch=false): tuple[key: string, val: var T] =
|
longestMatch = false): tuple[key: string, val: var T] =
|
||||||
## yields all (key, value)-pairs of `c` starting with `prefix`.
|
## yields all (key, value)-pairs of `c` starting with `prefix`.
|
||||||
## The yielded values can be modified.
|
## The yielded values can be modified.
|
||||||
let top = allprefixedAux(c, prefix, longestMatch)
|
let top = allprefixedAux(c, prefix, longestMatch)
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ template xBoundsCheck(deq, i) =
|
||||||
raise newException(IndexError,
|
raise newException(IndexError,
|
||||||
"Out of bounds: " & $i & " < 0")
|
"Out of bounds: " & $i & " < 0")
|
||||||
|
|
||||||
proc `[]`*[T](deq: Deque[T], i: Natural) : T {.inline.} =
|
proc `[]`*[T](deq: Deque[T], i: Natural): T {.inline.} =
|
||||||
## Access the i-th element of `deq`.
|
## Access the i-th element of `deq`.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var a = initDeque[int]()
|
var a = initDeque[int]()
|
||||||
|
|
@ -124,7 +124,7 @@ proc `[]`*[T](deq: var Deque[T], i: Natural): var T {.inline.} =
|
||||||
xBoundsCheck(deq, i)
|
xBoundsCheck(deq, i)
|
||||||
return deq.data[(deq.head + i) and deq.mask]
|
return deq.data[(deq.head + i) and deq.mask]
|
||||||
|
|
||||||
proc `[]=`*[T](deq: var Deque[T], i: Natural, val : T) {.inline.} =
|
proc `[]=`*[T](deq: var Deque[T], i: Natural, val: T) {.inline.} =
|
||||||
## Change the i-th element of `deq`.
|
## Change the i-th element of `deq`.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var a = initDeque[int]()
|
var a = initDeque[int]()
|
||||||
|
|
@ -306,7 +306,7 @@ proc addLast*[T](deq: var Deque[T], item: T) =
|
||||||
deq.data[deq.tail] = item
|
deq.data[deq.tail] = item
|
||||||
deq.tail = (deq.tail + 1) and deq.mask
|
deq.tail = (deq.tail + 1) and deq.mask
|
||||||
|
|
||||||
proc peekFirst*[T](deq: Deque[T]): T {.inline.}=
|
proc peekFirst*[T](deq: Deque[T]): T {.inline.} =
|
||||||
## Returns the first element of `deq`, but does not remove it from the deque.
|
## Returns the first element of `deq`, but does not remove it from the deque.
|
||||||
##
|
##
|
||||||
## See also:
|
## See also:
|
||||||
|
|
@ -547,9 +547,9 @@ when isMainModule:
|
||||||
assert deq.popFirst() > 0
|
assert deq.popFirst() > 0
|
||||||
|
|
||||||
#foo(0,0)
|
#foo(0,0)
|
||||||
foo(8,5)
|
foo(8, 5)
|
||||||
foo(10,9)
|
foo(10, 9)
|
||||||
foo(1,1)
|
foo(1, 1)
|
||||||
foo(2,1)
|
foo(2, 1)
|
||||||
foo(1,5)
|
foo(1, 5)
|
||||||
foo(3,2)
|
foo(3, 2)
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,8 @@ proc contains*(s: IntSet, key: int): bool =
|
||||||
var t = intSetGet(s, `shr`(key, TrunkShift))
|
var t = intSetGet(s, `shr`(key, TrunkShift))
|
||||||
if t != nil:
|
if t != nil:
|
||||||
var u = key and TrunkMask
|
var u = key and TrunkMask
|
||||||
result = (t.bits[u shr IntShift] and (BitScalar(1) shl (u and IntMask))) != 0
|
result = (t.bits[u shr IntShift] and
|
||||||
|
(BitScalar(1) shl (u and IntMask))) != 0
|
||||||
else:
|
else:
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
|
|
@ -316,7 +317,7 @@ proc excl*(s: var IntSet, other: IntSet) =
|
||||||
|
|
||||||
for item in other: excl(s, item)
|
for item in other: excl(s, item)
|
||||||
|
|
||||||
proc missingOrExcl*(s: var IntSet, key: int) : bool =
|
proc missingOrExcl*(s: var IntSet, key: int): bool =
|
||||||
## Excludes `key` in the set `s` and tells if `key` was already missing from `s`.
|
## Excludes `key` in the set `s` and tells if `key` was already missing from `s`.
|
||||||
##
|
##
|
||||||
## The difference with regards to the `excl proc <#excl,IntSet,int>`_ is
|
## The difference with regards to the `excl proc <#excl,IntSet,int>`_ is
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,8 @@ when not defined(nimhygiene):
|
||||||
{.pragma: dirty.}
|
{.pragma: dirty.}
|
||||||
|
|
||||||
type
|
type
|
||||||
DoublyLinkedNodeObj*[T] = object ## A node a doubly linked list consists of.
|
DoublyLinkedNodeObj*[T] = object ## \
|
||||||
|
## A node a doubly linked list consists of.
|
||||||
##
|
##
|
||||||
## It consists of a `value` field, and pointers to `next` and `prev`.
|
## It consists of a `value` field, and pointers to `next` and `prev`.
|
||||||
next*: <//>(ref DoublyLinkedNodeObj[T])
|
next*: <//>(ref DoublyLinkedNodeObj[T])
|
||||||
|
|
@ -85,35 +86,40 @@ type
|
||||||
value*: T
|
value*: T
|
||||||
DoublyLinkedNode*[T] = ref DoublyLinkedNodeObj[T]
|
DoublyLinkedNode*[T] = ref DoublyLinkedNodeObj[T]
|
||||||
|
|
||||||
SinglyLinkedNodeObj*[T] = object ## A node a singly linked list consists of.
|
SinglyLinkedNodeObj*[T] = object ## \
|
||||||
|
## A node a singly linked list consists of.
|
||||||
##
|
##
|
||||||
## It consists of a `value` field, and a pointer to `next`.
|
## It consists of a `value` field, and a pointer to `next`.
|
||||||
next*: <//>(ref SinglyLinkedNodeObj[T])
|
next*: <//>(ref SinglyLinkedNodeObj[T])
|
||||||
value*: T
|
value*: T
|
||||||
SinglyLinkedNode*[T] = ref SinglyLinkedNodeObj[T]
|
SinglyLinkedNode*[T] = ref SinglyLinkedNodeObj[T]
|
||||||
|
|
||||||
SinglyLinkedList*[T] = object ## A singly linked list.
|
SinglyLinkedList*[T] = object ## \
|
||||||
|
## A singly linked list.
|
||||||
##
|
##
|
||||||
## Use `initSinglyLinkedList proc <#initSinglyLinkedList>`_ to create
|
## Use `initSinglyLinkedList proc <#initSinglyLinkedList>`_ to create
|
||||||
## a new empty list.
|
## a new empty list.
|
||||||
head*: <//>(SinglyLinkedNode[T])
|
head*: <//>(SinglyLinkedNode[T])
|
||||||
tail*: SinglyLinkedNode[T]
|
tail*: SinglyLinkedNode[T]
|
||||||
|
|
||||||
DoublyLinkedList*[T] = object ## A doubly linked list.
|
DoublyLinkedList*[T] = object ## \
|
||||||
|
## A doubly linked list.
|
||||||
##
|
##
|
||||||
## Use `initDoublyLinkedList proc <#initDoublyLinkedList>`_ to create
|
## Use `initDoublyLinkedList proc <#initDoublyLinkedList>`_ to create
|
||||||
## a new empty list.
|
## a new empty list.
|
||||||
head*: <//>(DoublyLinkedNode[T])
|
head*: <//>(DoublyLinkedNode[T])
|
||||||
tail*: DoublyLinkedNode[T]
|
tail*: DoublyLinkedNode[T]
|
||||||
|
|
||||||
SinglyLinkedRing*[T] = object ## A singly linked ring.
|
SinglyLinkedRing*[T] = object ## \
|
||||||
|
## A singly linked ring.
|
||||||
##
|
##
|
||||||
## Use `initSinglyLinkedRing proc <#initSinglyLinkedRing>`_ to create
|
## Use `initSinglyLinkedRing proc <#initSinglyLinkedRing>`_ to create
|
||||||
## a new empty ring.
|
## a new empty ring.
|
||||||
head*: <//>(SinglyLinkedNode[T])
|
head*: <//>(SinglyLinkedNode[T])
|
||||||
tail*: SinglyLinkedNode[T]
|
tail*: SinglyLinkedNode[T]
|
||||||
|
|
||||||
DoublyLinkedRing*[T] = object ## A doubly linked ring.
|
DoublyLinkedRing*[T] = object ## \
|
||||||
|
## A doubly linked ring.
|
||||||
##
|
##
|
||||||
## Use `initDoublyLinkedRing proc <#initDoublyLinkedRing>`_ to create
|
## Use `initDoublyLinkedRing proc <#initDoublyLinkedRing>`_ to create
|
||||||
## a new empty ring.
|
## a new empty ring.
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,8 @@ when not defined(nimhygiene):
|
||||||
{.pragma: dirty.}
|
{.pragma: dirty.}
|
||||||
|
|
||||||
|
|
||||||
macro evalOnceAs(expAlias, exp: untyped, letAssigneable: static[bool]): untyped =
|
macro evalOnceAs(expAlias, exp: untyped,
|
||||||
|
letAssigneable: static[bool]): untyped =
|
||||||
## Injects ``expAlias`` in caller scope, to avoid bugs involving multiple
|
## Injects ``expAlias`` in caller scope, to avoid bugs involving multiple
|
||||||
## substitution in macro arguments such as
|
## substitution in macro arguments such as
|
||||||
## https://github.com/nim-lang/Nim/issues/7187
|
## https://github.com/nim-lang/Nim/issues/7187
|
||||||
|
|
@ -426,8 +427,8 @@ proc delete*[T](s: var seq[T]; first, last: Natural) =
|
||||||
## This modifies `s` itself, it does not return a copy.
|
## This modifies `s` itself, it does not return a copy.
|
||||||
##
|
##
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
let outcome = @[1,1,1,1,1,1,1,1]
|
let outcome = @[1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
|
var dest = @[1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1]
|
||||||
dest.delete(3, 8)
|
dest.delete(3, 8)
|
||||||
assert outcome == dest
|
assert outcome == dest
|
||||||
|
|
||||||
|
|
@ -440,17 +441,17 @@ proc delete*[T](s: var seq[T]; first, last: Natural) =
|
||||||
inc(j)
|
inc(j)
|
||||||
setLen(s, newLen)
|
setLen(s, newLen)
|
||||||
|
|
||||||
proc insert*[T](dest: var seq[T], src: openArray[T], pos=0) =
|
proc insert*[T](dest: var seq[T], src: openArray[T], pos = 0) =
|
||||||
## Inserts items from `src` into `dest` at position `pos`. This modifies
|
## Inserts items from `src` into `dest` at position `pos`. This modifies
|
||||||
## `dest` itself, it does not return a copy.
|
## `dest` itself, it does not return a copy.
|
||||||
##
|
##
|
||||||
## Notice that `src` and `dest` must be of the same type.
|
## Notice that `src` and `dest` must be of the same type.
|
||||||
##
|
##
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
var dest = @[1,1,1,1,1,1,1,1]
|
var dest = @[1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
let
|
let
|
||||||
src = @[2,2,2,2,2,2]
|
src = @[2, 2, 2, 2, 2, 2]
|
||||||
outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
|
outcome = @[1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1]
|
||||||
dest.insert(src, 3)
|
dest.insert(src, 3)
|
||||||
assert dest == outcome
|
assert dest == outcome
|
||||||
|
|
||||||
|
|
@ -639,7 +640,7 @@ template toSeq2(iter: iterator): untyped =
|
||||||
var result: seq[outType] = @[]
|
var result: seq[outType] = @[]
|
||||||
when compiles(iter2()):
|
when compiles(iter2()):
|
||||||
evalOnceAs(iter4, iter, false)
|
evalOnceAs(iter4, iter, false)
|
||||||
let iter3=iter4()
|
let iter3 = iter4()
|
||||||
for x in iter3():
|
for x in iter3():
|
||||||
result.add(x)
|
result.add(x)
|
||||||
else:
|
else:
|
||||||
|
|
@ -900,7 +901,7 @@ template newSeqWith*(len: int, init: untyped): untyped =
|
||||||
proc mapLitsImpl(constructor: NimNode; op: NimNode; nested: bool;
|
proc mapLitsImpl(constructor: NimNode; op: NimNode; nested: bool;
|
||||||
filter = nnkLiterals): NimNode =
|
filter = nnkLiterals): NimNode =
|
||||||
if constructor.kind in filter:
|
if constructor.kind in filter:
|
||||||
result = newNimNode(nnkCall, lineInfoFrom=constructor)
|
result = newNimNode(nnkCall, lineInfoFrom = constructor)
|
||||||
result.add op
|
result.add op
|
||||||
result.add constructor
|
result.add constructor
|
||||||
else:
|
else:
|
||||||
|
|
@ -962,7 +963,7 @@ when isMainModule:
|
||||||
# helper for testing double substitution side effects which are handled
|
# helper for testing double substitution side effects which are handled
|
||||||
# by `evalOnceAs`
|
# by `evalOnceAs`
|
||||||
var counter = 0
|
var counter = 0
|
||||||
proc identity[T](a:T):auto=
|
proc identity[T](a: T): auto =
|
||||||
counter.inc
|
counter.inc
|
||||||
a
|
a
|
||||||
|
|
||||||
|
|
@ -1020,8 +1021,8 @@ when isMainModule:
|
||||||
|
|
||||||
block: # repeat tests
|
block: # repeat tests
|
||||||
assert repeat(10, 5) == @[10, 10, 10, 10, 10]
|
assert repeat(10, 5) == @[10, 10, 10, 10, 10]
|
||||||
assert repeat(@[1,2,3], 2) == @[@[1,2,3], @[1,2,3]]
|
assert repeat(@[1, 2, 3], 2) == @[@[1, 2, 3], @[1, 2, 3]]
|
||||||
assert repeat([1,2,3], 2) == @[[1,2,3], [1,2,3]]
|
assert repeat([1, 2, 3], 2) == @[[1, 2, 3], [1, 2, 3]]
|
||||||
|
|
||||||
block: # deduplicates test
|
block: # deduplicates test
|
||||||
let
|
let
|
||||||
|
|
@ -1115,9 +1116,9 @@ when isMainModule:
|
||||||
colors = @["red", "yellow", "black"]
|
colors = @["red", "yellow", "black"]
|
||||||
acolors = ["red", "yellow", "black"]
|
acolors = ["red", "yellow", "black"]
|
||||||
f1 = filter(colors, proc(x: string): bool = x.len < 6)
|
f1 = filter(colors, proc(x: string): bool = x.len < 6)
|
||||||
f2 = filter(colors) do (x: string) -> bool : x.len > 5
|
f2 = filter(colors) do (x: string) -> bool: x.len > 5
|
||||||
f3 = filter(acolors, proc(x: string): bool = x.len < 6)
|
f3 = filter(acolors, proc(x: string): bool = x.len < 6)
|
||||||
f4 = filter(acolors) do (x: string) -> bool : x.len > 5
|
f4 = filter(acolors) do (x: string) -> bool: x.len > 5
|
||||||
assert f1 == @["red", "black"]
|
assert f1 == @["red", "black"]
|
||||||
assert f2 == @["yellow"]
|
assert f2 == @["yellow"]
|
||||||
assert f3 == @["red", "black"]
|
assert f3 == @["red", "black"]
|
||||||
|
|
@ -1137,18 +1138,18 @@ when isMainModule:
|
||||||
assert floats == @[13.0, 12.5, 10.1]
|
assert floats == @[13.0, 12.5, 10.1]
|
||||||
|
|
||||||
block: # delete tests
|
block: # delete tests
|
||||||
let outcome = @[1,1,1,1,1,1,1,1]
|
let outcome = @[1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
var dest = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
|
var dest = @[1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1]
|
||||||
dest.delete(3, 8)
|
dest.delete(3, 8)
|
||||||
assert outcome == dest, """\
|
assert outcome == dest, """\
|
||||||
Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1]
|
Deleting range 3-9 from [1,1,1,2,2,2,2,2,2,1,1,1,1,1]
|
||||||
is [1,1,1,1,1,1,1,1]"""
|
is [1,1,1,1,1,1,1,1]"""
|
||||||
|
|
||||||
block: # insert tests
|
block: # insert tests
|
||||||
var dest = @[1,1,1,1,1,1,1,1]
|
var dest = @[1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
let
|
let
|
||||||
src = @[2,2,2,2,2,2]
|
src = @[2, 2, 2, 2, 2, 2]
|
||||||
outcome = @[1,1,1,2,2,2,2,2,2,1,1,1,1,1]
|
outcome = @[1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1]
|
||||||
dest.insert(src, 3)
|
dest.insert(src, 3)
|
||||||
assert dest == outcome, """\
|
assert dest == outcome, """\
|
||||||
Inserting [2,2,2,2,2,2] into [1,1,1,1,1,1,1,1]
|
Inserting [2,2,2,2,2,2] into [1,1,1,1,1,1,1,1]
|
||||||
|
|
@ -1171,7 +1172,7 @@ when isMainModule:
|
||||||
let
|
let
|
||||||
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
||||||
anumbers = [1, 4, 5, 8, 9, 7, 4]
|
anumbers = [1, 4, 5, 8, 9, 7, 4]
|
||||||
len0seq : seq[int] = @[]
|
len0seq: seq[int] = @[]
|
||||||
assert all(numbers, proc (x: int): bool = return x < 10) == true
|
assert all(numbers, proc (x: int): bool = return x < 10) == true
|
||||||
assert all(numbers, proc (x: int): bool = return x < 9) == false
|
assert all(numbers, proc (x: int): bool = return x < 9) == false
|
||||||
assert all(len0seq, proc (x: int): bool = return false) == true
|
assert all(len0seq, proc (x: int): bool = return false) == true
|
||||||
|
|
@ -1182,7 +1183,7 @@ when isMainModule:
|
||||||
let
|
let
|
||||||
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
||||||
anumbers = [1, 4, 5, 8, 9, 7, 4]
|
anumbers = [1, 4, 5, 8, 9, 7, 4]
|
||||||
len0seq : seq[int] = @[]
|
len0seq: seq[int] = @[]
|
||||||
assert allIt(numbers, it < 10) == true
|
assert allIt(numbers, it < 10) == true
|
||||||
assert allIt(numbers, it < 9) == false
|
assert allIt(numbers, it < 9) == false
|
||||||
assert allIt(len0seq, false) == true
|
assert allIt(len0seq, false) == true
|
||||||
|
|
@ -1193,7 +1194,7 @@ when isMainModule:
|
||||||
let
|
let
|
||||||
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
||||||
anumbers = [1, 4, 5, 8, 9, 7, 4]
|
anumbers = [1, 4, 5, 8, 9, 7, 4]
|
||||||
len0seq : seq[int] = @[]
|
len0seq: seq[int] = @[]
|
||||||
assert any(numbers, proc (x: int): bool = return x > 8) == true
|
assert any(numbers, proc (x: int): bool = return x > 8) == true
|
||||||
assert any(numbers, proc (x: int): bool = return x > 9) == false
|
assert any(numbers, proc (x: int): bool = return x > 9) == false
|
||||||
assert any(len0seq, proc (x: int): bool = return true) == false
|
assert any(len0seq, proc (x: int): bool = return true) == false
|
||||||
|
|
@ -1204,7 +1205,7 @@ when isMainModule:
|
||||||
let
|
let
|
||||||
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
numbers = @[1, 4, 5, 8, 9, 7, 4]
|
||||||
anumbers = [1, 4, 5, 8, 9, 7, 4]
|
anumbers = [1, 4, 5, 8, 9, 7, 4]
|
||||||
len0seq : seq[int] = @[]
|
len0seq: seq[int] = @[]
|
||||||
assert anyIt(numbers, it > 8) == true
|
assert anyIt(numbers, it > 8) == true
|
||||||
assert anyIt(numbers, it > 9) == false
|
assert anyIt(numbers, it > 9) == false
|
||||||
assert anyIt(len0seq, true) == false
|
assert anyIt(len0seq, true) == false
|
||||||
|
|
@ -1221,63 +1222,63 @@ when isMainModule:
|
||||||
assert odd_numbers == @[1, 3, 5, 7, 9]
|
assert odd_numbers == @[1, 3, 5, 7, 9]
|
||||||
|
|
||||||
block:
|
block:
|
||||||
doAssert [1,2].toSeq == @[1,2]
|
doAssert [1, 2].toSeq == @[1, 2]
|
||||||
doAssert @[1,2].toSeq == @[1,2]
|
doAssert @[1, 2].toSeq == @[1, 2]
|
||||||
|
|
||||||
doAssert @[1,2].toSeq == @[1,2]
|
doAssert @[1, 2].toSeq == @[1, 2]
|
||||||
doAssert toSeq(@[1,2]) == @[1,2]
|
doAssert toSeq(@[1, 2]) == @[1, 2]
|
||||||
|
|
||||||
block:
|
block:
|
||||||
iterator myIter(seed:int):auto=
|
iterator myIter(seed: int): auto =
|
||||||
for i in 0..<seed:
|
for i in 0..<seed:
|
||||||
yield i
|
yield i
|
||||||
doAssert toSeq(myIter(2)) == @[0, 1]
|
doAssert toSeq(myIter(2)) == @[0, 1]
|
||||||
|
|
||||||
block:
|
block:
|
||||||
iterator myIter():auto{.inline.}=
|
iterator myIter(): auto {.inline.} =
|
||||||
yield 1
|
yield 1
|
||||||
yield 2
|
yield 2
|
||||||
|
|
||||||
doAssert myIter.toSeq == @[1,2]
|
doAssert myIter.toSeq == @[1, 2]
|
||||||
doAssert toSeq(myIter) == @[1,2]
|
doAssert toSeq(myIter) == @[1, 2]
|
||||||
|
|
||||||
block:
|
block:
|
||||||
iterator myIter():int {.closure.} =
|
iterator myIter(): int {.closure.} =
|
||||||
yield 1
|
yield 1
|
||||||
yield 2
|
yield 2
|
||||||
|
|
||||||
doAssert myIter.toSeq == @[1,2]
|
doAssert myIter.toSeq == @[1, 2]
|
||||||
doAssert toSeq(myIter) == @[1,2]
|
doAssert toSeq(myIter) == @[1, 2]
|
||||||
|
|
||||||
block:
|
block:
|
||||||
proc myIter():auto=
|
proc myIter(): auto =
|
||||||
iterator ret():int{.closure.}=
|
iterator ret(): int {.closure.} =
|
||||||
yield 1
|
yield 1
|
||||||
yield 2
|
yield 2
|
||||||
result = ret
|
result = ret
|
||||||
|
|
||||||
doAssert myIter().toSeq == @[1,2]
|
doAssert myIter().toSeq == @[1, 2]
|
||||||
doAssert toSeq(myIter()) == @[1,2]
|
doAssert toSeq(myIter()) == @[1, 2]
|
||||||
|
|
||||||
block:
|
block:
|
||||||
proc myIter(n:int):auto=
|
proc myIter(n: int): auto =
|
||||||
var counter = 0
|
var counter = 0
|
||||||
iterator ret():int{.closure.}=
|
iterator ret(): int {.closure.} =
|
||||||
while counter<n:
|
while counter < n:
|
||||||
yield counter
|
yield counter
|
||||||
counter.inc
|
counter.inc
|
||||||
result = ret
|
result = ret
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let myIter3 = myIter(3)
|
let myIter3 = myIter(3)
|
||||||
doAssert myIter3.toSeq == @[0,1,2]
|
doAssert myIter3.toSeq == @[0, 1, 2]
|
||||||
block:
|
block:
|
||||||
let myIter3 = myIter(3)
|
let myIter3 = myIter(3)
|
||||||
doAssert toSeq(myIter3) == @[0,1,2]
|
doAssert toSeq(myIter3) == @[0, 1, 2]
|
||||||
block:
|
block:
|
||||||
# makes sure this does not hang forever
|
# makes sure this does not hang forever
|
||||||
doAssert myIter(3).toSeq == @[0,1,2]
|
doAssert myIter(3).toSeq == @[0, 1, 2]
|
||||||
doAssert toSeq(myIter(3)) == @[0,1,2]
|
doAssert toSeq(myIter(3)) == @[0, 1, 2]
|
||||||
|
|
||||||
block:
|
block:
|
||||||
# tests https://github.com/nim-lang/Nim/issues/7187
|
# tests https://github.com/nim-lang/Nim/issues/7187
|
||||||
|
|
@ -1331,30 +1332,32 @@ when isMainModule:
|
||||||
block: # mapLiterals tests
|
block: # mapLiterals tests
|
||||||
let x = mapLiterals([0.1, 1.2, 2.3, 3.4], int)
|
let x = mapLiterals([0.1, 1.2, 2.3, 3.4], int)
|
||||||
doAssert x is array[4, int]
|
doAssert x is array[4, int]
|
||||||
doAssert mapLiterals((1, ("abc"), 2), float, nested=false) == (float(1), "abc", float(2))
|
doAssert mapLiterals((1, ("abc"), 2), float, nested = false) ==
|
||||||
doAssert mapLiterals(([1], ("abc"), 2), `$`, nested=true) == (["1"], "abc", "2")
|
(float(1), "abc", float(2))
|
||||||
|
doAssert mapLiterals(([1], ("abc"), 2), `$`, nested = true) ==
|
||||||
|
(["1"], "abc", "2")
|
||||||
|
|
||||||
block: # mapIt with openArray
|
block: # mapIt with openArray
|
||||||
counter = 0
|
counter = 0
|
||||||
proc foo(x: openArray[int]): seq[int] = x.mapIt(it * 10)
|
proc foo(x: openArray[int]): seq[int] = x.mapIt(it * 10)
|
||||||
doAssert foo([identity(1),identity(2)]) == @[10, 20]
|
doAssert foo([identity(1), identity(2)]) == @[10, 20]
|
||||||
doAssert counter == 2
|
doAssert counter == 2
|
||||||
|
|
||||||
block: # mapIt with direct openArray
|
block: # mapIt with direct openArray
|
||||||
proc foo1(x: openArray[int]): seq[int] = x.mapIt(it * 10)
|
proc foo1(x: openArray[int]): seq[int] = x.mapIt(it * 10)
|
||||||
counter = 0
|
counter = 0
|
||||||
doAssert foo1(openArray[int]([identity(1),identity(2)])) == @[10,20]
|
doAssert foo1(openArray[int]([identity(1), identity(2)])) == @[10, 20]
|
||||||
doAssert counter == 2
|
doAssert counter == 2
|
||||||
|
|
||||||
# Corner cases (openArray litterals should not be common)
|
# Corner cases (openArray litterals should not be common)
|
||||||
template foo2(x: openArray[int]): seq[int] = x.mapIt(it * 10)
|
template foo2(x: openArray[int]): seq[int] = x.mapIt(it * 10)
|
||||||
counter = 0
|
counter = 0
|
||||||
doAssert foo2(openArray[int]([identity(1),identity(2)])) == @[10,20]
|
doAssert foo2(openArray[int]([identity(1), identity(2)])) == @[10, 20]
|
||||||
# TODO: this fails; not sure how to fix this case
|
# TODO: this fails; not sure how to fix this case
|
||||||
# doAssert counter == 2
|
# doAssert counter == 2
|
||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
doAssert openArray[int]([identity(1), identity(2)]).mapIt(it) == @[1,2]
|
doAssert openArray[int]([identity(1), identity(2)]).mapIt(it) == @[1, 2]
|
||||||
# ditto
|
# ditto
|
||||||
# doAssert counter == 2
|
# doAssert counter == 2
|
||||||
|
|
||||||
|
|
@ -1366,12 +1369,12 @@ when isMainModule:
|
||||||
doAssert newSeq[int](0).mapIt(it) == @[]
|
doAssert newSeq[int](0).mapIt(it) == @[]
|
||||||
|
|
||||||
block: # mapIt redifinition check, see https://github.com/nim-lang/Nim/issues/8580
|
block: # mapIt redifinition check, see https://github.com/nim-lang/Nim/issues/8580
|
||||||
let s2 = [1,2].mapIt(it)
|
let s2 = [1, 2].mapIt(it)
|
||||||
doAssert s2 == @[1,2]
|
doAssert s2 == @[1, 2]
|
||||||
|
|
||||||
block:
|
block:
|
||||||
counter = 0
|
counter = 0
|
||||||
doAssert [1,2].identity().mapIt(it*2).mapIt(it*10) == @[20, 40]
|
doAssert [1, 2].identity().mapIt(it*2).mapIt(it*10) == @[20, 40]
|
||||||
# https://github.com/nim-lang/Nim/issues/7187 test case
|
# https://github.com/nim-lang/Nim/issues/7187 test case
|
||||||
doAssert counter == 1
|
doAssert counter == 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ template doWhile(a, b) =
|
||||||
b
|
b
|
||||||
if not a: break
|
if not a: break
|
||||||
|
|
||||||
proc exclImpl[A](s: var HashSet[A], key: A) : bool {. inline .} =
|
proc exclImpl[A](s: var HashSet[A], key: A): bool {.inline.} =
|
||||||
var hc: Hash
|
var hc: Hash
|
||||||
var i = rawGet(s, key, hc)
|
var i = rawGet(s, key, hc)
|
||||||
var msk = high(s.data)
|
var msk = high(s.data)
|
||||||
|
|
@ -130,7 +130,7 @@ proc enlarge[A](s: var OrderedSet[A]) =
|
||||||
rawInsert(s, s.data, n[h].key, n[h].hcode, j)
|
rawInsert(s, s.data, n[h].key, n[h].hcode, j)
|
||||||
h = nxt
|
h = nxt
|
||||||
|
|
||||||
proc exclImpl[A](s: var OrderedSet[A], key: A) : bool {.inline.} =
|
proc exclImpl[A](s: var OrderedSet[A], key: A): bool {.inline.} =
|
||||||
if len(s.data) == 0:
|
if len(s.data) == 0:
|
||||||
return true
|
return true
|
||||||
var n: OrderedKeyValuePairSeq[A]
|
var n: OrderedKeyValuePairSeq[A]
|
||||||
|
|
|
||||||
|
|
@ -604,13 +604,13 @@ proc rightSize*(count: Natural): int {.inline.} =
|
||||||
|
|
||||||
|
|
||||||
proc initSet*[A](initialSize = defaultInitialSize): HashSet[A] {.deprecated:
|
proc initSet*[A](initialSize = defaultInitialSize): HashSet[A] {.deprecated:
|
||||||
"Deprecated since v0.20, use 'initHashSet'"} = initHashSet[A](initialSize)
|
"Deprecated since v0.20, use 'initHashSet'".} = initHashSet[A](initialSize)
|
||||||
|
|
||||||
proc toSet*[A](keys: openArray[A]): HashSet[A] {.deprecated:
|
proc toSet*[A](keys: openArray[A]): HashSet[A] {.deprecated:
|
||||||
"Deprecated since v0.20, use 'toHashSet'"} = toHashSet[A](keys)
|
"Deprecated since v0.20, use 'toHashSet'".} = toHashSet[A](keys)
|
||||||
|
|
||||||
proc isValid*[A](s: HashSet[A]): bool {.deprecated:
|
proc isValid*[A](s: HashSet[A]): bool {.deprecated:
|
||||||
"Deprecated since v0.20; sets are initialized by default"} =
|
"Deprecated since v0.20; sets are initialized by default".} =
|
||||||
## Returns `true` if the set has been initialized (with `initHashSet proc
|
## Returns `true` if the set has been initialized (with `initHashSet proc
|
||||||
## <#initHashSet,int>`_ or `init proc <#init,HashSet[A],int>`_).
|
## <#initHashSet,int>`_ or `init proc <#init,HashSet[A],int>`_).
|
||||||
##
|
##
|
||||||
|
|
@ -937,7 +937,7 @@ iterator pairs*[A](s: OrderedSet[A]): tuple[a: int, b: A] =
|
||||||
|
|
||||||
|
|
||||||
proc isValid*[A](s: OrderedSet[A]): bool {.deprecated:
|
proc isValid*[A](s: OrderedSet[A]): bool {.deprecated:
|
||||||
"Deprecated since v0.20; sets are initialized by default"} =
|
"Deprecated since v0.20; sets are initialized by default".} =
|
||||||
##
|
##
|
||||||
## Returns `true` if the set has been initialized (with `initHashSet proc
|
## Returns `true` if the set has been initialized (with `initHashSet proc
|
||||||
## <#initOrderedSet,int>`_ or `init proc <#init,OrderedSet[A],int>`_).
|
## <#initOrderedSet,int>`_ or `init proc <#init,OrderedSet[A],int>`_).
|
||||||
|
|
@ -1162,8 +1162,8 @@ when isMainModule and not defined(release):
|
||||||
var aa = initOrderedSet[pair]()
|
var aa = initOrderedSet[pair]()
|
||||||
var bb = initOrderedSet[pair]()
|
var bb = initOrderedSet[pair]()
|
||||||
|
|
||||||
var x = (a:1,b:2)
|
var x = (a: 1, b: 2)
|
||||||
var y = (a:3,b:4)
|
var y = (a: 3, b: 4)
|
||||||
|
|
||||||
aa.incl(x)
|
aa.incl(x)
|
||||||
aa.incl(y)
|
aa.incl(y)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## Shared list support.
|
## Shared list support.
|
||||||
|
|
||||||
{.push stackTrace:off.}
|
{.push stackTrace: off.}
|
||||||
|
|
||||||
import
|
import
|
||||||
locks
|
locks
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ include "system/inclrtl"
|
||||||
type
|
type
|
||||||
KeyValuePair[A, B] = tuple[hcode: Hash, key: A, val: B]
|
KeyValuePair[A, B] = tuple[hcode: Hash, key: A, val: B]
|
||||||
KeyValuePairSeq[A, B] = ptr UncheckedArray[KeyValuePair[A, B]]
|
KeyValuePairSeq[A, B] = ptr UncheckedArray[KeyValuePair[A, B]]
|
||||||
SharedTable* [A, B] = object ## generic hash SharedTable
|
SharedTable*[A, B] = object ## generic hash SharedTable
|
||||||
data: KeyValuePairSeq[A, B]
|
data: KeyValuePairSeq[A, B]
|
||||||
counter, dataLen: int
|
counter, dataLen: int
|
||||||
lock: Lock
|
lock: Lock
|
||||||
|
|
@ -202,7 +202,7 @@ proc del*[A, B](t: var SharedTable[A, B], key: A) =
|
||||||
withLock t:
|
withLock t:
|
||||||
delImpl()
|
delImpl()
|
||||||
|
|
||||||
proc init*[A, B](t: var SharedTable[A, B], initialSize=64) =
|
proc init*[A, B](t: var SharedTable[A, B], initialSize = 64) =
|
||||||
## creates a new hash table that is empty.
|
## creates a new hash table that is empty.
|
||||||
##
|
##
|
||||||
## This proc must be called before any other usage of `t`.
|
## This proc must be called before any other usage of `t`.
|
||||||
|
|
@ -221,7 +221,7 @@ proc deinitSharedTable*[A, B](t: var SharedTable[A, B]) =
|
||||||
deallocShared(t.data)
|
deallocShared(t.data)
|
||||||
deinitLock t.lock
|
deinitLock t.lock
|
||||||
|
|
||||||
proc initSharedTable*[A, B](initialSize=64): SharedTable[A, B] {.deprecated:
|
proc initSharedTable*[A, B](initialSize = 64): SharedTable[A, B] {.deprecated:
|
||||||
"use 'init' instead".} =
|
"use 'init' instead".} =
|
||||||
## This is not posix compliant, may introduce undefined behavior.
|
## This is not posix compliant, may introduce undefined behavior.
|
||||||
assert isPowerOfTwo(initialSize)
|
assert isPowerOfTwo(initialSize)
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@ type
|
||||||
## For creating an empty Table, use `initTable proc<#initTable,int>`_.
|
## For creating an empty Table, use `initTable proc<#initTable,int>`_.
|
||||||
data: KeyValuePairSeq[A, B]
|
data: KeyValuePairSeq[A, B]
|
||||||
counter: int
|
counter: int
|
||||||
TableRef*[A,B] = ref Table[A, B] ## Ref version of `Table<#Table>`_.
|
TableRef*[A, B] = ref Table[A, B] ## Ref version of `Table<#Table>`_.
|
||||||
##
|
##
|
||||||
## For creating a new empty TableRef, use `newTable proc
|
## For creating a new empty TableRef, use `newTable proc
|
||||||
## <#newTable,int>`_.
|
## <#newTable,int>`_.
|
||||||
|
|
@ -1201,7 +1201,7 @@ type
|
||||||
OrderedKeyValuePair[A, B] = tuple[
|
OrderedKeyValuePair[A, B] = tuple[
|
||||||
hcode: Hash, next: int, key: A, val: B]
|
hcode: Hash, next: int, key: A, val: B]
|
||||||
OrderedKeyValuePairSeq[A, B] = seq[OrderedKeyValuePair[A, B]]
|
OrderedKeyValuePairSeq[A, B] = seq[OrderedKeyValuePair[A, B]]
|
||||||
OrderedTable* [A, B] = object
|
OrderedTable*[A, B] = object
|
||||||
## Hash table that remembers insertion order.
|
## Hash table that remembers insertion order.
|
||||||
##
|
##
|
||||||
## For creating an empty OrderedTable, use `initOrderedTable proc
|
## For creating an empty OrderedTable, use `initOrderedTable proc
|
||||||
|
|
@ -1326,7 +1326,7 @@ proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B =
|
||||||
|
|
||||||
get(t, key)
|
get(t, key)
|
||||||
|
|
||||||
proc `[]`*[A, B](t: var OrderedTable[A, B], key: A): var B=
|
proc `[]`*[A, B](t: var OrderedTable[A, B], key: A): var B =
|
||||||
## Retrieves the value at ``t[key]``. The value can be modified.
|
## Retrieves the value at ``t[key]``. The value can be modified.
|
||||||
##
|
##
|
||||||
## If ``key`` is not in ``t``, the ``KeyError`` exception is raised.
|
## If ``key`` is not in ``t``, the ``KeyError`` exception is raised.
|
||||||
|
|
@ -1527,7 +1527,8 @@ proc clear*[A, B](t: var OrderedTable[A, B]) =
|
||||||
t.first = -1
|
t.first = -1
|
||||||
t.last = -1
|
t.last = -1
|
||||||
|
|
||||||
proc sort*[A, B](t: var OrderedTable[A, B], cmp: proc (x,y: (A, B)): int, order = SortOrder.Ascending) =
|
proc sort*[A, B](t: var OrderedTable[A, B], cmp: proc (x, y: (A, B)): int,
|
||||||
|
order = SortOrder.Ascending) =
|
||||||
## Sorts ``t`` according to the function ``cmp``.
|
## Sorts ``t`` according to the function ``cmp``.
|
||||||
##
|
##
|
||||||
## This modifies the internal list
|
## This modifies the internal list
|
||||||
|
|
@ -1542,7 +1543,7 @@ proc sort*[A, B](t: var OrderedTable[A, B], cmp: proc (x,y: (A, B)): int, order
|
||||||
doAssert a == {'c': 0, 'a': 10, 'b': 20}.toOrderedTable
|
doAssert a == {'c': 0, 'a': 10, 'b': 20}.toOrderedTable
|
||||||
a.sort(system.cmp)
|
a.sort(system.cmp)
|
||||||
doAssert a == {'a': 10, 'b': 20, 'c': 0}.toOrderedTable
|
doAssert a == {'a': 10, 'b': 20, 'c': 0}.toOrderedTable
|
||||||
a.sort(system.cmp, order=SortOrder.Descending)
|
a.sort(system.cmp, order = SortOrder.Descending)
|
||||||
doAssert a == {'c': 0, 'b': 20, 'a': 10}.toOrderedTable
|
doAssert a == {'c': 0, 'b': 20, 'a': 10}.toOrderedTable
|
||||||
|
|
||||||
var list = t.first
|
var list = t.first
|
||||||
|
|
@ -1660,7 +1661,8 @@ iterator mpairs*[A, B](t: var OrderedTable[A, B]): (A, var B) =
|
||||||
}.toOrderedTable
|
}.toOrderedTable
|
||||||
for k, v in a.mpairs:
|
for k, v in a.mpairs:
|
||||||
v.add(v[0] + 10)
|
v.add(v[0] + 10)
|
||||||
doAssert a == {'o': @[1, 5, 7, 9, 11], 'e': @[2, 4, 6, 8, 12]}.toOrderedTable
|
doAssert a == {'o': @[1, 5, 7, 9, 11],
|
||||||
|
'e': @[2, 4, 6, 8, 12]}.toOrderedTable
|
||||||
|
|
||||||
let L = len(t)
|
let L = len(t)
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
|
|
@ -1680,7 +1682,8 @@ iterator keys*[A, B](t: OrderedTable[A, B]): A =
|
||||||
}.toOrderedTable
|
}.toOrderedTable
|
||||||
for k in a.keys:
|
for k in a.keys:
|
||||||
a[k].add(99)
|
a[k].add(99)
|
||||||
doAssert a == {'o': @[1, 5, 7, 9, 99], 'e': @[2, 4, 6, 8, 99]}.toOrderedTable
|
doAssert a == {'o': @[1, 5, 7, 9, 99],
|
||||||
|
'e': @[2, 4, 6, 8, 99]}.toOrderedTable
|
||||||
|
|
||||||
let L = len(t)
|
let L = len(t)
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
|
|
@ -1722,7 +1725,8 @@ iterator mvalues*[A, B](t: var OrderedTable[A, B]): var B =
|
||||||
}.toOrderedTable
|
}.toOrderedTable
|
||||||
for v in a.mvalues:
|
for v in a.mvalues:
|
||||||
v.add(99)
|
v.add(99)
|
||||||
doAssert a == {'o': @[1, 5, 7, 9, 99], 'e': @[2, 4, 6, 8, 99]}.toOrderedTable
|
doAssert a == {'o': @[1, 5, 7, 9, 99],
|
||||||
|
'e': @[2, 4, 6, 8, 99]}.toOrderedTable
|
||||||
|
|
||||||
let L = len(t)
|
let L = len(t)
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
|
|
@ -1964,7 +1968,8 @@ proc clear*[A, B](t: var OrderedTableRef[A, B]) =
|
||||||
|
|
||||||
clear(t[])
|
clear(t[])
|
||||||
|
|
||||||
proc sort*[A, B](t: OrderedTableRef[A, B], cmp: proc (x,y: (A, B)): int, order = SortOrder.Ascending) =
|
proc sort*[A, B](t: OrderedTableRef[A, B], cmp: proc (x, y: (A, B)): int,
|
||||||
|
order = SortOrder.Ascending) =
|
||||||
## Sorts ``t`` according to the function ``cmp``.
|
## Sorts ``t`` according to the function ``cmp``.
|
||||||
##
|
##
|
||||||
## This modifies the internal list
|
## This modifies the internal list
|
||||||
|
|
@ -1979,10 +1984,10 @@ proc sort*[A, B](t: OrderedTableRef[A, B], cmp: proc (x,y: (A, B)): int, order =
|
||||||
doAssert a == {'c': 0, 'a': 10, 'b': 20}.newOrderedTable
|
doAssert a == {'c': 0, 'a': 10, 'b': 20}.newOrderedTable
|
||||||
a.sort(system.cmp)
|
a.sort(system.cmp)
|
||||||
doAssert a == {'a': 10, 'b': 20, 'c': 0}.newOrderedTable
|
doAssert a == {'a': 10, 'b': 20, 'c': 0}.newOrderedTable
|
||||||
a.sort(system.cmp, order=SortOrder.Descending)
|
a.sort(system.cmp, order = SortOrder.Descending)
|
||||||
doAssert a == {'c': 0, 'b': 20, 'a': 10}.newOrderedTable
|
doAssert a == {'c': 0, 'b': 20, 'a': 10}.newOrderedTable
|
||||||
|
|
||||||
t[].sort(cmp, order=order)
|
t[].sort(cmp, order = order)
|
||||||
|
|
||||||
proc `$`*[A, B](t: OrderedTableRef[A, B]): string =
|
proc `$`*[A, B](t: OrderedTableRef[A, B]): string =
|
||||||
## The ``$`` operator for hash tables. Used internally when calling `echo`
|
## The ``$`` operator for hash tables. Used internally when calling `echo`
|
||||||
|
|
@ -2050,7 +2055,8 @@ iterator mpairs*[A, B](t: OrderedTableRef[A, B]): (A, var B) =
|
||||||
}.newOrderedTable
|
}.newOrderedTable
|
||||||
for k, v in a.mpairs:
|
for k, v in a.mpairs:
|
||||||
v.add(v[0] + 10)
|
v.add(v[0] + 10)
|
||||||
doAssert a == {'o': @[1, 5, 7, 9, 11], 'e': @[2, 4, 6, 8, 12]}.newOrderedTable
|
doAssert a == {'o': @[1, 5, 7, 9, 11],
|
||||||
|
'e': @[2, 4, 6, 8, 12]}.newOrderedTable
|
||||||
|
|
||||||
let L = len(t)
|
let L = len(t)
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
|
|
@ -2070,7 +2076,8 @@ iterator keys*[A, B](t: OrderedTableRef[A, B]): A =
|
||||||
}.newOrderedTable
|
}.newOrderedTable
|
||||||
for k in a.keys:
|
for k in a.keys:
|
||||||
a[k].add(99)
|
a[k].add(99)
|
||||||
doAssert a == {'o': @[1, 5, 7, 9, 99], 'e': @[2, 4, 6, 8, 99]}.newOrderedTable
|
doAssert a == {'o': @[1, 5, 7, 9, 99], 'e': @[2, 4, 6, 8,
|
||||||
|
99]}.newOrderedTable
|
||||||
|
|
||||||
let L = len(t)
|
let L = len(t)
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
|
|
@ -2111,7 +2118,8 @@ iterator mvalues*[A, B](t: OrderedTableRef[A, B]): var B =
|
||||||
}.newOrderedTable
|
}.newOrderedTable
|
||||||
for v in a.mvalues:
|
for v in a.mvalues:
|
||||||
v.add(99)
|
v.add(99)
|
||||||
doAssert a == {'o': @[1, 5, 7, 9, 99], 'e': @[2, 4, 6, 8, 99]}.newOrderedTable
|
doAssert a == {'o': @[1, 5, 7, 9, 99],
|
||||||
|
'e': @[2, 4, 6, 8, 99]}.newOrderedTable
|
||||||
|
|
||||||
let L = len(t)
|
let L = len(t)
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
|
|
@ -2129,7 +2137,7 @@ iterator mvalues*[A, B](t: OrderedTableRef[A, B]): var B =
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
CountTable* [A] = object
|
CountTable*[A] = object
|
||||||
## Hash table that counts the number of each key.
|
## Hash table that counts the number of each key.
|
||||||
##
|
##
|
||||||
## For creating an empty CountTable, use `initCountTable proc
|
## For creating an empty CountTable, use `initCountTable proc
|
||||||
|
|
@ -2336,7 +2344,7 @@ proc sort*[A](t: var CountTable[A], order = SortOrder.Descending) =
|
||||||
a.sort(SortOrder.Ascending)
|
a.sort(SortOrder.Ascending)
|
||||||
doAssert toSeq(a.values) == @[1, 1, 2, 2, 5]
|
doAssert toSeq(a.values) == @[1, 1, 2, 2, 5]
|
||||||
|
|
||||||
t.data.sort(cmp=ctCmp, order=order)
|
t.data.sort(cmp = ctCmp, order = order)
|
||||||
t.isSorted = true
|
t.isSorted = true
|
||||||
|
|
||||||
proc merge*[A](s: var CountTable[A], t: CountTable[A]) =
|
proc merge*[A](s: var CountTable[A], t: CountTable[A]) =
|
||||||
|
|
@ -2613,7 +2621,7 @@ proc sort*[A](t: CountTableRef[A], order = SortOrder.Descending) =
|
||||||
## You can use the iterators `pairs<#pairs.i,CountTableRef[A]>`_,
|
## You can use the iterators `pairs<#pairs.i,CountTableRef[A]>`_,
|
||||||
## `keys<#keys.i,CountTableRef[A]>`_, and `values<#values.i,CountTableRef[A]>`_
|
## `keys<#keys.i,CountTableRef[A]>`_, and `values<#values.i,CountTableRef[A]>`_
|
||||||
## to iterate over ``t`` in the sorted order.
|
## to iterate over ``t`` in the sorted order.
|
||||||
t[].sort(order=order)
|
t[].sort(order = order)
|
||||||
|
|
||||||
proc merge*[A](s, t: CountTableRef[A]) =
|
proc merge*[A](s, t: CountTableRef[A]) =
|
||||||
## Merges the second table into the first one.
|
## Merges the second table into the first one.
|
||||||
|
|
@ -2880,15 +2888,15 @@ when isMainModule:
|
||||||
doAssert clearTable.getOrDefault(42) == ""
|
doAssert clearTable.getOrDefault(42) == ""
|
||||||
|
|
||||||
block: #5482
|
block: #5482
|
||||||
var a = [("wrong?","foo"), ("wrong?", "foo2")].newOrderedTable()
|
var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
|
||||||
var b = newOrderedTable[string, string](initialSize=2)
|
var b = newOrderedTable[string, string](initialSize = 2)
|
||||||
b.add("wrong?", "foo")
|
b.add("wrong?", "foo")
|
||||||
b.add("wrong?", "foo2")
|
b.add("wrong?", "foo2")
|
||||||
assert a == b
|
assert a == b
|
||||||
|
|
||||||
block: #5482
|
block: #5482
|
||||||
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
|
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
|
||||||
var b = newOrderedTable[string, string](initialSize=2)
|
var b = newOrderedTable[string, string](initialSize = 2)
|
||||||
b.add("wrong?", "foo")
|
b.add("wrong?", "foo")
|
||||||
b.add("wrong?", "foo2")
|
b.add("wrong?", "foo2")
|
||||||
assert a == b
|
assert a == b
|
||||||
|
|
@ -2901,7 +2909,7 @@ when isMainModule:
|
||||||
assert a == b
|
assert a == b
|
||||||
|
|
||||||
block: #5487
|
block: #5487
|
||||||
var a = [("wrong?","foo"), ("wrong?", "foo2")].newOrderedTable()
|
var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
|
||||||
var b = newOrderedTable[string, string]() # notice, default size!
|
var b = newOrderedTable[string, string]() # notice, default size!
|
||||||
b.add("wrong?", "foo")
|
b.add("wrong?", "foo")
|
||||||
b.add("wrong?", "foo2")
|
b.add("wrong?", "foo2")
|
||||||
|
|
@ -2909,7 +2917,7 @@ when isMainModule:
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
|
var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
|
||||||
var b = [("wrong?","foo"), ("wrong?", "foo2")].newOrderedTable()
|
var b = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
|
||||||
var c = newOrderedTable[string, string]() # notice, default size!
|
var c = newOrderedTable[string, string]() # notice, default size!
|
||||||
c.add("wrong?", "foo")
|
c.add("wrong?", "foo")
|
||||||
c.add("wrong?", "foo2")
|
c.add("wrong?", "foo2")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue