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 ≎ 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 ≎ 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 ≎ 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 ≎ 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 ≎ 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 ≎ 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 ≎ 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 ≎ 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 ≎ 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 ≎ 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 ≎ 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 ≎ 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;