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

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

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

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

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

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

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

            
50
            /// Converts the C-slice to a Rust slice.
51
            #[inline]
52
28
            #[must_use] pub const fn as_slice(&self) -> &[$struct_type] {
53
28
                if self.ptr.is_null() || self.len == 0 {
54
6
                    &[]
55
                } else {
56
22
                    unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
57
                }
58
28
            }
59

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

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

            
73
        unsafe impl Send for $slice_name {}
74
        unsafe impl Sync for $slice_name {}
75

            
76
        impl<'a> IntoIterator for &'a $slice_name {
77
            type Item = &'a $struct_type;
78
            type IntoIter = core::slice::Iter<'a, $struct_type>;
79
            #[inline]
80
            fn into_iter(self) -> Self::IntoIter {
81
                self.iter()
82
            }
83
        }
84

            
85
        impl<'a> IntoIterator for &'a $struct_name {
86
            type Item = &'a $struct_type;
87
            type IntoIter = core::slice::Iter<'a, $struct_type>;
88
            #[inline]
89
1462253
            fn into_iter(self) -> Self::IntoIter {
90
1462253
                self.iter()
91
1462253
            }
92
        }
93

            
94
        #[repr(C)]
95
        pub struct $struct_name {
96
            ptr: *const $struct_type,
97
            len: usize,
98
            cap: usize,
99
            destructor: $destructor_name,
100
        }
101

            
102
        #[derive(Debug, Copy, Clone)]
103
        #[repr(C, u8)]
104
        pub enum $destructor_name {
105
            DefaultRust,
106
            NoDestructor,
107
            External($destructor_type_name),
108
            /// Destructor was already run — prevents double-free.
109
            /// Set by Drop impl after destruction.
110
            AlreadyDestroyed,
111
        }
112

            
113
        unsafe impl Send for $struct_name {}
114
        unsafe impl Sync for $struct_name {}
115

            
116
        impl $struct_name {
117
            #[inline]
118
736198
            #[must_use] pub const fn new() -> $struct_name {
119
                // lets hope the optimizer catches this
120
736198
                Self::from_vec(alloc::vec::Vec::new())
121
736198
            }
122

            
123
            #[inline]
124
1
            #[must_use] pub fn with_capacity(cap: usize) -> Self {
125
1
                Self::from_vec(alloc::vec::Vec::<$struct_type>::with_capacity(cap))
126
1
            }
127

            
128
            #[inline]
129
26708820
            #[must_use] pub const fn from_const_slice(input: &'static [$struct_type]) -> Self {
130
26708820
                Self {
131
26708820
                    ptr: input.as_ptr(),
132
26708820
                    len: input.len(),
133
26708820
                    cap: input.len(),
134
26708820
                    destructor: $destructor_name::NoDestructor, // because of &'static
135
26708820
                }
136
26708820
            }
137

            
138
            /// True when the buffer is heap memory THIS type allocated, and may
139
            /// therefore be realloc'd / deep-cloned / freed by us.
140
            ///
141
            /// Private, and deliberately not part of the C API surface. Lives here
142
            /// rather than in `impl_vec_mut!` because only `impl_vec!` is given the
143
            /// name of the destructor enum.
144
            #[inline]
145
344791
            const fn owns_buffer(&self) -> bool {
146
344791
                matches!(self.destructor, $destructor_name::DefaultRust)
147
344791
            }
148

            
149
            /// Records that the buffer is now heap memory we own. Must be called after
150
            /// any allocation that replaces a borrowed (`NoDestructor`/`External`)
151
            /// buffer, or `clone_self`/`Drop` keep believing it is borrowed.
152
            #[inline]
153
344791
            const fn mark_rust_owned(&mut self) {
154
344791
                self.destructor = $destructor_name::DefaultRust;
155
344791
            }
156

            
157
            #[inline]
158
87472872
            #[must_use] pub const fn from_vec(input: alloc::vec::Vec<$struct_type>) -> Self {
159
87472872
                let ptr = input.as_ptr();
160
87472872
                let len = input.len();
161
87472872
                let cap = input.capacity();
162

            
163
87472872
                let _ = ::core::mem::ManuallyDrop::new(input);
164

            
165
87472872
                Self {
166
87472872
                    ptr,
167
87472872
                    len,
168
87472872
                    cap,
169
87472872
                    destructor: $destructor_name::DefaultRust,
170
87472872
                }
171
87472872
            }
172

            
173
            #[inline]
174
5825624
            pub fn iter(&self) -> core::slice::Iter<'_, $struct_type> {
175
5825624
                self.as_ref().iter()
176
5825624
            }
177

            
178
            #[inline]
179
1775358
            #[must_use] pub const fn len(&self) -> usize {
180
1775358
                self.len
181
1775358
            }
182

            
183
            #[inline]
184
1327376
            #[must_use] pub const fn capacity(&self) -> usize {
185
1327376
                self.cap
186
1327376
            }
187

            
188
            #[inline]
189
4805299
            #[must_use] pub const fn is_empty(&self) -> bool {
190
4805299
                self.len == 0
191
4805299
            }
192

            
193
            /// Returns a reference to the element at the given index (Rust-only, inline).
