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.
- checksums.yaml +4 -4
- data/docs/index.html +4 -3
- data/lib/milk_tea/base.rb +1 -1
- data/std/asset_pack.mt +267 -0
- data/std/async/libuv_runtime.mt +539 -0
- data/std/async/mailbox.mt +191 -0
- data/std/async/runtime.mt +87 -0
- data/std/async.mt +87 -0
- data/std/base64.mt +185 -0
- data/std/behavior_tree.mt +396 -0
- data/std/binary.mt +314 -0
- data/std/binary_heap.mt +157 -0
- data/std/bitset.mt +239 -0
- data/std/box2d.mt +535 -0
- data/std/bytes.mt +46 -0
- data/std/c/box2d.mt +1254 -0
- data/std/c/cgltf.mt +647 -0
- data/std/c/cjson.mt +106 -0
- data/std/c/crypto.mt +11 -0
- data/std/c/crypto_support.h +51 -0
- data/std/c/ctype.mt +19 -0
- data/std/c/ctype_bindgen.h +29 -0
- data/std/c/curl.mt +1223 -0
- data/std/c/enet.mt +473 -0
- data/std/c/errno.mt +41 -0
- data/std/c/errno_bindgen.h +53 -0
- data/std/c/flecs.mt +2945 -0
- data/std/c/fs.linux.mt +43 -0
- data/std/c/fs.windows.mt +43 -0
- data/std/c/fs_support.h +954 -0
- data/std/c/gl.mt +2065 -0
- data/std/c/gl_registry_helpers.h +10748 -0
- data/std/c/glfw.mt +499 -0
- data/std/c/libc.mt +167 -0
- data/std/c/libuv.mt +1491 -0
- data/std/c/math.mt +22 -0
- data/std/c/math_bindgen.h +31 -0
- data/std/c/miniaudio.mt +3420 -0
- data/std/c/pcre2.mt +735 -0
- data/std/c/process.mt +58 -0
- data/std/c/process_support.h +1147 -0
- data/std/c/raygui.mt +1602 -0
- data/std/c/raylib.mt +1245 -0
- data/std/c/raymath.mt +163 -0
- data/std/c/rlgl.mt +434 -0
- data/std/c/rpng.mt +60 -0
- data/std/c/rres.mt +187 -0
- data/std/c/sdl3.mt +4132 -0
- data/std/c/sqlite3.mt +951 -0
- data/std/c/stb_image.mt +52 -0
- data/std/c/stb_image_resize2.mt +128 -0
- data/std/c/stb_image_write.mt +19 -0
- data/std/c/stb_rect_pack.mt +38 -0
- data/std/c/stb_truetype.mt +175 -0
- data/std/c/stb_vorbis.mt +31 -0
- data/std/c/stdio.mt +90 -0
- data/std/c/steamworks.h +5769 -0
- data/std/c/steamworks.mt +4771 -0
- data/std/c/string.mt +16 -0
- data/std/c/string_bindgen.h +36 -0
- data/std/c/sync.mt +33 -0
- data/std/c/sync_support.h +219 -0
- data/std/c/terminal.mt +24 -0
- data/std/c/terminal_support.h +408 -0
- data/std/c/time.mt +26 -0
- data/std/c/tls.mt +24 -0
- data/std/c/tls_support.h +626 -0
- data/std/c/tracy.mt +53 -0
- data/std/c/zlib.mt +20 -0
- data/std/c/zlib_support.h +239 -0
- data/std/c/zstd.mt +231 -0
- data/std/cell.mt +60 -0
- data/std/cgltf.mt +115 -0
- data/std/cjson.mt +90 -0
- data/std/cli.mt +768 -0
- data/std/cookie.mt +198 -0
- data/std/counter.mt +160 -0
- data/std/crypto.mt +74 -0
- data/std/cstring.mt +13 -0
- data/std/ctype.mt +52 -0
- data/std/curl/runtime.mt +261 -0
- data/std/curl.mt +38 -0
- data/std/deque.mt +348 -0
- data/std/encoding.mt +93 -0
- data/std/enet.mt +133 -0
- data/std/env.mt +41 -0
- data/std/errno.mt +47 -0
- data/std/flecs.mt +978 -0
- data/std/fmt.mt +271 -0
- data/std/fs.linux.mt +696 -0
- data/std/fs.windows.mt +711 -0
- data/std/fsm.mt +267 -0
- data/std/gl.mt +2062 -0
- data/std/glfw.mt +471 -0
- data/std/goap.mt +342 -0
- data/std/graph.mt +521 -0
- data/std/gzip.mt +77 -0
- data/std/hash.mt +429 -0
- data/std/http/server.mt +810 -0
- data/std/http.mt +1227 -0
- data/std/intern.mt +53 -0
- data/std/jobs.mt +288 -0
- data/std/json.mt +627 -0
- data/std/libc.mt +34 -0
- data/std/libuv.mt +554 -0
- data/std/linear_algebra.mt +243 -0
- data/std/linked_map.mt +372 -0
- data/std/linked_map_view.mt +49 -0
- data/std/linked_set.mt +117 -0
- data/std/log.mt +69 -0
- data/std/map.mt +418 -0
- data/std/math.mt +24 -0
- data/std/mem/arena.mt +137 -0
- data/std/mem/endian.mt +51 -0
- data/std/mem/heap.mt +298 -0
- data/std/mem/pool.mt +164 -0
- data/std/mem/stack.mt +47 -0
- data/std/mem/tracking.mt +119 -0
- data/std/miniaudio.mt +1299 -0
- data/std/multiset.mt +191 -0
- data/std/net/channel.mt +727 -0
- data/std/net/clock.mt +237 -0
- data/std/net/discovery.mt +277 -0
- data/std/net/lobby.mt +813 -0
- data/std/net/manager.mt +539 -0
- data/std/net/mux.mt +839 -0
- data/std/net/nat.mt +122 -0
- data/std/net/packet.mt +219 -0
- data/std/net/punch.mt +162 -0
- data/std/net/rpc.mt +119 -0
- data/std/net/session.mt +1157 -0
- data/std/net/stun.mt +252 -0
- data/std/net/sync.mt +183 -0
- data/std/net/turn.mt +459 -0
- data/std/net.mt +2944 -0
- data/std/oauth2.mt +408 -0
- data/std/option.mt +51 -0
- data/std/ordered_map.mt +497 -0
- data/std/ordered_set.mt +348 -0
- data/std/path.mt +368 -0
- data/std/pcre2/runtime.mt +35 -0
- data/std/pcre2.mt +78 -0
- data/std/priority_queue.mt +55 -0
- data/std/process.mt +837 -0
- data/std/queue.mt +55 -0
- data/std/random.mt +146 -0
- data/std/raygui.mt +99 -0
- data/std/raylib/debug_console.mt +71 -0
- data/std/raylib/easing.mt +388 -0
- data/std/raylib/packed_assets.mt +255 -0
- data/std/raylib/runtime.mt +30 -0
- data/std/raylib/tracy_gpu.mt +37 -0
- data/std/raylib.mt +1510 -0
- data/std/raymath.mt +153 -0
- data/std/result.mt +89 -0
- data/std/rlgl.mt +268 -0
- data/std/rpng.mt +46 -0
- data/std/rres.mt +36 -0
- data/std/sdl3/runtime.mt +54 -0
- data/std/sdl3.mt +1731 -0
- data/std/serialize.mt +68 -0
- data/std/set.mt +124 -0
- data/std/spatial.mt +176 -0
- data/std/sqlite3.mt +151 -0
- data/std/stack.mt +55 -0
- data/std/stb_image.mt +47 -0
- data/std/stb_image_resize2.mt +41 -0
- data/std/stb_image_write.mt +17 -0
- data/std/stb_rect_pack.mt +15 -0
- data/std/stb_truetype.mt +77 -0
- data/std/stb_vorbis.mt +16 -0
- data/std/stdio.mt +88 -0
- data/std/steamworks.mt +1542 -0
- data/std/str.mt +293 -0
- data/std/string.mt +234 -0
- data/std/sync.mt +194 -0
- data/std/tar.mt +704 -0
- data/std/terminal.mt +1002 -0
- data/std/testing.mt +266 -0
- data/std/thread.mt +120 -0
- data/std/time.mt +105 -0
- data/std/tls.mt +616 -0
- data/std/toml.mt +1310 -0
- data/std/tracy.mt +42 -0
- data/std/uri.mt +118 -0
- data/std/url.mt +372 -0
- data/std/vec.mt +433 -0
- data/std/zstd.mt +94 -0
- 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))
|