mt-lang 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/docs/index.html +4 -3
  3. data/lib/milk_tea/base.rb +1 -1
  4. data/std/asset_pack.mt +267 -0
  5. data/std/async/libuv_runtime.mt +539 -0
  6. data/std/async/mailbox.mt +191 -0
  7. data/std/async/runtime.mt +87 -0
  8. data/std/async.mt +87 -0
  9. data/std/base64.mt +185 -0
  10. data/std/behavior_tree.mt +396 -0
  11. data/std/binary.mt +314 -0
  12. data/std/binary_heap.mt +157 -0
  13. data/std/bitset.mt +239 -0
  14. data/std/box2d.mt +535 -0
  15. data/std/bytes.mt +46 -0
  16. data/std/c/box2d.mt +1254 -0
  17. data/std/c/cgltf.mt +647 -0
  18. data/std/c/cjson.mt +106 -0
  19. data/std/c/crypto.mt +11 -0
  20. data/std/c/crypto_support.h +51 -0
  21. data/std/c/ctype.mt +19 -0
  22. data/std/c/ctype_bindgen.h +29 -0
  23. data/std/c/curl.mt +1223 -0
  24. data/std/c/enet.mt +473 -0
  25. data/std/c/errno.mt +41 -0
  26. data/std/c/errno_bindgen.h +53 -0
  27. data/std/c/flecs.mt +2945 -0
  28. data/std/c/fs.linux.mt +43 -0
  29. data/std/c/fs.windows.mt +43 -0
  30. data/std/c/fs_support.h +954 -0
  31. data/std/c/gl.mt +2065 -0
  32. data/std/c/gl_registry_helpers.h +10748 -0
  33. data/std/c/glfw.mt +499 -0
  34. data/std/c/libc.mt +167 -0
  35. data/std/c/libuv.mt +1491 -0
  36. data/std/c/math.mt +22 -0
  37. data/std/c/math_bindgen.h +31 -0
  38. data/std/c/miniaudio.mt +3420 -0
  39. data/std/c/pcre2.mt +735 -0
  40. data/std/c/process.mt +58 -0
  41. data/std/c/process_support.h +1147 -0
  42. data/std/c/raygui.mt +1602 -0
  43. data/std/c/raylib.mt +1245 -0
  44. data/std/c/raymath.mt +163 -0
  45. data/std/c/rlgl.mt +434 -0
  46. data/std/c/rpng.mt +60 -0
  47. data/std/c/rres.mt +187 -0
  48. data/std/c/sdl3.mt +4132 -0
  49. data/std/c/sqlite3.mt +951 -0
  50. data/std/c/stb_image.mt +52 -0
  51. data/std/c/stb_image_resize2.mt +128 -0
  52. data/std/c/stb_image_write.mt +19 -0
  53. data/std/c/stb_rect_pack.mt +38 -0
  54. data/std/c/stb_truetype.mt +175 -0
  55. data/std/c/stb_vorbis.mt +31 -0
  56. data/std/c/stdio.mt +90 -0
  57. data/std/c/steamworks.h +5769 -0
  58. data/std/c/steamworks.mt +4771 -0
  59. data/std/c/string.mt +16 -0
  60. data/std/c/string_bindgen.h +36 -0
  61. data/std/c/sync.mt +33 -0
  62. data/std/c/sync_support.h +219 -0
  63. data/std/c/terminal.mt +24 -0
  64. data/std/c/terminal_support.h +408 -0
  65. data/std/c/time.mt +26 -0
  66. data/std/c/tls.mt +24 -0
  67. data/std/c/tls_support.h +626 -0
  68. data/std/c/tracy.mt +53 -0
  69. data/std/c/zlib.mt +20 -0
  70. data/std/c/zlib_support.h +239 -0
  71. data/std/c/zstd.mt +231 -0
  72. data/std/cell.mt +60 -0
  73. data/std/cgltf.mt +115 -0
  74. data/std/cjson.mt +90 -0
  75. data/std/cli.mt +768 -0
  76. data/std/cookie.mt +198 -0
  77. data/std/counter.mt +160 -0
  78. data/std/crypto.mt +74 -0
  79. data/std/cstring.mt +13 -0
  80. data/std/ctype.mt +52 -0
  81. data/std/curl/runtime.mt +261 -0
  82. data/std/curl.mt +38 -0
  83. data/std/deque.mt +348 -0
  84. data/std/encoding.mt +93 -0
  85. data/std/enet.mt +133 -0
  86. data/std/env.mt +41 -0
  87. data/std/errno.mt +47 -0
  88. data/std/flecs.mt +978 -0
  89. data/std/fmt.mt +271 -0
  90. data/std/fs.linux.mt +696 -0
  91. data/std/fs.windows.mt +711 -0
  92. data/std/fsm.mt +267 -0
  93. data/std/gl.mt +2062 -0
  94. data/std/glfw.mt +471 -0
  95. data/std/goap.mt +342 -0
  96. data/std/graph.mt +521 -0
  97. data/std/gzip.mt +77 -0
  98. data/std/hash.mt +429 -0
  99. data/std/http/server.mt +810 -0
  100. data/std/http.mt +1227 -0
  101. data/std/intern.mt +53 -0
  102. data/std/jobs.mt +288 -0
  103. data/std/json.mt +627 -0
  104. data/std/libc.mt +34 -0
  105. data/std/libuv.mt +554 -0
  106. data/std/linear_algebra.mt +243 -0
  107. data/std/linked_map.mt +372 -0
  108. data/std/linked_map_view.mt +49 -0
  109. data/std/linked_set.mt +117 -0
  110. data/std/log.mt +69 -0
  111. data/std/map.mt +418 -0
  112. data/std/math.mt +24 -0
  113. data/std/mem/arena.mt +137 -0
  114. data/std/mem/endian.mt +51 -0
  115. data/std/mem/heap.mt +298 -0
  116. data/std/mem/pool.mt +164 -0
  117. data/std/mem/stack.mt +47 -0
  118. data/std/mem/tracking.mt +119 -0
  119. data/std/miniaudio.mt +1299 -0
  120. data/std/multiset.mt +191 -0
  121. data/std/net/channel.mt +727 -0
  122. data/std/net/clock.mt +237 -0
  123. data/std/net/discovery.mt +277 -0
  124. data/std/net/lobby.mt +813 -0
  125. data/std/net/manager.mt +539 -0
  126. data/std/net/mux.mt +839 -0
  127. data/std/net/nat.mt +122 -0
  128. data/std/net/packet.mt +219 -0
  129. data/std/net/punch.mt +162 -0
  130. data/std/net/rpc.mt +119 -0
  131. data/std/net/session.mt +1157 -0
  132. data/std/net/stun.mt +252 -0
  133. data/std/net/sync.mt +183 -0
  134. data/std/net/turn.mt +459 -0
  135. data/std/net.mt +2944 -0
  136. data/std/oauth2.mt +408 -0
  137. data/std/option.mt +51 -0
  138. data/std/ordered_map.mt +497 -0
  139. data/std/ordered_set.mt +348 -0
  140. data/std/path.mt +368 -0
  141. data/std/pcre2/runtime.mt +35 -0
  142. data/std/pcre2.mt +78 -0
  143. data/std/priority_queue.mt +55 -0
  144. data/std/process.mt +837 -0
  145. data/std/queue.mt +55 -0
  146. data/std/random.mt +146 -0
  147. data/std/raygui.mt +99 -0
  148. data/std/raylib/debug_console.mt +71 -0
  149. data/std/raylib/easing.mt +388 -0
  150. data/std/raylib/packed_assets.mt +255 -0
  151. data/std/raylib/runtime.mt +30 -0
  152. data/std/raylib/tracy_gpu.mt +37 -0
  153. data/std/raylib.mt +1510 -0
  154. data/std/raymath.mt +153 -0
  155. data/std/result.mt +89 -0
  156. data/std/rlgl.mt +268 -0
  157. data/std/rpng.mt +46 -0
  158. data/std/rres.mt +36 -0
  159. data/std/sdl3/runtime.mt +54 -0
  160. data/std/sdl3.mt +1731 -0
  161. data/std/serialize.mt +68 -0
  162. data/std/set.mt +124 -0
  163. data/std/spatial.mt +176 -0
  164. data/std/sqlite3.mt +151 -0
  165. data/std/stack.mt +55 -0
  166. data/std/stb_image.mt +47 -0
  167. data/std/stb_image_resize2.mt +41 -0
  168. data/std/stb_image_write.mt +17 -0
  169. data/std/stb_rect_pack.mt +15 -0
  170. data/std/stb_truetype.mt +77 -0
  171. data/std/stb_vorbis.mt +16 -0
  172. data/std/stdio.mt +88 -0
  173. data/std/steamworks.mt +1542 -0
  174. data/std/str.mt +293 -0
  175. data/std/string.mt +234 -0
  176. data/std/sync.mt +194 -0
  177. data/std/tar.mt +704 -0
  178. data/std/terminal.mt +1002 -0
  179. data/std/testing.mt +266 -0
  180. data/std/thread.mt +120 -0
  181. data/std/time.mt +105 -0
  182. data/std/tls.mt +616 -0
  183. data/std/toml.mt +1310 -0
  184. data/std/tracy.mt +42 -0
  185. data/std/uri.mt +118 -0
  186. data/std/url.mt +372 -0
  187. data/std/vec.mt +433 -0
  188. data/std/zstd.mt +94 -0
  189. metadata +187 -2
