@shd101wyy/yo 0.1.14 → 0.1.16
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.
- package/README.md +43 -1
- package/out/cjs/index.cjs +581 -601
- package/out/cjs/yo-cli.cjs +739 -733
- package/out/cjs/yo-lsp.cjs +11615 -0
- package/out/esm/index.mjs +530 -550
- package/out/types/src/cache.d.ts +2 -0
- package/out/types/src/codegen/exprs/return.d.ts +1 -1
- package/out/types/src/codegen/types/generation.d.ts +0 -2
- package/out/types/src/codegen/utils/index.d.ts +2 -8
- package/out/types/src/doc/extractor.d.ts +4 -0
- package/out/types/src/evaluator/builtins/rc-fns.d.ts +0 -5
- package/out/types/src/evaluator/context.d.ts +7 -3
- package/out/types/src/evaluator/trait-checking.d.ts +2 -0
- package/out/types/src/evaluator/types/object.d.ts +2 -1
- package/out/types/src/evaluator/types/struct.d.ts +2 -1
- package/out/types/src/evaluator/types/utils.d.ts +3 -8
- package/out/types/src/evaluator/values/impl.d.ts +9 -1
- package/out/types/src/expr.d.ts +1 -2
- package/out/types/src/function-value.d.ts +1 -0
- package/out/types/src/lsp/completion.d.ts +3 -0
- package/out/types/src/lsp/definition.d.ts +3 -0
- package/out/types/src/lsp/diagnostics.d.ts +6 -0
- package/out/types/src/lsp/document-manager.d.ts +31 -0
- package/out/types/src/lsp/folding.d.ts +3 -0
- package/out/types/src/lsp/hover.d.ts +3 -0
- package/out/types/src/lsp/inlay-hints.d.ts +3 -0
- package/out/types/src/lsp/references.d.ts +3 -0
- package/out/types/src/lsp/rename.d.ts +16 -0
- package/out/types/src/lsp/server.d.ts +1 -0
- package/out/types/src/lsp/signature-help.d.ts +3 -0
- package/out/types/src/lsp/symbols.d.ts +3 -0
- package/out/types/src/lsp/utils.d.ts +11 -0
- package/out/types/src/tests/lsp.test.d.ts +1 -0
- package/out/types/src/tests/version.test.d.ts +1 -0
- package/out/types/src/types/creators.d.ts +2 -3
- package/out/types/src/types/definitions.d.ts +3 -6
- package/out/types/src/types/guards.d.ts +5 -2
- package/out/types/src/types/tags.d.ts +0 -1
- package/out/types/src/version-cache.d.ts +7 -0
- package/out/types/src/version.d.ts +5 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -1
- package/scripts/build-site.ts +32 -15
- package/scripts/check-liburing.js +2 -2
- package/std/imm/list.yo +254 -0
- package/std/imm/map.yo +917 -0
- package/std/imm/set.yo +179 -0
- package/std/imm/sorted_map.yo +595 -0
- package/std/imm/sorted_set.yo +202 -0
- package/std/imm/string.yo +667 -0
- package/std/imm/vec.yo +456 -0
- package/std/prelude.yo +22 -5
- package/std/sync/channel.yo +92 -44
- package/std/sync/cond.yo +5 -1
- package/std/sync/mutex.yo +5 -1
- package/std/sync/once.yo +2 -1
- package/std/sync/rwlock.yo +2 -1
- package/std/sync/waitgroup.yo +2 -1
- package/out/types/src/codegen/exprs/arc.d.ts +0 -5
- package/out/types/src/evaluator/calls/arc.d.ts +0 -15
package/std/imm/vec.yo
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
//! Persistent immutable vector with efficient indexed access and append.
|
|
2
|
+
//!
|
|
3
|
+
//! `Vec(T)` is an immutable vector backed by `atomic object` for thread-safe
|
|
4
|
+
//! structural sharing. All mutations return new vectors, leaving the original
|
|
5
|
+
//! unchanged.
|
|
6
|
+
//!
|
|
7
|
+
//! All elements must implement `Send` to guarantee thread safety.
|
|
8
|
+
//!
|
|
9
|
+
//! # Examples
|
|
10
|
+
//!
|
|
11
|
+
//! ```rust
|
|
12
|
+
//! { Vec } :: import "std/imm/vec";
|
|
13
|
+
//!
|
|
14
|
+
//! v := Vec(i32).new();
|
|
15
|
+
//! v = v.push(i32(1)).push(i32(2)).push(i32(3));
|
|
16
|
+
//! assert((v.get(usize(0)).unwrap() == i32(1)), "first element");
|
|
17
|
+
//! assert((v.len() == usize(3)), "length is 3");
|
|
18
|
+
//! ```
|
|
19
|
+
|
|
20
|
+
{ GlobalAllocator } :: import "../allocator.yo";
|
|
21
|
+
{ malloc, free } :: GlobalAllocator;
|
|
22
|
+
|
|
23
|
+
/// Persistent immutable vector.
|
|
24
|
+
///
|
|
25
|
+
/// Backed by a shared flat array with copy-on-write semantics.
|
|
26
|
+
/// All mutations create a new vector, sharing the backing buffer via
|
|
27
|
+
/// atomic reference counting when possible.
|
|
28
|
+
Vec :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))(
|
|
29
|
+
atomic object(
|
|
30
|
+
_ptr : *(T),
|
|
31
|
+
_len : usize,
|
|
32
|
+
_cap : usize
|
|
33
|
+
)
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
impl(forall(T : Type), where(T <: Send), Vec(T), Dispose(
|
|
37
|
+
dispose : (fn(self: Self) -> unit)({
|
|
38
|
+
i := usize(0);
|
|
39
|
+
while (i < self._len), (i = (i + usize(1))), {
|
|
40
|
+
unsafe.drop((self._ptr &+ i).*);
|
|
41
|
+
};
|
|
42
|
+
free(.Some(*(void)(self._ptr)));
|
|
43
|
+
})
|
|
44
|
+
));
|
|
45
|
+
|
|
46
|
+
/// Result of a pop operation.
|
|
47
|
+
PopResult :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))(
|
|
48
|
+
struct(vec: Vec(T), value: Option(T))
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
impl(forall(T : Type), where(T <: Send), Vec(T),
|
|
52
|
+
/// Allocate raw buffer without creating an intermediate atomic object.
|
|
53
|
+
_raw_alloc : (fn(cap: usize) -> *(T))({
|
|
54
|
+
alloc_cap := cond(
|
|
55
|
+
(cap > usize(0)) => cap,
|
|
56
|
+
true => usize(1)
|
|
57
|
+
);
|
|
58
|
+
sz := (sizeof(T) * alloc_cap);
|
|
59
|
+
match(malloc(sz),
|
|
60
|
+
.Some(p) => *(T)(p),
|
|
61
|
+
.None => panic("imm.Vec: allocation failed")
|
|
62
|
+
)
|
|
63
|
+
}),
|
|
64
|
+
|
|
65
|
+
/// Copy elements element-by-element so RC-backed values duplicate correctly.
|
|
66
|
+
_copy_elems : (fn(
|
|
67
|
+
dst: *(T), src: *(T),
|
|
68
|
+
dst_offset: usize, src_offset: usize, count: usize
|
|
69
|
+
) -> unit)({
|
|
70
|
+
i := usize(0);
|
|
71
|
+
while (i < count), (i = (i + usize(1))), {
|
|
72
|
+
consume((dst &+ (dst_offset + i)).* = (src &+ (src_offset + i)).*);
|
|
73
|
+
};
|
|
74
|
+
}),
|
|
75
|
+
|
|
76
|
+
/// Create a new empty vector.
|
|
77
|
+
new : (fn() -> Self)(
|
|
78
|
+
Self(_ptr: Self._raw_alloc(usize(4)), _len: usize(0), _cap: usize(4))
|
|
79
|
+
),
|
|
80
|
+
|
|
81
|
+
/// Create a new empty vector with the given initial capacity.
|
|
82
|
+
with_capacity : (fn(cap: usize) -> Self)(
|
|
83
|
+
Self(_ptr: Self._raw_alloc(cap), _len: usize(0), _cap: cap)
|
|
84
|
+
),
|
|
85
|
+
|
|
86
|
+
/// Number of elements in the vector.
|
|
87
|
+
len : (fn(self: Self) -> usize)(self._len),
|
|
88
|
+
|
|
89
|
+
/// Check if the vector is empty.
|
|
90
|
+
is_empty : (fn(self: Self) -> bool)(self._len == usize(0)),
|
|
91
|
+
|
|
92
|
+
/// Get the element at `idx`, or `.None` if out of bounds.
|
|
93
|
+
get : (fn(self: Self, idx: usize) -> Option(T))({
|
|
94
|
+
if((idx >= self._len), {
|
|
95
|
+
return .None;
|
|
96
|
+
});
|
|
97
|
+
.Some((self._ptr &+ idx).*)
|
|
98
|
+
}),
|
|
99
|
+
|
|
100
|
+
/// Return a new vector with the element at `idx` replaced by `val`.
|
|
101
|
+
/// Panics if `idx >= len`.
|
|
102
|
+
set : (fn(own(self): Self, idx: usize, val: T) -> Self)({
|
|
103
|
+
assert((idx < self._len), "imm.Vec.set: index out of bounds");
|
|
104
|
+
if((rc(self) == usize(1)), {
|
|
105
|
+
unsafe.drop((self._ptr &+ idx).*);
|
|
106
|
+
consume((self._ptr &+ idx).* = val);
|
|
107
|
+
return self;
|
|
108
|
+
});
|
|
109
|
+
new_ptr := Self._raw_alloc(self._len);
|
|
110
|
+
if((self._len > usize(0)), {
|
|
111
|
+
Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
|
|
112
|
+
});
|
|
113
|
+
unsafe.drop((new_ptr &+ idx).*);
|
|
114
|
+
consume((new_ptr &+ idx).* = val);
|
|
115
|
+
result := Self(_ptr: new_ptr, _len: self._len, _cap: self._len);
|
|
116
|
+
unsafe.drop(self);
|
|
117
|
+
result
|
|
118
|
+
}),
|
|
119
|
+
|
|
120
|
+
/// Return a new vector with `val` appended.
|
|
121
|
+
push : (fn(own(self): Self, val: T) -> Self)({
|
|
122
|
+
if((rc(self) == usize(1)), {
|
|
123
|
+
if((self._len >= self._cap), {
|
|
124
|
+
new_cap := (self._cap * usize(2));
|
|
125
|
+
new_ptr := Self._raw_alloc(new_cap);
|
|
126
|
+
if((self._len > usize(0)), {
|
|
127
|
+
Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
|
|
128
|
+
});
|
|
129
|
+
free(.Some(*(void)(self._ptr)));
|
|
130
|
+
self._ptr = new_ptr;
|
|
131
|
+
self._cap = new_cap;
|
|
132
|
+
});
|
|
133
|
+
consume((self._ptr &+ self._len).* = val);
|
|
134
|
+
self._len = (self._len + usize(1));
|
|
135
|
+
return self;
|
|
136
|
+
});
|
|
137
|
+
new_cap := cond(
|
|
138
|
+
(self._len < self._cap) => self._cap,
|
|
139
|
+
(self._cap == usize(0)) => usize(4),
|
|
140
|
+
true => (self._cap * usize(2))
|
|
141
|
+
);
|
|
142
|
+
new_ptr := Self._raw_alloc(new_cap);
|
|
143
|
+
if((self._len > usize(0)), {
|
|
144
|
+
Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
|
|
145
|
+
});
|
|
146
|
+
consume((new_ptr &+ self._len).* = val);
|
|
147
|
+
result := Self(_ptr: new_ptr, _len: (self._len + usize(1)), _cap: new_cap);
|
|
148
|
+
unsafe.drop(self);
|
|
149
|
+
result
|
|
150
|
+
}),
|
|
151
|
+
|
|
152
|
+
/// Return the first element, or `.None` if empty.
|
|
153
|
+
first : (fn(self: Self) -> Option(T))({
|
|
154
|
+
if(self.is_empty(), {
|
|
155
|
+
return .None;
|
|
156
|
+
});
|
|
157
|
+
.Some(self._ptr.*)
|
|
158
|
+
}),
|
|
159
|
+
|
|
160
|
+
/// Return the last element, or `.None` if empty.
|
|
161
|
+
last : (fn(self: Self) -> Option(T))({
|
|
162
|
+
if(self.is_empty(), {
|
|
163
|
+
return .None;
|
|
164
|
+
});
|
|
165
|
+
.Some((self._ptr &+ (self._len - usize(1))).*)
|
|
166
|
+
}),
|
|
167
|
+
|
|
168
|
+
/// Return a new vector without the last element, and the removed element.
|
|
169
|
+
pop : (fn(own(self): Self) -> PopResult(T))({
|
|
170
|
+
if(self.is_empty(), {
|
|
171
|
+
return PopResult(T)(vec: self, value: .None);
|
|
172
|
+
});
|
|
173
|
+
val := (self._ptr &+ (self._len - usize(1))).*;
|
|
174
|
+
new_len := (self._len - usize(1));
|
|
175
|
+
if((rc(self) == usize(1)), {
|
|
176
|
+
self._len = new_len;
|
|
177
|
+
return PopResult(T)(vec: self, value: .Some(val));
|
|
178
|
+
});
|
|
179
|
+
new_ptr := Self._raw_alloc(self._cap);
|
|
180
|
+
if((new_len > usize(0)), {
|
|
181
|
+
Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), new_len);
|
|
182
|
+
});
|
|
183
|
+
new_vec := Self(_ptr: new_ptr, _len: new_len, _cap: self._cap);
|
|
184
|
+
unsafe.drop(self);
|
|
185
|
+
PopResult(T)(vec: new_vec, value: .Some(val))
|
|
186
|
+
}),
|
|
187
|
+
|
|
188
|
+
/// Return a new vector containing only elements in range [start, end).
|
|
189
|
+
slice : (fn(self: Self, start: usize, end: usize) -> Self)({
|
|
190
|
+
(actual_start : usize) = cond(
|
|
191
|
+
(start > self._len) => self._len,
|
|
192
|
+
true => start
|
|
193
|
+
);
|
|
194
|
+
(actual_end : usize) = cond(
|
|
195
|
+
(end > self._len) => self._len,
|
|
196
|
+
true => end
|
|
197
|
+
);
|
|
198
|
+
if((actual_start >= actual_end), {
|
|
199
|
+
return Self.new();
|
|
200
|
+
});
|
|
201
|
+
new_len := (actual_end - actual_start);
|
|
202
|
+
new_ptr := Self._raw_alloc(new_len);
|
|
203
|
+
Self._copy_elems(new_ptr, self._ptr, usize(0), actual_start, new_len);
|
|
204
|
+
Self(_ptr: new_ptr, _len: new_len, _cap: new_len)
|
|
205
|
+
}),
|
|
206
|
+
|
|
207
|
+
/// Return a new vector that is the concatenation of self and other.
|
|
208
|
+
concat : (fn(own(self): Self, other: Self) -> Self)({
|
|
209
|
+
total := (self._len + other._len);
|
|
210
|
+
if((rc(self) == usize(1)), {
|
|
211
|
+
if((total <= self._cap), {
|
|
212
|
+
if((other._len > usize(0)), {
|
|
213
|
+
Self._copy_elems(self._ptr, other._ptr, self._len, usize(0), other._len);
|
|
214
|
+
});
|
|
215
|
+
self._len = total;
|
|
216
|
+
return self;
|
|
217
|
+
});
|
|
218
|
+
new_cap := cond(
|
|
219
|
+
(total > (self._cap * usize(2))) => total,
|
|
220
|
+
true => (self._cap * usize(2))
|
|
221
|
+
);
|
|
222
|
+
new_ptr := Self._raw_alloc(new_cap);
|
|
223
|
+
if((self._len > usize(0)), {
|
|
224
|
+
Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
|
|
225
|
+
});
|
|
226
|
+
if((other._len > usize(0)), {
|
|
227
|
+
Self._copy_elems(new_ptr, other._ptr, self._len, usize(0), other._len);
|
|
228
|
+
});
|
|
229
|
+
free(.Some(*(void)(self._ptr)));
|
|
230
|
+
self._ptr = new_ptr;
|
|
231
|
+
self._len = total;
|
|
232
|
+
self._cap = new_cap;
|
|
233
|
+
return self;
|
|
234
|
+
});
|
|
235
|
+
new_ptr := Self._raw_alloc(total);
|
|
236
|
+
if((self._len > usize(0)), {
|
|
237
|
+
Self._copy_elems(new_ptr, self._ptr, usize(0), usize(0), self._len);
|
|
238
|
+
});
|
|
239
|
+
if((other._len > usize(0)), {
|
|
240
|
+
Self._copy_elems(new_ptr, other._ptr, self._len, usize(0), other._len);
|
|
241
|
+
});
|
|
242
|
+
result := Self(_ptr: new_ptr, _len: total, _cap: total);
|
|
243
|
+
unsafe.drop(self);
|
|
244
|
+
result
|
|
245
|
+
}),
|
|
246
|
+
|
|
247
|
+
/// Return a new vector with elements reversed.
|
|
248
|
+
reverse : (fn(own(self): Self) -> Self)({
|
|
249
|
+
if((self._len <= usize(1)), {
|
|
250
|
+
return self;
|
|
251
|
+
});
|
|
252
|
+
if((rc(self) == usize(1)), {
|
|
253
|
+
left := usize(0);
|
|
254
|
+
right := (self._len - usize(1));
|
|
255
|
+
while (left < right), { left = (left + usize(1)); right = (right - usize(1)); }, {
|
|
256
|
+
tmp := (self._ptr &+ left).*;
|
|
257
|
+
consume((self._ptr &+ left).* = (self._ptr &+ right).*);
|
|
258
|
+
consume((self._ptr &+ right).* = tmp);
|
|
259
|
+
};
|
|
260
|
+
return self;
|
|
261
|
+
});
|
|
262
|
+
new_ptr := Self._raw_alloc(self._len);
|
|
263
|
+
i := usize(0);
|
|
264
|
+
while (i < self._len), (i = (i + usize(1))), {
|
|
265
|
+
(new_ptr &+ i).* = (self._ptr &+ ((self._len - usize(1)) - i)).*;
|
|
266
|
+
};
|
|
267
|
+
result := Self(_ptr: new_ptr, _len: self._len, _cap: self._len);
|
|
268
|
+
unsafe.drop(self);
|
|
269
|
+
result
|
|
270
|
+
}),
|
|
271
|
+
|
|
272
|
+
/// Apply a function to each element, producing a new vector.
|
|
273
|
+
map : (fn(forall(U : Type), self: Self, f: Impl(Fn(a: T) -> U), where(U <: Send)) -> Vec(U))({
|
|
274
|
+
new_ptr := Vec(U)._raw_alloc(self._len);
|
|
275
|
+
i := usize(0);
|
|
276
|
+
while (i < self._len), (i = (i + usize(1))), {
|
|
277
|
+
(new_ptr &+ i).* = f((self._ptr &+ i).*);
|
|
278
|
+
};
|
|
279
|
+
Vec(U)(_ptr: new_ptr, _len: self._len, _cap: self._len)
|
|
280
|
+
}),
|
|
281
|
+
|
|
282
|
+
/// Filter elements by a predicate, returning a new vector.
|
|
283
|
+
filter : (fn(self: Self, f: Impl(Fn(a: T) -> bool)) -> Self)({
|
|
284
|
+
new_ptr := Self._raw_alloc(self._len);
|
|
285
|
+
count := usize(0);
|
|
286
|
+
i := usize(0);
|
|
287
|
+
while (i < self._len), (i = (i + usize(1))), {
|
|
288
|
+
elem := (self._ptr &+ i).*;
|
|
289
|
+
if(f(elem), {
|
|
290
|
+
(new_ptr &+ count).* = elem;
|
|
291
|
+
count = (count + usize(1));
|
|
292
|
+
});
|
|
293
|
+
};
|
|
294
|
+
Self(_ptr: new_ptr, _len: count, _cap: self._len)
|
|
295
|
+
}),
|
|
296
|
+
|
|
297
|
+
/// Left fold over elements.
|
|
298
|
+
fold : (fn(forall(U : Type), self: Self, init: U, f: Impl(Fn(acc: U, elem: T) -> U)) -> U)({
|
|
299
|
+
(acc : U) = init;
|
|
300
|
+
i := usize(0);
|
|
301
|
+
while (i < self._len), (i = (i + usize(1))), {
|
|
302
|
+
acc = f(acc, (self._ptr &+ i).*);
|
|
303
|
+
};
|
|
304
|
+
acc
|
|
305
|
+
}),
|
|
306
|
+
|
|
307
|
+
/// Check if any element satisfies the predicate.
|
|
308
|
+
any : (fn(self: Self, f: Impl(Fn(a: T) -> bool)) -> bool)({
|
|
309
|
+
i := usize(0);
|
|
310
|
+
(found : bool) = false;
|
|
311
|
+
while ((i < self._len) && !(found)), (i = (i + usize(1))), {
|
|
312
|
+
if(f((self._ptr &+ i).*), {
|
|
313
|
+
found = true;
|
|
314
|
+
});
|
|
315
|
+
};
|
|
316
|
+
found
|
|
317
|
+
}),
|
|
318
|
+
|
|
319
|
+
/// Check if all elements satisfy the predicate.
|
|
320
|
+
all : (fn(self: Self, f: Impl(Fn(a: T) -> bool)) -> bool)({
|
|
321
|
+
i := usize(0);
|
|
322
|
+
(ok : bool) = true;
|
|
323
|
+
while ((i < self._len) && ok), (i = (i + usize(1))), {
|
|
324
|
+
if(!(f((self._ptr &+ i).*)), {
|
|
325
|
+
ok = false;
|
|
326
|
+
});
|
|
327
|
+
};
|
|
328
|
+
ok
|
|
329
|
+
}),
|
|
330
|
+
|
|
331
|
+
/// Find the first element satisfying the predicate.
|
|
332
|
+
find : (fn(self: Self, f: Impl(Fn(a: T) -> bool)) -> Option(T))({
|
|
333
|
+
i := usize(0);
|
|
334
|
+
(result : Option(T)) = .None;
|
|
335
|
+
while ((i < self._len) && result.is_none()), (i = (i + usize(1))), {
|
|
336
|
+
elem := (self._ptr &+ i).*;
|
|
337
|
+
if(f(elem), {
|
|
338
|
+
result = .Some(elem);
|
|
339
|
+
});
|
|
340
|
+
};
|
|
341
|
+
result
|
|
342
|
+
}),
|
|
343
|
+
|
|
344
|
+
/// Return the index of the first element equal to `val`, or `.None`.
|
|
345
|
+
index_of : (fn(self: Self, val: T, where(T <: Eq(T))) -> Option(usize))({
|
|
346
|
+
i := usize(0);
|
|
347
|
+
(result : Option(usize)) = .None;
|
|
348
|
+
while ((i < self._len) && result.is_none()), (i = (i + usize(1))), {
|
|
349
|
+
if(((self._ptr &+ i).* == val), {
|
|
350
|
+
result = .Some(i);
|
|
351
|
+
});
|
|
352
|
+
};
|
|
353
|
+
result
|
|
354
|
+
}),
|
|
355
|
+
|
|
356
|
+
/// Check if the vector contains `val`.
|
|
357
|
+
contains : (fn(self: Self, val: T, where(T <: Eq(T))) -> bool)(
|
|
358
|
+
self.index_of(val).is_some()
|
|
359
|
+
),
|
|
360
|
+
|
|
361
|
+
/// Return a new vector with duplicate elements removed (preserves first occurrence).
|
|
362
|
+
dedup : (fn(own(self): Self, where(T <: Eq(T))) -> Self)({
|
|
363
|
+
if((self._len <= usize(1)), {
|
|
364
|
+
return self;
|
|
365
|
+
});
|
|
366
|
+
if((rc(self) == usize(1)), {
|
|
367
|
+
count := usize(1);
|
|
368
|
+
i := usize(1);
|
|
369
|
+
while (i < self._len), (i = (i + usize(1))), {
|
|
370
|
+
elem := (self._ptr &+ i).*;
|
|
371
|
+
(found : bool) = false;
|
|
372
|
+
j := usize(0);
|
|
373
|
+
while ((j < count) && !(found)), (j = (j + usize(1))), {
|
|
374
|
+
if(((self._ptr &+ j).* == elem), {
|
|
375
|
+
found = true;
|
|
376
|
+
});
|
|
377
|
+
};
|
|
378
|
+
if(!(found), {
|
|
379
|
+
if((count != i), {
|
|
380
|
+
consume((self._ptr &+ count).* = elem);
|
|
381
|
+
});
|
|
382
|
+
count = (count + usize(1));
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
self._len = count;
|
|
386
|
+
return self;
|
|
387
|
+
});
|
|
388
|
+
new_ptr := Self._raw_alloc(self._len);
|
|
389
|
+
count := usize(0);
|
|
390
|
+
i := usize(0);
|
|
391
|
+
while (i < self._len), (i = (i + usize(1))), {
|
|
392
|
+
elem := (self._ptr &+ i).*;
|
|
393
|
+
(found : bool) = false;
|
|
394
|
+
j := usize(0);
|
|
395
|
+
while ((j < count) && !(found)), (j = (j + usize(1))), {
|
|
396
|
+
if(((new_ptr &+ j).* == elem), {
|
|
397
|
+
found = true;
|
|
398
|
+
});
|
|
399
|
+
};
|
|
400
|
+
if(!(found), {
|
|
401
|
+
(new_ptr &+ count).* = elem;
|
|
402
|
+
count = (count + usize(1));
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
result := Self(_ptr: new_ptr, _len: count, _cap: self._len);
|
|
406
|
+
unsafe.drop(self);
|
|
407
|
+
result
|
|
408
|
+
}),
|
|
409
|
+
|
|
410
|
+
/// Zip two vectors together using a combining function.
|
|
411
|
+
zip_with : (fn(forall(U : Type, V : Type), self: Self, other: Vec(U), f: Impl(Fn(a: T, b: U) -> V), where(U <: Send, V <: Send)) -> Vec(V))({
|
|
412
|
+
min_len := cond(
|
|
413
|
+
(self._len < other._len) => self._len,
|
|
414
|
+
true => other._len
|
|
415
|
+
);
|
|
416
|
+
new_ptr := Vec(V)._raw_alloc(min_len);
|
|
417
|
+
i := usize(0);
|
|
418
|
+
while (i < min_len), (i = (i + usize(1))), {
|
|
419
|
+
(new_ptr &+ i).* = f((self._ptr &+ i).*, other.get(i).unwrap());
|
|
420
|
+
};
|
|
421
|
+
Vec(V)(_ptr: new_ptr, _len: min_len, _cap: min_len)
|
|
422
|
+
}),
|
|
423
|
+
|
|
424
|
+
/// Create a vector from a slice, copying all elements.
|
|
425
|
+
from_slice : (fn(s: Slice(T)) -> Self)({
|
|
426
|
+
slen := s.len();
|
|
427
|
+
cap := cond(
|
|
428
|
+
(slen > usize(0)) => slen,
|
|
429
|
+
true => usize(4)
|
|
430
|
+
);
|
|
431
|
+
new_ptr := Self._raw_alloc(cap);
|
|
432
|
+
if((slen > usize(0)), {
|
|
433
|
+
Self._copy_elems(new_ptr, s.ptr(), usize(0), usize(0), slen);
|
|
434
|
+
});
|
|
435
|
+
Self(_ptr: new_ptr, _len: slen, _cap: cap)
|
|
436
|
+
})
|
|
437
|
+
);
|
|
438
|
+
|
|
439
|
+
/// Eq trait for Vec(T) — element-wise equality.
|
|
440
|
+
impl(forall(T : Type), where(T <: (Send, Eq(T))), Vec(T), Eq(Vec(T))(
|
|
441
|
+
(==) : (fn(lhs: Self, rhs: Self) -> bool)({
|
|
442
|
+
if((lhs._len != rhs._len), {
|
|
443
|
+
return false;
|
|
444
|
+
});
|
|
445
|
+
i := usize(0);
|
|
446
|
+
(equal : bool) = true;
|
|
447
|
+
while ((i < lhs._len) && equal), (i = (i + usize(1))), {
|
|
448
|
+
if(((lhs._ptr &+ i).* != (rhs._ptr &+ i).*), {
|
|
449
|
+
equal = false;
|
|
450
|
+
});
|
|
451
|
+
};
|
|
452
|
+
equal
|
|
453
|
+
})
|
|
454
|
+
));
|
|
455
|
+
|
|
456
|
+
export Vec, PopResult;
|
package/std/prelude.yo
CHANGED
|
@@ -4077,6 +4077,8 @@ StructKind :: enum(
|
|
|
4077
4077
|
Struct,
|
|
4078
4078
|
/// Reference-counted object.
|
|
4079
4079
|
Object,
|
|
4080
|
+
/// Atomic reference-counted object.
|
|
4081
|
+
AtomicObject,
|
|
4080
4082
|
/// Single-field newtype wrapper.
|
|
4081
4083
|
NewType
|
|
4082
4084
|
);
|
|
@@ -4222,7 +4224,6 @@ TypeInfo :: enum(
|
|
|
4222
4224
|
Function(info : FunctionInfo),
|
|
4223
4225
|
Ptr(pointee : Type),
|
|
4224
4226
|
Iso(child : Type),
|
|
4225
|
-
Arc(child : Type),
|
|
4226
4227
|
Dyn(
|
|
4227
4228
|
required_traits : ComptimeList(TraitInfo),
|
|
4228
4229
|
negative_traits : ComptimeList(TraitInfo)
|
|
@@ -5483,12 +5484,28 @@ impl(forall(T : Type), Iso(T),
|
|
|
5483
5484
|
export (^);
|
|
5484
5485
|
|
|
5485
5486
|
/// === Arc ===
|
|
5486
|
-
|
|
5487
|
-
|
|
5487
|
+
/// Arc — an atomically reference-counted, thread-safe container for a single value.
|
|
5488
|
+
///
|
|
5489
|
+
/// Use `arc(value)` to allocate. Access the inner value with `a.*`.
|
|
5490
|
+
///
|
|
5491
|
+
/// # Example
|
|
5492
|
+
/// ```rust
|
|
5493
|
+
/// a := arc(i32(42));
|
|
5494
|
+
/// assert((a.* == i32(42)), "inner value is 42");
|
|
5495
|
+
/// ```
|
|
5496
|
+
Arc :: (fn(comptime(V) : Type, where(V <: (Send, Acyclic))) -> comptime(Type))
|
|
5497
|
+
atomic object(
|
|
5498
|
+
(*) : V
|
|
5499
|
+
)
|
|
5488
5500
|
;
|
|
5489
|
-
|
|
5501
|
+
/// Allocate a value inside an Arc, returning an `Arc(V)`.
|
|
5502
|
+
arc :: (fn(forall(V : Type), own(value) : V, where(V <: (Send, Acyclic))) -> Arc(V))
|
|
5503
|
+
Arc(V)(value)
|
|
5504
|
+
;
|
|
5505
|
+
|
|
5506
|
+
impl(forall(T : Type), where(T <: (Send, Acyclic)), Arc(T), Send());
|
|
5490
5507
|
|
|
5491
|
-
export arc;
|
|
5508
|
+
export Arc, arc;
|
|
5492
5509
|
|
|
5493
5510
|
/// === MaybeUninit ===
|
|
5494
5511
|
extern "Yo",
|