diff options
Diffstat (limited to 'lib/pure')
-rwxr-xr-x | lib/pure/collections/sets.nim | 9 | ||||
-rwxr-xr-x | lib/pure/collections/tables.nim | 64 | ||||
-rwxr-xr-x | lib/pure/strtabs.nim | 8 |
3 files changed, 63 insertions, 18 deletions
diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index 00056ff14..5f4b5a530 100755 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -10,17 +10,12 @@ ## The ``sets`` module implements an efficient hash set and ordered hash set. ## ## **Note**: The data types declared here have *value semantics*: This means -## that ``=`` performs a copy of the hash table. If you are overly concerned -## with efficiency and know what you do (!), you can define the symbol -## ``shallowADT`` to compile a version that uses shallow copies instead. +## that ``=`` performs a copy of the set. import os, hashes, math -when defined(shallowADT): - {.pragma: myShallow, shallow.} -else: - {.pragma: myShallow.} +{.pragma: myShallow.} type TSlotEnum = enum seEmpty, seFilled, seDeleted diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 6fe77b26f..31b98a0cc 100755 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -11,17 +11,12 @@ ## a mapping from keys to values. ## ## **Note:** The data types declared here have *value semantics*: This means -## that ``=`` performs a copy of the hash table. If you are overly concerned -## with efficiency and know what you do (!), you can define the symbol -## ``shallowADT`` to compile a version that uses shallow copies instead. +## that ``=`` performs a copy of the hash table. import hashes, math -when defined(shallowADT): - {.pragma: myShallow, shallow.} -else: - {.pragma: myShallow.} +{.pragma: myShallow.} type TSlotEnum = enum seEmpty, seFilled, seDeleted @@ -40,6 +35,12 @@ iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] = for h in 0..high(t.data): if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) +iterator mpairs*[A, B](t: var TTable[A, B]): tuple[key: A, val: var B] = + ## iterates over any (key, value) pair in the table `t`. The values + ## can be modified. + for h in 0..high(t.data): + if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) + iterator keys*[A, B](t: TTable[A, B]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): @@ -50,6 +51,11 @@ iterator values*[A, B](t: TTable[A, B]): B = for h in 0..high(t.data): if t.data[h].slot == seFilled: yield t.data[h].val +iterator mvalues*[A, B](t: var TTable[A, B]): var B = + ## iterates over any value in the table `t`. The values can be modified. + for h in 0..high(t.data): + if t.data[h].slot == seFilled: yield t.data[h].val + const growthFactor = 2 @@ -87,6 +93,13 @@ proc `[]`*[A, B](t: TTable[A, B], key: A): B = var index = RawGet(t, key) if index >= 0: result = t.data[index].val +proc mget*[A, B](t: var TTable[A, B], key: A): var B = + ## retrieves the value at ``t[key]``. The value can be modified. + ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. + var index = RawGet(t, key) + if index >= 0: result = t.data[index].val + else: raise newException(EInvalidKey, "key not found: " & $key) + proc hasKey*[A, B](t: TTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 @@ -197,6 +210,12 @@ iterator pairs*[A, B](t: TOrderedTable[A, B]): tuple[key: A, val: B] = forAllOrderedPairs: yield (t.data[h].key, t.data[h].val) +iterator mpairs*[A, B](t: var TOrderedTable[A, B]): tuple[key: A, val: var B] = + ## iterates over any (key, value) pair in the table `t` in insertion + ## order. The values can be modified. + forAllOrderedPairs: + yield (t.data[h].key, t.data[h].val) + iterator keys*[A, B](t: TOrderedTable[A, B]): A = ## iterates over any key in the table `t` in insertion order. forAllOrderedPairs: @@ -207,6 +226,12 @@ iterator values*[A, B](t: TOrderedTable[A, B]): B = forAllOrderedPairs: yield t.data[h].val +iterator mvalues*[A, B](t: var TOrderedTable[A, B]): var B = + ## iterates over any value in the table `t` in insertion order. The values + ## can be modified. + forAllOrderedPairs: + yield t.data[h].val + proc RawGet[A, B](t: TOrderedTable[A, B], key: A): int = rawGetImpl() @@ -218,6 +243,13 @@ proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = var index = RawGet(t, key) if index >= 0: result = t.data[index].val +proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B = + ## retrieves the value at ``t[key]``. The value can be modified. + ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. + var index = RawGet(t, key) + if index >= 0: result = t.data[index].val + else: raise newException(EInvalidKey, "key not found: " & $key) + proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 @@ -288,6 +320,12 @@ iterator pairs*[A](t: TCountTable[A]): tuple[key: A, val: int] = for h in 0..high(t.data): if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) +iterator mpairs*[A](t: var TCountTable[A]): tuple[key: A, val: var int] = + ## iterates over any (key, value) pair in the table `t`. The values can + ## be modified. + for h in 0..high(t.data): + if t.data[h].val != 0: yield (t.data[h].key, t.data[h].val) + iterator keys*[A](t: TCountTable[A]): A = ## iterates over any key in the table `t`. for h in 0..high(t.data): @@ -298,6 +336,11 @@ iterator values*[A](t: TCountTable[A]): int = for h in 0..high(t.data): if t.data[h].val != 0: yield t.data[h].val +iterator mvalues*[A](t: TCountTable[A]): var int = + ## iterates over any value in the table `t`. The values can be modified. + for h in 0..high(t.data): + if t.data[h].val != 0: yield t.data[h].val + proc RawGet[A](t: TCountTable[A], key: A): int = var h: THash = hash(key) and high(t.data) # start with real hash value while t.data[h].val != 0: @@ -312,6 +355,13 @@ proc `[]`*[A](t: TCountTable[A], key: A): int = var index = RawGet(t, key) if index >= 0: result = t.data[index].val +proc mget*[A](t: var TCountTable[A], key: A): var int = + ## retrieves the value at ``t[key]``. The value can be modified. + ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. + var index = RawGet(t, key) + if index >= 0: result = t.data[index].val + else: raise newException(EInvalidKey, "key not found: " & $key) + proc hasKey*[A](t: TCountTable[A], key: A): bool = ## returns true iff `key` is in the table `t`. result = rawGet(t, key) >= 0 diff --git a/lib/pure/strtabs.nim b/lib/pure/strtabs.nim index 584282fbc..a9ce9016c 100755 --- a/lib/pure/strtabs.nim +++ b/lib/pure/strtabs.nim @@ -92,13 +92,13 @@ proc `[]`*(t: PStringTable, key: string): string {.rtl, extern: "nstGet".} = if index >= 0: result = t.data[index].val else: result = "" -proc modGet*(t: PStringTable, key: string): var string {. +proc mget*(t: PStringTable, key: string): var string {. rtl, extern: "nstTake".} = ## retrieves the location at ``t[key]``. If `key` is not in `t`, the - ## ``EInvalidValue`` exception is raised. + ## ``EInvalidKey`` exception is raised. var index = RawGet(t, key) if index >= 0: result = t.data[index].val - else: raise newException(EInvalidValue, "key does not exist: " & key) + else: raise newException(EInvalidKey, "key does not exist: " & key) proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} = ## returns true iff `key` is in the table `t`. @@ -221,6 +221,6 @@ when isMainModule: assert x["k"] == "v" assert x["11"] == "22" assert x["565"] == "67" - x.modGet("11") = "23" + x.mget("11") = "23" assert x["11"] == "23" |