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