-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathmodule.ae
More file actions
129 lines (114 loc) · 3.89 KB
/
Copy pathmodule.ae
File metadata and controls
129 lines (114 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// std.set - unordered set of unique strings
//
// Backed by the same hash table as std.map, so lookups are O(1) on
// average and items are copied on insert (the caller's string lifetime
// does not matter).
//
// import std.set
//
// main() {
// seen = set.new()
// set.add(seen, "alpha")
// set.add(seen, "alpha") // already present, set stays size 1
// if set.contains(seen, "alpha") {
// println("size=${set.size(seen)}")
// }
// set.free(seen)
// }
//
// API shape:
// - Raw externs mirror the C entry points and use the C-style int
// returns. They are the escape hatch for advanced callers.
// - Aether-native wrappers (below) return bools and Go-style
// `(value, err)` tuples.
exports(
aether_set_new, aether_set_add, aether_set_has, aether_set_remove, aether_set_size, aether_set_clear, aether_set_free,
aether_set_items_raw, aether_set_items_free,
map_keys_size_raw, map_keys_get_raw,
new, add, contains, remove, size, clear, free, items, items_free,
items_size, items_get
)
// ---- raw externs (std/collections/aether_set.c) ----
extern aether_set_new() -> ptr
extern aether_set_add(set: ptr, item: string) -> int
extern aether_set_has(set: ptr, item: string) -> int
extern aether_set_remove(set: ptr, item: string)
extern aether_set_size(set: ptr) -> int
extern aether_set_clear(set: ptr)
extern aether_set_free(set: ptr)
extern aether_set_items_raw(set: ptr) -> ptr
extern aether_set_items_free(items: ptr)
// aether_set_items_raw returns the same MapKeys snapshot map.keys does, so
// the read side is literally the same two functions (#1724).
extern map_keys_size_raw(items: ptr) -> int
extern map_keys_get_raw(items: ptr, index: int) -> string
// ---- Aether-side wrappers ----
// Create an empty set. Returns null on allocation failure.
new() -> ptr {
return aether_set_new()
}
// Insert `item`. Returns true if it was added, false if it was already
// present or the insert failed.
add(set: ptr, item: string) -> bool {
return aether_set_add(set, item) == 1
}
// True when `item` is in the set.
contains(set: ptr, item: string) -> bool {
return aether_set_has(set, item) == 1
}
// Drop `item`. Absent items are ignored.
remove(set: ptr, item: string) {
aether_set_remove(set, item)
}
// Number of items currently in the set.
size(set: ptr) -> int {
return aether_set_size(set)
}
// Drop every item, keeping the set usable.
clear(set: ptr) {
aether_set_clear(set)
}
// Release the set. Items were copied in, so nothing else needs freeing.
free(set: ptr) {
aether_set_free(set)
}
// Snapshot the set's items, in unspecified order. Returns
// (MapKeys ptr, "") on success, (null, error) otherwise. The snapshot
// is released with `set.items_free`.
items(set: ptr) -> {
if set == null {
return null, "null set"
}
it = aether_set_items_raw(set)
if it == null {
return null, "allocation failed"
}
return it, ""
}
// Release a snapshot returned by `set.items`.
items_free(items: ptr) {
aether_set_items_free(items)
}
// ---- reading an items snapshot (#1724) ------------------------------------
//
// Same contract as map.keys_size / map.keys_get, because `items` returns the
// same snapshot type: the strings are BORROWED, valid until `items_free` and
// only while the set still holds them, and iteration order is unspecified.
// Sort (std.sort.strings) for a deterministic order.
items_size(items: ptr) -> int {
if items == null {
return 0
}
return map_keys_size_raw(items)
}
// Out of range or null returns "" rather than trapping. An empty string is
// also a legitimate item, so callers who must distinguish check items_size.
items_get(items: ptr, index: int) -> string {
if items == null {
return ""
}
if index < 0 || index >= map_keys_size_raw(items) {
return ""
}
return map_keys_get_raw(items, index)
}