1
//! Macros for generating C-ABI-compatible collection types (`Vec`, `Option`, `Result`)
2
//! used throughout the codebase for FFI interop. Each macro produces `#[repr(C)]` types
3
//! with a destructor model: `DefaultRust` (library-owned), `NoDestructor` (`&'static`),
4
//! `External` (caller-provided destructor fn), and `AlreadyDestroyed` (post-drop guard).
5

            
6
#[macro_export]
7
macro_rules! impl_vec {
8
    ($struct_type:ident, $struct_name:ident, $destructor_name:ident, $destructor_type_name:ident, $slice_name:ident, $option_type:ident) => {
9
        pub type $destructor_type_name = extern "C" fn(*mut $struct_name);
10

            
11
        /// C-compatible slice type for $struct_name.
12
        /// This is a non-owning view into a Vec's data.
13
        #[repr(C)]
14
        #[derive(Debug, Copy, Clone)]
15
        pub struct $slice_name {
16
            pub ptr: *const $struct_type,
17
            pub len: usize,
18
        }
19

            
20
        impl $slice_name {
21
            /// Creates an empty slice.
22
            #[inline(always)]
23
            pub const fn empty() -> Self {
24
                Self {
25
                    ptr: core::ptr::null(),
26
                    len: 0,
27
                }
28
            }
29

            
30
            /// Returns the number of elements in the slice.
31
            #[inline(always)]
32
            pub const fn len(&self) -> usize {
33
                self.len
34
            }
35

            
36
            /// Returns true if the slice is empty.
37
            #[inline(always)]
38
            pub const fn is_empty(&self) -> bool {
39
                self.len == 0
40
            }
41

            
42
            /// Returns a pointer to the slice's data.
43
            #[inline(always)]
44
            pub const fn as_ptr(&self) -> *const $struct_type {
45
                self.ptr
46
            }
47

            
48
            /// Converts the C-slice to a Rust slice.
49
            #[inline(always)]
50
2
            pub fn as_slice(&self) -> &[$struct_type] {
51
2
                if self.ptr.is_null() || self.len == 0 {
52
1
                    &[]
53
                } else {
54
1
                    unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
55
                }
56
2
            }
57

            
58
            /// Returns a reference to the element at the given index, or None if out of bounds.
59
            #[inline(always)]
60
            pub fn get(&self, index: usize) -> Option<&$struct_type> {
61
                self.as_slice().get(index)
62
            }
63

            
64
            /// Returns an iterator over the elements.
65
            #[inline]
66
            pub fn iter(&self) -> core::slice::Iter<'_, $struct_type> {
67
                self.as_slice().iter()
68
            }
69
        }
70

            
71
        unsafe impl Send for $slice_name {}
72
        unsafe impl Sync for $slice_name {}
73

            
74
        #[repr(C)]
75
        pub struct $struct_name {
76
            ptr: *const $struct_type,
77
            len: usize,
78
            cap: usize,
79
            destructor: $destructor_name,
80
        }
81

            
82
        #[derive(Debug, Copy, Clone)]
83
        #[repr(C, u8)]
84
        pub enum $destructor_name {
85
            DefaultRust,
86
            NoDestructor,
87
            External($destructor_type_name),
88
            /// Destructor was already run — prevents double-free.
89
            /// Set by Drop impl after destruction.
90
            AlreadyDestroyed,
91
        }
92

            
93
        unsafe impl Send for $struct_name {}
94
        unsafe impl Sync for $struct_name {}
95

            
96
        impl $struct_name {
97
            #[inline(always)]
98
44749
            pub fn new() -> $struct_name {
99
                // lets hope the optimizer catches this
100
44749
                Self::from_vec(alloc::vec::Vec::new())
101
44749
            }
102

            
103
            #[inline]
104
            pub fn with_capacity(cap: usize) -> Self {
105
                Self::from_vec(alloc::vec::Vec::<$struct_type>::with_capacity(cap))
106
            }
107

            
108
            #[inline(always)]
109
1299641
            pub const fn from_const_slice(input: &'static [$struct_type]) -> Self {
110
1299641
                Self {
111
1299641
                    ptr: input.as_ptr(),
112
1299641
                    len: input.len(),
113
1299641
                    cap: input.len(),
114
1299641
                    destructor: $destructor_name::NoDestructor, // because of &'static
115
1299641
                }
116
1299641
            }
117

            
118
            #[inline(always)]
119
17819853
            pub fn from_vec(input: alloc::vec::Vec<$struct_type>) -> Self {
120
17819853
                let ptr = input.as_ptr();
121
17819853
                let len = input.len();
122
17819853
                let cap = input.capacity();
123

            
124
17819853
                let _ = ::core::mem::ManuallyDrop::new(input);
125

            
126
17819853
                Self {
127
17819853
                    ptr,
128
17819853
                    len,
129
17819853
                    cap,
130
17819853
                    destructor: $destructor_name::DefaultRust,
131
17819853
                }
132
17819853
            }
133

            
134
            #[inline]
135
713876
            pub fn iter(&self) -> core::slice::Iter<'_, $struct_type> {
136
713876
                self.as_ref().iter()
137
713876
            }
138

            
139
            #[inline(always)]
140
499236
            pub const fn len(&self) -> usize {
141
499236
                self.len
142
499236
            }
143

            
144
            #[inline(always)]
145
326835
            pub const fn capacity(&self) -> usize {
146
326835
                self.cap
147
326835
            }
148

            
149
            #[inline(always)]
150
1181327
            pub const fn is_empty(&self) -> bool {
151
1181327
                self.len == 0
152
1181327
            }
153

            
154
            /// Returns a reference to the element at the given index (Rust-only, inline).
155
            #[inline(always)]
156
201879
            pub fn get(&self, index: usize) -> Option<&$struct_type> {
157
201879
                self.as_ref().get(index)
158
201879
            }
159

            
160
            /// C-API compatible get function. Returns a copy of the element at the given index.
161
            /// Returns None if the index is out of bounds.
162
            #[inline]
163
            pub fn c_get(&self, index: usize) -> $option_type
164
            where
165
                $struct_type: Clone,
166
            {
167
                self.get(index).cloned().into()
168
            }
169

            
170
            #[allow(dead_code)]
171
            #[inline(always)]
172
            unsafe fn get_unchecked(&self, index: usize) -> &$struct_type {
173
                self.as_ref().get_unchecked(index)
174
            }
175

            
176
            /// Returns the vec as a Rust slice (Rust-only, not C-API compatible).
177
            #[inline(always)]
178
3689889
            pub fn as_slice(&self) -> &[$struct_type] {
179
3689889
                self.as_ref()
180
3689889
            }
181

            
182
            /// Returns a C-compatible slice of the entire Vec.
183
            #[inline(always)]
184
2
            pub fn as_c_slice(&self) -> $slice_name {
185
2
                $slice_name {
186
2
                    ptr: self.ptr,
187
2
                    len: self.len,
188
2
                }
189
2
            }
190

            
191
            /// Returns a C-compatible slice of a range within the Vec.
192
            /// If the range is out of bounds, it is clamped to the valid range.
193
            #[inline]
194
            pub fn as_c_slice_range(&self, start: usize, end: usize) -> $slice_name {
195
                let start = start.min(self.len);
196
                let end = end.min(self.len).max(start);
197
                let len = end - start;
198
                if len == 0 || self.ptr.is_null() {
199
                    $slice_name::empty()
200
                } else {
201
                    $slice_name {
202
                        ptr: unsafe { self.ptr.add(start) },
203
                        len,
204
                    }
205
                }
206
            }
207

            
208
            /// Returns a pointer to the Vec's data.
209
            /// Use `len()` to get the number of elements.
210
            #[inline(always)]
211
            pub fn as_ptr(&self) -> *const $struct_type {
212
                self.ptr
213
            }
214
        }
215

            
216
        impl AsRef<[$struct_type]> for $struct_name {
217
29657242
            fn as_ref(&self) -> &[$struct_type] {
218
29657242
                if self.ptr.is_null() || self.len == 0 {
219
4922180
                    &[]
220
                } else {
221
24735062
                    unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
222
                }
223
29657242
            }
224
        }
225

            
226
        impl Default for $struct_name {
227
159339
            fn default() -> Self {
228
159339
                Self::from_vec(alloc::vec::Vec::new())
229
159339
            }
230
        }
231

            
232
        impl core::iter::FromIterator<$struct_type> for $struct_name {
233
            fn from_iter<T>(iter: T) -> Self
234
            where
235
                T: IntoIterator<Item = $struct_type>,
236
            {
237
                Self::from_vec(alloc::vec::Vec::from_iter(iter))
238
            }
239
        }
240

            
241
        impl From<alloc::vec::Vec<$struct_type>> for $struct_name {
242
1263776
            fn from(input: alloc::vec::Vec<$struct_type>) -> $struct_name {
243
1263776
                $struct_name::from_vec(input)
244
1263776
            }
245
        }
246

            
247
        impl From<&'static [$struct_type]> for $struct_name {
248
            fn from(input: &'static [$struct_type]) -> $struct_name {
249
                Self::from_const_slice(input)
250
            }
251
        }
252

            
253
        impl Drop for $struct_name {
254
19116618
            fn drop(&mut self) {
255
19116618
                match self.destructor {
256
                    $destructor_name::DefaultRust => {
257
                        // Defensive: a library-owned Vec only owns an allocation
258
                        // when `ptr` is non-null and `cap != 0`. A zeroed / moved-
259
                        // from FFI husk (e.g. a struct field a C++ wrapper move-
260
                        // cleared, leaving destructor == DefaultRust [tag 0] with a
261
                        // null ptr but a stale len) would otherwise hit
262
                        // `Vec::from_raw_parts(null, len, _)` and deref 0x0 on drop.
263
                        // Skip when there is nothing to free. (Empty Vecs have
264
                        // cap == 0; valid non-empty Vecs are unaffected.)
265
17590922
                        if !self.ptr.is_null() && self.cap != 0 {
266
16337775
                            let _ = unsafe {
267
16337775
                                alloc::vec::Vec::from_raw_parts(
268
16337775
                                    self.ptr as *mut $struct_type,
269
16337775
                                    self.len,
270
16337775
                                    self.cap,
271
16337775
                                )
272
16337775
                            };
273
16337775
                        }
274
17590922
                        self.destructor = $destructor_name::AlreadyDestroyed;
275
                    }
276
106
                    $destructor_name::External(f) => {
277
106
                        f(self);
278
106
                        self.destructor = $destructor_name::AlreadyDestroyed;
279
106
                    }
280
1525590
                    $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => {}
281
                }
282
19116618
            }
283
        }
284
    };
285
}
286

            
287
/// Implement the `From` trait for any type.
288
/// Example usage:
289
/// ```no_run,ignore
290
/// enum MyError<'a> {
291
///     Bar(BarError<'a>),
292
///     Foo(FooError<'a>)
293
/// }
294
///
295
/// impl_from!(BarError<'a>, MyError::Bar);
296
/// impl_from!(FooError<'a>, MyError::Foo);
297
/// ```
298
macro_rules! impl_from {
299
    // From a type with a lifetime to a type which also has a lifetime
300
    ($a:ident < $c:lifetime > , $b:ident:: $enum_type:ident) => {
301
        impl<$c> From<$a<$c>> for $b<$c> {
302
5001
            fn from(e: $a<$c>) -> Self {
303
5001
                $b::$enum_type(e)
304
5001
            }
305
        }
306
    };
307

            
308
    // From a type without a lifetime to a type with a lifetime
309
    ($a:ident, $b:ident < $c:lifetime > :: $enum_type:ident) => {
310
        impl<$c> From<$a> for $b<$c> {
311
            fn from(e: $a) -> Self {
312
                $b::$enum_type(e)
313
            }
314
        }
315
    };
316

            
317
    // From a type without a lifetime to a type which also does not have a lifetime
318
    ($a:ident, $b:ident:: $enum_type:ident) => {
319
        impl From<$a> for $b {
320
            fn from(e: $a) -> Self {
321
                $b::$enum_type(e)
322
            }
323
        }
324
    };
325
}
326

            
327
/// Implement `Display` for an enum.
328
///
329
/// Example usage:
330
/// ```no_run,ignore
331
/// enum Foo<'a> {
332
///     Bar(&'a str),
333
///     Baz(i32)
334
/// }
335
///
336
/// impl_display!{ Foo<'a>, {
337
///     Bar(s) => s,
338
///     Baz(i) => format!("{}", i)
339
/// }}
340
/// ```
341
#[macro_export]
342
macro_rules! impl_display {
343
    // For a type with a lifetime
344
    ($enum:ident<$lt:lifetime>, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
345

            
346
        impl<$lt> ::core::fmt::Display for $enum<$lt> {
347
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
348
                use self::$enum::*;
349
                match &self {
350
                    $(
351
                        $variant => write!(f, "{}", $fmt_string),
352
                    )+
353
                }
354
            }
355
        }
356

            
357
    };
358

            
359
    // For a type without a lifetime
360
    ($enum:ident, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
361

            
362
        impl ::core::fmt::Display for $enum {
363
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
364
                use self::$enum::*;
365
                match &self {
366
                    $(
367
                        $variant => write!(f, "{}", $fmt_string),
368
                    )+
369
                }
370
            }
371
        }
372

            
373
    };
374
}
375

            
376
/// Implements `Debug` to use `Display` instead - assumes the that the type has implemented
377
/// `Display`
378
#[macro_export]
379
macro_rules! impl_debug_as_display {
380
    // For a type with a lifetime
381
    ($enum:ident < $lt:lifetime >) => {
382
        impl<$lt> ::core::fmt::Debug for $enum<$lt> {
383
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
384
                write!(f, "{}", self)
385
            }
386
        }
387
    };
388

            
389
    // For a type without a lifetime
390
    ($enum:ident) => {
391
        impl ::core::fmt::Debug for $enum {
392
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
393
                write!(f, "{}", self)
394
            }
395
        }
396
    };
397
}
398

            
399
#[macro_export]
400
macro_rules! impl_vec_as_hashmap {
401
    ($struct_type:ident, $struct_name:ident) => {
402
        impl $struct_name {
403
            pub fn insert_hm_item(&mut self, item: $struct_type) {
404
                if !self.contains_hm_item(&item) {
405
                    self.push(item);
406
                }
407
            }
408

            
409
            pub fn remove_hm_item(&mut self, remove_key: &$struct_type) {
410
                *self = Self::from_vec(
411
                    self.as_ref()
412
                        .iter()
413
                        .filter_map(|r| if *r == *remove_key { None } else { Some(*r) })
414
                        .collect::<Vec<_>>(),
415
                );
416
            }
417

            
418
            pub fn contains_hm_item(&self, searched: &$struct_type) -> bool {
419
                self.as_ref().iter().any(|i| i == searched)
420
            }
421
        }
422
    };
423
}
424

            
425
/// NOTE: impl_vec_mut can only exist for vectors that are known to be library-allocated!
426
#[macro_export]
427
macro_rules! impl_vec_mut {
428
    ($struct_type:ident, $struct_name:ident) => {
429
        impl AsMut<[$struct_type]> for $struct_name {
430
257279
            fn as_mut(&mut self) -> &mut [$struct_type] {
431
257279
                unsafe { core::slice::from_raw_parts_mut(self.ptr as *mut $struct_type, self.len) }
432
257279
            }
433
        }
434

            
435
        impl From<$struct_name> for alloc::vec::Vec<$struct_type> {
436
            #[allow(unused_mut)]
437
4745
            fn from(mut input: $struct_name) -> alloc::vec::Vec<$struct_type> {
438
4745
                input.into_library_owned_vec()
439
4745
            }
440
        }
441

            
442
        impl core::iter::Extend<$struct_type> for $struct_name {
443
            fn extend<T: core::iter::IntoIterator<Item = $struct_type>>(&mut self, iter: T) {
444
                for elem in iter {
445
                    self.push(elem);
446
                }
447
            }
448
        }
449

            
450
        impl $struct_name {
451
            #[inline]
452
181740
            pub fn as_mut_ptr(&mut self) -> *mut $struct_type {
453
181740
                self.ptr as *mut $struct_type
454
181740
            }
455

            
456
            #[inline]
457
228
            pub fn sort_by<F: FnMut(&$struct_type, &$struct_type) -> core::cmp::Ordering>(
458
228
                &mut self,
459
228
                compare: F,
460
228
            ) {
461
228
                self.as_mut().sort_by(compare);
462
228
            }
463

            
464
            #[inline]
465
155320
            pub fn push(&mut self, value: $struct_type) {
466
                // code is copied from the rust stdlib, since it's not possible to
467
                // create a temporary Vec here. Doing that would create two
468
155320
                if self.len == self.capacity() {
469
125180
                    self.buf_reserve(self.len, 1);
470
125180
                }
471
155320
                unsafe {
472
155320
                    let end = self.as_mut_ptr().add(self.len);
473
155320
                    core::ptr::write(end, value);
474
155320
                    self.len += 1;
475
155320
                }
476
155320
            }
477

            
478
            pub fn insert(&mut self, index: usize, element: $struct_type) {
479
                let len = self.len();
480
                if index > len {
481
                    return;
482
                }
483

            
484
                // space for the new element
485
                if len == self.capacity() {
486
                    self.reserve(1);
487
                }
488

            
489
                unsafe {
490
                    // infallible
491
                    // The spot to put the new value
492
                    {
493
                        let p = self.as_mut_ptr().add(index);
494
                        // Shift everything over to make space. (Duplicating the
495
                        // `index`th element into two consecutive places.)
496
                        core::ptr::copy(p, p.offset(1), len - index);
497
                        // Write it in, overwriting the first copy of the `index`th
498
                        // element.
499
                        core::ptr::write(p, element);
500
                    }
501
                    self.set_len(len + 1);
502
                }
503
            }
504

            
505
            pub fn remove(&mut self, index: usize) {
506
                let len = self.len();
507
                if index >= len {
508
                    return;
509
                }
510

            
511
                unsafe {
512
                    // infallible
513
                    let ret;
514
                    {
515
                        // the place we are taking from.
516
                        let ptr = self.as_mut_ptr().add(index);
517
                        // copy it out, unsafely having a copy of the value on
518
                        // the stack and in the vector at the same time.
519
                        ret = core::ptr::read(ptr);
520

            
521
                        // Shift everything down to fill in that spot.
522
                        core::ptr::copy(ptr.offset(1), ptr, len - index - 1);
523
                    }
524
                    self.set_len(len - 1);
525
                    let _ = ret;
526
                }
527
            }
528

            
529
            #[inline]
530
            pub fn pop(&mut self) -> Option<$struct_type> {
531
                if self.len == 0 {
532
                    None
533
                } else {
534
                    unsafe {
535
                        self.len -= 1;
536
                        Some(core::ptr::read(self.ptr.add(self.len())))
537
                    }
538
                }
539
            }
540

            
541
            #[inline]
542
45801
            pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, $struct_type> {
543
45801
                self.as_mut().iter_mut()
544
45801
            }
545

            
546
            #[inline]
547
2
            pub fn into_iter(self) -> alloc::vec::IntoIter<$struct_type> {
548
2
                let v1: alloc::vec::Vec<$struct_type> = self.into();
549
2
                v1.into_iter()
550
2
            }
551

            
552
            #[inline]
553
145950
            fn amortized_new_size(
554
145950
                &self,
555
145950
                used_cap: usize,
556
145950
                needed_extra_cap: usize,
557
145950
            ) -> Result<usize, bool> {
558
                // Nothing we can really do about these checks :(
559
145950
                let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(true)?;
560
                // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
561
145950
                let double_cap = self.cap * 2;
562
                // `double_cap` guarantees exponential growth.
563
145950
                Ok(core::cmp::max(double_cap, required_cap))
564
145950
            }
565

            
566
            #[inline]
567
145950
            fn current_layout(&self) -> Option<core::alloc::Layout> {
568
145950
                if self.cap == 0 {
569
70673
                    None
570
                } else {
571
                    // We have an allocated chunk of memory, so we can bypass runtime
572
                    // checks to get our current layout.
573
                    unsafe {
574
75277
                        let align = core::mem::align_of::<$struct_type>();
575
75277
                        let size = core::mem::size_of::<$struct_type>() * self.cap;
576
75277
                        Some(core::alloc::Layout::from_size_align_unchecked(size, align))
577
                    }
578
                }
579
145950
            }
580

            
581
            #[inline]
582
145950
            fn alloc_guard(alloc_size: usize) -> Result<(), bool> {
583
145950
                if core::mem::size_of::<usize>() < 8 && alloc_size > ::core::isize::MAX as usize {
584
                    Err(true)
585
                } else {
586
145950
                    Ok(())
587
                }
588
145950
            }
589

            
590
            #[inline]
591
146805
            fn try_reserve(
592
146805
                &mut self,
593
146805
                used_cap: usize,
594
146805
                needed_extra_cap: usize,
595
146805
            ) -> Result<(), bool> {
596
                // NOTE: we don't early branch on ZSTs here because we want this
597
                // to actually catch "asking for more than usize::MAX" in that case.
598
                // If we make it past the first branch then we are guaranteed to
599
                // panic.
600

            
601
                // Don't actually need any more capacity.
602
                // Wrapping in case they give a bad `used_cap`
603
146805
                if self.capacity().wrapping_sub(used_cap) >= needed_extra_cap {
604
855
                    return Ok(());
605
145950
                }
606

            
607
145950
                let new_cap = self.amortized_new_size(used_cap, needed_extra_cap)?;
608
145950
                let new_layout =
609
145950
                    alloc::alloc::Layout::array::<$struct_type>(new_cap).map_err(|_| true)?;
610

            
611
145950
                $struct_name::alloc_guard(new_layout.size())?;
612

            
613
145950
                let res = unsafe {
614
145950
                    match self.current_layout() {
615
75277
                        Some(layout) => {
616
75277
                            alloc::alloc::realloc(self.ptr as *mut u8, layout, new_layout.size())
617
                        }
618
70673
                        None => alloc::alloc::alloc(new_layout),
619
                    }
620
                };
621

            
622
145950
                if res == core::ptr::null_mut() {
623
                    return Err(false);
624
145950
                }
625

            
626
145950
                self.ptr = res as *mut $struct_type;
627
145950
                self.cap = new_cap;
628

            
629
145950
                Ok(())
630
146805
            }
631

            
632
146805
            fn buf_reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
633
146805
                match self.try_reserve(used_cap, needed_extra_cap) {
634
                    Err(true /* Overflow */) => {
635
                        panic!("memory allocation failed: overflow");
636
                    }
637
                    Err(false /* AllocError(_) */) => {
638
                        panic!("memory allocation failed: error allocating new memory");
639
                    }
640
146805
                    Ok(()) => { /* yay */ }
641
                }
642
146805
            }
643

            
644
1710
            pub fn append(&mut self, other: &mut Self) {
645
1710
                unsafe {
646
1710
                    self.append_elements(other.as_slice() as _);
647
1710
                    other.set_len(0);
648
1710
                }
649
1710
            }
650

            
651
1710
            unsafe fn set_len(&mut self, new_len: usize) {
652
1710
                debug_assert!(new_len <= self.capacity());
653
1710
                self.len = new_len;
654
1710
            }
655

            
656
1710
            pub fn reserve(&mut self, additional: usize) {
657
1710
                self.buf_reserve(self.len, additional);
658
1710
            }
659

            
660
            /// Appends elements to `Self` from other buffer.
661
            #[inline]
662
1710
            unsafe fn append_elements(&mut self, other: *const [$struct_type]) {
663
1710
                let count = (&(*other)).len();
664
1710
                self.reserve(count);
665
1710
                let len = self.len();
666
1710
                core::ptr::copy_nonoverlapping(
667
1710
                    other as *const $struct_type,
668
1710
                    self.as_mut_ptr().add(len),
669
1710
                    count,
670
                );
671
1710
                self.len += count;
672
1710
            }
673

            
674
            pub fn truncate(&mut self, len: usize) {
675
                // This is safe because:
676
                //
677
                // * the slice passed to `drop_in_place` is valid; the `len > self.len` case avoids
678
                //   creating an invalid slice, and
679
                // * the `len` of the vector is shrunk before calling `drop_in_place`, such that no
680
                //   value will be dropped twice in case `drop_in_place` were to panic once (if it
681
                //   panics twice, the program aborts).
682
                unsafe {
683
                    if len > self.len {
684
                        return;
685
                    }
686
                    let remaining_len = self.len - len;
687
                    let s = core::ptr::slice_from_raw_parts_mut(
688
                        self.as_mut_ptr().add(len),
689
                        remaining_len,
690
                    );
691
                    self.len = len;
692
                    core::ptr::drop_in_place(s);
693
                }
694
            }
695

            
696
            pub fn retain<F>(&mut self, mut f: F)
697
            where
698
                F: FnMut(&$struct_type) -> bool,
699
            {
700
                let len = self.len();
701
                let mut del = 0;
702

            
703
                {
704
                    for i in 0..len {
705
                        if unsafe { !f(self.get_unchecked(i)) } {
706
                            del += 1;
707
                        } else if del > 0 {
708
                            self.as_mut().swap(i - del, i);
709
                        }
710
                    }
711
                }
712

            
713
                if del > 0 {
714
                    self.truncate(len - del);
715
                }
716
            }
717
        }
718
    };
719
}
720

            
721
#[macro_export]
722
macro_rules! impl_vec_debug {
723
    ($struct_type:ident, $struct_name:ident) => {
724
        impl core::fmt::Debug for $struct_name {
725
14
            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
726
14
                self.as_ref().fmt(f)
727
14
            }
728
        }
729
    };
730
}
731

            
732
#[macro_export]
733
macro_rules! impl_vec_partialord {
734
    ($struct_type:ident, $struct_name:ident) => {
735
        impl PartialOrd for $struct_name {
736
            fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
737
                self.as_ref().partial_cmp(rhs.as_ref())
738
            }
739
        }
740
    };
741
}
742

            
743
#[macro_export]
744
macro_rules! impl_vec_ord {
745
    ($struct_type:ident, $struct_name:ident) => {
746
        impl Ord for $struct_name {
747
            fn cmp(&self, rhs: &Self) -> core::cmp::Ordering {
748
                self.as_ref().cmp(rhs.as_ref())
749
            }
750
        }
751
    };
752
}
753

            
754
#[macro_export]
755
macro_rules! impl_vec_clone {
756
    ($struct_type:ident, $struct_name:ident, $destructor_name:ident) => {
757
        impl $struct_name {
758
            // Creates a `Vec` from a `Cow<'static, [T]>` - useful to avoid allocating in the case
759
            // of &'static memory
760
            #[inline(always)]
761
            pub fn from_copy_on_write(
762
                input: alloc::borrow::Cow<'static, [$struct_type]>,
763
            ) -> $struct_name {
764
                match input {
765
                    alloc::borrow::Cow::Borrowed(static_array) => {
766
                        Self::from_const_slice(static_array)
767
                    }
768
                    alloc::borrow::Cow::Owned(owned_vec) => Self::from_vec(owned_vec),
769
                }
770
            }
771

            
772
            /// Creates a Vec containing a single element
773
            #[inline(always)]
774
            pub fn from_item(item: $struct_type) -> Self {
775
                Self::from_vec(alloc::vec![item])
776
            }
777

            
778
            /// Copies elements from a C array pointer into a new Vec.
779
            /// 
780
            /// # Safety
781
            /// - `ptr` must be valid for reading `len` elements
782
            /// - The memory must be properly aligned for `$struct_type`
783
            /// - The elements are cloned, so `$struct_type` must implement `Clone`
784
            #[inline]
785
            pub unsafe fn copy_from_ptr(ptr: *const $struct_type, len: usize) -> Self {
786
                if ptr.is_null() || len == 0 {
787
                    return Self::new();
788
                }
789
                let slice = core::slice::from_raw_parts(ptr, len);
790
                Self::from_vec(slice.to_vec())
791
            }
792

            
793
            /// NOTE: CLONES the memory if the memory is external or &'static
794
            /// Moves the memory out if the memory is library-allocated
795
            #[inline(always)]
796
894346
            pub fn clone_self(&self) -> Self {
797
894346
                match self.destructor {
798
221436
                    $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => Self {
799
221436
                        ptr: self.ptr,
800
221436
                        len: self.len,
801
221436
                        cap: self.cap,
802
221436
                        destructor: $destructor_name::NoDestructor,
803
221436
                    },
804
                    $destructor_name::External(_) | $destructor_name::DefaultRust => {
805
672910
                        Self::from_vec(self.as_ref().to_vec())
806
                    }
807
                }
808
894346
            }
809

            
810
            /// NOTE: CLONES the memory if the memory is external or &'static
811
            /// Moves the memory out if the memory is library-allocated
812
            #[inline(always)]
813
159168
            pub fn into_library_owned_vec(self) -> alloc::vec::Vec<$struct_type> {
814
159168
                match self.destructor {
815
                    $destructor_name::NoDestructor | $destructor_name::External(_) | $destructor_name::AlreadyDestroyed => {
816
36308
                        self.as_ref().to_vec()
817
                    }
818
                    $destructor_name::DefaultRust => {
819
122860
                        let v = unsafe {
820
122860
                            alloc::vec::Vec::from_raw_parts(
821
122860
                                self.ptr as *mut $struct_type,
822
122860
                                self.len,
823
122860
                                self.cap,
824
                            )
825
                        };
826
122860
                        core::mem::forget(self);
827
122860
                        v
828
                    }
829
                }
830
159168
            }
831
        }
832
        impl Clone for $struct_name {
833
569796
            fn clone(&self) -> Self {
834
569796
                self.clone_self()
835
569796
            }
836
        }
837
    };
838
}
839

            
840
#[macro_export]
841
macro_rules! impl_vec_partialeq {
842
    ($struct_type:ident, $struct_name:ident) => {
843
        impl PartialEq for $struct_name {
844
1638
            fn eq(&self, rhs: &Self) -> bool {
845
1638
                self.as_ref().eq(rhs.as_ref())
846
1638
            }
847
        }
848
    };
849
}
850

            
851
#[macro_export]
852
macro_rules! impl_vec_eq {
853
    ($struct_type:ident, $struct_name:ident) => {
854
        impl Eq for $struct_name {}
855
    };
856
}
857

            
858
#[macro_export]
859
macro_rules! impl_vec_hash {
860
    ($struct_type:ident, $struct_name:ident) => {
861
        impl core::hash::Hash for $struct_name {
862
1791
            fn hash<H>(&self, state: &mut H)
863
1791
            where
864
1791
                H: core::hash::Hasher,
865
            {
866
1791
                self.as_ref().hash(state);
867
1791
            }
868
        }
869
    };
870
}
871

            
872
#[macro_export]
873
macro_rules! impl_option_inner {
874
    ($struct_type:ident, $struct_name:ident) => {
875
        impl From<$struct_name> for Option<$struct_type> {
876
            fn from(o: $struct_name) -> Option<$struct_type> {
877
                match o {
878
                    $struct_name::None => None,
879
                    $struct_name::Some(t) => Some(t),
880
                }
881
            }
882
        }
883

            
884
        impl From<Option<$struct_type>> for $struct_name {
885
970253
            fn from(o: Option<$struct_type>) -> $struct_name {
886
970253
                match o {
887
960341
                    None => $struct_name::None,
888
9912
                    Some(t) => $struct_name::Some(t),
889
                }
890
970253
            }
891
        }
892

            
893
        impl Default for $struct_name {
894
112406
            fn default() -> $struct_name {
895
112406
                $struct_name::None
896
112406
            }
897
        }
898

            
899
        impl $struct_name {
900
4
            pub fn as_option(&self) -> Option<&$struct_type> {
901
4
                match self {
902
2
                    $struct_name::None => None,
903
2
                    $struct_name::Some(t) => Some(t),
904
                }
905
4
            }
906
            pub fn replace(&mut self, value: $struct_type) -> $struct_name {
907
                ::core::mem::replace(self, $struct_name::Some(value))
908
            }
909
1
            pub fn is_some(&self) -> bool {
910
1
                match self {
911
1
                    $struct_name::None => false,
912
                    $struct_name::Some(_) => true,
913
                }
914
1
            }
915
1
            pub fn is_none(&self) -> bool {
916
1
                !self.is_some()
917
1
            }
918
487
            pub const fn as_ref(&self) -> Option<&$struct_type> {
919
487
                match *self {
920
431
                    $struct_name::Some(ref x) => Some(x),
921
56
                    $struct_name::None => None,
922
                }
923
487
            }
924
            pub fn as_mut(&mut self) -> Option<&mut $struct_type> {
925
                match self {
926
                    $struct_name::Some(x) => Some(x),
927
                    $struct_name::None => None,
928
                }
929
            }
930
            pub fn map<U, F: FnOnce($struct_type) -> U>(self, f: F) -> Option<U> {
931
                match self {
932
                    $struct_name::Some(x) => Some(f(x)),
933
                    $struct_name::None => None,
934
                }
935
            }
936
            pub fn and_then<U, F>(self, f: F) -> Option<U>
937
            where
938
                F: FnOnce($struct_type) -> Option<U>,
939
            {
940
                match self {
941
                    $struct_name::None => None,
942
                    $struct_name::Some(x) => f(x),
943
                }
944
            }
945
        }
946
    };
947
}
948

            
949
#[macro_export]
950
macro_rules! impl_option {
951
    ($struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
952
        $(#[derive($derive)])*
953
        #[repr(C, u8)]
954
        pub enum $struct_name {
955
            None,
956
            Some($struct_type)
957
        }
958

            
959
        impl $struct_name {
960
            pub fn into_option(self) -> Option<$struct_type> {
961
                match self {
962
                    $struct_name::None => None,
963
                    $struct_name::Some(t) => Some(t),
964
                }
965
            }
966
        }
967

            
968
        impl_option_inner!($struct_type, $struct_name);
969
    );
970
    ($struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
971
        $(#[derive($derive)])*
972
        #[repr(C, u8)]
973
        pub enum $struct_name {
974
            None,
975
            Some($struct_type)
976
        }
977

            
978
        impl $struct_name {
979
51
            pub fn into_option(&self) -> Option<$struct_type> {
980
51
                match self {
981
51
                    $struct_name::None => None,
982
                    $struct_name::Some(t) => Some(t.clone()),
983
                }
984
51
            }
985
        }
986

            
987
        impl_option_inner!($struct_type, $struct_name);
988
    );
989
    ($struct_type:ident, $struct_name:ident, [$($derive:meta),* ]) => (
990
        $(#[derive($derive)])*
991
        #[repr(C, u8)]
992
        pub enum $struct_name {
993
            None,
994
            Some($struct_type)
995
        }
996

            
997
        impl $struct_name {
998
1465
            pub fn into_option(&self) -> Option<$struct_type> {
999
1465
                match self {
863
                    $struct_name::None => None,
602
                    $struct_name::Some(t) => Some(t.clone()),
                }
1465
            }
        }
        impl_option_inner!($struct_type, $struct_name);
    );
}
#[macro_export]
macro_rules! impl_result_inner {
    ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident) => {
        impl From<$struct_name> for Result<$ok_struct_type, $err_struct_type> {
            fn from(o: $struct_name) -> Result<$ok_struct_type, $err_struct_type> {
                match o {
                    $struct_name::Ok(o) => Ok(o),
                    $struct_name::Err(e) => Err(e),
                }
            }
        }
        impl From<Result<$ok_struct_type, $err_struct_type>> for $struct_name {
            fn from(o: Result<$ok_struct_type, $err_struct_type>) -> $struct_name {
                match o {
                    Ok(o) => $struct_name::Ok(o),
                    Err(e) => $struct_name::Err(e),
                }
            }
        }
        impl $struct_name {
            pub fn as_result(&self) -> Result<&$ok_struct_type, &$err_struct_type> {
                match self {
                    $struct_name::Ok(o) => Ok(o),
                    $struct_name::Err(e) => Err(e),
                }
            }
            pub fn is_ok(&self) -> bool {
                match self {
                    $struct_name::Ok(_) => true,
                    $struct_name::Err(_) => false,
                }
            }
            pub fn is_err(&self) -> bool {
                !self.is_ok()
            }
        }
    };
}
#[macro_export]
macro_rules! impl_result {
    ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
        $(#[derive($derive)])*
        #[repr(C, u8)]
        pub enum $struct_name {
            Ok($ok_struct_type),
            Err($err_struct_type)
        }
        impl $struct_name {
            pub fn into_result(self) -> Result<$ok_struct_type, $err_struct_type> {
                match self {
                    $struct_name::Ok(o) => Ok(o),
                    $struct_name::Err(e) => Err(e),
                }
            }
        }
        impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
    );
    ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
        $(#[derive($derive)])*
        #[repr(C, u8)]
        pub enum $struct_name {
            Ok($ok_struct_type),
            Err($err_struct_type)
        }
        impl $struct_name {
            pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
                match self {
                    $struct_name::Ok(o) => Ok(o.clone()),
                    $struct_name::Err(e) => Err(e.clone()),
                }
            }
        }
        impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
    );
    ($ok_struct_type:ident, $err_struct_type:ident,  $struct_name:ident, [$($derive:meta),* ]) => (
        $(#[derive($derive)])*
        #[repr(C, u8)]
        pub enum $struct_name {
            Ok($ok_struct_type),
            Err($err_struct_type)
        }
        impl $struct_name {
            pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
                match self {
                    $struct_name::Ok(o) => Ok(*o),
                    $struct_name::Err(e) => Err(*e),
                }
            }
        }
        impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
    );
}
macro_rules! impl_color_value_fmt {
    ($struct_name:ty) => {
        impl FormatAsRustCode for $struct_name {
            fn format_as_rust_code(&self, _tabs: usize) -> String {
                format!(
                    "{} {{ inner: {} }}",
                    stringify!($struct_name),
                    format_color_value(&self.inner)
                )
            }
        }
    };
}
macro_rules! impl_enum_fmt {($enum_name:ident, $($enum_type:ident),+) => (
    impl crate::codegen::format::FormatAsRustCode for $enum_name {
        fn format_as_rust_code(&self, _tabs: usize) -> String {
            match self {
                $(
                    $enum_name::$enum_type => {
                        String::from(
                            concat!(stringify!($enum_name), "::", stringify!($enum_type))
                        )
                    },
                )+
            }
        }
    }
)}