aiscript_arena/
collect_impl.rs1use alloc::boxed::Box;
2use alloc::collections::{BTreeMap, BTreeSet};
3use alloc::collections::{LinkedList, VecDeque};
4use alloc::rc::Rc;
5use alloc::string::String;
6use alloc::vec::Vec;
7use core::cell::{Cell, RefCell};
8use core::marker::PhantomData;
9#[cfg(feature = "std")]
10use std::collections::{HashMap, HashSet};
11
12use crate::collect::Collect;
13use crate::context::Collection;
14
15#[macro_export]
18macro_rules! static_collect {
19 ($type:ty) => {
20 unsafe impl Collect for $type
21 where
22 $type: 'static,
23 {
24 #[inline]
25 fn needs_trace() -> bool {
26 false
27 }
28 }
29 };
30}
31
32static_collect!(bool);
33static_collect!(char);
34static_collect!(u8);
35static_collect!(u16);
36static_collect!(u32);
37static_collect!(u64);
38static_collect!(usize);
39static_collect!(i8);
40static_collect!(i16);
41static_collect!(i32);
42static_collect!(i64);
43static_collect!(isize);
44static_collect!(f32);
45static_collect!(f64);
46static_collect!(String);
47static_collect!(str);
48static_collect!(alloc::ffi::CString);
49static_collect!(core::ffi::CStr);
50static_collect!(core::any::TypeId);
51#[cfg(feature = "std")]
52static_collect!(std::path::Path);
53#[cfg(feature = "std")]
54static_collect!(std::path::PathBuf);
55#[cfg(feature = "std")]
56static_collect!(std::ffi::OsStr);
57#[cfg(feature = "std")]
58static_collect!(std::ffi::OsString);
59
60unsafe impl<T: ?Sized + 'static> Collect for &'static T {
87 #[inline]
88 fn needs_trace() -> bool {
89 false
90 }
91}
92
93unsafe impl<T: ?Sized + Collect> Collect for Box<T> {
94 #[inline]
95 fn trace(&self, cc: &Collection) {
96 (**self).trace(cc)
97 }
98}
99
100unsafe impl<T: Collect> Collect for [T] {
101 #[inline]
102 fn needs_trace() -> bool {
103 T::needs_trace()
104 }
105
106 #[inline]
107 fn trace(&self, cc: &Collection) {
108 for t in self.iter() {
109 t.trace(cc)
110 }
111 }
112}
113
114unsafe impl<T: Collect> Collect for Option<T> {
115 #[inline]
116 fn needs_trace() -> bool {
117 T::needs_trace()
118 }
119
120 #[inline]
121 fn trace(&self, cc: &Collection) {
122 if let Some(t) = self.as_ref() {
123 t.trace(cc)
124 }
125 }
126}
127
128unsafe impl<T: Collect, E: Collect> Collect for Result<T, E> {
129 #[inline]
130 fn needs_trace() -> bool {
131 T::needs_trace() || E::needs_trace()
132 }
133
134 #[inline]
135 fn trace(&self, cc: &Collection) {
136 match self {
137 Ok(r) => r.trace(cc),
138 Err(e) => e.trace(cc),
139 }
140 }
141}
142
143unsafe impl<T: Collect> Collect for Vec<T> {
144 #[inline]
145 fn needs_trace() -> bool {
146 T::needs_trace()
147 }
148
149 #[inline]
150 fn trace(&self, cc: &Collection) {
151 for t in self {
152 t.trace(cc)
153 }
154 }
155}
156
157unsafe impl<T: Collect> Collect for VecDeque<T> {
158 #[inline]
159 fn needs_trace() -> bool {
160 T::needs_trace()
161 }
162
163 #[inline]
164 fn trace(&self, cc: &Collection) {
165 for t in self {
166 t.trace(cc)
167 }
168 }
169}
170
171unsafe impl<T: Collect> Collect for LinkedList<T> {
172 #[inline]
173 fn needs_trace() -> bool {
174 T::needs_trace()
175 }
176
177 #[inline]
178 fn trace(&self, cc: &Collection) {
179 for t in self {
180 t.trace(cc)
181 }
182 }
183}
184
185#[cfg(feature = "std")]
186unsafe impl<K, V, S> Collect for HashMap<K, V, S>
187where
188 K: Collect,
189 V: Collect,
190 S: 'static,
191{
192 #[inline]
193 fn needs_trace() -> bool {
194 K::needs_trace() || V::needs_trace()
195 }
196
197 #[inline]
198 fn trace(&self, cc: &Collection) {
199 for (k, v) in self {
200 k.trace(cc);
201 v.trace(cc);
202 }
203 }
204}
205
206#[cfg(feature = "std")]
207unsafe impl<T, S> Collect for HashSet<T, S>
208where
209 T: Collect,
210 S: 'static,
211{
212 #[inline]
213 fn needs_trace() -> bool {
214 T::needs_trace()
215 }
216
217 #[inline]
218 fn trace(&self, cc: &Collection) {
219 for v in self {
220 v.trace(cc);
221 }
222 }
223}
224
225unsafe impl<K, V> Collect for BTreeMap<K, V>
226where
227 K: Collect,
228 V: Collect,
229{
230 #[inline]
231 fn needs_trace() -> bool {
232 K::needs_trace() || V::needs_trace()
233 }
234
235 #[inline]
236 fn trace(&self, cc: &Collection) {
237 for (k, v) in self {
238 k.trace(cc);
239 v.trace(cc);
240 }
241 }
242}
243
244unsafe impl<T> Collect for BTreeSet<T>
245where
246 T: Collect,
247{
248 #[inline]
249 fn needs_trace() -> bool {
250 T::needs_trace()
251 }
252
253 #[inline]
254 fn trace(&self, cc: &Collection) {
255 for v in self {
256 v.trace(cc);
257 }
258 }
259}
260
261unsafe impl<T> Collect for Rc<T>
262where
263 T: ?Sized + Collect,
264{
265 #[inline]
266 fn trace(&self, cc: &Collection) {
267 (**self).trace(cc);
268 }
269}
270
271#[cfg(target_has_atomic = "ptr")]
272unsafe impl<T> Collect for alloc::sync::Arc<T>
273where
274 T: ?Sized + Collect,
275{
276 #[inline]
277 fn trace(&self, cc: &Collection) {
278 (**self).trace(cc);
279 }
280}
281
282unsafe impl<T> Collect for Cell<T>
283where
284 T: 'static,
285{
286 #[inline]
287 fn needs_trace() -> bool {
288 false
289 }
290}
291
292unsafe impl<T> Collect for RefCell<T>
293where
294 T: 'static,
295{
296 #[inline]
297 fn needs_trace() -> bool {
298 false
299 }
300}
301
302unsafe impl<T> Collect for PhantomData<T> {
304 #[inline]
305 fn needs_trace() -> bool {
306 false
307 }
308}
309
310unsafe impl<T: Collect, const N: usize> Collect for [T; N] {
311 #[inline]
312 fn needs_trace() -> bool {
313 T::needs_trace()
314 }
315
316 #[inline]
317 fn trace(&self, cc: &Collection) {
318 for t in self {
319 t.trace(cc)
320 }
321 }
322}
323
324macro_rules! impl_tuple {
325 () => (
326 unsafe impl Collect for () {
327 #[inline]
328 fn needs_trace() -> bool {
329 false
330 }
331 }
332 );
333
334 ($($name:ident)+) => (
335 unsafe impl<$($name,)*> Collect for ($($name,)*)
336 where $($name: Collect,)*
337 {
338 #[inline]
339 fn needs_trace() -> bool {
340 $($name::needs_trace() ||)* false
341 }
342
343 #[allow(non_snake_case)]
344 #[inline]
345 fn trace(&self, cc: &Collection) {
346 let ($($name,)*) = self;
347 $($name.trace(cc);)*
348 }
349 }
350 );
351}
352
353impl_tuple! {}
354impl_tuple! {A}
355impl_tuple! {A B}
356impl_tuple! {A B C}
357impl_tuple! {A B C D}
358impl_tuple! {A B C D E}
359impl_tuple! {A B C D E F}
360impl_tuple! {A B C D E F G}
361impl_tuple! {A B C D E F G H}
362impl_tuple! {A B C D E F G H I}
363impl_tuple! {A B C D E F G H I J}
364impl_tuple! {A B C D E F G H I J K}
365impl_tuple! {A B C D E F G H I J K L}
366impl_tuple! {A B C D E F G H I J K L M}
367impl_tuple! {A B C D E F G H I J K L M N}
368impl_tuple! {A B C D E F G H I J K L M N O}
369impl_tuple! {A B C D E F G H I J K L M N O P}