194
            #[inline]
195
170280
            #[must_use] pub fn get(&self, index: usize) -> Option<&$struct_type> {
196
170280
                self.as_ref().get(index)
197
170280
            }
198

            
199
            /// C-API compatible get function. Returns a copy of the element at the given index.
200
            /// Returns None if the index is out of bounds.
201
            #[inline]
202
37
            #[must_use] pub fn c_get(&self, index: usize) -> $option_type
203
37
            where
204
37
                $struct_type: Clone,
205
            {
206
37
                self.get(index).cloned().into()
207
37
            }
208

            
209
            #[allow(dead_code)]
210
            #[inline]
211
58674
            unsafe fn get_unchecked(&self, index: usize) -> &$struct_type { unsafe {
212
58674
                self.as_ref().get_unchecked(index)
213
58674
            }}
214

            
215
            /// Returns the vec as a Rust slice (Rust-only, not C-API compatible).
216
            #[inline]
217
107036661
            #[must_use] pub fn as_slice(&self) -> &[$struct_type] {
218
107036661
                self.as_ref()
219
107036661
            }
220

            
221
            /// Returns a C-compatible slice of the entire Vec.
222
            #[inline]
223
26
            #[must_use] pub const fn as_c_slice(&self) -> $slice_name {
224
26
                $slice_name {
225
26
                    ptr: self.ptr,
226
26
                    len: self.len,
227
26
                }
228
26
            }
229

            
230
            /// Returns a C-compatible slice of a range within the Vec.
231
            /// If the range is out of bounds, it is clamped to the valid range.
232
            #[inline]
233
15
            #[must_use] pub fn as_c_slice_range(&self, start: usize, end: usize) -> $slice_name {
234
15
                let start = start.min(self.len);
235
15
                let end = end.min(self.len).max(start);
236
15
                let len = end - start;
237
15
                if len == 0 || self.ptr.is_null() {
238
7
                    $slice_name::empty()
239
                } else {
240
8
                    $slice_name {
241
8
                        ptr: unsafe { self.ptr.add(start) },
242
8
                        len,
243
8
                    }
244
                }
245
15
            }
246

            
247
            /// Returns a pointer to the Vec's data.
248
            /// Use `len()` to get the number of elements.
249
            #[inline]
250
11115
            #[must_use] pub const fn as_ptr(&self) -> *const $struct_type {
251
11115
                self.ptr
252
11115
            }
253
        }
254

            
255
        impl AsRef<[$struct_type]> for $struct_name {
256
376923862
            fn as_ref(&self) -> &[$struct_type] {
257
376923862
                if self.ptr.is_null() || self.len == 0 {
258
115864647
                    &[]
259
                } else {
260
261059215
                    unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
261
                }
262
376923862
            }
263
        }
264

            
265
        impl Default for $struct_name {
266
3046602
            fn default() -> Self {
267
3046602
                Self::from_vec(alloc::vec::Vec::new())
268
3046602
            }
269
        }
270

            
271
        impl core::iter::FromIterator<$struct_type> for $struct_name {
272
14
            fn from_iter<T>(iter: T) -> Self
273
14
            where
274
14
                T: IntoIterator<Item = $struct_type>,
275
            {
276
14
                Self::from_vec(alloc::vec::Vec::from_iter(iter))
277
14
            }
278
        }
279

            
280
        impl From<alloc::vec::Vec<$struct_type>> for $struct_name {
281
28436982
            fn from(input: alloc::vec::Vec<$struct_type>) -> $struct_name {
282
28436982
                $struct_name::from_vec(input)
283
28436982
            }
284
        }
285

            
286
        impl From<&'static [$struct_type]> for $struct_name {
287
4620
            fn from(input: &'static [$struct_type]) -> $struct_name {
288
4620
                Self::from_const_slice(input)
289
4620
            }
290
        }
291

            
292
        impl Drop for $struct_name {
293
127946457
            fn drop(&mut self) {
294
127946457
                match self.destructor {
295
                    $destructor_name::DefaultRust => {
296
                        // Defensive: a library-owned Vec only owns an allocation
297
                        // when `ptr` is non-null and `cap != 0`. A zeroed / moved-
298
                        // from FFI husk (e.g. a struct field a C++ wrapper move-
299
                        // cleared, leaving destructor == DefaultRust [tag 0] with a
300
                        // null ptr but a stale len) would otherwise hit
301
                        // `Vec::from_raw_parts(null, len, _)` and deref 0x0 on drop.
302
                        // Skip when there is nothing to free. (Empty Vecs have
303
                        // cap == 0; valid non-empty Vecs are unaffected.)
304
86158702
                        if !self.ptr.is_null() && self.cap != 0 {
305
65605090
                            drop(unsafe {
306
65605090
                                alloc::vec::Vec::from_raw_parts(
307
65605090
                                    self.ptr.cast_mut(),
308
65605090
                                    self.len,
309
65605090
                                    self.cap,
310
65605090
                                )
311
65605090
                            });
312
65605090
                        }
313
86158702
                        self.destructor = $destructor_name::AlreadyDestroyed;
314
                    }
315
24762
                    $destructor_name::External(f) => {
316
24762
                        f(self);
317
24762
                        self.destructor = $destructor_name::AlreadyDestroyed;
318
24762
                    }
319
41762993
                    $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => {}
320
                }
321
127946457
            }
322
        }
323
    };
324
}
325

            
326
/// Implement the `From` trait for any type.
327
/// Example usage:
328
/// ```no_run,ignore
329
/// enum MyError<'a> {
330
///     Bar(BarError<'a>),
331
///     Foo(FooError<'a>)
332
/// }
333
///
334
/// impl_from!(BarError<'a>, MyError::Bar);
335
/// impl_from!(FooError<'a>, MyError::Foo);
336
/// ```
337
macro_rules! impl_from {
338
    // From a type with a lifetime to a type which also has a lifetime
339
    ($a:ident < $c:lifetime > , $b:ident:: $enum_type:ident) => {
340
        impl<$c> From<$a<$c>> for $b<$c> {
341
35331
            fn from(e: $a<$c>) -> Self {
342
35331
                $b::$enum_type(e)
343
35331
            }
344
        }
345
    };
346

            
347
    // (No "non-lifetime → lifetime-bearing target" arm: it can only generate
348
    // `impl<'a> From<A> for B<'a>` where 'a is single-use, which trips
349
    // single_use_lifetimes. Write those impls out by hand with `B<'_>` instead.)
350

            
351
    // From a type without a lifetime to a type which also does not have a lifetime
352
    ($a:ident, $b:ident:: $enum_type:ident) => {
353
        impl From<$a> for $b {
354
            fn from(e: $a) -> Self {
355
                $b::$enum_type(e)
356
            }
357
        }
358
    };
359
}
360

            
361
/// Implement `Display` for an enum.
362
///
363
/// Example usage:
364
/// ```no_run,ignore
365
/// enum Foo<'a> {
366
///     Bar(&'a str),
367
///     Baz(i32)
368
/// }
369
///
370
/// impl_display!{ Foo<'a>, {
371
///     Bar(s) => s,
372
///     Baz(i) => format!("{}", i)
373
/// }}
374
/// ```
375
#[macro_export]
376
macro_rules! impl_display {
377
    // For a type with a lifetime
378
    ($enum:ident<$lt:lifetime>, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
379

            
380
        impl ::core::fmt::Display for $enum<'_> {
381
1022
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
382
                use self::$enum::*;
383
1022
                match &self {
384
                    $(
385
580
                        $variant => write!(f, "{}", $fmt_string),
386
                    )+
387
                }
388
1022
            }
389
        }
390

            
391
    };
392

            
393
    // For a type without a lifetime
394
    ($enum:ident, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
395

            
396
        impl ::core::fmt::Display for $enum {
397
41
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
398
                use self::$enum::*;
399
41
                match &self {
400
                    $(
401
23
                        $variant => write!(f, "{}", $fmt_string),
402
                    )+
403
                }
404
41
            }
405
        }
406

            
407
    };
408
}
409

            
410
/// Implements `Debug` to use `Display` instead - assumes the that the type has implemented
411
/// `Display`
412
#[macro_export]
413
macro_rules! impl_debug_as_display {
414
    // For a type with a lifetime
415
    ($enum:ident < $lt:lifetime >) => {
416
        impl ::core::fmt::Debug for $enum<'_> {
417
105
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
418
105
                write!(f, "{}", self)
419
105
            }
420
        }
421
    };
422

            
423
    // For a type without a lifetime
424
    ($enum:ident) => {
425
        impl ::core::fmt::Debug for $enum {
426
10
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
427
10
                write!(f, "{}", self)
428
10
            }
429
        }
430
    };
