Rename mget to []
- In sets, tables, strtabs, critbits, xmltree - This uses the new var parameter overloading - mget variants still exist, but are deprecated in favor of `[]` - Includes tests and fixed tests and usages of mget - The non-var `[]` now throws an exception instead of returning binary 0 or an empty string
This commit is contained in:
parent
3751019823
commit
63f9385327
12 changed files with 322 additions and 122 deletions
|
|
@ -17,11 +17,11 @@ type
|
|||
otherbits: char
|
||||
case isLeaf: bool
|
||||
of false: child: array[0..1, ref NodeObj[T]]
|
||||
of true:
|
||||
of true:
|
||||
key: string
|
||||
when T isnot void:
|
||||
val: T
|
||||
|
||||
|
||||
Node[T] = ref NodeObj[T]
|
||||
CritBitTree*[T] = object ## The crit bit tree can either be used
|
||||
## as a mapping from strings to
|
||||
|
|
@ -66,7 +66,7 @@ proc rawInsert[T](c: var CritBitTree[T], key: string): Node[T] =
|
|||
let ch = if it.byte < key.len: key[it.byte] else: '\0'
|
||||
let dir = (1 + (ch.ord or it.otherBits.ord)) shr 8
|
||||
it = it.child[dir]
|
||||
|
||||
|
||||
var newOtherBits = 0
|
||||
var newByte = 0
|
||||
block blockX:
|
||||
|
|
@ -84,7 +84,7 @@ proc rawInsert[T](c: var CritBitTree[T], key: string): Node[T] =
|
|||
newOtherBits = newOtherBits xor 255
|
||||
let ch = it.key[newByte]
|
||||
let dir = (1 + (ord(ch) or newOtherBits)) shr 8
|
||||
|
||||
|
||||
var inner: Node[T]
|
||||
new inner
|
||||
new result
|
||||
|
|
@ -93,7 +93,7 @@ proc rawInsert[T](c: var CritBitTree[T], key: string): Node[T] =
|
|||
inner.otherBits = chr(newOtherBits)
|
||||
inner.byte = newByte
|
||||
inner.child[1 - dir] = result
|
||||
|
||||
|
||||
var wherep = addr(c.root)
|
||||
while true:
|
||||
var p = wherep[]
|
||||
|
|
@ -132,20 +132,31 @@ proc `[]=`*[T](c: var CritBitTree[T], key: string, val: T) =
|
|||
var n = rawInsert(c, key)
|
||||
n.val = val
|
||||
|
||||
proc `[]`*[T](c: CritBitTree[T], key: string): T {.inline.} =
|
||||
## retrieves the value at ``c[key]``. If `key` is not in `t`,
|
||||
## default empty value for the type `B` is returned
|
||||
## and no exception is raised. One can check with ``hasKey`` whether the key
|
||||
## exists.
|
||||
template get[T](c: CritBitTree[T], key: string): T {.immediate.} =
|
||||
let n = rawGet(c, key)
|
||||
if n != nil: result = n.val
|
||||
else:
|
||||
when compiles($key):
|
||||
raise newException(KeyError, "key not found: " & $key)
|
||||
else:
|
||||
raise newException(KeyError, "key not found")
|
||||
|
||||
proc mget*[T](c: var CritBitTree[T], key: string): var T {.inline.} =
|
||||
proc `[]`*[T](c: CritBitTree[T], key: string): T {.inline.} =
|
||||
## retrieves the value at ``c[key]``. If `key` is not in `t`, the
|
||||
## ``KeyError`` exception is raised. One can check with ``hasKey`` whether
|
||||
## the key exists.
|
||||
get(c, key)
|
||||
|
||||
proc `[]`*[T](c: var CritBitTree[T], key: string): var T {.inline.} =
|
||||
## retrieves the value at ``c[key]``. The value can be modified.
|
||||
## If `key` is not in `t`, the ``KeyError`` exception is raised.
|
||||
let n = rawGet(c, key)
|
||||
if n != nil: result = n.val
|
||||
else: raise newException(KeyError, "key not found: " & $key)
|
||||
get(c, key)
|
||||
|
||||
proc mget*[T](c: var CritBitTree[T], key: string): var T {.inline, deprecated.} =
|
||||
## retrieves the value at ``c[key]``. The value can be modified.
|
||||
## If `key` is not in `t`, the ``KeyError`` exception is raised.
|
||||
## Use ```[]``` instead.
|
||||
get(c, key)
|
||||
|
||||
proc excl*[T](c: var CritBitTree[T], key: string) =
|
||||
## removes `key` (and its associated value) from the set `c`.
|
||||
|
|
@ -176,7 +187,7 @@ iterator leaves[T](n: Node[T]): Node[T] =
|
|||
# XXX actually we could compute the necessary stack size in advance:
|
||||
# it's roughly log2(c.count).
|
||||
var stack = @[n]
|
||||
while stack.len > 0:
|
||||
while stack.len > 0:
|
||||
var it = stack.pop
|
||||
while not it.isLeaf:
|
||||
stack.add(it.child[1])
|
||||
|
|
@ -205,7 +216,7 @@ iterator items*[T](c: CritBitTree[T]): string =
|
|||
iterator pairs*[T](c: CritBitTree[T]): tuple[key: string, val: T] =
|
||||
## yields all (key, value)-pairs of `c`.
|
||||
for x in leaves(c.root): yield (x.key, x.val)
|
||||
|
||||
|
||||
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.
|
||||
for x in leaves(c.root): yield (x.key, x.val)
|
||||
|
|
@ -251,7 +262,7 @@ iterator pairsWithPrefix*[T](c: CritBitTree[T],
|
|||
## yields all (key, value)-pairs of `c` starting with `prefix`.
|
||||
let top = allprefixedAux(c, prefix)
|
||||
for x in leaves(top): yield (x.key, x.val)
|
||||
|
||||
|
||||
iterator mpairsWithPrefix*[T](c: var CritBitTree[T],
|
||||
prefix: string): tuple[key: string, val: var T] =
|
||||
## yields all (key, value)-pairs of `c` starting with `prefix`.
|
||||
|
|
@ -297,7 +308,6 @@ when isMainModule:
|
|||
|
||||
for w in r.items:
|
||||
echo w
|
||||
|
||||
|
||||
for w in r.itemsWithPrefix("de"):
|
||||
echo w
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue