1use core::mem::MaybeUninit;
2
3use zerocopy_08::FromZeros;
4
5use crate::{
6 BaseAllocator, Bump, BumpBox, BumpScope, MinimumAlignment, SupportedMinimumAlignment, alloc::AllocError,
7 error_behavior::ErrorBehavior,
8};
9
10#[cfg(feature = "panic-on-alloc")]
11use crate::panic_on_error;
12
13mod vec_ext;
14
15pub use vec_ext::VecExt;
16
17mod init_zeroed {
18 use super::*;
19
20 pub trait Sealed {}
21
22 impl<T: FromZeros> Sealed for BumpBox<'_, MaybeUninit<T>> {}
23 impl<T: FromZeros> Sealed for BumpBox<'_, [MaybeUninit<T>]> {}
24}
25
26pub trait InitZeroed<'a>: init_zeroed::Sealed {
28 type Output: ?Sized;
30
31 #[must_use]
50 fn init_zeroed(self) -> BumpBox<'a, Self::Output>;
51}
52
53impl<'a, T: FromZeros> InitZeroed<'a> for BumpBox<'a, MaybeUninit<T>> {
54 type Output = T;
55
56 #[inline]
57 fn init_zeroed(mut self) -> BumpBox<'a, T> {
58 unsafe {
59 self.as_mut_ptr().write_bytes(0, 1);
60 self.assume_init()
61 }
62 }
63}
64
65impl<'a, T: FromZeros> InitZeroed<'a> for BumpBox<'a, [MaybeUninit<T>]> {
66 type Output = [T];
67
68 #[inline]
69 fn init_zeroed(mut self) -> BumpBox<'a, [T]> {
70 unsafe {
71 let len = self.len();
72 self.as_mut_ptr().write_bytes(0, len);
73 self.assume_init()
74 }
75 }
76}
77
78mod bump_ext {
79 use super::*;
80
81 pub trait Sealed {}
82
83 impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> Sealed
84 for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
85 where
86 MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
87 A: BaseAllocator<GUARANTEED_ALLOCATED>,
88 {
89 }
90}
91
92mod bump_scope_ext {
93 use super::*;
94
95 pub trait Sealed {}
96
97 impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> Sealed
98 for BumpScope<'_, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
99 where
100 MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
101 A: BaseAllocator<GUARANTEED_ALLOCATED>,
102 {
103 }
104}
105
106pub trait BumpExt: bump_ext::Sealed {
108 #[cfg(feature = "panic-on-alloc")]
122 fn alloc_zeroed<T>(&self) -> BumpBox<'_, T>
123 where
124 T: FromZeros;
125
126 fn try_alloc_zeroed<T>(&self) -> Result<BumpBox<'_, T>, AllocError>
141 where
142 T: FromZeros;
143
144 #[cfg(feature = "panic-on-alloc")]
158 fn alloc_zeroed_slice<T>(&self, len: usize) -> BumpBox<'_, [T]>
159 where
160 T: FromZeros;
161
162 fn try_alloc_zeroed_slice<T>(&self, len: usize) -> Result<BumpBox<'_, [T]>, AllocError>
177 where
178 T: FromZeros;
179}
180
181pub trait BumpScopeExt<'a>: bump_scope_ext::Sealed {
183 #[cfg(feature = "panic-on-alloc")]
199 fn alloc_zeroed<T>(&self) -> BumpBox<'a, T>
200 where
201 T: FromZeros;
202
203 fn try_alloc_zeroed<T>(&self) -> Result<BumpBox<'a, T>, AllocError>
221 where
222 T: FromZeros;
223
224 #[cfg(feature = "panic-on-alloc")]
240 fn alloc_zeroed_slice<T>(&self, len: usize) -> BumpBox<'a, [T]>
241 where
242 T: FromZeros;
243
244 fn try_alloc_zeroed_slice<T>(&self, len: usize) -> Result<BumpBox<'a, [T]>, AllocError>
262 where
263 T: FromZeros;
264}
265
266impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> BumpExt
267 for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
268where
269 MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
270 A: BaseAllocator<GUARANTEED_ALLOCATED>,
271{
272 #[inline(always)]
273 #[cfg(feature = "panic-on-alloc")]
274 fn alloc_zeroed<T>(&self) -> BumpBox<'_, T>
275 where
276 T: FromZeros,
277 {
278 self.as_scope().alloc_zeroed()
279 }
280
281 #[inline(always)]
282 fn try_alloc_zeroed<T>(&self) -> Result<BumpBox<'_, T>, AllocError>
283 where
284 T: FromZeros,
285 {
286 self.as_scope().try_alloc_zeroed()
287 }
288
289 #[inline(always)]
290 #[cfg(feature = "panic-on-alloc")]
291 fn alloc_zeroed_slice<T>(&self, len: usize) -> BumpBox<'_, [T]>
292 where
293 T: FromZeros,
294 {
295 self.as_scope().alloc_zeroed_slice(len)
296 }
297
298 #[inline(always)]
299 fn try_alloc_zeroed_slice<T>(&self, len: usize) -> Result<BumpBox<'_, [T]>, AllocError>
300 where
301 T: FromZeros,
302 {
303 self.as_scope().try_alloc_zeroed_slice(len)
304 }
305}
306
307impl<'a, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool>
308 BumpScopeExt<'a> for BumpScope<'a, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
309where
310 MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
311 A: BaseAllocator<GUARANTEED_ALLOCATED>,
312{
313 #[inline(always)]
314 #[cfg(feature = "panic-on-alloc")]
315 fn alloc_zeroed<T>(&self) -> BumpBox<'a, T>
316 where
317 T: FromZeros,
318 {
319 panic_on_error(self.generic_alloc_zeroed())
320 }
321
322 #[inline(always)]
323 fn try_alloc_zeroed<T>(&self) -> Result<BumpBox<'a, T>, AllocError>
324 where
325 T: FromZeros,
326 {
327 self.generic_alloc_zeroed()
328 }
329
330 #[inline(always)]
331 #[cfg(feature = "panic-on-alloc")]
332 fn alloc_zeroed_slice<T>(&self, len: usize) -> BumpBox<'a, [T]>
333 where
334 T: FromZeros,
335 {
336 panic_on_error(self.generic_alloc_zeroed_slice(len))
337 }
338
339 #[inline(always)]
340 fn try_alloc_zeroed_slice<T>(&self, len: usize) -> Result<BumpBox<'a, [T]>, AllocError>
341 where
342 T: FromZeros,
343 {
344 self.generic_alloc_zeroed_slice(len)
345 }
346}
347
348trait PrivateBumpScopeExt<'a> {
349 fn generic_alloc_zeroed<B: ErrorBehavior, T>(&self) -> Result<BumpBox<'a, T>, B>
350 where
351 T: FromZeros;
352
353 fn generic_alloc_zeroed_slice<B: ErrorBehavior, T>(&self, len: usize) -> Result<BumpBox<'a, [T]>, B>
354 where
355 T: FromZeros;
356}
357
358impl<'a, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool>
359 PrivateBumpScopeExt<'a> for BumpScope<'a, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
360where
361 MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
362 A: BaseAllocator<GUARANTEED_ALLOCATED>,
363{
364 #[inline(always)]
365 fn generic_alloc_zeroed<B: ErrorBehavior, T>(&self) -> Result<BumpBox<'a, T>, B>
366 where
367 T: FromZeros,
368 {
369 Ok(self.generic_alloc_uninit::<B, T>()?.init_zeroed())
370 }
371
372 #[inline(always)]
373 fn generic_alloc_zeroed_slice<B: ErrorBehavior, T>(&self, len: usize) -> Result<BumpBox<'a, [T]>, B>
374 where
375 T: FromZeros,
376 {
377 Ok(self.generic_alloc_uninit_slice::<B, T>(len)?.init_zeroed())
378 }
379}