431
}
432

            
433
#[macro_export]
434
macro_rules! impl_vec_as_hashmap {
435
    ($struct_type:ident, $struct_name:ident) => {
436
        impl $struct_name {
437
            pub fn insert_hm_item(&mut self, item: $struct_type) {
438
                if !self.contains_hm_item(&item) {
439
                    self.push(item);
440
                }
441
            }
442

            
443
            pub fn remove_hm_item(&mut self, remove_key: &$struct_type) {
444
                *self = Self::from_vec(
445
                    self.as_ref()
446
                        .iter()
447
                        .filter_map(|r| if *r == *remove_key { None } else { Some(*r) })
448
                        .collect::<Vec<_>>(),
449
                );
450
            }
451

            
452
            pub fn contains_hm_item(&self, searched: &$struct_type) -> bool {
453
                self.as_ref().iter().any(|i| i == searched)
454
            }
455
        }
456
    };
457
}
458

            
459
/// NOTE: `impl_vec_mut` can only exist for vectors that are known to be library-allocated!
460
#[macro_export]
461
macro_rules! impl_vec_mut {
462
    ($struct_type:ident, $struct_name:ident) => {
463
        impl<'a> IntoIterator for &'a mut $struct_name {
464
            type Item = &'a mut $struct_type;
465
            type IntoIter = core::slice::IterMut<'a, $struct_type>;
466
            #[inline]
467
845
            fn into_iter(self) -> Self::IntoIter {
468
845
                self.iter_mut()
469
845
            }
470
        }
471

            
472
        impl AsMut<[$struct_type]> for $struct_name {
473
2957967
            fn as_mut(&mut self) -> &mut [$struct_type] {
474
2957967
                unsafe { core::slice::from_raw_parts_mut(self.ptr.cast_mut(), self.len) }
475
2957967
            }
476
        }
477

            
478
        impl From<$struct_name> for alloc::vec::Vec<$struct_type> {
479
            #[allow(unused_mut)]
480
4634
            fn from(mut input: $struct_name) -> alloc::vec::Vec<$struct_type> {
481
4634
                input.into_library_owned_vec()
482
4634
            }
483
        }
484

            
485
        impl core::iter::Extend<$struct_type> for $struct_name {
486
1
            fn extend<T: core::iter::IntoIterator<Item = $struct_type>>(&mut self, iter: T) {
487
5
                for elem in iter {
488
4
                    self.push(elem);
489
4
                }
490
1
            }
491
        }
492

            
493
        impl $struct_name {
494
            #[inline]
495
978263
            pub const fn as_mut_ptr(&mut self) -> *mut $struct_type {
496
978263
                self.ptr.cast_mut()
497
978263
            }
498

            
499
            #[inline]
500
240
            pub fn sort_by<F: FnMut(&$struct_type, &$struct_type) -> core::cmp::Ordering>(
501
240
                &mut self,
502
240
                compare: F,
503
240
            ) {
504
240
                self.as_mut().sort_by(compare);
505
240
            }
506

            
507
            #[inline]
508
893091
            pub fn push(&mut self, value: $struct_type) {
509
                // code is copied from the rust stdlib, since it's not possible to
510
                // create a temporary Vec here. Doing that would create two
511
893091
                if self.len == self.capacity() {
512
316807
                    self.buf_reserve(self.len, 1);
513
576284
                }
514
893091
                unsafe {
515
893091
                    let end = self.as_mut_ptr().add(self.len);
516
893091
                    core::ptr::write(end, value);
517
893091
                    self.len += 1;
518
893091
                }
519
893091
            }
520

            
521
4
            pub fn insert(&mut self, index: usize, element: $struct_type) {
522
4
                let len = self.len();
523
4
                if index > len {
524
2
                    return;
525
2
                }
526

            
527
                // space for the new element
528
2
                if len == self.capacity() {
529
1
                    self.reserve(1);
530
1
                }
531

            
532
2
                unsafe {
533
2
                    // infallible
534
2
                    // The spot to put the new value
535
2
                    {
536
2
                        let p = self.as_mut_ptr().add(index);
537
2
                        // Shift everything over to make space. (Duplicating the
538
2
                        // `index`th element into two consecutive places.)
539
2
                        core::ptr::copy(p, p.offset(1), len - index);
540
2
                        // Write it in, overwriting the first copy of the `index`th
541
2
                        // element.
542
2
                        core::ptr::write(p, element);
543
2
                    }
544
2
                    self.set_len(len + 1);
545
2
                }
546
4
            }
547

            
548
18
            pub fn remove(&mut self, index: usize) {
549
18
                let len = self.len();
550
18
                if index >= len {
551
2
                    return;
552
16
                }
553

            
554
16
                unsafe {
555
16
                    // infallible
556
16
                    let ret;
557
16
                    {
558
16
                        // the place we are taking from.
559
16
                        let ptr = self.as_mut_ptr().add(index);
560
16
                        // copy it out, unsafely having a copy of the value on
561
16
                        // the stack and in the vector at the same time.
562
16
                        ret = core::ptr::read(ptr);
563
16

            
564
16
                        // Shift everything down to fill in that spot.
565
16
                        core::ptr::copy(ptr.offset(1), ptr, len - index - 1);
566
16
                    }
567
16
                    self.set_len(len - 1);
568
16
                    // Named binding (not `let _ =` / `drop()`): this macro is
569
16
                    // generic over the element type, so a bare drop trips
570
16
                    // dropping_copy_types for Copy elements while `let _ =` trips
571
16
                    // let_underscore_drop for ones with a destructor. A named
572
16
                    // unused binding drops at scope end and satisfies both.
573
16
                    let _ret = ret;
574
16
                }
575
18
            }
576

            
577
            #[inline]
578
3
            pub const fn pop(&mut self) -> Option<$struct_type> {
579
3
                if self.len == 0 {
580
2
                    None
581
                } else {
582
                    unsafe {
583
1
                        self.len -= 1;
584
1
                        Some(core::ptr::read(self.ptr.add(self.len())))
585
                    }
586
                }
587
3
            }
588

            
589
            #[inline]
590
475774
            pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, $struct_type> {
591
475774
                self.as_mut().iter_mut()
592
475774
            }
593

            
594
            #[inline]
595
19
            #[must_use] pub fn into_iter(self) -> alloc::vec::IntoIter<$struct_type> {
596
19
                let v1: alloc::vec::Vec<$struct_type> = self.into();
597
19
                v1.into_iter()
598
19
            }
599

            
600
            #[inline]
601
344791
            fn amortized_new_size(
602
344791
                &self,
603
344791
                used_cap: usize,
604
344791
                needed_extra_cap: usize,
605
344791
            ) -> Result<usize, bool> {
606
                // Nothing we can really do about these checks :(
607
344791
                let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(true)?;
608
                // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
609
344791
                let double_cap = self.cap * 2;
610
                // `double_cap` guarantees exponential growth.
611
344791
                Ok(core::cmp::max(double_cap, required_cap))
612
344791
            }
613

            
614
            #[inline]
615
344791
            const fn current_layout(&self) -> Option<core::alloc::Layout> {
616
344791
                if self.cap == 0 {
617
304814
                    None
618
                } else {
619
                    // We have an allocated chunk of memory, so we can bypass runtime
620
                    // checks to get our current layout.
621
                    unsafe {
622
39977
                        let align = core::mem::align_of::<$struct_type>();
623
39977
                        let size = core::mem::size_of::<$struct_type>() * self.cap;
624
39977
                        Some(core::alloc::Layout::from_size_align_unchecked(size, align))
625
                    }
626
                }
627
344791
            }
628

            
629
            #[inline]
630
344791
            const fn alloc_guard(alloc_size: usize) -> Result<(), bool> {
631
344791
                if core::mem::size_of::<usize>() < 8 && alloc_size > ::core::isize::MAX as usize {
632
                    Err(true)
633
                } else {
634
344791
                    Ok(())
635
                }
636
344791
            }
637

            
638
            #[inline]
639
            // the reallocated pointer comes from the global allocator with a Layout
640
            // computed for `$struct_type`, so it is correctly aligned for the cast.
641
            #[allow(clippy::cast_ptr_alignment)]
642
345674
            fn try_reserve(
643
345674
                &mut self,
644
345674
                used_cap: usize,
645
345674
                needed_extra_cap: usize,
646
345674
            ) -> Result<(), bool> {
647
                // NOTE: we don't early branch on ZSTs here because we want this
648
                // to actually catch "asking for more than usize::MAX" in that case.
649
                // If we make it past the first branch then we are guaranteed to
650
                // panic.
651

            
652
                // Don't actually need any more capacity.
653
                // Wrapping in case they give a bad `used_cap`
654
345674
                if self.capacity().wrapping_sub(used_cap) >= needed_extra_cap {
655
883
                    return Ok(());
656
344791
                }
657

            
658
344791
                let new_cap = self.amortized_new_size(used_cap, needed_extra_cap)?;
659
344791
                let new_layout =
660
344791
                    alloc::alloc::Layout::array::<$struct_type>(new_cap).map_err(|_| true)?;
661

            
662
344791
                $struct_name::alloc_guard(new_layout.size())?;
663

            
664
                // ONLY a buffer we allocated ourselves (`DefaultRust`) may be handed to
665
                // `realloc`. `current_layout()` reports `Some` for any `cap != 0`, which
666
                // is NOT the same question: a vec built by `from_const_slice` points at
667
                // `&'static` memory (`NoDestructor`), and one handed over by C owns its
668
                // buffer elsewhere (`External`). Realloc'ing either would tell the Rust
669
                // allocator to free memory it never handed out.
670
                //
671
                // Everything else therefore gets a fresh allocation with the existing
672
                // elements copied across.
673
344791
                let owns_buffer = self.owns_buffer();
674

            
675
344791
                let res = unsafe {
676
344791
                    match self.current_layout() {
677
39977
                        Some(layout) if owns_buffer => {
678
39977
                            alloc::alloc::realloc(self.ptr.cast::<u8>().cast_mut(), layout, new_layout.size())
679
                        }
680
                        _ => {
681
304814
                            let fresh = alloc::alloc::alloc(new_layout);
682
                            // NOTE: for `External`, the original buffer is left for its
683
                            // owner to free — we must not touch it. That orphans its
684
                            // destructor, but leaking is strictly better than the
685
                            // cross-allocator free this used to do.
686
304814
                            if !fresh.is_null() && self.len > 0 {
687
                                core::ptr::copy_nonoverlapping(
688
                                    self.ptr,
689
                                    fresh.cast::<$struct_type>(),
690
                                    self.len,
691
                                );
692
304814
                            }
693
304814
                            fresh
694
                        }
695
                    }
696
                };
697

            
698
344791
                if res.is_null() {
699
                    return Err(false);
700
344791
                }
701

            
702
344791
                self.ptr = res as *mut $struct_type;
703
344791
                self.cap = new_cap;
704
                // The buffer is now heap memory WE own, whatever it was before, so the
705
                // tag has to follow. Leaving it as `NoDestructor` was a use-after-free:
706
                // `clone_self` branches on this tag and would take the shallow
707
                // pointer-copy path, so the clone and the original aliased one
708
                // allocation — and the next growth realloc'd it out from under the other
709
                // side. (`Drop` would also have leaked it.)
710
344791
                self.mark_rust_owned();
711

            
712
344791
                Ok(())
713
345674
            }
714

            
715
345674
            fn buf_reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
716
345674
                match self.try_reserve(used_cap, needed_extra_cap) {
717
                    Err(true /* Overflow */) => {
718
                        panic!("memory allocation failed: overflow");
719
                    }
720
                    Err(false /* AllocError(_) */) => {
721
                        panic!("memory allocation failed: error allocating new memory");
722
                    }
723
345674
                    Ok(()) => { /* yay */ }
724
                }
725
345674
            }
726

            
727
1816
            pub fn append(&mut self, other: &mut Self) {
728
1816
                unsafe {
729
1816
                    self.append_elements(core::ptr::from_ref(other.as_slice()));
730
1816
                    other.set_len(0);
731
1816
                }
732
1816
            }
733

            
734
1834
            unsafe fn set_len(&mut self, new_len: usize) {
735
1834
                debug_assert!(new_len <= self.capacity());
736
1834
                self.len = new_len;
737
1834
            }
738

            
739
1817
            pub fn reserve(&mut self, additional: usize) {
740
1817
                self.buf_reserve(self.len, additional);
741
1817
            }
742

            
743
            /// Appends elements to `Self` from other buffer.
744
            #[inline]
745
1816
            unsafe fn append_elements(&mut self, other: *const [$struct_type]) { unsafe {
746
1816
                let count = (&(*other)).len();
747
1816
                self.reserve(count);
748
1816
                let len = self.len();
749
1816
                core::ptr::copy_nonoverlapping(
750
1816
                    other as *const $struct_type,
751
1816
                    self.as_mut_ptr().add(len),
752
1816
                    count,
753
1816
                );
754
1816
                self.len += count;
755
1816
            }}
756

            
757
4
            pub fn truncate(&mut self, len: usize) {
758
                // This is safe because:
759
                //
760
                // * the slice passed to `drop_in_place` is valid; the `len > self.len` case avoids
761
                //   creating an invalid slice, and
762
                // * the `len` of the vector is shrunk before calling `drop_in_place`, such that no
763
                //   value will be dropped twice in case `drop_in_place` were to panic once (if it
764
                //   panics twice, the program aborts).
765
                unsafe {
766
4
                    if len > self.len {
767
1
                        return;
768
3
                    }
769
3
                    let remaining_len = self.len - len;
770
3
                    let s = core::ptr::slice_from_raw_parts_mut(
771
3
                        self.as_mut_ptr().add(len),
772
3
                        remaining_len,
773
                    );
774
3
                    self.len = len;
775
3
                    core::ptr::drop_in_place(s);
776
                }
777
4
            }
778

            
779
42516
            pub fn retain<F>(&mut self, mut f: F)
780
42516
            where
781
42516
                F: FnMut(&$struct_type) -> bool,
782
            {
783
42516
                let len = self.len();
784
42516
                let mut del = 0;
785

            
786
                {
787
59054
                    for i in 0..len {
788
58674
                        if unsafe { !f(self.get_unchecked(i)) } {
789
128
                            del += 1;
790
58546
                        } else if del > 0 {
791
127
                            self.as_mut().swap(i - del, i);
792
58419
                        }
793
                    }
794
                }
795

            
796
42516
                if del > 0 {
797
2
                    self.truncate(len - del);
798
42514
                }
799
42516
            }
800
        }
