summary refs log tree commit diff stats
path: root/lib/system/sets.nim
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2009-06-08 08:06:25 +0200
committerAndreas Rumpf <rumpf_a@web.de>2009-06-08 08:06:25 +0200
commit4d4b3b1c04d41868ebb58bd9ccba7b303007e900 (patch)
tree909ed0aad0b145733521f4ac2bfb938dd4b43785 /lib/system/sets.nim
parentce88dc3e67436939b03f97e624c11ca6058fedce (diff)
downloadNim-4d4b3b1c04d41868ebb58bd9ccba7b303007e900.tar.gz
version0.7.10
Diffstat (limited to 'lib/system/sets.nim')
-rw-r--r--lib/system/sets.nim88
1 files changed, 88 insertions, 0 deletions
diff --git a/lib/system/sets.nim b/lib/system/sets.nim
new file mode 100644
index 000000000..651cc534b
--- /dev/null
+++ b/lib/system/sets.nim
@@ -0,0 +1,88 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2006 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+# set handling
+
+type
+  TMyByte = int8
+  TNimSet = array [0..4*2048-1, TMyByte]
+
+# implementation:
+
+proc countBits(n: int32): int {.exportc: "countBits".}
+# We use a prototype here, not in "cntbits.nim", because that is included
+# in math.nim too. So when linking with math.nim it'd give a duplicated
+# symbol error which we avoid by renaming here.
+
+include "system/cntbits"
+
+proc unionSets(res: var TNimSet, a, b: TNimSet, len: int) {.
+    compilerproc, inline.} =
+  for i in countup(0, len-1): res[i] = a[i] or b[i]
+
+proc diffSets(res: var TNimSet, a, b: TNimSet, len: int) {.
+    compilerproc, inline.} =
+  for i in countup(0, len-1): res[i] = a[i] and not b[i]
+
+proc intersectSets(res: var TNimSet, a, b: TNimSet, len: int) {.
+    compilerproc, inline.} =
+  for i in countup(0, len-1): res[i] = a[i] and b[i]
+
+proc symdiffSets(res: var TNimSet, a, b: TNimSet, len: int) {.
+    compilerproc, inline.} =
+  for i in countup(0, len-1): res[i] = a[i] xor b[i]
+
+proc containsSets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
+  # s1 <= s2 ?
+  for i in countup(0, len-1):
+    if (a[i] and not b[i]) != 0'i8: return false
+  return true
+
+proc containsSubsets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
+  # s1 < s2 ?
+  result = false # assume they are equal
+  for i in countup(0, len-1):
+    if (a[i]) and not b[i]) != 0'i32: return false
+    if a[i] != b[i]: result = true # they are not equal
+
+proc equalSets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
+  for i in countup(0, len-1):
+    if a[i] != b[i]: return false
+  return true
+
+proc cardSet(s: TNimSet, len: int): int {.compilerproc, inline.} =
+  result = 0
+  for i in countup(0, len-1):
+    inc(result, countBits(ze(s[i])))
+
+const
+  WORD_SIZE = sizeof(TMyByte)*8
+
+proc inSet(s: TNimSet, elem: int): bool {.compilerproc, inline.} =
+  return (s[elem /% WORD_SIZE] and (1 shl (elem %% WORD_SIZE))) != 0
+
+proc inclSets(s: var TNimSet, e: int) {.compilerproc, inline.} =
+  s[e /% WORD_SIZE] = s[e /% WORD_SIZE] or toU8(1 shl (e %% WORD_SIZE))
+
+proc inclRange(s: var TNimSet, first, last: int) {.compilerproc.} =
+  # not very fast, but it is seldom used
+  for i in countup(first, last): inclSets(s, i)
+
+proc smallInclRange(s: var int, first, last: int) {.compilerproc.} =
+  # not very fast, but it is seldom used
+  for i in countup(first, last):
+    s = s or (1 shl (i %% sizeof(int)*8))
+
+proc exclSets(s: var TNimSet, e: int) {.compilerproc, inline.} =
+  s[e /% WORD_SIZE] = s[e /% WORD_SIZE] and
+    not toU8(1 shl (e %% WORD_SIZE))
+
+proc smallContainsSubsets(a, b: int): bool {.compilerProc, inline.} =
+  # not used by new code generator
+  return ((a and not b) != 0) and (a != b)