Skip to main content

bump_scope/features/
bytemuck_or_zerocopy.rs

1macro_rules! bytemuck_or_zerocopy {
2    (
3        crate $name:literal
4        mod $mod:ident
5        trait $trait:ident
6    ) => {
7        #[doc = concat!("Extension traits for zero-initializable types using [`", $name, "::", stringify!($trait), "`](::", stringify!($mod), "::", stringify!($trait), ").")]
8        pub mod $mod {
9            use core::mem::MaybeUninit;
10
11            use ::$mod::$trait;
12
13            use crate::{
14                BumpBox, BumpVec, ErrorBehavior, FixedBumpVec, MutBumpVec, MutBumpVecRev,
15                alloc::AllocError,
16                traits::{BumpAllocatorTyped, BumpAllocatorTypedScope, MutBumpAllocatorTyped},
17            };
18
19            #[cfg(feature = "panic-on-alloc")]
20            use crate::panic_on_error;
21
22            mod init_zeroed {
23                use super::*;
24
25                pub trait Sealed {}
26
27                impl<T: $trait> Sealed for BumpBox<'_, MaybeUninit<T>> {}
28                impl<T: $trait> Sealed for BumpBox<'_, [MaybeUninit<T>]> {}
29            }
30
31            /// Extension trait for [`BumpBox`] that adds the `init_zeroed` method.
32            pub trait InitZeroed<'a>: init_zeroed::Sealed {
33                /// The initialized type.
34                type Output: ?Sized;
35
36                /// Initializes `self` by filling it with zero.
37                ///
38                /// # Examples
39                ///
40                /// ```
41                #[doc = concat!("use bump_scope::{Bump, ", stringify!($mod), "::InitZeroed};")]
42                ///
43                /// let bump: Bump = Bump::new();
44                ///
45                /// // single value
46                /// let uninit = bump.alloc_uninit::<i32>();
47                /// let init = uninit.init_zeroed();
48                /// assert_eq!(*init, 0);
49                ///
50                /// // slice
51                /// let uninit = bump.alloc_uninit_slice::<i32>(10);
52                /// let init = uninit.init_zeroed();
53                /// assert_eq!(*init, [0; 10]);
54                /// ```
55                #[must_use]
56                fn init_zeroed(self) -> BumpBox<'a, Self::Output>;
57            }
58
59            impl<'a, T: $trait> InitZeroed<'a> for BumpBox<'a, MaybeUninit<T>> {
60                type Output = T;
61
62                #[inline]
63                fn init_zeroed(mut self) -> BumpBox<'a, T> {
64                    unsafe {
65                        self.as_mut_ptr().write_bytes(0, 1);
66                        self.assume_init()
67                    }
68                }
69            }
70
71            impl<'a, T: $trait> InitZeroed<'a> for BumpBox<'a, [MaybeUninit<T>]> {
72                type Output = [T];
73
74                #[inline]
75                fn init_zeroed(mut self) -> BumpBox<'a, [T]> {
76                    unsafe {
77                        let len = self.len();
78                        self.as_mut_ptr().write_bytes(0, len);
79                        self.assume_init()
80                    }
81                }
82            }
83
84            /// Extension trait for [`BumpAllocatorTypedScope`] that adds the `(try_)alloc_zeroed(_slice)` methods.
85            pub trait BumpAllocatorTypedScopeExt<'a>: BumpAllocatorTypedScope<'a> {
86                /// Allocate a zeroed object.
87                ///
88                /// # Panics
89                /// Panics if the allocation fails.
90                ///
91                /// # Examples
92                /// ```
93                #[doc = concat!("use bump_scope::{Bump, ", stringify!($mod), "::BumpAllocatorTypedScopeExt};")]
94                /// let bump: Bump = Bump::new();
95                ///
96                /// let zero = bump.as_scope().alloc_zeroed::<i32>();
97                /// assert_eq!(*zero, 0);
98                /// ```
99                #[inline(always)]
100                #[cfg(feature = "panic-on-alloc")]
101                fn alloc_zeroed<T>(&self) -> BumpBox<'a, T>
102                where
103                    T: $trait,
104                {
105                    self.alloc_uninit().init_zeroed()
106                }
107
108                /// Allocate a zeroed object.
109                ///
110                /// # Errors
111                /// Errors if the allocation fails.
112                ///
113                /// # Examples
114                /// ```
115                #[doc = concat!("use bump_scope::{Bump, ", stringify!($mod), "::BumpAllocatorTypedScopeExt};")]
116                /// let bump: Bump = Bump::new();
117                ///
118                /// let zero = bump.as_scope().try_alloc_zeroed::<i32>()?;
119                /// assert_eq!(*zero, 0);
120                /// # Ok::<(), bump_scope::alloc::AllocError>(())
121                /// ```
122                #[inline(always)]
123                fn try_alloc_zeroed<T>(&self) -> Result<BumpBox<'a, T>, AllocError>
124                where
125                    T: $trait,
126                {
127                    Ok(self.try_alloc_uninit()?.init_zeroed())
128                }
129
130                /// Allocate a zeroed object slice.
131                ///
132                /// # Panics
133                /// Panics if the allocation fails.
134                ///
135                /// # Examples
136                /// ```
137                #[doc = concat!("use bump_scope::{Bump, ", stringify!($mod), "::BumpAllocatorTypedScopeExt};")]
138                /// let bump: Bump = Bump::new();
139                ///
140                /// let zeroes = bump.as_scope().alloc_zeroed_slice::<i32>(3);
141                /// assert_eq!(*zeroes, [0; 3]);
142                /// ```
143                #[cfg(feature = "panic-on-alloc")]
144                fn alloc_zeroed_slice<T>(&self, len: usize) -> BumpBox<'a, [T]>
145                where
146                    T: $trait,
147                {
148                    self.alloc_uninit_slice(len).init_zeroed()
149                }
150
151                /// Allocate a zeroed object slice.
152                ///
153                /// # Errors
154                /// Errors if the allocation fails.
155                ///
156                /// # Examples
157                /// ```
158                #[doc = concat!("use bump_scope::{Bump, ", stringify!($mod), "::BumpAllocatorTypedScopeExt};")]
159                /// let bump: Bump = Bump::new();
160                ///
161                /// let zeroes = bump.as_scope().try_alloc_zeroed_slice::<i32>(3)?;
162                /// assert_eq!(*zeroes, [0; 3]);
163                /// # Ok::<(), bump_scope::alloc::AllocError>(())
164                /// ```
165                fn try_alloc_zeroed_slice<T>(&self, len: usize) -> Result<BumpBox<'a, [T]>, AllocError>
166                where
167                    T: $trait,
168                {
169                    Ok(self.try_alloc_uninit_slice(len)?.init_zeroed())
170                }
171            }
172
173            impl<'a, T> BumpAllocatorTypedScopeExt<'a> for T where T: BumpAllocatorTypedScope<'a> {}
174
175            mod vec_ext {
176                use super::*;
177
178                pub trait Sealed {}
179
180                impl<T> Sealed for FixedBumpVec<'_, T> {}
181                impl<T, A: BumpAllocatorTyped> Sealed for BumpVec<T, A> {}
182                impl<T, A: MutBumpAllocatorTyped> Sealed for MutBumpVec<T, A> {}
183                impl<T, A: MutBumpAllocatorTyped> Sealed for MutBumpVecRev<T, A> {}
184            }
185
186            /// Extension trait for this crate's vector types.
187            pub trait VecExt: vec_ext::Sealed {
188                /// The element type of this vector.
189                type T;
190
191                /// Extends this vector by pushing `additional` new items onto the end.
192                /// The new items are initialized with zeroes.
193                ///
194                /// # Panics
195                /// Panics if the allocation fails.
196                ///
197                /// # Examples
198                /// ```
199                #[doc = concat!("use bump_scope::{Bump, bump_vec, ", stringify!($mod), "::VecExt};")]
200                ///
201                /// let bump: Bump = Bump::new();
202                ///
203                /// let mut vec = bump_vec![in &bump; 1, 2, 3];
204                /// vec.extend_zeroed(2);
205                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
206                /// ```
207                #[cfg(feature = "panic-on-alloc")]
208                fn extend_zeroed(&mut self, additional: usize)
209                where
210                    Self::T: $trait;
211
212                /// Extends this vector by pushing `additional` new items onto the end.
213                /// The new items are initialized with zeroes.
214                ///
215                /// # Errors
216                /// Errors if the allocation fails.
217                ///
218                /// # Examples
219                /// ```
220                #[doc = concat!("use bump_scope::{Bump, bump_vec, ", stringify!($mod), "::VecExt};")]
221                ///
222                /// let bump: Bump = Bump::new();
223                ///
224                /// let mut vec = bump_vec![try in &bump; 1, 2, 3]?;
225                /// vec.try_extend_zeroed(2)?;
226                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
227                /// # Ok::<(), bump_scope::alloc::AllocError>(())
228                /// ```
229                fn try_extend_zeroed(&mut self, additional: usize) -> Result<(), AllocError>
230                where
231                    Self::T: $trait;
232
233                /// Resizes this vector in-place so that `len` is equal to `new_len`.
234                ///
235                /// If `new_len` is greater than `len`, the vector is extended by the
236                /// difference, with each additional slot filled with `value`.
237                /// If `new_len` is less than `len`, the vector is simply truncated.
238                ///
239                /// # Panics
240                /// Panics if the allocation fails.
241                ///
242                /// # Examples
243                /// ```
244                #[doc = concat!("use bump_scope::{Bump, bump_vec, ", stringify!($mod), "::VecExt};")]
245                ///
246                /// let bump: Bump = Bump::new();
247                ///
248                /// let mut vec = bump_vec![in &bump; 1, 2, 3];
249                /// vec.resize_zeroed(5);
250                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
251                ///
252                /// let mut vec = bump_vec![in &bump; 1, 2, 3];
253                /// vec.resize_zeroed(2);
254                /// assert_eq!(vec, [1, 2]);
255                /// ```
256                #[cfg(feature = "panic-on-alloc")]
257                fn resize_zeroed(&mut self, new_len: usize)
258                where
259                    Self::T: $trait;
260
261                /// Resizes this vector in-place so that `len` is equal to `new_len`.
262                ///
263                /// If `new_len` is greater than `len`, the vector is extended by the
264                /// difference, with each additional slot filled with `value`.
265                /// If `new_len` is less than `len`, the vector is simply truncated.
266                ///
267                /// # Errors
268                /// Errors if the allocation fails.
269                ///
270                /// # Examples
271                /// ```
272                #[doc = concat!("use bump_scope::{Bump, bump_vec, ", stringify!($mod), "::VecExt};")]
273                ///
274                /// let bump: Bump = Bump::new();
275                ///
276                /// let mut vec = bump_vec![try in &bump; 1, 2, 3]?;
277                /// vec.try_resize_zeroed(5)?;
278                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
279                ///
280                /// let mut vec = bump_vec![try in &bump; 1, 2, 3]?;
281                /// vec.try_resize_zeroed(2)?;
282                /// assert_eq!(vec, [1, 2]);
283                /// # Ok::<(), bump_scope::alloc::AllocError>(())
284                /// ```
285                fn try_resize_zeroed(&mut self, new_len: usize) -> Result<(), AllocError>
286                where
287                    Self::T: $trait;
288            }
289
290            impl<T> VecExt for FixedBumpVec<'_, T> {
291                type T = T;
292
293                /// Extends this vector by pushing `additional` new items onto the end.
294                /// The new items are initialized with zeroes.
295                ///
296                /// # Panics
297                /// Panics if the vector does not have enough capacity.
298                ///
299                /// # Examples
300                /// ```
301                #[doc = concat!("use bump_scope::{Bump, FixedBumpVec, ", stringify!($mod), "::VecExt};")]
302                ///
303                /// let bump: Bump = Bump::new();
304                ///
305                /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
306                /// vec.extend_from_slice_copy(&[1, 2, 3]);
307                /// vec.extend_zeroed(2);
308                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
309                /// ```
310                #[inline(always)]
311                #[cfg(feature = "panic-on-alloc")]
312                fn extend_zeroed(&mut self, additional: usize)
313                where
314                    Self::T: $trait,
315                {
316                    panic_on_error(self.generic_extend_zeroed(additional));
317                }
318
319                /// Extends this vector by pushing `additional` new items onto the end.
320                /// The new items are initialized with zeroes.
321                ///
322                /// # Errors
323                /// Errors if the vector does not have enough capacity.
324                ///
325                /// # Examples
326                /// ```
327                #[doc = concat!("use bump_scope::{Bump, FixedBumpVec, ", stringify!($mod), "::VecExt};")]
328                ///
329                /// let bump: Bump = Bump::new();
330                ///
331                /// let mut vec = FixedBumpVec::try_with_capacity_in(5, &bump)?;
332                /// vec.try_extend_from_slice_copy(&[1, 2, 3])?;
333                /// vec.try_extend_zeroed(2)?;
334                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
335                /// # Ok::<(), bump_scope::alloc::AllocError>(())
336                /// ```
337                #[inline(always)]
338                fn try_extend_zeroed(&mut self, additional: usize) -> Result<(), AllocError>
339                where
340                    Self::T: $trait,
341                {
342                    self.generic_extend_zeroed(additional)
343                }
344
345                /// Resizes this vector in-place so that `len` is equal to `new_len`.
346                ///
347                /// If `new_len` is greater than `len`, the vector is extended by the
348                /// difference, with each additional slot filled with `value`.
349                /// If `new_len` is less than `len`, the vector is simply truncated.
350                ///
351                /// # Panics
352                /// Panics if the vector does not have enough capacity.
353                ///
354                /// # Examples
355                /// ```
356                #[doc = concat!("use bump_scope::{Bump, FixedBumpVec, ", stringify!($mod), "::VecExt};")]
357                ///
358                /// let bump: Bump = Bump::new();
359                ///
360                /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
361                /// vec.extend_from_slice_copy(&[1, 2, 3]);
362                /// vec.resize_zeroed(5);
363                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
364                ///
365                /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
366                /// vec.extend_from_slice_copy(&[1, 2, 3]);
367                /// vec.resize_zeroed(2);
368                /// assert_eq!(vec, [1, 2]);
369                /// ```
370                #[inline(always)]
371                #[cfg(feature = "panic-on-alloc")]
372                fn resize_zeroed(&mut self, new_len: usize)
373                where
374                    T: $trait,
375                {
376                    panic_on_error(self.generic_resize_zeroed(new_len));
377                }
378
379                /// Resizes this vector in-place so that `len` is equal to `new_len`.
380                ///
381                /// If `new_len` is greater than `len`, the vector is extended by the
382                /// difference, with each additional slot filled with `value`.
383                /// If `new_len` is less than `len`, the vector is simply truncated.
384                ///
385                /// # Errors
386                /// Errors if the vector does not have enough capacity.
387                ///
388                /// # Examples
389                /// ```
390                #[doc = concat!("use bump_scope::{Bump, FixedBumpVec, ", stringify!($mod), "::VecExt};")]
391                ///
392                /// let bump: Bump = Bump::new();
393                ///
394                /// let mut vec = FixedBumpVec::try_with_capacity_in(5, &bump)?;
395                /// vec.try_extend_from_slice_copy(&[1, 2, 3])?;
396                /// vec.try_resize_zeroed(5)?;
397                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
398                ///
399                /// let mut vec = FixedBumpVec::try_with_capacity_in(5, &bump)?;
400                /// vec.try_extend_from_slice_copy(&[1, 2, 3])?;
401                /// vec.try_resize_zeroed(2)?;
402                /// assert_eq!(vec, [1, 2]);
403                /// # Ok::<(), bump_scope::alloc::AllocError>(())
404                /// ```
405                #[inline(always)]
406                fn try_resize_zeroed(&mut self, new_len: usize) -> Result<(), AllocError>
407                where
408                    Self::T: $trait,
409                {
410                    self.generic_resize_zeroed(new_len)
411                }
412            }
413
414            impl<T, A: BumpAllocatorTyped> VecExt for BumpVec<T, A> {
415                type T = T;
416
417                /// Extends this vector by pushing `additional` new items onto the end.
418                /// The new items are initialized with zeroes.
419                ///
420                /// # Panics
421                /// Panics if the allocation fails.
422                ///
423                /// # Examples
424                /// ```
425                #[doc = concat!("use bump_scope::{Bump, bump_vec, ", stringify!($mod), "::VecExt};")]
426                ///
427                /// let bump: Bump = Bump::new();
428                ///
429                /// let mut vec = bump_vec![in &bump; 1, 2, 3];
430                /// vec.extend_zeroed(2);
431                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
432                /// ```
433                #[inline(always)]
434                #[cfg(feature = "panic-on-alloc")]
435                fn extend_zeroed(&mut self, additional: usize)
436                where
437                    Self::T: $trait,
438                {
439                    panic_on_error(self.generic_extend_zeroed(additional));
440                }
441
442                /// Extends this vector by pushing `additional` new items onto the end.
443                /// The new items are initialized with zeroes.
444                ///
445                /// # Errors
446                /// Errors if the allocation fails.
447                ///
448                /// # Examples
449                /// ```
450                #[doc = concat!("use bump_scope::{Bump, bump_vec, ", stringify!($mod), "::VecExt};")]
451                ///
452                /// let bump: Bump = Bump::new();
453                ///
454                /// let mut vec = bump_vec![try in &bump; 1, 2, 3]?;
455                /// vec.try_extend_zeroed(2)?;
456                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
457                /// # Ok::<(), bump_scope::alloc::AllocError>(())
458                /// ```
459                #[inline(always)]
460                fn try_extend_zeroed(&mut self, additional: usize) -> Result<(), AllocError>
461                where
462                    Self::T: $trait,
463                {
464                    self.generic_extend_zeroed(additional)
465                }
466
467                /// Resizes this vector in-place so that `len` is equal to `new_len`.
468                ///
469                /// If `new_len` is greater than `len`, the vector is extended by the
470                /// difference, with each additional slot filled with `value`.
471                /// If `new_len` is less than `len`, the vector is simply truncated.
472                ///
473                /// # Panics
474                /// Panics if the allocation fails.
475                ///
476                /// # Examples
477                /// ```
478                #[doc = concat!("use bump_scope::{Bump, bump_vec, ", stringify!($mod), "::VecExt};")]
479                ///
480                /// let bump: Bump = Bump::new();
481                ///
482                /// let mut vec = bump_vec![in &bump; 1, 2, 3];
483                /// vec.resize_zeroed(5);
484                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
485                ///
486                /// let mut vec = bump_vec![in &bump; 1, 2, 3];
487                /// vec.resize_zeroed(2);
488                /// assert_eq!(vec, [1, 2]);
489                /// ```
490                #[inline(always)]
491                #[cfg(feature = "panic-on-alloc")]
492                fn resize_zeroed(&mut self, new_len: usize)
493                where
494                    Self::T: $trait,
495                {
496                    panic_on_error(self.generic_resize_zeroed(new_len));
497                }
498
499                /// Resizes this vector in-place so that `len` is equal to `new_len`.
500                ///
501                /// If `new_len` is greater than `len`, the vector is extended by the
502                /// difference, with each additional slot filled with `value`.
503                /// If `new_len` is less than `len`, the vector is simply truncated.
504                ///
505                /// # Errors
506                /// Errors if the allocation fails.
507                ///
508                /// # Examples
509                /// ```
510                #[doc = concat!("use bump_scope::{Bump, bump_vec, ", stringify!($mod), "::VecExt};")]
511                ///
512                /// let bump: Bump = Bump::new();
513                ///
514                /// let mut vec = bump_vec![try in &bump; 1, 2, 3]?;
515                /// vec.try_resize_zeroed(5)?;
516                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
517                ///
518                /// let mut vec = bump_vec![try in &bump; 1, 2, 3]?;
519                /// vec.try_resize_zeroed(2)?;
520                /// assert_eq!(vec, [1, 2]);
521                /// # Ok::<(), bump_scope::alloc::AllocError>(())
522                /// ```
523                #[inline(always)]
524                fn try_resize_zeroed(&mut self, new_len: usize) -> Result<(), AllocError>
525                where
526                    T: $trait,
527                {
528                    self.generic_resize_zeroed(new_len)
529                }
530            }
531
532            impl<T, A: MutBumpAllocatorTyped> VecExt for MutBumpVec<T, A> {
533                type T = T;
534
535                /// Extends this vector by pushing `additional` new items onto the end.
536                /// The new items are initialized with zeroes.
537                ///
538                /// # Panics
539                /// Panics if the allocation fails.
540                ///
541                /// # Examples
542                /// ```
543                #[doc = concat!("use bump_scope::{Bump, mut_bump_vec, ", stringify!($mod), "::VecExt};")]
544                ///
545                /// let mut bump: Bump = Bump::new();
546                ///
547                /// let mut vec = mut_bump_vec![in &mut bump; 1, 2, 3];
548                /// vec.extend_zeroed(2);
549                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
550                /// ```
551                #[inline(always)]
552                #[cfg(feature = "panic-on-alloc")]
553                fn extend_zeroed(&mut self, additional: usize)
554                where
555                    Self::T: $trait,
556                {
557                    panic_on_error(self.generic_extend_zeroed(additional));
558                }
559
560                /// Extends this vector by pushing `additional` new items onto the end.
561                /// The new items are initialized with zeroes.
562                ///
563                /// # Errors
564                /// Errors if the allocation fails.
565                ///
566                /// # Examples
567                /// ```
568                #[doc = concat!("use bump_scope::{Bump, mut_bump_vec, ", stringify!($mod), "::VecExt};")]
569                ///
570                /// let mut bump: Bump = Bump::new();
571                ///
572                /// let mut vec = mut_bump_vec![try in &mut bump; 1, 2, 3]?;
573                /// vec.try_extend_zeroed(2)?;
574                /// assert_eq!(vec, [1, 2, 3, 0, 0]);
575                /// # Ok::<(), bump_scope::alloc::AllocError>(())
576                /// ```
577                #[inline(always)]
578                fn try_extend_zeroed(&mut self, additional: usize) -> Result<(), AllocError>
579                where
580                    Self::T: $trait,
581                {
582                    self.generic_extend_zeroed(additional)
583                }
584
585                /// Resizes this vector in-place so that `len` is equal to `new_len`.
586                ///
587                /// If `new_len` is greater than `len`, the vector is extended by the
588                /// difference, with each additional slot filled with `value`.
589                /// If `new_len` is less than `len`, the vector is simply truncated.
590                ///
591                /// # Panics
592                /// Panics if the allocation fails.
593                ///
594                /// # Examples
595                /// ```
596                #[doc = concat!("use bump_scope::{Bump, mut_bump_vec, ", stringify!($mod), "::VecExt};")]
597                ///
598                /// let mut bump: Bump = Bump::new();
599                ///
600                /// {
601                ///     let mut vec = mut_bump_vec![in &mut bump; 1, 2, 3];
602                ///     vec.resize_zeroed(5);
603                ///     assert_eq!(vec, [1, 2, 3, 0, 0]);
604                /// }
605                ///
606                /// {
607                ///    let mut vec = mut_bump_vec![in &mut bump; 1, 2, 3];
608                ///    vec.resize_zeroed(2);
609                ///    assert_eq!(vec, [1, 2]);
610                /// }
611                /// ```
612                #[inline(always)]
613                #[cfg(feature = "panic-on-alloc")]
614                fn resize_zeroed(&mut self, new_len: usize)
615                where
616                    Self::T: $trait,
617                {
618                    panic_on_error(self.generic_resize_zeroed(new_len));
619                }
620
621                /// Resizes this vector in-place so that `len` is equal to `new_len`.
622                ///
623                /// If `new_len` is greater than `len`, the vector is extended by the
624                /// difference, with each additional slot filled with `value`.
625                /// If `new_len` is less than `len`, the vector is simply truncated.
626                ///
627                /// # Errors
628                /// Errors if the allocation fails.
629                ///
630                /// # Examples
631                /// ```
632                #[doc = concat!("use bump_scope::{Bump, mut_bump_vec, ", stringify!($mod), "::VecExt};")]
633                ///
634                /// let mut bump: Bump = Bump::new();
635                ///
636                /// {
637                ///     let mut vec = mut_bump_vec![try in &mut bump; 1, 2, 3]?;
638                ///     vec.try_resize_zeroed(5)?;
639                ///     assert_eq!(vec, [1, 2, 3, 0, 0]);
640                /// }
641                ///
642                /// {
643                ///    let mut vec = mut_bump_vec![try in &mut bump; 1, 2, 3]?;
644                ///    vec.try_resize_zeroed(2)?;
645                ///    assert_eq!(vec, [1, 2]);
646                /// }
647                /// # Ok::<(), bump_scope::alloc::AllocError>(())
648                /// ```
649                #[inline(always)]
650                fn try_resize_zeroed(&mut self, new_len: usize) -> Result<(), AllocError>
651                where
652                    Self::T: $trait,
653                {
654                    self.generic_resize_zeroed(new_len)
655                }
656            }
657
658            impl<T, A: MutBumpAllocatorTyped> VecExt for MutBumpVecRev<T, A> {
659                type T = T;
660
661                /// Extends this vector by pushing `additional` new items onto the end.
662                /// The new items are initialized with zeroes.
663                ///
664                /// # Panics
665                /// Panics if the allocation fails.
666                ///
667                /// # Examples
668                /// ```
669                #[doc = concat!("use bump_scope::{Bump, mut_bump_vec_rev, ", stringify!($mod), "::VecExt};")]
670                ///
671                /// let mut bump: Bump = Bump::new();
672                ///
673                /// let mut vec = mut_bump_vec_rev![in &mut bump; 1, 2, 3];
674                /// vec.extend_zeroed(2);
675                /// assert_eq!(vec, [0, 0, 1, 2, 3]);
676                /// ```
677                #[inline(always)]
678                #[cfg(feature = "panic-on-alloc")]
679                fn extend_zeroed(&mut self, additional: usize)
680                where
681                    T: $trait,
682                {
683                    panic_on_error(self.generic_extend_zeroed(additional));
684                }
685
686                /// Extends this vector by pushing `additional` new items onto the end.
687                /// The new items are initialized with zeroes.
688                ///
689                /// # Errors
690                /// Errors if the allocation fails.
691                ///
692                /// # Examples
693                /// ```
694                #[doc = concat!("use bump_scope::{Bump, mut_bump_vec_rev, ", stringify!($mod), "::VecExt};")]
695                ///
696                /// let mut bump: Bump = Bump::new();
697                ///
698                /// let mut vec = mut_bump_vec_rev![try in &mut bump; 1, 2, 3]?;
699                /// vec.try_extend_zeroed(2)?;
700                /// assert_eq!(vec, [0, 0, 1, 2, 3]);
701                /// # Ok::<(), bump_scope::alloc::AllocError>(())
702                /// ```
703                #[inline(always)]
704                fn try_extend_zeroed(&mut self, additional: usize) -> Result<(), AllocError>
705                where
706                    T: $trait,
707                {
708                    self.generic_extend_zeroed(additional)
709                }
710
711                /// Resizes this vector in-place so that `len` is equal to `new_len`.
712                ///
713                /// If `new_len` is greater than `len`, the vector is extended by the
714                /// difference, with each additional slot filled with `value`.
715                /// If `new_len` is less than `len`, the vector is simply truncated.
716                ///
717                /// # Panics
718                /// Panics if the allocation fails.
719                ///
720                /// # Examples
721                /// ```
722                #[doc = concat!("use bump_scope::{Bump, mut_bump_vec_rev, ", stringify!($mod), "::VecExt};")]
723                ///
724                /// let mut bump: Bump = Bump::new();
725                ///
726                /// {
727                ///     let mut vec = mut_bump_vec_rev![in &mut bump; 1, 2, 3];
728                ///     vec.resize_zeroed(5);
729                ///     assert_eq!(vec, [0, 0, 1, 2, 3]);
730                /// }
731                ///
732                /// {
733                ///     let mut vec = mut_bump_vec_rev![in &mut bump; 1, 2, 3];
734                ///     vec.resize_zeroed(2);
735                ///     assert_eq!(vec, [2, 3]);
736                /// }
737                /// ```
738                #[inline(always)]
739                #[cfg(feature = "panic-on-alloc")]
740                fn resize_zeroed(&mut self, new_len: usize)
741                where
742                    T: $trait,
743                {
744                    panic_on_error(self.generic_resize_zeroed(new_len));
745                }
746
747                /// Resizes this vector in-place so that `len` is equal to `new_len`.
748                ///
749                /// If `new_len` is greater than `len`, the vector is extended by the
750                /// difference, with each additional slot filled with `value`.
751                /// If `new_len` is less than `len`, the vector is simply truncated.
752                ///
753                /// # Errors
754                /// Errors if the allocation fails.
755                ///
756                /// # Examples
757                /// ```
758                #[doc = concat!("use bump_scope::{Bump, mut_bump_vec_rev, ", stringify!($mod), "::VecExt};")]
759                ///
760                /// let mut bump: Bump = Bump::new();
761                ///
762                /// {
763                ///     let mut vec = mut_bump_vec_rev![try in &mut bump; 1, 2, 3]?;
764                ///     vec.try_resize_zeroed(5)?;
765                ///     assert_eq!(vec, [0, 0, 1, 2, 3]);
766                /// }
767                ///
768                /// {
769                ///     let mut vec = mut_bump_vec_rev![try in &mut bump; 1, 2, 3]?;
770                ///     vec.try_resize_zeroed(2)?;
771                ///     assert_eq!(vec, [2, 3]);
772                /// }
773                /// # Ok::<(), bump_scope::alloc::AllocError>(())
774                /// ```
775                #[inline(always)]
776                fn try_resize_zeroed(&mut self, new_len: usize) -> Result<(), AllocError>
777                where
778                    T: $trait,
779                {
780                    self.generic_resize_zeroed(new_len)
781                }
782            }
783
784            trait PrivateVecExt {
785                fn generic_extend_zeroed<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E>;
786                fn generic_resize_zeroed<E: ErrorBehavior>(&mut self, new_len: usize) -> Result<(), E>;
787            }
788
789            impl<T: $trait> PrivateVecExt for FixedBumpVec<'_, T> {
790                #[inline]
791                fn generic_extend_zeroed<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
792                    self.generic_reserve(additional)?;
793
794                    unsafe {
795                        let ptr = self.as_mut_ptr();
796                        let len = self.len();
797
798                        ptr.add(len).write_bytes(0, additional);
799                        self.set_len(len + additional);
800                    }
801
802                    Ok(())
803                }
804
805                #[inline]
806                fn generic_resize_zeroed<E: ErrorBehavior>(&mut self, new_len: usize) -> Result<(), E> {
807                    let len = self.len();
808
809                    if new_len > len {
810                        self.generic_extend_zeroed(new_len - len)
811                    } else {
812                        self.truncate(new_len);
813                        Ok(())
814                    }
815                }
816            }
817
818            impl<T: $trait, A: BumpAllocatorTyped> PrivateVecExt for BumpVec<T, A> {
819                #[inline]
820                fn generic_extend_zeroed<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
821                    self.generic_reserve(additional)?;
822
823                    unsafe {
824                        let ptr = self.as_mut_ptr();
825                        let len = self.len();
826
827                        ptr.add(len).write_bytes(0, additional);
828                        self.set_len(len + additional);
829                    }
830
831                    Ok(())
832                }
833
834                #[inline]
835                fn generic_resize_zeroed<E: ErrorBehavior>(&mut self, new_len: usize) -> Result<(), E> {
836                    let len = self.len();
837
838                    if new_len > len {
839                        self.generic_extend_zeroed(new_len - len)
840                    } else {
841                        self.truncate(new_len);
842                        Ok(())
843                    }
844                }
845            }
846
847            impl<T: $trait, A: MutBumpAllocatorTyped> PrivateVecExt for MutBumpVec<T, A> {
848                #[inline]
849                fn generic_extend_zeroed<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E>
850                where
851                    T: $trait,
852                {
853                    self.generic_reserve(additional)?;
854
855                    unsafe {
856                        let ptr = self.as_mut_ptr();
857                        let len = self.len();
858
859                        ptr.add(len).write_bytes(0, additional);
860                        self.set_len(len + additional);
861                    }
862
863                    Ok(())
864                }
865
866                #[inline]
867                fn generic_resize_zeroed<E: ErrorBehavior>(&mut self, new_len: usize) -> Result<(), E>
868                where
869                    T: $trait,
870                {
871                    let len = self.len();
872
873                    if new_len > len {
874                        self.generic_extend_zeroed(new_len - len)
875                    } else {
876                        self.truncate(new_len);
877                        Ok(())
878                    }
879                }
880            }
881
882            impl<T: $trait, A: MutBumpAllocatorTyped> PrivateVecExt for MutBumpVecRev<T, A> {
883                #[inline]
884                fn generic_extend_zeroed<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
885                    self.generic_reserve(additional)?;
886
887                    unsafe {
888                        let new_len = self.len() + additional;
889                        self.end.sub(new_len).write_bytes(0, additional);
890                        self.set_len(new_len);
891                    }
892
893                    Ok(())
894                }
895
896                #[inline]
897                fn generic_resize_zeroed<E: ErrorBehavior>(&mut self, new_len: usize) -> Result<(), E> {
898                    let len = self.len();
899
900                    if new_len > len {
901                        self.generic_extend_zeroed(new_len - len)
902                    } else {
903                        self.truncate(new_len);
904                        Ok(())
905                    }
906                }
907            }
908        }
909    };
910}
911
912pub(crate) use bytemuck_or_zerocopy;