801
    };
802
}
803

            
804
#[macro_export]
805
macro_rules! impl_vec_debug {
806
    ($struct_type:ident, $struct_name:ident) => {
807
        impl core::fmt::Debug for $struct_name {
808
5579
            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
809
5579
                self.as_ref().fmt(f)
810
5579
            }
811
        }
812
    };
813
}
814

            
815
#[macro_export]
816
macro_rules! impl_vec_partialord {
817
    ($struct_type:ident, $struct_name:ident) => {
818
        impl PartialOrd for $struct_name {
819
36
            fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
820
36
                self.as_ref().partial_cmp(rhs.as_ref())
821
36
            }
822
        }
823
    };
824
}
825

            
826
#[macro_export]
827
macro_rules! impl_vec_ord {
828
    ($struct_type:ident, $struct_name:ident) => {
829
        impl Ord for $struct_name {
830
41
            fn cmp(&self, rhs: &Self) -> core::cmp::Ordering {
831
41
                self.as_ref().cmp(rhs.as_ref())
832
41
            }
833
        }
834
    };
835
}
836

            
837
#[macro_export]
838
macro_rules! impl_vec_clone {
839
    ($struct_type:ident, $struct_name:ident, $destructor_name:ident) => {
840
        impl $struct_name {
841
            // Creates a `Vec` from a `Cow<'static, [T]>` - useful to avoid allocating in the case
842
            // of &'static memory
843
            #[inline]
844
            #[must_use] pub fn from_copy_on_write(
845
                input: alloc::borrow::Cow<'static, [$struct_type]>,
846
            ) -> $struct_name {
847
                match input {
848
                    alloc::borrow::Cow::Borrowed(static_array) => {
849
                        Self::from_const_slice(static_array)
850
                    }
851
                    alloc::borrow::Cow::Owned(owned_vec) => Self::from_vec(owned_vec),
852
                }
853
            }
854

            
855
            /// Creates a Vec containing a single element
856
            #[inline]
857
17
            #[must_use] pub fn from_item(item: $struct_type) -> Self {
858
17
                Self::from_vec(alloc::vec![item])
859
17
            }
860

            
861
            /// Copies elements from a C array pointer into a new Vec.
862
            /// 
863
            /// # Safety
864
            /// - `ptr` must be valid for reading `len` elements
865
            /// - The memory must be properly aligned for `$struct_type`
866
            /// - The elements are cloned, so `$struct_type` must implement `Clone`
867
            #[inline]
868
            #[must_use] pub unsafe fn copy_from_ptr(ptr: *const $struct_type, len: usize) -> Self { unsafe {
869
                if ptr.is_null() || len == 0 {
870
                    return Self::new();
871
                }
872
                let slice = core::slice::from_raw_parts(ptr, len);
873
                Self::from_vec(slice.to_vec())
874
            }}