@@ -0,0 +1,243 @@
1
+ import std.math as math
2
+
3
+ # ---------------------------------------------------------------------------
4
+ # vec2 — 2-dimensional float vector
5
+ # ---------------------------------------------------------------------------
6
+
7
+ extending vec2:
8
+ public static function zero() -> vec2:
9
+ return zero[vec2]
10
+
11
+
12
+ public static function fill(value: float) -> vec2:
13
+ return vec2(x = value, y = value)
14
+
15
+
16
+ public function dot(v: vec2) -> float:
17
+ return this.x * v.x + this.y * v.y
18
+
19
+
20
+ public function length_squared() -> float:
21
+ return this.dot(this)
22
+
23
+
24
+ public function length() -> float:
25
+ return float<-math.sqrt(double<-(this.length_squared()))
26
+
27
+
28
+ public function normalized() -> vec2:
29
+ let len = this.length()
30
+ return this / len
31
+
32
+
33
+ public function distance_squared_to(v: vec2) -> float:
34
+ let dx = this.x - v.x
35
+ let dy = this.y - v.y
36
+ return dx * dx + dy * dy
37
+
38
+
39
+ public function distance_to(v: vec2) -> float:
40
+ return float<-math.sqrt(double<-(this.distance_squared_to(v)))
41
+
42
+
43
+ public function lerp(target: vec2, t: float) -> vec2:
44
+ return this + (target - this) * t
45
+
46
+ # ---------------------------------------------------------------------------
47
+ # vec3 — 3-dimensional float vector
48
+ # ---------------------------------------------------------------------------
49
+
50
+ extending vec3:
51
+ public static function zero() -> vec3:
52
+ return zero[vec3]
53
+
54
+
55
+ public static function fill(value: float) -> vec3:
56
+ return vec3(x = value, y = value, z = value)
57
+
58
+
59
+ public function dot(v: vec3) -> float:
60
+ return this.x * v.x + this.y * v.y + this.z * v.z
61
+
62
+
63
+ public function length_squared() -> float:
64
+ return this.dot(this)
65
+
66
+
67
+ public function length() -> float:
68
+ return float<-math.sqrt(double<-(this.length_squared()))
69
+
70
+
71
+ public function normalized() -> vec3:
72
+ let len = this.length()
73
+ return this / len
74
+
75
+
76
+ public function distance_squared_to(v: vec3) -> float:
77
+ let dx = this.x - v.x
78
+ let dy = this.y - v.y
79
+ let dz = this.z - v.z
80
+ return dx * dx + dy * dy + dz * dz
81
+
82
+
83
+ public function distance_to(v: vec3) -> float:
84
+ return float<-math.sqrt(double<-(this.distance_squared_to(v)))
85
+
86
+
87
+ public function cross(v: vec3) -> vec3:
88
+ return vec3(
89
+ x = this.y * v.z - this.z * v.y,
90
+ y = this.z * v.x - this.x * v.z,
91
+ z = this.x * v.y - this.y * v.x
92
+ )
93
+
94
+
95
+ public function lerp(target: vec3, t: float) -> vec3:
96
+ return this + (target - this) * t
97
+
98
+ # ---------------------------------------------------------------------------
99
+ # vec4 — 4-dimensional float vector
100
+ # ---------------------------------------------------------------------------
101
+
102
+ extending vec4:
103
+ public static function zero() -> vec4:
104
+ return zero[vec4]
105
+
106
+
107
+ public static function fill(value: float) -> vec4:
108
+ return vec4(x = value, y = value, z = value, w = value)
109
+
110
+
111
+ public function dot(v: vec4) -> float:
112
+ return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w
113
+
114
+
115
+ public function length_squared() -> float:
116
+ return this.dot(this)
117
+
118
+
119
+ public function length() -> float:
120
+ return float<-math.sqrt(double<-(this.length_squared()))
121
+
122
+
123
+ public function normalized() -> vec4:
124
+ let len = this.length()
125
+ return this / len
126
+
127
+
128
+ public function distance_squared_to(v: vec4) -> float:
129
+ let dx = this.x - v.x
130
+ let dy = this.y - v.y
131
+ let dz = this.z - v.z
132
+ let dw = this.w - v.w
133
+ return dx * dx + dy * dy + dz * dz + dw * dw
134
+
135
+
136
+ public function distance_to(v: vec4) -> float:
137
+ return float<-math.sqrt(double<-(this.distance_squared_to(v)))
138
+
139
+
140
+ public function lerp(target: vec4, t: float) -> vec4:
141
+ return this + (target - this) * t
142
+
143
+ # ---------------------------------------------------------------------------
144
+ # ivec2 — 2-dimensional integer vector
145
+ # ---------------------------------------------------------------------------
146
+
147
+ extending ivec2:
148
+ public static function zero() -> ivec2:
149
+ return zero[ivec2]
150
+
151
+
152
+ public function dot(v: ivec2) -> int:
153
+ return this.x * v.x + this.y * v.y
154
+
155
+
156
+ public function length_squared() -> int:
157
+ return this.dot(this)
158
+
159
+ # ---------------------------------------------------------------------------
160
+ # ivec3 — 3-dimensional integer vector
161
+ # ---------------------------------------------------------------------------
162
+
163
+ extending ivec3:
164
+ public static function zero() -> ivec3:
165
+ return zero[ivec3]
166
+
167
+
168
+ public function dot(v: ivec3) -> int:
169
+ return this.x * v.x + this.y * v.y + this.z * v.z
170
+
171
+
172
+ public function length_squared() -> int:
173
+ return this.dot(this)
174
+
175
+ # ---------------------------------------------------------------------------
176
+ # ivec4 — 4-dimensional integer vector
177
+ # ---------------------------------------------------------------------------
178
+
179
+ extending ivec4:
180
+ public static function zero() -> ivec4:
181
+ return zero[ivec4]
182
+
183
+
184
+ public function dot(v: ivec4) -> int:
185
+ return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w
186
+
187
+
188
+ public function length_squared() -> int:
189
+ return this.dot(this)
190
+
191
+ # ---------------------------------------------------------------------------
192
+ # mat3 — 3×3 column-major matrix
193
+ # ---------------------------------------------------------------------------
194
+
195
+ extending mat3:
196
+ public static function identity() -> mat3:
197
+ return mat3(
198
+ col0 = vec3(x = 1.0, y = 0.0, z = 0.0),
199
+ col1 = vec3(x = 0.0, y = 1.0, z = 0.0),
200
+ col2 = vec3(x = 0.0, y = 0.0, z = 1.0)
201
+ )
202
+
203
+
204
+ public function transpose() -> mat3:
205
+ return mat3(
206
+ col0 = vec3(x = this.col0.x, y = this.col1.x, z = this.col2.x),
207
+ col1 = vec3(x = this.col0.y, y = this.col1.y, z = this.col2.y),
208
+ col2 = vec3(x = this.col0.z, y = this.col1.z, z = this.col2.z)
209
+ )
210
+
211
+ # ---------------------------------------------------------------------------
212
+ # mat4 — 4×4 column-major matrix
213
+ # ---------------------------------------------------------------------------
214
+
215
+ extending mat4:
216
+ public static function identity() -> mat4:
217
+ return mat4(
218
+ col0 = vec4(x = 1.0, y = 0.0, z = 0.0, w = 0.0),
219
+ col1 = vec4(x = 0.0, y = 1.0, z = 0.0, w = 0.0),
220
+ col2 = vec4(x = 0.0, y = 0.0, z = 1.0, w = 0.0),
221
+ col3 = vec4(x = 0.0, y = 0.0, z = 0.0, w = 1.0)
222
+ )
223
+
224
+
225
+ public function transpose() -> mat4:
226
+ return mat4(
227
+ col0 = vec4(x = this.col0.x, y = this.col1.x, z = this.col2.x, w = this.col3.x),
228
+ col1 = vec4(x = this.col0.y, y = this.col1.y, z = this.col2.y, w = this.col3.y),
229
+ col2 = vec4(x = this.col0.z, y = this.col1.z, z = this.col2.z, w = this.col3.z),
230
+ col3 = vec4(x = this.col0.w, y = this.col1.w, z = this.col2.w, w = this.col3.w)
231
+ )
232
+
233
+ # ---------------------------------------------------------------------------
234
+ # quat — quaternion
235
+ # ---------------------------------------------------------------------------
236
+
237
+ extending quat:
238
+ public static function identity() -> quat:
239
+ return quat(x = 0.0, y = 0.0, z = 0.0, w = 1.0)
240
+
241
+
242
+ public function conjugate() -> quat:
243
+ return quat(x = -this.x, y = -this.y, z = -this.z, w = this.w)
data/std/linked_map.mt ADDED
@@ -0,0 +1,372 @@
1
+ import std.mem.heap as heap
2
+
3
+ struct Node[K, V]:
4
+ hash: uint
5
+ key: K
6
+ value: V
7
+ bucket_next: ptr[Node[K, V]]?
8
+ order_prev: ptr[Node[K, V]]?
9
+ order_next: ptr[Node[K, V]]?
10
+
11
+ public struct Entry[K, V]:
12
+ key: const_ptr[K]
13
+ value: ptr[V]
14
+
15
+ public struct RemovedEntry[K, V]:
16
+ key: K
17
+ value: V
18
+
19
+ public struct Keys[K, V]:
20
+ node: ptr[Node[K, V]]?
21
+
22
+ public struct Values[K, V]:
23
+ node: ptr[Node[K, V]]?
24
+
25
+ public struct Entries[K, V]:
26
+ node: ptr[Node[K, V]]?
27
+ started: bool
28
+
29
+ public struct LinkedMap[K, V]:
30
+ buckets: own[ptr[Node[K, V]]?]?
31
+ len: ptr_uint
32
+ capacity: ptr_uint
33
+ head: ptr[Node[K, V]]?
34
+ tail: ptr[Node[K, V]]?
35
+
36
+
37
+ extending LinkedMap[K, V]:
38
+ public static function create() -> LinkedMap[K, V]:
39
+ return LinkedMap[K, V](buckets = null, len = 0, capacity = 0, head = null, tail = null)
40
+
41
+
42
+ public static function with_capacity(capacity: ptr_uint) -> LinkedMap[K, V]:
43
+ var result = LinkedMap[K, V].create()
44
+ result.reserve(capacity)
45
+ return result
46
+
47
+
48
+ static function bucket_index(entry_hash: uint, capacity: ptr_uint) -> ptr_uint:
49
+ let bucket_count = uint<-capacity
50
+ return ptr_uint<-(entry_hash % bucket_count)
51
+
52
+
53
+ static function find_node(current: LinkedMap[K, V], key: K, key_hash: uint) -> ptr[Node[K, V]]?:
54
+ if current.len == 0:
55
+ return null
56
+
57
+ let buckets = current.buckets else:
58
+ fatal(c"linked_map.LinkedMap.find_node missing buckets")
59
+
60
+ unsafe:
61
+ let bucket_ptr = ptr[ptr[Node[K, V]]?]<-buckets
62
+ let index = LinkedMap[K, V].bucket_index(key_hash, current.capacity)
63
+ var node = read(bucket_ptr + index)
64
+ while node != null:
65
+ let node_ptr = ptr[Node[K, V]]<-node
66
+ let stored_key = const_ptr_of(read(node_ptr).key)
67
+ if read(node_ptr).hash == key_hash and equal[K](key, stored_key):
68
+ return node
69
+ node = read(node_ptr).bucket_next
70
+
71
+ return null
72
+
73
+
74
+ static function unlink_order_node(current: ref[LinkedMap[K, V]], node: ptr[Node[K, V]]) -> void:
75
+ let previous = unsafe: read(node).order_prev
76
+ let next = unsafe: read(node).order_next
77
+
78
+ if previous == null:
79
+ current.head = next
80
+ else:
81
+ unsafe:
82
+ read(ptr[Node[K, V]]<-previous).order_next = next
83
+
84
+ if next == null:
85
+ current.tail = previous
86
+ else:
87
+ unsafe:
88
+ read(ptr[Node[K, V]]<-next).order_prev = previous
89
+
90
+
91
+ public function len() -> ptr_uint:
92
+ return this.len
93
+
94
+
95
+ public function capacity() -> ptr_uint:
96
+ return this.capacity
97
+
98
+
99
+ public function is_empty() -> bool:
100
+ return this.len == 0
101
+
102
+
103
+ public function get(key: K) -> ptr[V]?:
104
+ let key_hash = hash[K](key)
105
+ let node = LinkedMap[K, V].find_node(this, key, key_hash) else:
106
+ return null
107
+
108
+ unsafe:
109
+ return ptr_of(read(ptr[Node[K, V]]<-node).value)
110
+
111
+
112
+ public function at(key: K) -> Option[V]:
113
+ let p = this.get(key) else:
114
+ return Option[V].none
115
+
116
+ unsafe:
117
+ return Option[V].some(value = read(p))
118
+
119
+
120
+ public function get_key(key: K) -> const_ptr[K]?:
121
+ let key_hash = hash[K](key)
122
+ let node = LinkedMap[K, V].find_node(this, key, key_hash) else:
123
+ return null
124
+
125
+ unsafe:
126
+ return const_ptr_of(read(ptr[Node[K, V]]<-node).key)
127
+
128
+
129
+ public function iter() -> Entries[K, V]:
130
+ return this.entries()
131
+
132
+
133
+ public function keys() -> Keys[K, V]:
134
+ return Keys[K, V](node = this.head)
135
+
136
+
137
+ public function values() -> Values[K, V]:
138
+ return Values[K, V](node = this.head)
139
+
140
+
141
+ public function entries() -> Entries[K, V]:
142
+ return Entries[K, V](node = this.head, started = false)
143
+
144
+
145
+ public function contains(key: K) -> bool:
146
+ return this.get(key) != null
147
+
148
+
149
+ public editable function clear() -> void:
150
+ if this.len == 0:
151
+ return
152
+
153
+ let buckets = this.buckets else:
154
+ fatal(c"linked_map.LinkedMap.clear missing buckets")
155
+
156
+ unsafe:
157
+ var node = this.head
158
+ while node != null:
159
+ let node_ptr = ptr[Node[K, V]]<-node
160
+ let next = read(node_ptr).order_next
161
+ heap.release(node)
162
+ node = next
163
+
164
+ let bucket_ptr = ptr[ptr[Node[K, V]]?]<-buckets
165
+ var index: ptr_uint = 0
166
+ while index < this.capacity:
167
+ read(bucket_ptr + index) = null
168
+ index += 1
169
+
170
+ this.len = 0
171
+ this.head = null
172
+ this.tail = null
173
+
174
+
175
+ public editable function release() -> void:
176
+ this.clear()
177
+ heap.release(this.buckets)
178
+ this.buckets = null
179
+ this.capacity = 0
180
+
181
+
182
+ public editable function reserve(min_capacity: ptr_uint) -> void:
183
+ if min_capacity <= this.capacity:
184
+ return
185
+
186
+ var new_capacity = this.capacity
187
+ if new_capacity == 0:
188
+ new_capacity = 8
189
+
190
+ while new_capacity < min_capacity:
191
+ if new_capacity > heap.ptr_uint_max / 2:
192
+ new_capacity = min_capacity
193
+ else:
194
+ new_capacity *= 2
195
+
196
+ let new_buckets = heap.must_alloc_zeroed[ptr[Node[K, V]]?](new_capacity)
197
+ let old_buckets = this.buckets
198
+
199
+ unsafe:
200
+ let new_ptr = ptr[ptr[Node[K, V]]?]<-new_buckets
201
+ var node = this.head
202
+ while node != null:
203
+ let node_ptr = ptr[Node[K, V]]<-node
204
+ let next = read(node_ptr).order_next
205
+ let target = LinkedMap[K, V].bucket_index(read(node_ptr).hash, new_capacity)
206
+ read(node_ptr).bucket_next = read(new_ptr + target)
207
+ read(new_ptr + target) = node
208
+ node = next
209
+
210
+ heap.release(old_buckets)
211
+ this.buckets = new_buckets
212
+ this.capacity = new_capacity
213
+
214
+
215
+ public editable function set(key: K, value: V) -> Option[V]:
216
+ let key_hash = hash[K](key)
217
+ let existing = LinkedMap[K, V].find_node(this, key, key_hash)
218
+ if existing != null:
219
+ unsafe:
220
+ let node_ptr = ptr[Node[K, V]]<-existing
221
+ let previous = read(node_ptr).value
222
+ read(node_ptr).value = value
223
+ return Option[V].some(value = previous)
224
+
225
+ if this.len == this.capacity:
226
+ this.reserve(this.len + 1)
227
+
228
+ let current_buckets = this.buckets else:
229
+ fatal(c"linked_map.LinkedMap.set missing buckets")
230
+
231
+ unsafe:
232
+ let bucket_ptr = ptr[ptr[Node[K, V]]?]<-current_buckets
233
+ let index = LinkedMap[K, V].bucket_index(key_hash, this.capacity)
234
+ let node = heap.must_alloc[Node[K, V]](1)
235
+ let tail = this.tail
236
+ read(node) = Node[K, V](
237
+ hash = key_hash,
238
+ key = key,
239
+ value = value,
240
+ bucket_next = read(bucket_ptr + index),
241
+ order_prev = tail,
242
+ order_next = null
243
+ )
244
+ read(bucket_ptr + index) = node
245
+
246
+ if tail == null:
247
+ this.head = node
248
+ else:
249
+ read(ptr[Node[K, V]]<-tail).order_next = node
250
+ this.tail = node
251
+
252
+ this.len += 1
253
+ return Option[V].none
254
+
255
+
256
+ public editable function get_or_insert(key: K, value: V) -> ptr[V]:
257
+ let key_hash = hash[K](key)
258
+ let existing = LinkedMap[K, V].find_node(this, key, key_hash)
259
+ if existing != null:
260
+ unsafe:
261
+ return ptr_of(read(ptr[Node[K, V]]<-existing).value)
262
+
263
+ let inserted = this.set(key, value)
264
+ match inserted:
265
+ Option.none:
266
+ let current = LinkedMap[K, V].find_node(this, key, key_hash) else:
267
+ fatal(c"linked_map.LinkedMap.get_or_insert missing inserted value")
268
+ unsafe:
269
+ return ptr_of(read(ptr[Node[K, V]]<-current).value)
270
+ Option.some as ignored_payload:
271
+ fatal(c"linked_map.LinkedMap.get_or_insert replaced unexpectedly")
272
+
273
+
274
+ public editable function remove_entry(key: K) -> Option[RemovedEntry[K, V]]:
275
+ if this.len == 0:
276
+ return Option[RemovedEntry[K, V]].none
277
+
278
+ let buckets = this.buckets else:
279
+ fatal(c"linked_map.LinkedMap.remove_entry missing buckets")
280
+
281
+ let key_hash = hash[K](key)
282
+
283
+ unsafe:
284
+ let bucket_ptr = ptr[ptr[Node[K, V]]?]<-buckets
285
+ let index = LinkedMap[K, V].bucket_index(key_hash, this.capacity)
286
+ var previous: ptr[Node[K, V]]? = null
287
+ var node = read(bucket_ptr + index)
288
+ while node != null:
289
+ let node_ptr = ptr[Node[K, V]]<-node
290
+ let stored_key = const_ptr_of(read(node_ptr).key)
291
+ if read(node_ptr).hash == key_hash and equal[K](key, stored_key):
292
+ let next_bucket = read(node_ptr).bucket_next
293
+ if previous == null:
294
+ read(bucket_ptr + index) = next_bucket
295
+ else:
296
+ read(ptr[Node[K, V]]<-previous).bucket_next = next_bucket
297
+
298
+ let removed = RemovedEntry[K, V](key = read(node_ptr).key, value = read(node_ptr).value)
299
+ LinkedMap[K, V].unlink_order_node(this, node_ptr)
300
+ heap.release(node)
301
+ this.len -= 1
302
+ return Option[RemovedEntry[K, V]].some(value = removed)
303
+
304
+ previous = node
305
+ node = read(node_ptr).bucket_next
306
+
307
+ return Option[RemovedEntry[K, V]].none
308
+
309
+
310
+ public editable function remove(key: K) -> Option[V]:
311
+ let removed = this.remove_entry(key)
312
+ if removed.is_none():
313
+ return Option[V].none
314
+ return Option[V].some(value = removed.unwrap().value)
315
+
316
+
317
+ extending Keys[K, V]:
318
+ public function iter() -> Keys[K, V]:
319
+ return this
320
+
321
+
322
+ public editable function next() -> const_ptr[K]?:
323
+ let current = this.node else:
324
+ return null
325
+
326
+ unsafe:
327
+ let current_ptr = ptr[Node[K, V]]<-current
328
+ this.node = read(current_ptr).order_next
329
+ return const_ptr_of(read(current_ptr).key)
330
+
331
+
332
+ extending Values[K, V]:
333
+ public function iter() -> Values[K, V]:
334
+ return this
335
+
336
+
337
+ public editable function next() -> ptr[V]?:
338
+ let current = this.node else:
339
+ return null
340
+
341
+ unsafe:
342
+ let current_ptr = ptr[Node[K, V]]<-current
343
+ this.node = read(current_ptr).order_next
344
+ return ptr_of(read(current_ptr).value)
345
+
346
+
347
+ extending Entries[K, V]:
348
+ public function iter() -> Entries[K, V]:
349
+ return this
350
+
351
+
352
+ public editable function next() -> bool:
353
+ let current = this.node else:
354
+ return false
355
+
356
+ if not this.started:
357
+ this.started = true
358
+ return true
359
+
360
+ let next = unsafe: read(ptr[Node[K, V]]<-current).order_next
361
+ this.node = next
362
+ return next != null
363
+
364
+
365
+ public function current() -> Entry[K, V]:
366
+ let current = this.node
367
+ if current == null or not this.started:
368
+ fatal(c"linked_map.Entries.current missing current node")
369
+
370
+ unsafe:
371
+ let node_ptr = ptr[Node[K, V]]<-current
372
+ return Entry[K, V](key = const_ptr_of(read(node_ptr).key), value = ptr_of(read(node_ptr).value))
@@ -0,0 +1,49 @@
1
+ import std.linked_map as linked_map
2
+
3
+ public struct SnapshotEntry[K, V]:
4
+ key: const_ptr[K]
5
+ value: V
6
+
7
+ public struct SnapshotValues[K, V]:
8
+ values: linked_map.Entries[K, V]
9
+
10
+ public struct SnapshotEntries[K, V]:
11
+ values: linked_map.Entries[K, V]
12
+
13
+
14
+ extending SnapshotValues[K, V]:
15
+ public static function create(values: linked_map.Entries[K, V]) -> SnapshotValues[K, V]:
16
+ return SnapshotValues[K, V](values = values)
17
+
18
+
19
+ public function iter() -> SnapshotValues[K, V]:
20
+ return this
21
+
22
+
23
+ public editable function next() -> bool:
24
+ return this.values.next()
25
+
26
+
27
+ public function current() -> V:
28
+ let entry = this.values.current()
29
+ unsafe:
30
+ return read(entry.value)
31
+
32
+
33
+ extending SnapshotEntries[K, V]:
34
+ public static function create(values: linked_map.Entries[K, V]) -> SnapshotEntries[K, V]:
35
+ return SnapshotEntries[K, V](values = values)
36
+
37
+
38
+ public function iter() -> SnapshotEntries[K, V]:
39
+ return this
40
+
41
+
42
+ public editable function next() -> bool:
43
+ return this.values.next()
44
+
45
+
46
+ public function current() -> SnapshotEntry[K, V]:
47
+ let entry = this.values.current()
48
+ unsafe:
49
+ return SnapshotEntry[K, V](key = entry.key, value = read(entry.value))