diff options
Diffstat (limited to 'set/set.ha')
| -rw-r--r-- | set/set.ha | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/set/set.ha b/set/set.ha new file mode 100644 index 0000000..2c56efe --- /dev/null +++ b/set/set.ha @@ -0,0 +1,80 @@ +export type set = struct { + items: []size, +}; + +export type nosuchitem = !void; + +export fn add(s: *set, item: size) bool = { + for (let i = 0z; i < len(s.items); i += 1) { + if (s.items[i] == item) { + return false; + }; + }; + append(s.items, item); + return true; +}; + +export fn del(s: *set, item: size) bool = { + match (contains(*s, item)) { + case let i: size => + delete(s.items[i]); + return true; + case nosuchitem => + return false; + }; +}; + +export fn contains(s: set, item: size) (size | nosuchitem) = { + for (let i = 0z; i < len(s.items); i += 1) { + if (s.items[i] == item) { + return i; + }; + }; + return nosuchitem; +}; + +// Clears all items +export fn clear(s: *set) void = { + delete(s.items[..]); +}; + +@test fn add() void = { + let s = set {...}; + assert(add(&s, 1z)); + assert(len(s.items) == 1); + assert(!add(&s, 1z)); + assert(len(s.items) == 1); +}; + +@test fn del() void = { + let s = set {...}; + assert(add(&s, 1z)); + assert(len(s.items) == 1); + assert(del(&s, 1z)); + assert(len(s.items) == 0); + assert(!del(&s, 1z)); + assert(len(s.items) == 0); +}; + +@test fn contains() void = { + let s = set {...}; + assert(add(&s, 1z)); + assert(!add(&s, 1z)); + const c = contains(s, 1z); + assert(c is size); + assert(c as size == 0); + assert(add(&s, 2z)); + const c = contains(s, 2z); + assert(c is size); + assert(c as size == 1); +}; + +@test fn clear() void = { + let s = set {...}; + assert(add(&s, 1z)); + assert(len(s.items) == 1); + assert(!add(&s, 1z)); + assert(len(s.items) == 1); + clear(&s); + assert(len(s.items) == 0); +}; |