875

            
876
            /// NOTE: CLONES the memory if the memory is external or &'static
877
            /// Moves the memory out if the memory is library-allocated
878
            #[inline]
879
20670084
            #[must_use] pub fn clone_self(&self) -> Self {
880
20670084
                match self.destructor {
881
14322990
                    $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => Self {
882
14322990
                        ptr: self.ptr,
883
14322990
                        len: self.len,
884
14322990
                        cap: self.cap,
885
14322990
                        destructor: $destructor_name::NoDestructor,
886
14322990
                    },
887
                    $destructor_name::External(_) | $destructor_name::DefaultRust => {
888
6347094
                        Self::from_vec(self.as_ref().to_vec())
889
                    }
890
                }
891
20670084
            }
892

            
893
            /// NOTE: CLONES the memory if the memory is external or &'static
894
            /// Moves the memory out if the memory is library-allocated
895
            #[inline]
896
2641114
            #[must_use] pub fn into_library_owned_vec(self) -> alloc::vec::Vec<$struct_type> {
897
2641114
                match self.destructor {
898
                    $destructor_name::NoDestructor | $destructor_name::External(_) | $destructor_name::AlreadyDestroyed => {
899
1304649
                        self.as_ref().to_vec()
900
                    }
901
                    $destructor_name::DefaultRust => {
902
1336465
                        let v = unsafe {
903
1336465
                            alloc::vec::Vec::from_raw_parts(
904
1336465
                                self.ptr.cast_mut(),
905
1336465
                                self.len,
906
1336465
                                self.cap,
907
                            )
908
                        };
909
1336465
                        core::mem::forget(self);
910
1336465
                        v
911
                    }
912
                }
