Added logical set operations to TSet

This commit is contained in:
Felix Krause 2014-06-25 21:57:06 +02:00
commit bdd3b6c612
2 changed files with 130 additions and 0 deletions

View file

@ -112,6 +112,10 @@ proc incl*[A](s: var TSet[A], key: A) =
## includes an element `key` in `s`.
inclImpl()
proc incl*[A](s: var TSet[A], other: TSet[A]) =
## includes everything in `other` in `s`
for item in other: incl(s, item)
proc excl*[A](s: var TSet[A], key: A) =
## excludes `key` from the set `s`.
var index = rawGet(s, key)
@ -119,6 +123,10 @@ proc excl*[A](s: var TSet[A], key: A) =
s.data[index].slot = seDeleted
dec(s.counter)
proc excl*[A](s: var TSet[A], other: TSet[A]) =
## excludes everything in `other` from `s`.
for item in other: excl(s, item)
proc containsOrIncl*[A](s: var TSet[A], key: A): bool =
## returns true if `s` contains `key`, otherwise `key` is included in `s`
## and false is returned.
@ -147,6 +155,43 @@ proc `$`*[A](s: TSet[A]): string =
## The `$` operator for hash sets.
dollarImpl()
proc union*[A](s1, s2: TSet[A]): TSet[A] =
## returns a new set of all items that are contained in at
## least one of `l` and `r`
result = s1
incl(result, s2)
proc intersection*[A](s1, s2: TSet[A]): TSet[A] =
## returns a new set of all items that are contained in both `l` and `r`
result = initSet[A](min(s1.data.len, s2.data.len))
for item in s1:
if item in s2: incl(result, item)
proc symmetricDifference*[A](s1, s2: TSet[A]): TSet[A] =
## returns a new set of all items that are contained in either
## `l` or `r`, but not both
result = s1
for item in s2:
if containsOrIncl(result, item): excl(result, item)
proc `or`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
## alias for `union`
result = union(s1, s2)
proc `and`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
## alias for `intersection`
result = intersection(s1, s2)
proc `xor`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
## alias for `symmetricDifference`
result = symmetricDifference(s1, s2)
proc disjoint*[A](s1, s2: TSet[A]): bool =
## returns true iff `l` and `r` have no items in common
for item in s1:
if item in s2: return false
return true
# ------------------------------ ordered set ------------------------------
type
@ -211,6 +256,10 @@ proc incl*[A](s: var TOrderedSet[A], key: A) =
## includes an element `key` in `s`.
inclImpl()
proc incl*[A](s: var TSet[A], other: TOrderedSet[A]) =
## includes everything in `other` in `s`
for item in other: incl(s, item)
proc containsOrIncl*[A](s: var TOrderedSet[A], key: A): bool =
## returns true if `s` contains `key`, otherwise `key` is included in `s`
## and false is returned.