913
2641114
            }
914
        }
915
        impl Clone for $struct_name {
916
17523304
            fn clone(&self) -> Self {
917
17523304
                self.clone_self()
918
17523304
            }
919
        }
920
    };
921
}
922

            
923
#[macro_export]
924
macro_rules! impl_vec_partialeq {
925
    ($struct_type:ident, $struct_name:ident) => {
926
        impl PartialEq for $struct_name {
927
1903211
            fn eq(&self, rhs: &Self) -> bool {
928
1903211
                self.as_ref().eq(rhs.as_ref())
929
1903211
            }
930
        }
931
    };
932
}
933

            
934
#[macro_export]
935
macro_rules! impl_vec_eq {
936
    ($struct_type:ident, $struct_name:ident) => {
937
        impl Eq for $struct_name {}
938
    };
939
}
940

            
941
#[macro_export]
942
macro_rules! impl_vec_hash {
943
    ($struct_type:ident, $struct_name:ident) => {
944
        impl core::hash::Hash for $struct_name {
945
209941
            fn hash<H>(&self, state: &mut H)
946
209941
            where
947
209941
                H: core::hash::Hasher,
948
            {
949
209941
                self.as_ref().hash(state);
950
209941
            }
951
        }
952
    };
953
}
954

            
955
#[macro_export]
956
macro_rules! impl_option_inner {
957
    ($struct_type:ident, $struct_name:ident) => {
958
        impl From<$struct_name> for Option<$struct_type> {
959
140
            fn from(o: $struct_name) -> Option<$struct_type> {
960
140
                match o {
961
69
                    $struct_name::None => None,
962
71
                    $struct_name::Some(t) => Some(t),
963
                }
964
140
            }
965
        }
966

            
967
        impl From<Option<$struct_type>> for $struct_name {
968
1976460
            fn from(o: Option<$struct_type>) -> $struct_name {
969
1976460
                match o {
970
1663901
                    None => $struct_name::None,
971
312559
                    Some(t) => $struct_name::Some(t),
972
                }
973
1976460
            }
974
        }
975

            
976
        impl Default for $struct_name {
977
2780898
            fn default() -> $struct_name {
978
2780898
                $struct_name::None
979
2780898
            }
980
        }
981

            
982
        impl $struct_name {
983
902
            #[must_use] pub const fn as_option(&self) -> Option<&$struct_type> {
984
902
                match self {
985
317
                    $struct_name::None => None,
986
585
                    $struct_name::Some(t) => Some(t),
987
                }
988
902
            }
989
            // Returns the PREVIOUS value (mem::replace semantics); callers may discard it,
990
            // so #[must_use] would be wrong here.
991
            #[allow(clippy::return_self_not_must_use)]
992
19
            pub const fn replace(&mut self, value: $struct_type) -> $struct_name {
993
19
                ::core::mem::replace(self, $struct_name::Some(value))
994
19
            }
995
27743
            #[must_use] pub const fn is_some(&self) -> bool {
996
27743
                match self {
997
27017
                    $struct_name::None => false,
998
726
                    $struct_name::Some(_) => true,
999
                }
27743
            }
736
            #[must_use] pub const fn is_none(&self) -> bool {
736
                !self.is_some()
736
            }
48951
            #[must_use] pub const fn as_ref(&self) -> Option<&$struct_type> {
48951
                match *self {
38844
                    $struct_name::Some(ref x) => Some(x),
10107
                    $struct_name::None => None,
                }
48951
            }
1620
            pub const fn as_mut(&mut self) -> Option<&mut $struct_type> {
1620
                match self {
205
                    $struct_name::Some(x) => Some(x),
1415
                    $struct_name::None => None,
                }
1620
            }
40
            pub fn map<U, F: FnOnce($struct_type) -> U>(self, f: F) -> Option<U> {
40
                match self {
35
                    $struct_name::Some(x) => Some(f(x)),
5
                    $struct_name::None => None,
                }
40
            }
13
            pub fn and_then<U, F>(self, f: F) -> Option<U>
13
            where
13
                F: FnOnce($struct_type) -> Option<U>,
            {
13
                match self {
3
                    $struct_name::None => None,
10
                    $struct_name::Some(x) => f(x),
                }
13
            }
        }
    };
}
#[macro_export]
macro_rules! impl_option {
    ($struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
        $(#[derive($derive)])*
        #[repr(C, u8)]
        pub enum $struct_name {
            None,
            Some($struct_type)
        }
        impl $struct_name {
            pub fn into_option(self) -> Option<$struct_type> {
                match self {
                    $struct_name::None => None,
                    $struct_name::Some(t) => Some(t),
                }
            }
        }
        impl_option_inner!($struct_type, $struct_name);
    );
    ($struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
        $(#[derive($derive)])*
        #[repr(C, u8)]
        // This arm (copy = false) deliberately does NOT derive Copy so the
        // wrapper can hold non-Copy payloads; missing_copy_implementations is a
        // false positive for the Copy-payload instantiations routed through here.
        #[allow(missing_copy_implementations, variant_size_differences)]
        pub enum $struct_name {
            None,
            Some($struct_type)
        }
        impl $struct_name {
42707
            #[must_use] pub fn into_option(&self) -> Option<$struct_type> {
42707
                match self {
40966
                    $struct_name::None => None,
1741
                    $struct_name::Some(t) => Some(t.clone()),
                }
42707
            }
        }
        impl_option_inner!($struct_type, $struct_name);
    );
    ($struct_type:ident, $struct_name:ident, [$($derive:meta),* ]) => (
        $(#[derive($derive)])*
        #[repr(C, u8)]
        // This (default) arm does NOT derive Copy so the wrapper can hold
        // non-Copy payloads; missing_copy_implementations is a false positive
        // for the Copy-payload instantiations routed through here.
        #[allow(missing_copy_implementations, variant_size_differences)]
        pub enum $struct_name {
            None,
            Some($struct_type)
        }
        impl $struct_name {
94779
            #[must_use] pub fn into_option(&self) -> Option<$struct_type> {
94779
                match self {
8009
                    $struct_name::None => None,
86770
                    $struct_name::Some(t) => Some(t.clone()),
                }
94779
            }
        }
        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> {
2
            fn from(o: $struct_name) -> Result<$ok_struct_type, $err_struct_type> {
2
                match o {
1
                    $struct_name::Ok(o) => Ok(o),
1
                    $struct_name::Err(e) => Err(e),
                }
2
            }
        }
        impl From<Result<$ok_struct_type, $err_struct_type>> for $struct_name {
32
            fn from(o: Result<$ok_struct_type, $err_struct_type>) -> $struct_name {
32
                match o {
29
                    Ok(o) => $struct_name::Ok(o),
3
                    Err(e) => $struct_name::Err(e),
                }
32
            }
        }
        impl $struct_name {
26
            pub fn as_result(&self) -> Result<&$ok_struct_type, &$err_struct_type> {
26
                match self {
3
                    $struct_name::Ok(o) => Ok(o),
23
                    $struct_name::Err(e) => Err(e),
                }
26
            }
299
            pub fn is_ok(&self) -> bool {
299
                match self {
7
                    $struct_name::Ok(_) => true,
292
                    $struct_name::Err(_) => false,
                }
299
            }
292
            pub fn is_err(&self) -> bool {
292
                !self.is_ok()
292
            }
        }
    };
}
#[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 {
4
            pub fn into_result(self) -> Result<$ok_struct_type, $err_struct_type> {
4
                match self {
2
                    $struct_name::Ok(o) => Ok(o),
2
                    $struct_name::Err(e) => Err(e),
                }
4
            }
        }
        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 {
3
        fn format_as_rust_code(&self, _tabs: usize) -> String {
3
            match self {
                $(
                    $enum_name::$enum_type => {
1
                        String::from(
                            concat!(stringify!($enum_name), "::", stringify!($enum_type))
                        )
                    },
                )+
            }
3
        }
    }
)}