bump_scope/
bump.rs

1use core::{
2    alloc::Layout,
3    cell::Cell,
4    ffi::CStr,
5    fmt::{self, Debug},
6    mem::{self, ManuallyDrop, MaybeUninit, transmute},
7    panic::{RefUnwindSafe, UnwindSafe},
8    ptr::{self, NonNull},
9};
10
11#[cfg(feature = "nightly-clone-to-uninit")]
12use core::clone::CloneToUninit;
13
14use crate::{
15    BaseAllocator, BumpBox, BumpScope, BumpScopeGuardRoot, Checkpoint, ErrorBehavior, FixedBumpString, FixedBumpVec,
16    MinimumAlignment, RawChunk, SupportedMinimumAlignment,
17    alloc::{AllocError, Allocator},
18    chunk_size::ChunkSize,
19    maybe_default_allocator,
20    owned_slice::OwnedSlice,
21    polyfill::{transmute_mut, transmute_ref},
22    stats::{AnyStats, Stats},
23};
24
25#[cfg(feature = "panic-on-alloc")]
26use crate::panic_on_error;
27
28macro_rules! make_type {
29    ($($allocator_parameter:tt)*) => {
30        /// The bump allocator.
31        ///
32        /// # Generic parameters
33        /// - **`A`** the base allocator, defaults to `Global` when the `alloc` feature is enabled
34        /// - **`MIN_ALIGN`** the alignment maintained for the bump pointer, see [What is minimum alignment?](crate#what-is-minimum-alignment)
35        /// - **`UP`** the bump direction, see [Bumping upwards or downwards?](crate#bumping-upwards-or-downwards)
36        /// - **`GUARANTEED_ALLOCATED`** see [What does *guaranteed allocated* mean?](crate#what-does-guaranteed-allocated-mean)
37        /// - **`DEALLOCATES`** toggles deallocation and shrinking for collections, [`alloc_iter`] and <code>[alloc_](Self::alloc_fmt)([cstr_](Self::alloc_cstr_fmt))[fmt](Self::alloc_fmt)</code>
38        ///
39        /// # Overview
40        /// All of the mentioned methods that do allocations panic if the base allocator returned an error.
41        /// For every such panicking method, there is a corresponding `try_`-prefixed version that returns a `Result` instead.
42        ///
43        /// #### Create a `Bump` ...
44        /// - with a default size hint: <code>[new]\([_in][new_in])</code> / <code>[default]</code>
45        /// - provide a size hint: <code>[with_size]\([_in][with_size_in])</code>
46        /// - provide a minimum capacity: <code>[with_capacity]\([_in][with_capacity_in])</code>
47        /// - without allocation: <code>[unallocated]</code>
48        ///
49        /// [new]: Self::new
50        /// [new_in]: Self::new_in
51        /// [default]: Self::default
52        /// [with_size]: Self::with_size
53        /// [with_size_in]: Self::with_size_in
54        /// [with_capacity]: Self::with_capacity
55        /// [with_capacity_in]: Self::with_capacity_in
56        /// [unallocated]: Self::unallocated
57        ///
58        /// #### Allocate ...
59        /// - sized values: [`alloc`], [`alloc_with`], [`alloc_default`], [`alloc_zeroed`]
60        /// - strings: [`alloc_str`], <code>[alloc_fmt](Self::alloc_fmt)([_mut](Self::alloc_fmt_mut))</code>
61        /// - c strings: [`alloc_cstr`], [`alloc_cstr_from_str`], <code>[alloc_cstr_fmt](Self::alloc_cstr_fmt)([_mut](Self::alloc_cstr_fmt_mut))</code>
62        /// - slices: <code>alloc_slice_{[copy](Self::alloc_slice_copy), [clone](Self::alloc_slice_clone), [move](Self::alloc_slice_move), [fill](Self::alloc_slice_fill), [fill_with](Self::alloc_slice_fill_with)}</code>,
63        ///   [`alloc_zeroed_slice`]
64        /// - slices from an iterator: [`alloc_iter`], [`alloc_iter_exact`], [`alloc_iter_mut`], [`alloc_iter_mut_rev`]
65        /// - uninitialized values: [`alloc_uninit`], [`alloc_uninit_slice`], [`alloc_uninit_slice_for`]
66        ///
67        ///   which can then be conveniently initialized by the [`init*` methods of `BumpBox`](crate::BumpBox#bumpbox-has-a-lot-of-methods).
68        /// - results: [`alloc_try_with`], [`alloc_try_with_mut`]
69        /// - via clone *(nightly only)*: [`alloc_clone`]
70        ///
71        /// #### Free memory using ...
72        /// - scopes: [`scoped`], [`scoped_aligned`], [`scope_guard`]
73        /// - checkpoints: [`checkpoint`], [`reset_to`]
74        /// - reset: [`reset`]
75        /// - dealloc: [`dealloc`]
76        ///
77        /// #### Configure allocator settings ...
78        /// - guaranteed allocated:
79        ///   <code>{[as](Self::as_guaranteed_allocated), [as_mut](Self::as_mut_guaranteed_allocated), [into](Self::into_guaranteed_allocated)}_guaranteed_allocated</code>,
80        ///   <code>{[as](Self::as_not_guaranteed_allocated), [into](Self::into_not_guaranteed_allocated)}_not_guaranteed_allocated</code>
81        /// - minimum alignment: [`aligned`], [`as_mut_aligned`], [`into_aligned`]
82        /// - deallocation:
83        ///   <code>{[as](Self::as_with_dealloc), [as_mut](Self::as_mut_with_dealloc), [into](Self::into_with_dealloc)}_with_dealloc</code>
84        ///   <code>{[as](Self::as_without_dealloc), [as_mut](Self::as_mut_without_dealloc), [into](Self::into_without_dealloc)}_without_dealloc</code>
85        ///
86        /// ## Collections
87        /// A `Bump` (and [`BumpScope`]) can be used to allocate collections of this crate...
88        /// ```
89        /// use bump_scope::{Bump, BumpString};
90        /// let bump: Bump = Bump::new();
91        ///
92        /// let mut string = BumpString::new_in(&bump);
93        /// string.push_str("Hello,");
94        /// string.push_str(" world!");
95        /// ```
96        ///
97        /// ... and collections from crates that use `allocator_api2`'s `Allocator` like [hashbrown](https://docs.rs/hashbrown)'s [`HashMap`](https://docs.rs/hashbrown/latest/hashbrown/struct.HashMap.html):
98        ///
99        /// *This requires the `allocator-api2-02` feature OR the `nightly-allocator-api` feature along with hashbrown's `nightly` feature.*
100        // NOTE: This code is tested in `crates/test-hashbrown/lib.rs`.
101        // It's not tested here because using hashbrown requires us to either have both the crate features for a nightly allocator api in bump-scope and hashbrown or neither.
102        // This could be solved by making bump-scope's "nightly-allocator-api" depend on "hashbrown/nightly" but that currently breaks tools like cargo-hack and cargo-minimal-versions.
103        /// ```
104        /// # /*
105        /// use bump_scope::Bump;
106        /// use hashbrown::HashMap;
107        ///
108        /// let bump: Bump = Bump::new();
109        /// let mut map = HashMap::new_in(&bump);
110        /// map.insert("tau", 6.283);
111        /// # */
112        /// # ()
113        /// ```
114        ///
115        /// On nightly and with the feature `nightly-allocator-api` you can also allocate collections from `std` that have an allocator parameter:
116        #[cfg_attr(feature = "nightly-allocator-api", doc = "```")]
117        #[cfg_attr(not(feature = "nightly-allocator-api"), doc = "```no_run")]
118        /// # /*
119        /// # those features are already been enabled by a `doc(test(attr`
120        /// # but we still want it here for demonstration
121        /// #![feature(allocator_api, btreemap_alloc)]
122        /// # */
123        /// # #[cfg(feature = "nightly-allocator-api")] fn main() {
124        /// use bump_scope::Bump;
125        /// use std::collections::{VecDeque, BTreeMap, LinkedList};
126        ///
127        /// let bump: Bump = Bump::new();
128        /// let vec = Vec::new_in(&bump);
129        /// let queue = VecDeque::new_in(&bump);
130        /// let map = BTreeMap::new_in(&bump);
131        /// let list = LinkedList::new_in(&bump);
132        /// # let _: Vec<i32, _> = vec;
133        /// # let _: VecDeque<i32, _> = queue;
134        /// # let _: BTreeMap<i32, i32, _> = map;
135        /// # let _: LinkedList<i32, _> = list;
136        /// # }
137        /// # #[cfg(not(feature = "nightly-allocator-api"))] fn main() {}
138        /// ```
139        ///
140        /// [`alloc`]: Self::alloc
141        /// [`alloc_with`]: Self::alloc_with
142        /// [`alloc_default`]: Self::alloc_default
143        /// [`alloc_zeroed`]: crate::zerocopy_08::BumpExt::alloc_zeroed
144        ///
145        /// [`alloc_str`]: Self::alloc_str
146        ///
147        /// [`alloc_cstr`]: Self::alloc_cstr
148        /// [`alloc_cstr_from_str`]: Self::alloc_cstr_from_str
149        ///
150        /// [`alloc_zeroed_slice`]: crate::zerocopy_08::BumpExt::alloc_zeroed_slice
151        ///
152        /// [`alloc_iter`]: Self::alloc_iter
153        /// [`alloc_iter_exact`]: Self::alloc_iter_exact
154        /// [`alloc_iter_mut`]: Self::alloc_iter_mut
155        /// [`alloc_iter_mut_rev`]: Self::alloc_iter_mut_rev
156        ///
157        /// [`alloc_uninit`]: Self::alloc_uninit
158        /// [`alloc_uninit_slice`]: Self::alloc_uninit_slice
159        /// [`alloc_uninit_slice_for`]: Self::alloc_uninit_slice_for
160        ///
161        /// [`alloc_try_with`]: Self::alloc_try_with
162        /// [`alloc_try_with_mut`]: Self::alloc_try_with_mut
163        ///
164        /// [`alloc_clone`]: Self::alloc_clone
165        ///
166        /// [`scoped`]: Self::scoped
167        /// [`scoped_aligned`]: Self::scoped_aligned
168        /// [`scope_guard`]: Self::scope_guard
169        ///
170        /// [`checkpoint`]: Self::checkpoint
171        /// [`reset_to`]: Self::reset_to
172        ///
173        /// [`reset`]: Self::reset
174        /// [`dealloc`]: Self::dealloc
175        ///
176        /// [`aligned`]: Self::aligned
177        /// [`as_mut_aligned`]: Self::as_mut_aligned
178        /// [`into_aligned`]: Self::into_aligned
179        ///
180        /// [`into_with_dealloc`]: Self::into_with_dealloc
181        /// [`as_with_dealloc`]: Self::as_with_dealloc
182        /// [`as_mut_with_dealloc`]: Self::as_mut_with_dealloc
183        ///
184        /// [`into_without_dealloc`]: Self::into_without_dealloc
185        /// [`as_without_dealloc`]: Self::as_without_dealloc
186        /// [`as_mut_without_dealloc`]: Self::as_mut_without_dealloc
187        ///
188        /// # Gotcha
189        ///
190        /// Having live allocations and entering bump scopes at the same time requires a `BumpScope`.
191        /// This is due to the way lifetimes work, since `Bump` returns allocations with the lifetime
192        /// of its own borrow instead of a separate lifetime like `BumpScope` does.
193        ///
194        /// So you can't do this:
195        /// ```compile_fail,E0502
196        /// # use bump_scope::Bump;
197        /// let mut bump: Bump = Bump::new();
198        ///
199        /// let one = bump.alloc(1);
200        ///
201        /// bump.scoped(|bump| {
202        ///     // whatever
203        ///     # _ = bump;
204        /// });
205        /// # _ = one;
206        /// ```
207        /// But you can make the code work by converting the `Bump` it to a [`BumpScope`] first using [`as_mut_scope`]:
208        /// ```
209        /// # use bump_scope::Bump;
210        /// let mut bump: Bump = Bump::new();
211        /// let bump = bump.as_mut_scope();
212        ///
213        /// let one = bump.alloc(1);
214        ///
215        /// bump.scoped(|bump| {
216        ///     // whatever
217        ///     # _ = bump;
218        /// });
219        /// # _ = one;
220        /// ```
221        ///
222        /// [`as_mut_scope`]: Self::as_mut_scope
223        #[repr(transparent)]
224        pub struct Bump<
225            $($allocator_parameter)*,
226            const MIN_ALIGN: usize = 1,
227            const UP: bool = true,
228            const GUARANTEED_ALLOCATED: bool = true,
229            const DEALLOCATES: bool = true,
230        > where
231            MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
232            A: Allocator,
233        {
234            pub(crate) chunk: Cell<RawChunk<A, UP, GUARANTEED_ALLOCATED>>,
235        }
236    };
237}
238
239maybe_default_allocator!(make_type);
240
241// Sending Bumps when nothing is allocated is fine.
242// When something is allocated Bump is borrowed and sending is not possible.
243unsafe impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> Send
244    for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
245where
246    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
247    A: Allocator,
248{
249}
250
251impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> UnwindSafe
252    for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
253where
254    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
255    A: Allocator + UnwindSafe,
256{
257}
258
259impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> RefUnwindSafe
260    for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
261where
262    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
263    A: Allocator + UnwindSafe,
264{
265}
266
267impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> Drop
268    for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
269where
270    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
271    A: Allocator,
272{
273    fn drop(&mut self) {
274        let Some(chunk) = self.chunk.get().guaranteed_allocated() else {
275            return;
276        };
277
278        unsafe {
279            chunk.for_each_prev(|chunk| chunk.deallocate());
280            chunk.for_each_next(|chunk| chunk.deallocate());
281            chunk.deallocate();
282        }
283    }
284}
285
286impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> Debug
287    for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
288where
289    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
290    A: Allocator,
291{
292    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
293        AnyStats::from(self.stats()).debug_format("Bump", f)
294    }
295}
296
297#[cfg(feature = "panic-on-alloc")]
298impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> Default
299    for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
300where
301    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
302    A: Allocator + Default,
303{
304    #[inline(always)]
305    fn default() -> Self {
306        Self::new_in(Default::default())
307    }
308}
309
310unsafe impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool> Allocator
311    for Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
312where
313    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
314    A: BaseAllocator<GUARANTEED_ALLOCATED>,
315{
316    #[inline(always)]
317    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
318        self.as_scope().allocate(layout)
319    }
320
321    #[inline(always)]
322    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
323        unsafe { self.as_scope().deallocate(ptr, layout) };
324    }
325
326    #[inline(always)]
327    unsafe fn grow(&self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
328        unsafe { self.as_scope().grow(ptr, old_layout, new_layout) }
329    }
330
331    #[inline(always)]
332    unsafe fn grow_zeroed(
333        &self,
334        ptr: NonNull<u8>,
335        old_layout: Layout,
336        new_layout: Layout,
337    ) -> Result<NonNull<[u8]>, AllocError> {
338        unsafe { self.as_scope().grow_zeroed(ptr, old_layout, new_layout) }
339    }
340
341    #[inline(always)]
342    unsafe fn shrink(&self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
343        unsafe { self.as_scope().shrink(ptr, old_layout, new_layout) }
344    }
345}
346
347/// Methods for a `Bump` with a default base allocator.
348impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool>
349    Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
350where
351    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
352    A: Allocator + Default,
353{
354    /// Constructs a new `Bump` with a default size hint for the first chunk.
355    ///
356    /// This is equivalent to <code>[with_size](Bump::with_size)(512)</code>.
357    ///
358    /// # Panics
359    /// Panics if the allocation fails.
360    ///
361    /// # Examples
362    /// ```
363    /// use bump_scope::Bump;
364    ///
365    /// let bump: Bump = Bump::new();
366    /// # _ = bump;
367    /// ```
368    #[must_use]
369    #[inline(always)]
370    #[cfg(feature = "panic-on-alloc")]
371    pub fn new() -> Self {
372        panic_on_error(Self::generic_new())
373    }
374
375    /// Constructs a new `Bump` with a default size hint for the first chunk.
376    ///
377    /// This is equivalent to <code>[try_with_size](Bump::try_with_size)(512)</code>.
378    ///
379    /// # Errors
380    /// Errors if the allocation fails.
381    ///
382    /// # Examples
383    /// ```
384    /// use bump_scope::Bump;
385    ///
386    /// let bump: Bump = Bump::try_new()?;
387    /// # _ = bump;
388    /// # Ok::<(), bump_scope::alloc::AllocError>(())
389    /// ```
390    #[inline(always)]
391    pub fn try_new() -> Result<Self, AllocError> {
392        Self::generic_new()
393    }
394
395    #[inline]
396    pub(crate) fn generic_new<E: ErrorBehavior>() -> Result<Self, E> {
397        Self::generic_new_in(Default::default())
398    }
399
400    /// Constructs a new `Bump` with a size hint for the first chunk.
401    ///
402    /// If you want to ensure a specific capacity, use [`with_capacity`](Self::with_capacity) instead.
403    ///
404    /// An effort is made to ensure the size requested from the base allocator is friendly to an allocator that uses size classes and stores metadata alongside allocations.
405    /// To achieve this, the requested size is rounded up to either the next power of two or the next multiple of `0x1000`, whichever is smaller.
406    /// After that, the size of `[usize; 2]` is subtracted.
407    ///
408    /// If the base allocator returns a memory block that is larger than requested, then the chunk will use the extra space.
409    ///
410    /// **Disclaimer:** The way in which the chunk layout is calculated might change.
411    /// Such a change is not considered semver breaking.
412    ///
413    /// # Panics
414    /// Panics if the allocation fails.
415    ///
416    /// # Examples
417    /// ```
418    /// use bump_scope::Bump;
419    ///
420    /// // `Bump` with a roughly 1 Mebibyte sized chunk
421    /// let bump_1mib: Bump = Bump::with_size(1024 * 1024);
422    /// # _ = bump_1mib;
423    /// ```
424    #[must_use]
425    #[inline(always)]
426    #[cfg(feature = "panic-on-alloc")]
427    pub fn with_size(size: usize) -> Self {
428        panic_on_error(Self::generic_with_size(size))
429    }
430
431    /// Constructs a new `Bump` with a size hint for the first chunk.
432    ///
433    /// If you want to ensure a specific capacity, use [`try_with_capacity`](Self::try_with_capacity) instead.
434    ///
435    /// An effort is made to ensure the size requested from the base allocator is friendly to an allocator that uses size classes and stores metadata alongside allocations.
436    /// To achieve this, the requested size is rounded up to either the next power of two or the next multiple of `0x1000`, whichever is smaller.
437    /// After that, the size of `[usize; 2]` is subtracted.
438    ///
439    /// If the base allocator returns a memory block that is larger than requested, then the chunk will use the extra space.
440    ///
441    /// **Disclaimer:** The way in which the chunk layout is calculated might change.
442    /// Such a change is not considered semver breaking.
443    ///
444    /// # Errors
445    /// Errors if the allocation fails.
446    ///
447    /// # Examples
448    /// ```
449    /// use bump_scope::Bump;
450    ///
451    /// // `Bump` with a roughly 1 Mebibyte sized chunk
452    /// let bump_1mib: Bump = Bump::try_with_size(1024 * 1024)?;
453    /// # _ = bump_1mib;
454    /// # Ok::<(), bump_scope::alloc::AllocError>(())
455    /// ```
456    #[inline(always)]
457    pub fn try_with_size(size: usize) -> Result<Self, AllocError> {
458        Self::generic_with_size(size)
459    }
460
461    #[inline]
462    pub(crate) fn generic_with_size<E: ErrorBehavior>(size: usize) -> Result<Self, E> {
463        Self::generic_with_size_in(size, Default::default())
464    }
465
466    /// Constructs a new `Bump` with at least enough space for `layout`.
467    ///
468    /// To construct a `Bump` with a size hint use <code>[with_size](Bump::with_size)</code> instead.
469    ///
470    /// # Panics
471    /// Panics if the allocation fails.
472    ///
473    /// # Examples
474    /// ```
475    /// use bump_scope::Bump;
476    /// use core::alloc::Layout;
477    ///
478    /// let layout = Layout::array::<u8>(1234).unwrap();
479    /// let bump: Bump = Bump::with_capacity(layout);
480    /// assert!(bump.stats().capacity() >= layout.size());
481    /// ```
482    #[must_use]
483    #[inline(always)]
484    #[cfg(feature = "panic-on-alloc")]
485    pub fn with_capacity(layout: Layout) -> Self {
486        panic_on_error(Self::generic_with_capacity(layout))
487    }
488
489    /// Constructs a new `Bump` with at least enough space for `layout`.
490    ///
491    /// To construct a `Bump` with a size hint use <code>[try_with_size](Bump::try_with_size)</code> instead.
492    ///
493    /// # Errors
494    /// Errors if the allocation fails.
495    ///
496    /// # Examples
497    /// ```
498    /// use bump_scope::Bump;
499    /// use core::alloc::Layout;
500    ///
501    /// let layout = Layout::array::<u8>(1234).unwrap();
502    /// let bump: Bump = Bump::try_with_capacity(layout)?;
503    /// assert!(bump.stats().capacity() >= layout.size());
504    /// # Ok::<(), bump_scope::alloc::AllocError>(())
505    /// ```
506    #[inline(always)]
507    pub fn try_with_capacity(layout: Layout) -> Result<Self, AllocError> {
508        Self::generic_with_capacity(layout)
509    }
510
511    #[inline]
512    pub(crate) fn generic_with_capacity<E: ErrorBehavior>(layout: Layout) -> Result<Self, E> {
513        Self::generic_with_capacity_in(layout, Default::default())
514    }
515}
516
517/// Methods for a [*guaranteed allocated*](crate#what-does-guaranteed-allocated-mean) `Bump`.
518impl<A, const MIN_ALIGN: usize, const UP: bool, const DEALLOCATES: bool> Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>
519where
520    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
521    A: Allocator,
522{
523    /// Calls `f` with a new child scope.
524    ///
525    /// # Examples
526    ///
527    /// ```
528    /// # use bump_scope::Bump;
529    /// let mut bump: Bump = Bump::new();
530    ///
531    /// bump.scoped(|bump| {
532    ///     bump.alloc_str("Hello, world!");
533    ///     assert_eq!(bump.stats().allocated(), 13);
534    /// });
535    ///
536    /// assert_eq!(bump.stats().allocated(), 0);
537    /// ```
538    #[inline(always)]
539    pub fn scoped<R>(&mut self, f: impl FnOnce(BumpScope<A, MIN_ALIGN, UP, true, DEALLOCATES>) -> R) -> R {
540        let mut guard = self.scope_guard();
541        f(guard.scope())
542    }
543
544    /// Calls `f` with a new child scope of a new minimum alignment.
545    ///
546    /// # Examples
547    ///
548    #[cfg_attr(feature = "nightly-tests", doc = "```")]
549    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
550    /// # #![feature(pointer_is_aligned_to)]
551    /// # use bump_scope::Bump;
552    /// let mut bump: Bump = Bump::new();
553    ///
554    /// // bump starts off by being aligned to 16
555    /// assert!(bump.stats().current_chunk().bump_position().is_aligned_to(16));
556    ///
557    /// // allocate one byte
558    /// bump.alloc(1u8);
559    ///
560    /// // now the bump is only aligned to 1
561    /// // (if our `MIN_ALIGN` was higher, it would be that)
562    /// assert!(bump.stats().current_chunk().bump_position().addr().get() % 2 == 1);
563    /// assert_eq!(bump.stats().allocated(), 1);
564    ///
565    /// bump.scoped_aligned::<8, ()>(|bump| {
566    ///    // in here, the bump will have the specified minimum alignment of 8
567    ///    assert!(bump.stats().current_chunk().bump_position().is_aligned_to(8));
568    ///    assert_eq!(bump.stats().allocated(), 8);
569    ///
570    ///    // allocating a value with its size being a multiple of 8 will no longer have
571    ///    // to align the bump pointer before allocation
572    ///    bump.alloc(1u64);
573    ///    assert!(bump.stats().current_chunk().bump_position().is_aligned_to(8));
574    ///    assert_eq!(bump.stats().allocated(), 16);
575    ///    
576    ///    // allocating a value smaller than the minimum alignment must align the bump pointer
577    ///    // after the allocation, resulting in some wasted space
578    ///    bump.alloc(1u8);
579    ///    assert!(bump.stats().current_chunk().bump_position().is_aligned_to(8));
580    ///    assert_eq!(bump.stats().allocated(), 24);
581    /// });
582    ///
583    /// assert_eq!(bump.stats().allocated(), 1);
584    /// ```
585    #[inline(always)]
586    pub fn scoped_aligned<const NEW_MIN_ALIGN: usize, R>(
587        &mut self,
588        f: impl FnOnce(BumpScope<A, NEW_MIN_ALIGN, UP, true, DEALLOCATES>) -> R,
589    ) -> R
590    where
591        MinimumAlignment<NEW_MIN_ALIGN>: SupportedMinimumAlignment,
592    {
593        self.as_mut_scope().scoped_aligned::<NEW_MIN_ALIGN, R>(f)
594    }
595
596    /// Calls `f` with this scope but with a new minimum alignment.
597    ///
598    /// # Examples
599    ///
600    /// Increase the minimum alignment:
601    #[cfg_attr(feature = "nightly-tests", doc = "```")]
602    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
603    /// # #![feature(pointer_is_aligned_to)]
604    /// # use bump_scope::Bump;
605    /// let mut bump: Bump = Bump::new();
606    /// let bump = bump.as_mut_scope();
607    ///
608    /// // here we're allocating with a `MIN_ALIGN` of `1`
609    /// let foo = bump.alloc_str("foo");
610    /// assert_eq!(bump.stats().allocated(), 3);
611    ///
612    /// let bar = bump.aligned::<8, _>(|bump| {
613    ///     // in here the bump position has been aligned to `8`
614    ///     assert_eq!(bump.stats().allocated(), 8);
615    ///     assert!(bump.stats().current_chunk().bump_position().is_aligned_to(8));
616    ///
617    ///     // make some allocations that benefit from the higher `MIN_ALIGN` of `8`
618    ///     let bar = bump.alloc(0u64);
619    ///     assert_eq!(bump.stats().allocated(), 16);
620    ///  
621    ///     // the bump position will stay aligned to `8`
622    ///     bump.alloc(0u8);
623    ///     assert_eq!(bump.stats().allocated(), 24);
624    ///
625    ///     bar
626    /// });
627    ///
628    /// assert_eq!(bump.stats().allocated(), 24);
629    ///
630    /// // continue making allocations with a `MIN_ALIGN` of `1`
631    /// let baz = bump.alloc_str("baz");
632    /// assert_eq!(bump.stats().allocated(), 24 + 3);
633    ///
634    /// dbg!(foo, bar, baz);
635    /// ```
636    ///
637    /// Decrease the minimum alignment:
638    #[cfg_attr(feature = "nightly-tests", doc = "```")]
639    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
640    /// # #![feature(pointer_is_aligned_to)]
641    /// # use bump_scope::{Bump, alloc::Global};
642    /// let mut bump: Bump<Global, 8> = Bump::new();
643    /// let bump = bump.as_mut_scope();
644    ///
645    /// // make some allocations that benefit from the `MIN_ALIGN` of `8`
646    /// let foo = bump.alloc(0u64);
647    ///
648    /// let bar = bump.aligned::<1, _>(|bump| {
649    ///     // make some allocations that benefit from the lower `MIN_ALIGN` of `1`
650    ///     let bar = bump.alloc(0u8);
651    ///
652    ///     // the bump position will not get aligned to `8` in here
653    ///     assert_eq!(bump.stats().allocated(), 8 + 1);
654    ///
655    ///     bar
656    /// });
657    ///
658    /// // after `aligned()`, the bump position will be aligned to `8` again
659    /// // to satisfy our `MIN_ALIGN`
660    /// assert!(bump.stats().current_chunk().bump_position().is_aligned_to(8));
661    /// assert_eq!(bump.stats().allocated(), 16);
662    ///
663    /// // continue making allocations that benefit from the `MIN_ALIGN` of `8`
664    /// let baz = bump.alloc(0u64);
665    ///
666    /// dbg!(foo, bar, baz);
667    /// ```
668    #[inline(always)]
669    pub fn aligned<'a, const NEW_MIN_ALIGN: usize, R>(
670        &'a mut self,
671        f: impl FnOnce(BumpScope<'a, A, NEW_MIN_ALIGN, UP, true, DEALLOCATES>) -> R,
672    ) -> R
673    where
674        MinimumAlignment<NEW_MIN_ALIGN>: SupportedMinimumAlignment,
675    {
676        self.as_mut_scope().aligned(f)
677    }
678
679    /// Creates a new [`BumpScopeGuardRoot`].
680    ///
681    /// This allows for creation of child scopes.
682    ///
683    /// # Examples
684    ///
685    /// ```
686    /// # use bump_scope::Bump;
687    /// let mut bump: Bump = Bump::new();
688    ///
689    /// {
690    ///     let mut guard = bump.scope_guard();
691    ///     let bump = guard.scope();
692    ///     bump.alloc_str("Hello, world!");
693    ///     assert_eq!(bump.stats().allocated(), 13);
694    /// }
695    ///
696    /// assert_eq!(bump.stats().allocated(), 0);
697    /// ```
698    #[must_use]
699    #[inline(always)]
700    pub fn scope_guard(&mut self) -> BumpScopeGuardRoot<'_, A, MIN_ALIGN, UP, DEALLOCATES> {
701        BumpScopeGuardRoot::new(self)
702    }
703
704    /// Returns a reference to the base allocator.
705    #[must_use]
706    #[inline(always)]
707    pub fn allocator(&self) -> &A {
708        self.as_scope().allocator()
709    }
710}
711
712/// Methods for a **not** [*guaranteed allocated*](crate#what-does-guaranteed-allocated-mean) `Bump`.
713impl<A, const MIN_ALIGN: usize, const UP: bool, const DEALLOCATES: bool> Bump<A, MIN_ALIGN, UP, false, DEALLOCATES>
714where
715    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
716    A: Allocator,
717{
718    /// Constructs a new `Bump` without allocating a chunk.
719    ///
720    /// See [*What does guaranteed allocated mean?*](crate#what-does-guaranteed-allocated-mean).
721    ///
722    /// # Examples
723    ///
724    /// ```
725    /// use bump_scope::Bump;
726    /// use bump_scope::alloc::Global;
727    ///
728    /// let bump: Bump<Global, 1, true, false> = Bump::unallocated();
729    /// # _ = bump;
730    /// ```
731    #[must_use]
732    pub const fn unallocated() -> Self {
733        Self {
734            chunk: Cell::new(RawChunk::UNALLOCATED),
735        }
736    }
737
738    /// Returns a reference to the base allocator.
739    #[must_use]
740    #[inline(always)]
741    pub fn allocator(&self) -> Option<&A> {
742        self.as_scope().allocator()
743    }
744}
745
746/// Methods that are always available.
747impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool>
748    Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
749where
750    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
751    A: Allocator,
752{
753    /// Creates a checkpoint of the current bump position.
754    ///
755    /// The bump position can be reset to this checkpoint with [`reset_to`].
756    ///
757    /// [`reset_to`]: Self::reset_to
758    ///
759    /// # Examples
760    ///
761    /// ```
762    /// # use bump_scope::Bump;
763    /// let bump: Bump = Bump::new();
764    /// let checkpoint = bump.checkpoint();
765    ///
766    /// {
767    ///     let hello = bump.alloc_str("hello");
768    ///     assert_eq!(bump.stats().allocated(), 5);
769    ///     # _ = hello;
770    /// }
771    ///
772    /// unsafe { bump.reset_to(checkpoint); }
773    /// assert_eq!(bump.stats().allocated(), 0);
774    /// ```
775    #[inline]
776    pub fn checkpoint(&self) -> Checkpoint {
777        Checkpoint::new(self.chunk.get())
778    }
779
780    /// Resets the bump position to a previously created checkpoint.
781    /// The memory that has been allocated since then will be reused by future allocations.
782    ///
783    /// # Safety
784    ///
785    /// - the checkpoint must have been created by this bump allocator
786    /// - the bump allocator must not have been [`reset`] since creation of this checkpoint
787    /// - there must be no references to allocations made since creation of this checkpoint
788    /// - the checkpoint must not have been created by an`!GUARANTEED_ALLOCATED` when self is `GUARANTEED_ALLOCATED`
789    ///
790    /// [`reset`]: crate::Bump::reset
791    ///
792    /// # Examples
793    ///
794    /// ```
795    /// # use bump_scope::Bump;
796    /// let bump: Bump = Bump::new();
797    /// let checkpoint = bump.checkpoint();
798    ///
799    /// {
800    ///     let hello = bump.alloc_str("hello");
801    ///     assert_eq!(bump.stats().allocated(), 5);
802    ///     # _ = hello;
803    /// }
804    ///
805    /// unsafe { bump.reset_to(checkpoint); }
806    /// assert_eq!(bump.stats().allocated(), 0);
807    /// ```
808    #[inline]
809    pub unsafe fn reset_to(&self, checkpoint: Checkpoint) {
810        unsafe { self.as_scope().reset_to(checkpoint) };
811    }
812
813    /// Constructs a new `Bump` with a default size hint for the first chunk.
814    ///
815    /// This is equivalent to <code>[with_size_in](Bump::with_size_in)(512, allocator)</code>.
816    ///
817    /// # Panics
818    /// Panics if the allocation fails.
819    ///
820    /// # Examples
821    /// ```
822    /// use bump_scope::Bump;
823    /// use bump_scope::alloc::Global;
824    ///
825    /// let bump: Bump = Bump::new_in(Global);
826    /// # _ = bump;
827    /// ```
828    #[must_use]
829    #[inline(always)]
830    #[cfg(feature = "panic-on-alloc")]
831    pub fn new_in(allocator: A) -> Self {
832        panic_on_error(Self::generic_new_in(allocator))
833    }
834
835    /// Constructs a new `Bump` with a default size hint for the first chunk.
836    ///
837    /// This is equivalent to <code>[try_with_size_in](Bump::try_with_size_in)(512, allocator)</code>.
838    ///
839    /// # Errors
840    /// Errors if the allocation fails.
841    ///
842    /// # Examples
843    /// ```
844    /// use bump_scope::Bump;
845    /// use bump_scope::alloc::Global;
846    ///
847    /// let bump: Bump = Bump::try_new_in(Global)?;
848    /// # _ = bump;
849    /// # Ok::<(), bump_scope::alloc::AllocError>(())
850    /// ```
851    #[inline(always)]
852    pub fn try_new_in(allocator: A) -> Result<Self, AllocError> {
853        Self::generic_new_in(allocator)
854    }
855
856    #[inline]
857    pub(crate) fn generic_new_in<E: ErrorBehavior>(allocator: A) -> Result<Self, E> {
858        Ok(Self {
859            chunk: Cell::new(RawChunk::new_in(ChunkSize::DEFAULT, None, allocator)?.coerce_guaranteed_allocated()),
860        })
861    }
862
863    /// Constructs a new `Bump` with a size hint for the first chunk.
864    ///
865    /// If you want to ensure a specific capacity, use [`with_capacity_in`](Self::with_capacity_in) instead.
866    ///
867    /// An effort is made to ensure the size requested from the base allocator is friendly to an allocator that uses size classes and stores metadata alongside allocations.
868    /// To achieve this, the requested size is rounded up to either the next power of two or the next multiple of `0x1000`, whichever is smaller.
869    /// After that, the size of `[usize; 2]` is subtracted.
870    ///
871    /// If the base allocator returns a memory block that is larger than requested, then the chunk will use the extra space.
872    ///
873    /// **Disclaimer:** The way in which the chunk layout is calculated might change.
874    /// Such a change is not considered semver breaking.
875    ///
876    /// # Panics
877    /// Panics if the allocation fails.
878    ///
879    /// # Examples
880    /// ```
881    /// use bump_scope::Bump;
882    /// use bump_scope::alloc::Global;
883    ///
884    /// // `Bump` with a roughly 1 Mebibyte sized chunk
885    /// let bump_1mib: Bump = Bump::with_size_in(1024 * 1024, Global);
886    /// # _ = bump_1mib;
887    /// ```
888    #[must_use]
889    #[inline(always)]
890    #[cfg(feature = "panic-on-alloc")]
891    pub fn with_size_in(size: usize, allocator: A) -> Self {
892        panic_on_error(Self::generic_with_size_in(size, allocator))
893    }
894
895    /// Constructs a new `Bump` with a size hint for the first chunk.
896    ///
897    /// If you want to ensure a specific capacity, use [`try_with_capacity`](Self::try_with_capacity) instead.
898    ///
899    /// An effort is made to ensure the size requested from the base allocator is friendly to an allocator that uses size classes and stores metadata alongside allocations.
900    /// To achieve this, the requested size is rounded up to either the next power of two or the next multiple of `0x1000`, whichever is smaller.
901    /// After that, the size of `[usize; 2]` is subtracted.
902    ///
903    /// If the base allocator returns a memory block that is larger than requested, then the chunk will use the extra space.
904    ///
905    /// **Disclaimer:** The way in which the chunk layout is calculated might change.
906    /// Such a change is not considered semver breaking.
907    ///
908    /// # Errors
909    /// Errors if the allocation fails.
910    ///
911    /// # Examples
912    /// ```
913    /// use bump_scope::Bump;
914    /// use bump_scope::alloc::Global;
915    ///
916    /// // `Bump` with a roughly 1 Mebibyte sized chunk
917    /// let bump_1mib: Bump = Bump::try_with_size_in(1024 * 1024, Global)?;
918    /// # _ = bump_1mib;
919    /// # Ok::<(), bump_scope::alloc::AllocError>(())
920    /// ```
921    #[inline(always)]
922    pub fn try_with_size_in(size: usize, allocator: A) -> Result<Self, AllocError> {
923        Self::generic_with_size_in(size, allocator)
924    }
925
926    #[inline]
927    pub(crate) fn generic_with_size_in<E: ErrorBehavior>(size: usize, allocator: A) -> Result<Self, E> {
928        Ok(Self {
929            chunk: Cell::new(
930                RawChunk::new_in(ChunkSize::from_hint(size).ok_or_else(E::capacity_overflow)?, None, allocator)?
931                    .coerce_guaranteed_allocated(),
932            ),
933        })
934    }
935
936    /// Constructs a new `Bump` with at least enough space for `layout`.
937    ///
938    /// To construct a `Bump` with a size hint use <code>[with_size_in](Bump::with_size_in)</code> instead.
939    ///
940    /// # Panics
941    /// Panics if the allocation fails.
942    ///
943    /// # Examples
944    /// ```
945    /// use bump_scope::Bump;
946    /// use bump_scope::alloc::Global;
947    /// use core::alloc::Layout;
948    ///
949    /// let layout = Layout::array::<u8>(1234).unwrap();
950    /// let bump: Bump = Bump::with_capacity_in(layout, Global);
951    /// assert!(bump.stats().capacity() >= layout.size());
952    /// # Ok::<(), bump_scope::alloc::AllocError>(())
953    /// ```
954    #[must_use]
955    #[inline(always)]
956    #[cfg(feature = "panic-on-alloc")]
957    pub fn with_capacity_in(layout: Layout, allocator: A) -> Self {
958        panic_on_error(Self::generic_with_capacity_in(layout, allocator))
959    }
960
961    /// Constructs a new `Bump` with at least enough space for `layout`.
962    ///
963    /// To construct a `Bump` with a size hint use <code>[try_with_size_in](Bump::try_with_size_in)</code> instead.
964    ///
965    /// # Errors
966    /// Errors if the allocation fails.
967    ///
968    /// # Examples
969    /// ```
970    /// use bump_scope::Bump;
971    /// use bump_scope::alloc::Global;
972    /// use core::alloc::Layout;
973    ///
974    /// let layout = Layout::array::<u8>(1234).unwrap();
975    /// let bump: Bump = Bump::try_with_capacity_in(layout, Global)?;
976    /// assert!(bump.stats().capacity() >= layout.size());
977    /// # Ok::<(), bump_scope::alloc::AllocError>(())
978    /// ```
979    #[inline(always)]
980    pub fn try_with_capacity_in(layout: Layout, allocator: A) -> Result<Self, AllocError> {
981        Self::generic_with_capacity_in(layout, allocator)
982    }
983
984    #[inline]
985    pub(crate) fn generic_with_capacity_in<E: ErrorBehavior>(layout: Layout, allocator: A) -> Result<Self, E> {
986        Ok(Self {
987            chunk: Cell::new(
988                RawChunk::new_in(
989                    ChunkSize::from_capacity(layout).ok_or_else(E::capacity_overflow)?,
990                    None,
991                    allocator,
992                )?
993                .coerce_guaranteed_allocated(),
994            ),
995        })
996    }
997
998    // This needs `&mut self` to make sure that no allocations are alive.
999    /// Deallocates every chunk but the newest, which is also the biggest.
1000    ///
1001    /// ```
1002    /// use bump_scope::Bump;
1003    ///
1004    /// let mut bump: Bump = Bump::new();
1005    ///
1006    /// // won't fit in the default sized first chunk
1007    /// bump.alloc_uninit_slice::<u8>(600);
1008    ///
1009    /// let chunks = bump.stats().small_to_big().collect::<Vec<_>>();
1010    /// assert_eq!(chunks.len(), 2);
1011    /// assert!(chunks[0].size() < chunks[1].size());
1012    /// assert_eq!(chunks[0].allocated(), 0);
1013    /// assert_eq!(chunks[1].allocated(), 600);
1014    /// let last_chunk_size = chunks[1].size();
1015    ///
1016    /// bump.reset();
1017    ///
1018    /// let chunks = bump.stats().small_to_big().collect::<Vec<_>>();
1019    /// assert_eq!(chunks.len(), 1);
1020    /// assert_eq!(chunks[0].size(), last_chunk_size);
1021    /// assert_eq!(chunks[0].allocated(), 0);
1022    /// ```
1023    #[inline(always)]
1024    pub fn reset(&mut self) {
1025        let Some(mut chunk) = self.chunk.get().guaranteed_allocated() else {
1026            return;
1027        };
1028
1029        unsafe {
1030            chunk.for_each_prev(|chunk| chunk.deallocate());
1031
1032            while let Some(next) = chunk.next() {
1033                chunk.deallocate();
1034                chunk = next;
1035            }
1036        }
1037
1038        chunk.set_prev(None);
1039        chunk.reset();
1040        self.chunk.set(chunk.coerce_guaranteed_allocated());
1041    }
1042
1043    /// Returns a type which provides statistics about the memory usage of the bump allocator.
1044    #[must_use]
1045    #[inline(always)]
1046    pub fn stats(&self) -> Stats<'_, A, UP, GUARANTEED_ALLOCATED> {
1047        self.as_scope().stats()
1048    }
1049
1050    /// Returns this `&Bump` as a `&BumpScope`.
1051    #[inline(always)]
1052    pub fn as_scope(&self) -> &BumpScope<'_, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES> {
1053        // SAFETY: `Bump` and `BumpScope` both have the layout of `Cell<RawChunk>`
1054        //         `BumpScope`'s api is a subset of `Bump`'s
1055        unsafe { &*ptr::from_ref(self).cast() }
1056    }
1057
1058    /// Returns this `&mut Bump` as a `&mut BumpScope`.
1059    #[inline(always)]
1060    pub fn as_mut_scope(&mut self) -> &mut BumpScope<'_, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES> {
1061        // SAFETY: `Bump` and `BumpScope` both have the layout of `Cell<RawChunk>`
1062        //         `BumpScope`'s api is a subset of `Bump`'s
1063        unsafe { &mut *ptr::from_mut(self).cast() }
1064    }
1065
1066    /// Converts this `Bump` into a `Bump` with a new minimum alignment.
1067    #[inline(always)]
1068    pub fn into_aligned<const NEW_MIN_ALIGN: usize>(self) -> Bump<A, NEW_MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
1069    where
1070        MinimumAlignment<NEW_MIN_ALIGN>: SupportedMinimumAlignment,
1071    {
1072        self.as_scope().align::<NEW_MIN_ALIGN>();
1073        unsafe { self.cast_align() }
1074    }
1075
1076    /// Mutably borrows `Bump` with a new minimum alignment.
1077    ///
1078    /// **This cannot decrease the alignment.** Trying to decrease alignment will result in a compile error.
1079    /// You can use [`aligned`](Self::aligned) or [`scoped_aligned`](Self::scoped_aligned) to decrease the alignment.
1080    ///
1081    /// When decreasing the alignment we need to make sure that the bump position is realigned to the original alignment.
1082    /// That can only be ensured by having a function that takes a closure, like the methods mentioned above do.
1083    #[inline(always)]
1084    pub fn as_mut_aligned<const NEW_MIN_ALIGN: usize>(
1085        &mut self,
1086    ) -> &mut Bump<A, NEW_MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
1087    where
1088        MinimumAlignment<NEW_MIN_ALIGN>: SupportedMinimumAlignment,
1089    {
1090        self.as_scope().must_align_more::<NEW_MIN_ALIGN>();
1091        unsafe { self.cast_align_mut() }
1092    }
1093
1094    #[doc(hidden)]
1095    #[inline(always)]
1096    #[deprecated = "renamed to `as_mut_aligned`"]
1097    pub fn as_aligned_mut<const NEW_MIN_ALIGN: usize>(
1098        &mut self,
1099    ) -> &mut Bump<A, NEW_MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
1100    where
1101        MinimumAlignment<NEW_MIN_ALIGN>: SupportedMinimumAlignment,
1102    {
1103        self.as_mut_aligned()
1104    }
1105
1106    #[inline(always)]
1107    pub(crate) unsafe fn cast_align<const NEW_MIN_ALIGN: usize>(
1108        self,
1109    ) -> Bump<A, NEW_MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
1110    where
1111        MinimumAlignment<NEW_MIN_ALIGN>: SupportedMinimumAlignment,
1112    {
1113        let chunk = self.chunk.get();
1114        mem::forget(self);
1115
1116        Bump { chunk: Cell::new(chunk) }
1117    }
1118
1119    #[inline(always)]
1120    pub(crate) unsafe fn cast_align_mut<const NEW_MIN_ALIGN: usize>(
1121        &mut self,
1122    ) -> &mut Bump<A, NEW_MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
1123    where
1124        MinimumAlignment<NEW_MIN_ALIGN>: SupportedMinimumAlignment,
1125    {
1126        unsafe { &mut *ptr::from_mut(self).cast::<Bump<A, NEW_MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>>() }
1127    }
1128
1129    /// Converts this `Bump` into a [guaranteed allocated](crate#what-does-guaranteed-allocated-mean) `Bump`.
1130    ///
1131    /// If this `Bump` is not yet allocated, `f` will be called to allocate it.
1132    ///
1133    /// # Panics
1134    ///
1135    /// Panics if the closure panics.
1136    ///
1137    /// # Examples
1138    ///
1139    /// Creating scopes with a non-`GUARANTEED_ALLOCATED` bump is not possible.
1140    /// ```compile_fail,E0599
1141    /// # use bump_scope::Bump;
1142    /// # use bump_scope::alloc::Global;
1143    /// let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1144    ///
1145    /// bump.scoped(|bump| {
1146    ///     // ...
1147    ///     # _ = bump;
1148    /// });
1149    /// ```
1150    ///
1151    /// Using this function you can make a `Bump` guaranteed allocated and create scopes.
1152    /// ```
1153    /// # use bump_scope::Bump;
1154    /// # use bump_scope::alloc::Global;
1155    /// let bump: Bump<Global, 1, true, false> = Bump::unallocated();
1156    /// let mut bump = bump.into_guaranteed_allocated(Bump::new);
1157    ///
1158    /// bump.scoped(|bump| {
1159    ///     // ...
1160    ///     # _ = bump;
1161    /// });
1162    /// ```
1163    ///
1164    /// Initialize an unallocated `Bump` with a custom size or capacity:
1165    /// ```
1166    /// # use core::alloc::Layout;
1167    /// # use bump_scope::{Bump, alloc::Global};
1168    /// # let bump: Bump<Global, 1, true, false> = Bump::unallocated();
1169    /// let bump = bump.into_guaranteed_allocated(|| {
1170    ///     Bump::with_size(2048)
1171    /// });
1172    ///
1173    /// // or
1174    ///
1175    /// # let bump: Bump<Global, 1, true, false> = Bump::unallocated();
1176    /// let bump = bump.into_guaranteed_allocated(|| {
1177    ///     Bump::with_capacity(Layout::new::<[i32; 1024]>())
1178    /// });
1179    /// ```
1180    #[inline(always)]
1181    #[cfg(feature = "panic-on-alloc")]
1182    pub fn into_guaranteed_allocated(
1183        self,
1184        f: impl FnOnce() -> Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>,
1185    ) -> Bump<A, MIN_ALIGN, UP, true, DEALLOCATES> {
1186        self.as_scope().ensure_allocated(f);
1187        unsafe { transmute(self) }
1188    }
1189
1190    /// Converts this `Bump` into a [guaranteed allocated](crate#what-does-guaranteed-allocated-mean) `Bump`.
1191    ///
1192    /// If this `Bump` is not yet allocated, `f` will be called to allocate it.
1193    ///
1194    /// # Errors
1195    ///
1196    /// Errors if the closure fails.
1197    ///
1198    /// # Examples
1199    ///
1200    /// Creating scopes with a non-`GUARANTEED_ALLOCATED` bump is not possible.
1201    /// ```compile_fail,E0599
1202    /// # use bump_scope::Bump;
1203    /// # use bump_scope::alloc::Global;
1204    /// let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1205    ///
1206    /// bump.scoped(|bump| {
1207    ///     // ...
1208    ///     # _ = bump;
1209    /// });
1210    /// ```
1211    ///
1212    /// Using this function you can make a `Bump` guaranteed allocated and create scopes.
1213    /// ```
1214    /// # use bump_scope::Bump;
1215    /// # use bump_scope::alloc::Global;
1216    /// let bump: Bump<Global, 1, true, false> = Bump::unallocated();
1217    /// let mut bump = bump.try_into_guaranteed_allocated(Bump::try_new)?;
1218    ///
1219    /// bump.scoped(|bump| {
1220    ///     // ...
1221    ///     # _ = bump;
1222    /// });
1223    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1224    /// ```
1225    ///
1226    /// Initialize an unallocated `Bump` with a custom size or capacity:
1227    /// ```
1228    /// # use core::alloc::Layout;
1229    /// # use bump_scope::{Bump, alloc::Global};
1230    /// # let bump: Bump<Global, 1, true, false> = Bump::unallocated();
1231    /// let bump = bump.try_into_guaranteed_allocated(|| {
1232    ///     Bump::try_with_size(2048)
1233    /// })?;
1234    ///
1235    /// // or
1236    ///
1237    /// # let bump: Bump<Global, 1, true, false> = Bump::unallocated();
1238    /// let bump = bump.try_into_guaranteed_allocated(|| {
1239    ///     Bump::try_with_capacity(Layout::new::<[i32; 1024]>())
1240    /// })?;
1241    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1242    /// ```
1243    #[inline(always)]
1244    pub fn try_into_guaranteed_allocated(
1245        self,
1246        f: impl FnOnce() -> Result<Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>, AllocError>,
1247    ) -> Result<Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>, AllocError> {
1248        self.as_scope().try_ensure_allocated(f)?;
1249        Ok(unsafe { transmute(self) })
1250    }
1251
1252    /// Borrows `Bump` as a [guaranteed allocated](crate#what-does-guaranteed-allocated-mean) `Bump`.
1253    ///
1254    /// If this `Bump` is not yet allocated, `f` will be called to allocate it.
1255    ///
1256    /// # Panics
1257    ///
1258    /// Panics if the closure panics.
1259    ///
1260    /// # Examples
1261    ///
1262    /// Initialize an unallocated `Bump` with a custom size or capacity:
1263    /// ```
1264    /// # use core::alloc::Layout;
1265    /// # use bump_scope::{Bump, alloc::Global};
1266    /// # let bump: Bump<Global, 1, true, false> = Bump::unallocated();
1267    /// let bump = bump.as_guaranteed_allocated(|| {
1268    ///     Bump::with_size(2048)
1269    /// });
1270    /// # _ = bump;
1271    ///
1272    /// // or
1273    ///
1274    /// # let bump: Bump<Global, 1, true, false> = Bump::unallocated();
1275    /// let bump = bump.as_guaranteed_allocated(|| {
1276    ///     Bump::with_capacity(Layout::new::<[i32; 1024]>())
1277    /// });
1278    /// # _ = bump;
1279    /// ```
1280    #[inline(always)]
1281    #[cfg(feature = "panic-on-alloc")]
1282    pub fn as_guaranteed_allocated(
1283        &self,
1284        f: impl FnOnce() -> Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>,
1285    ) -> &Bump<A, MIN_ALIGN, UP, true, DEALLOCATES> {
1286        self.as_scope().ensure_allocated(f);
1287        unsafe { transmute_ref(self) }
1288    }
1289
1290    /// Borrows `Bump` as an [guaranteed allocated](crate#what-does-guaranteed-allocated-mean) `Bump`.
1291    ///
1292    /// If this `Bump` is not yet allocated, `f` will be called to allocate it.
1293    ///
1294    /// # Errors
1295    ///
1296    /// Errors if the closure fails.
1297    ///
1298    /// [`try_as_mut_guaranteed_allocated`]: Self::try_as_mut_guaranteed_allocated
1299    ///
1300    /// # Examples
1301    ///
1302    /// Initialize an unallocated `Bump` with a custom size or capacity:
1303    /// ```
1304    /// # use core::alloc::Layout;
1305    /// # use bump_scope::{Bump, alloc::Global};
1306    /// # let bump: Bump<Global, 1, true, false> = Bump::unallocated();
1307    /// let bump = bump.try_as_guaranteed_allocated(|| {
1308    ///     Bump::try_with_size(2048)
1309    /// })?;
1310    /// # _ = bump;
1311    ///
1312    /// // or
1313    ///
1314    /// let bump = bump.try_as_guaranteed_allocated(|| {
1315    ///     Bump::try_with_capacity(Layout::new::<[i32; 1024]>())
1316    /// })?;
1317    /// # _ = bump;
1318    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1319    /// ```
1320    #[inline(always)]
1321    pub fn try_as_guaranteed_allocated(
1322        &self,
1323        f: impl FnOnce() -> Result<Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>, AllocError>,
1324    ) -> Result<&Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>, AllocError> {
1325        self.as_scope().try_ensure_allocated(f)?;
1326        Ok(unsafe { transmute_ref(self) })
1327    }
1328
1329    /// Mutably borrows `Bump` as a [guaranteed allocated](crate#what-does-guaranteed-allocated-mean) `Bump`.
1330    ///
1331    /// If this `Bump` is not yet allocated, `f` will be called to allocate it.
1332    ///
1333    /// # Panics
1334    ///
1335    /// Panics if the closure panics.
1336    ///
1337    /// # Examples
1338    ///
1339    /// Creating scopes with a non-`GUARANTEED_ALLOCATED` bump is not possible.
1340    /// ```compile_fail,E0599
1341    /// # use bump_scope::Bump;
1342    /// # use bump_scope::alloc::Global;
1343    /// let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1344    ///
1345    /// bump.scoped(|bump| {
1346    ///     // ...
1347    ///     # _ = bump;
1348    /// });
1349    /// ```
1350    ///
1351    /// Using this function you can make a `Bump` guaranteed allocated and create scopes.
1352    /// ```
1353    /// # use bump_scope::Bump;
1354    /// # use bump_scope::alloc::Global;
1355    /// let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1356    ///
1357    /// bump.as_mut_guaranteed_allocated(Bump::new).scoped(|bump| {
1358    ///     // ...
1359    ///     # _ = bump;
1360    /// });
1361    /// ```
1362    ///
1363    /// Initialize an unallocated `Bump` with a custom size or capacity:
1364    /// ```
1365    /// # use core::alloc::Layout;
1366    /// # use bump_scope::{Bump, alloc::Global};
1367    /// # let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1368    /// let bump = bump.as_mut_guaranteed_allocated(|| {
1369    ///     Bump::with_size(2048)
1370    /// });
1371    /// # _ = bump;
1372    ///
1373    /// // or
1374    ///
1375    /// # let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1376    /// let bump = bump.as_mut_guaranteed_allocated(|| {
1377    ///     Bump::with_capacity(Layout::new::<[i32; 1024]>())
1378    /// });
1379    /// # _ = bump;
1380    /// ```
1381    #[inline(always)]
1382    #[cfg(feature = "panic-on-alloc")]
1383    pub fn as_mut_guaranteed_allocated(
1384        &mut self,
1385        f: impl FnOnce() -> Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>,
1386    ) -> &mut Bump<A, MIN_ALIGN, UP, true, DEALLOCATES> {
1387        self.as_scope().ensure_allocated(f);
1388        unsafe { transmute_mut(self) }
1389    }
1390
1391    /// Mutably borrows `Bump` as an [guaranteed allocated](crate#what-does-guaranteed-allocated-mean) `Bump`.
1392    ///
1393    /// If this `Bump` is not yet allocated, `f` will be called to allocate it.
1394    ///
1395    /// # Errors
1396    ///
1397    /// Errors if the closure fails.
1398    ///
1399    /// # Examples
1400    ///
1401    /// Creating scopes with a non-`GUARANTEED_ALLOCATED` bump is not possible.
1402    /// ```compile_fail,E0599
1403    /// # use bump_scope::Bump;
1404    /// # use bump_scope::alloc::Global;
1405    /// let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1406    ///
1407    /// bump.scoped(|bump| {
1408    ///     // ...
1409    ///     # _ = bump;
1410    /// });
1411    /// ```
1412    ///
1413    /// Using this function you can make a `Bump` guaranteed allocated and create scopes.
1414    /// ```
1415    /// # use bump_scope::Bump;
1416    /// # use bump_scope::alloc::Global;
1417    /// let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1418    ///
1419    /// bump.try_as_mut_guaranteed_allocated(Bump::try_new)?.scoped(|bump| {
1420    ///     // ...
1421    ///     # _ = bump;
1422    /// });
1423    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1424    /// ```
1425    ///
1426    /// Initialize an unallocated `Bump` with a custom size or capacity:
1427    /// ```
1428    /// # use core::alloc::Layout;
1429    /// # use bump_scope::{Bump, alloc::Global};
1430    /// # let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1431    /// let bump = bump.try_as_mut_guaranteed_allocated(|| {
1432    ///     Bump::try_with_size(2048)
1433    /// })?;
1434    /// # _ = bump;
1435    ///
1436    /// // or
1437    ///
1438    /// # let mut bump: Bump<Global, 1, true, false> = Bump::unallocated();
1439    /// let bump = bump.try_as_mut_guaranteed_allocated(|| {
1440    ///     Bump::try_with_capacity(Layout::new::<[i32; 1024]>())
1441    /// })?;
1442    /// # _ = bump;
1443    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1444    /// ```
1445    #[inline(always)]
1446    pub fn try_as_mut_guaranteed_allocated(
1447        &mut self,
1448        f: impl FnOnce() -> Result<Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>, AllocError>,
1449    ) -> Result<&mut Bump<A, MIN_ALIGN, UP, true, DEALLOCATES>, AllocError> {
1450        self.as_scope().try_ensure_allocated(f)?;
1451        Ok(unsafe { transmute_mut(self) })
1452    }
1453
1454    /// Converts this `BumpScope` into a ***not*** [guaranteed allocated](crate#what-does-guaranteed-allocated-mean) `Bump`.
1455    #[inline(always)]
1456    pub fn into_not_guaranteed_allocated(self) -> Bump<A, MIN_ALIGN, UP, false, DEALLOCATES>
1457    where
1458        A: Default,
1459    {
1460        // SAFETY: it's always valid to interpret a guaranteed allocated as a non guaranteed allocated
1461        unsafe { transmute(self) }
1462    }
1463
1464    /// Borrows `Bump` as a ***not*** [guaranteed allocated](crate#what-does-guaranteed-allocated-mean) `Bump`.
1465    ///
1466    /// Note that it's not possible to mutably borrow as a not guaranteed allocated bump allocator. That's because
1467    /// a user could `mem::swap` it with an actual unallocated bump allocator which in turn would make `&mut self`
1468    /// unallocated.
1469    #[inline(always)]
1470    pub fn as_not_guaranteed_allocated(&self) -> &Bump<A, MIN_ALIGN, UP, false, DEALLOCATES>
1471    where
1472        A: Default,
1473    {
1474        // SAFETY: it's always valid to interpret a guaranteed allocated as a non guaranteed allocated
1475        unsafe { transmute_ref(self) }
1476    }
1477
1478    /// Converts this `Bump` into a raw pointer.
1479    ///
1480    /// ```
1481    /// use bump_scope::Bump;
1482    ///
1483    /// let bump: Bump = Bump::new();
1484    /// let ptr = bump.into_raw();
1485    /// let bump: Bump = unsafe { Bump::from_raw(ptr) };
1486    ///
1487    /// bump.alloc_str("Why did i do this?");
1488    /// ```
1489    #[inline]
1490    #[must_use]
1491    pub fn into_raw(self) -> NonNull<()> {
1492        let this = ManuallyDrop::new(self);
1493        this.chunk.get().header().cast()
1494    }
1495
1496    /// Converts the raw pointer that was created with [`into_raw`](Bump::into_raw) back into a `Bump`.
1497    ///
1498    /// # Safety
1499    /// - `ptr` must have been created with `Self::into_raw`.
1500    /// - This function must only be called once with this `ptr`.
1501    #[inline]
1502    #[must_use]
1503    pub unsafe fn from_raw(ptr: NonNull<()>) -> Self {
1504        Self {
1505            chunk: Cell::new(unsafe { RawChunk::from_header(ptr.cast()) }),
1506        }
1507    }
1508
1509    /// Turns off deallocation and shrinking.
1510    pub fn into_without_dealloc(self) -> Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, false> {
1511        unsafe { transmute(self) }
1512    }
1513
1514    /// Turns off deallocation and shrinking.
1515    pub fn as_without_dealloc(&self) -> &Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, false> {
1516        unsafe { transmute_ref(self) }
1517    }
1518
1519    /// Turns off deallocation and shrinking.
1520    pub fn as_mut_without_dealloc(&mut self) -> &mut Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, false> {
1521        unsafe { transmute_mut(self) }
1522    }
1523
1524    /// Turns on deallocation and shrinking.
1525    pub fn into_with_dealloc(self) -> Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, true> {
1526        unsafe { transmute(self) }
1527    }
1528
1529    /// Turns on deallocation and shrinking.
1530    pub fn as_with_dealloc(&self) -> &Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, true> {
1531        unsafe { transmute_ref(self) }
1532    }
1533
1534    /// Turns on deallocation and shrinking.
1535    pub fn as_mut_with_dealloc(&mut self) -> &mut Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, true> {
1536        unsafe { transmute_mut(self) }
1537    }
1538}
1539
1540impl<'b, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool>
1541    From<&'b Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>>
1542    for &'b BumpScope<'b, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
1543where
1544    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
1545    A: Allocator,
1546{
1547    #[inline(always)]
1548    fn from(value: &'b Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>) -> Self {
1549        value.as_scope()
1550    }
1551}
1552
1553impl<'b, A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool>
1554    From<&'b mut Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>>
1555    for &'b mut BumpScope<'b, A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
1556where
1557    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
1558    A: Allocator,
1559{
1560    #[inline(always)]
1561    fn from(value: &'b mut Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>) -> Self {
1562        value.as_mut_scope()
1563    }
1564}
1565
1566/// Methods to allocate. Available as fallible or infallible.
1567impl<A, const MIN_ALIGN: usize, const UP: bool, const GUARANTEED_ALLOCATED: bool, const DEALLOCATES: bool>
1568    Bump<A, MIN_ALIGN, UP, GUARANTEED_ALLOCATED, DEALLOCATES>
1569where
1570    MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
1571    A: BaseAllocator<GUARANTEED_ALLOCATED>,
1572{
1573    /// Allocate an object.
1574    ///
1575    /// # Panics
1576    /// Panics if the allocation fails.
1577    ///
1578    /// # Examples
1579    /// ```
1580    /// # use bump_scope::Bump;
1581    /// # let bump: Bump = Bump::new();
1582    /// let allocated = bump.alloc(123);
1583    /// assert_eq!(allocated, 123);
1584    /// ```
1585    #[inline(always)]
1586    #[cfg(feature = "panic-on-alloc")]
1587    pub fn alloc<T>(&self, value: T) -> BumpBox<'_, T> {
1588        self.as_scope().alloc(value)
1589    }
1590
1591    /// Allocate an object.
1592    ///
1593    /// # Errors
1594    /// Errors if the allocation fails.
1595    ///
1596    /// # Examples
1597    /// ```
1598    /// # use bump_scope::Bump;
1599    /// # let bump: Bump = Bump::try_new()?;
1600    /// let allocated = bump.try_alloc(123)?;
1601    /// assert_eq!(allocated, 123);
1602    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1603    /// ```
1604    #[inline(always)]
1605    pub fn try_alloc<T>(&self, value: T) -> Result<BumpBox<'_, T>, AllocError> {
1606        self.as_scope().try_alloc(value)
1607    }
1608
1609    /// Allocates space for an object, then calls `f` to produce the
1610    /// value to be put in that place.
1611    ///
1612    /// In some cases this could be more performant than `alloc(f())` because it
1613    /// permits the compiler to directly place `T` in the allocated memory instead of
1614    /// constructing it on the stack and copying it over.
1615    ///
1616    /// # Panics
1617    /// Panics if the allocation fails.
1618    ///
1619    /// # Examples
1620    /// ```
1621    /// # use bump_scope::Bump;
1622    /// # let bump: Bump = Bump::new();
1623    /// let allocated = bump.alloc_with(|| 123);
1624    /// assert_eq!(allocated, 123);
1625    /// ```
1626    #[inline(always)]
1627    #[cfg(feature = "panic-on-alloc")]
1628    pub fn alloc_with<T>(&self, f: impl FnOnce() -> T) -> BumpBox<'_, T> {
1629        self.as_scope().alloc_with(f)
1630    }
1631
1632    /// Allocates space for an object, then calls `f` to produce the
1633    /// value to be put in that place.
1634    ///
1635    /// In some cases this could be more performant than `try_alloc(f())` because it
1636    /// permits the compiler to directly place `T` in the allocated memory instead of
1637    /// constructing it on the stack and copying it over.
1638    ///
1639    /// # Errors
1640    /// Errors if the allocation fails.
1641    ///
1642    /// # Examples
1643    /// ```
1644    /// # use bump_scope::Bump;
1645    /// # let bump: Bump = Bump::try_new()?;
1646    /// let allocated = bump.try_alloc_with(|| 123)?;
1647    /// assert_eq!(allocated, 123);
1648    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1649    /// ```
1650    #[inline(always)]
1651    pub fn try_alloc_with<T>(&self, f: impl FnOnce() -> T) -> Result<BumpBox<'_, T>, AllocError> {
1652        self.as_scope().try_alloc_with(f)
1653    }
1654
1655    /// Allocate an object with its default value.
1656    ///
1657    /// This is equivalent to <code>[alloc_with](Self::alloc_with)(T::default)</code>.
1658    ///
1659    /// # Panics
1660    /// Panics if the allocation fails.
1661    ///
1662    /// # Examples
1663    /// ```
1664    /// # use bump_scope::Bump;
1665    /// # let bump: Bump = Bump::new();
1666    /// let allocated = bump.alloc_default::<i32>();
1667    /// assert_eq!(allocated, 0);
1668    /// ```
1669    #[inline(always)]
1670    #[cfg(feature = "panic-on-alloc")]
1671    pub fn alloc_default<T: Default>(&self) -> BumpBox<'_, T> {
1672        self.as_scope().alloc_default()
1673    }
1674
1675    /// Allocate an object with its default value.
1676    ///
1677    /// This is equivalent to <code>[try_alloc_with](Self::try_alloc_with)(T::default)</code>.
1678    ///
1679    /// # Errors
1680    /// Errors if the allocation fails.
1681    ///
1682    /// # Examples
1683    /// ```
1684    /// # use bump_scope::Bump;
1685    /// # let bump: Bump = Bump::try_new()?;
1686    /// let allocated = bump.try_alloc_default()?;
1687    /// assert_eq!(allocated, 0);
1688    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1689    /// ```
1690    #[inline(always)]
1691    pub fn try_alloc_default<T: Default>(&self) -> Result<BumpBox<'_, T>, AllocError> {
1692        self.as_scope().try_alloc_default()
1693    }
1694
1695    /// Allocate an object by cloning it.
1696    ///
1697    /// Unlike `alloc(value.clone())` this method also works for dynamically-sized types.
1698    ///
1699    /// # Panics
1700    /// Panics if the allocation fails.
1701    ///
1702    /// # Examples
1703    ///
1704    /// Allocate a `slice`, `str`, `CStr`, `Path`:
1705    #[cfg_attr(feature = "nightly-clone-to-uninit", doc = "```")]
1706    #[cfg_attr(not(feature = "nightly-clone-to-uninit"), doc = "```ignore")]
1707    /// #![feature(clone_to_uninit)]
1708    ///
1709    /// use std::path::Path;
1710    /// # use bump_scope::Bump;
1711    /// # let bump: Bump = Bump::new();
1712    ///
1713    /// let cloned = bump.alloc_clone(&[1, 2, 3]);
1714    /// assert_eq!(cloned, &[1, 2, 3]);
1715    ///
1716    /// let cloned = bump.alloc_clone("foo");
1717    /// assert_eq!(cloned, "foo");
1718    ///
1719    /// let cloned = bump.alloc_clone(c"foo");
1720    /// assert_eq!(cloned, c"foo");
1721    ///
1722    /// let cloned = bump.alloc_clone(Path::new("foo"));
1723    /// assert_eq!(cloned, Path::new("foo"));
1724    /// ```
1725    ///
1726    /// Allocate a trait object:
1727    #[cfg_attr(feature = "nightly-clone-to-uninit", doc = "```")]
1728    #[cfg_attr(not(feature = "nightly-clone-to-uninit"), doc = "```ignore")]
1729    /// #![feature(clone_to_uninit)]
1730    ///
1731    /// use core::clone::CloneToUninit;
1732    /// # use bump_scope::Bump;
1733    ///
1734    /// trait FnClone: Fn() -> String + CloneToUninit {}
1735    /// impl<T: ?Sized + Fn() -> String + CloneToUninit> FnClone for T {}
1736    ///
1737    /// // the closure references a local variable
1738    /// let reference = &String::from("Hello,");
1739    ///
1740    /// // and owns a string that it will have to clone
1741    /// let value = String::from("world!");
1742    ///
1743    /// let closure = move || format!("{reference} {value}");
1744    /// let object: &dyn FnClone = &closure;
1745    ///
1746    /// assert_eq!(object(), "Hello, world!");
1747    ///
1748    /// let bump: Bump = Bump::new();
1749    /// let object_clone = bump.alloc_clone(object);
1750    ///
1751    /// assert_eq!(object_clone(), "Hello, world!");
1752    /// ```    
1753    #[cfg(feature = "nightly-clone-to-uninit")]
1754    pub fn alloc_clone<T: CloneToUninit + ?Sized>(&self, value: &T) -> BumpBox<'_, T> {
1755        self.as_scope().alloc_clone(value)
1756    }
1757
1758    /// Allocate an object by cloning it.
1759    ///
1760    /// Unlike `alloc(value.clone())` this method also works for dynamically-sized types.
1761    ///
1762    /// # Errors
1763    /// Errors if the allocation fails.
1764    ///
1765    /// # Examples
1766    ///
1767    /// Allocate a `slice`, `str`, `CStr`, `Path`:
1768    #[cfg_attr(feature = "nightly-clone-to-uninit", doc = "```")]
1769    #[cfg_attr(not(feature = "nightly-clone-to-uninit"), doc = "```ignore")]
1770    /// #![feature(clone_to_uninit)]
1771    ///
1772    /// use std::path::Path;
1773    /// # use bump_scope::Bump;
1774    /// # let bump: Bump = Bump::try_new()?;
1775    ///
1776    /// let cloned = bump.try_alloc_clone(&[1, 2, 3])?;
1777    /// assert_eq!(cloned, &[1, 2, 3]);
1778    ///
1779    /// let cloned = bump.try_alloc_clone("foo")?;
1780    /// assert_eq!(cloned, "foo");
1781    ///
1782    /// let cloned = bump.try_alloc_clone(c"foo")?;
1783    /// assert_eq!(cloned, c"foo");
1784    ///
1785    /// let cloned = bump.try_alloc_clone(Path::new("foo"))?;
1786    /// assert_eq!(cloned, Path::new("foo"));
1787    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1788    /// ```
1789    ///
1790    /// Allocate a trait object:
1791    #[cfg_attr(feature = "nightly-clone-to-uninit", doc = "```")]
1792    #[cfg_attr(not(feature = "nightly-clone-to-uninit"), doc = "```ignore")]
1793    /// #![feature(clone_to_uninit)]
1794    ///
1795    /// use core::clone::CloneToUninit;
1796    /// # use bump_scope::Bump;
1797    ///
1798    /// trait FnClone: Fn() -> String + CloneToUninit {}
1799    /// impl<T: ?Sized + Fn() -> String + CloneToUninit> FnClone for T {}
1800    ///
1801    /// // the closure references a local variable
1802    /// let reference = &String::from("Hello,");
1803    ///
1804    /// // and owns a string that it will have to clone
1805    /// let value = String::from("world!");
1806    ///
1807    /// let closure = move || format!("{reference} {value}");
1808    /// let object: &dyn FnClone = &closure;
1809    ///
1810    /// assert_eq!(object(), "Hello, world!");
1811    ///
1812    /// let bump: Bump = Bump::try_new()?;
1813    /// let object_clone = bump.try_alloc_clone(object)?;
1814    ///
1815    /// assert_eq!(object_clone(), "Hello, world!");
1816    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1817    /// ```
1818    #[cfg(feature = "nightly-clone-to-uninit")]
1819    pub fn try_alloc_clone<T: CloneToUninit + ?Sized>(&self, value: &T) -> Result<BumpBox<'_, T>, AllocError> {
1820        self.as_scope().try_alloc_clone(value)
1821    }
1822
1823    /// Allocate a slice and fill it by moving elements from an existing slice.
1824    ///
1825    /// # Panics
1826    /// Panics if the allocation fails.
1827    ///
1828    /// # Examples
1829    /// ```
1830    /// # use bump_scope::Bump;
1831    /// # let bump: Bump = Bump::new();
1832    /// // by value
1833    /// let a = bump.alloc_slice_move([1, 2]);
1834    /// let b = bump.alloc_slice_move(vec![3, 4]);
1835    /// let c = bump.alloc_slice_move(bump.alloc_iter(5..=6));
1836    ///
1837    /// // by mutable reference
1838    /// let mut other = vec![7, 8];
1839    /// let d = bump.alloc_slice_move(&mut other);
1840    /// assert!(other.is_empty());
1841    ///
1842    /// assert_eq!(a, [1, 2]);
1843    /// assert_eq!(b, [3, 4]);
1844    /// assert_eq!(c, [5, 6]);
1845    /// assert_eq!(d, [7, 8]);
1846    /// ```
1847    #[inline(always)]
1848    #[cfg(feature = "panic-on-alloc")]
1849    pub fn alloc_slice_move<T>(&self, slice: impl OwnedSlice<Item = T>) -> BumpBox<'_, [T]> {
1850        self.as_scope().alloc_slice_move(slice)
1851    }
1852
1853    /// Allocate a slice and fill it by moving elements from an existing slice.
1854    ///
1855    /// # Errors
1856    /// Errors if the allocation fails.
1857    ///
1858    /// # Examples
1859    /// ```
1860    /// # use bump_scope::Bump;
1861    /// # let bump: Bump = Bump::try_new()?;
1862    /// // by value
1863    /// let a = bump.try_alloc_slice_move([1, 2])?;
1864    /// let b = bump.try_alloc_slice_move(vec![3, 4])?;
1865    /// let c = bump.try_alloc_slice_move(bump.alloc_iter(5..=6))?;
1866    ///
1867    /// // by mutable reference
1868    /// let mut other = vec![7, 8];
1869    /// let d = bump.try_alloc_slice_move(&mut other)?;
1870    /// assert!(other.is_empty());
1871    ///
1872    /// assert_eq!(a, [1, 2]);
1873    /// assert_eq!(b, [3, 4]);
1874    /// assert_eq!(c, [5, 6]);
1875    /// assert_eq!(d, [7, 8]);
1876    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1877    /// ```
1878    #[inline(always)]
1879    pub fn try_alloc_slice_move<T>(&self, slice: impl OwnedSlice<Item = T>) -> Result<BumpBox<'_, [T]>, AllocError> {
1880        self.as_scope().try_alloc_slice_move(slice)
1881    }
1882
1883    /// Allocate a slice and fill it by `Copy`ing elements from an existing slice.
1884    ///
1885    /// # Panics
1886    /// Panics if the allocation fails.
1887    ///
1888    /// # Examples
1889    /// ```
1890    /// # use bump_scope::Bump;
1891    /// # let bump: Bump = Bump::new();
1892    /// let allocated = bump.alloc_slice_copy(&[1, 2, 3]);
1893    /// assert_eq!(allocated, [1, 2, 3]);
1894    /// ```
1895    #[inline(always)]
1896    #[cfg(feature = "panic-on-alloc")]
1897    pub fn alloc_slice_copy<T: Copy>(&self, slice: &[T]) -> BumpBox<'_, [T]> {
1898        self.as_scope().alloc_slice_copy(slice)
1899    }
1900
1901    /// Allocate a slice and fill it by `Copy`ing elements from an existing slice.
1902    ///
1903    /// # Errors
1904    /// Errors if the allocation fails.
1905    ///
1906    /// # Examples
1907    /// ```
1908    /// # use bump_scope::Bump;
1909    /// # let bump: Bump = Bump::try_new()?;
1910    /// let allocated = bump.try_alloc_slice_copy(&[1, 2, 3])?;
1911    /// assert_eq!(allocated, [1, 2, 3]);
1912    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1913    /// ```
1914    #[inline(always)]
1915    pub fn try_alloc_slice_copy<T: Copy>(&self, slice: &[T]) -> Result<BumpBox<'_, [T]>, AllocError> {
1916        self.as_scope().try_alloc_slice_copy(slice)
1917    }
1918
1919    /// Allocate a slice and fill it by `Clone`ing elements from an existing slice.
1920    ///
1921    /// # Panics
1922    /// Panics if the allocation fails.
1923    ///
1924    /// # Examples
1925    /// ```
1926    /// # use bump_scope::Bump;
1927    /// # let bump: Bump = Bump::new();
1928    /// let allocated = bump.alloc_slice_clone(&[String::from("a"), String::from("b")]);
1929    /// assert_eq!(allocated, [String::from("a"), String::from("b")]);
1930    /// ```
1931    #[inline(always)]
1932    #[cfg(feature = "panic-on-alloc")]
1933    pub fn alloc_slice_clone<T: Clone>(&self, slice: &[T]) -> BumpBox<'_, [T]> {
1934        self.as_scope().alloc_slice_clone(slice)
1935    }
1936
1937    /// Allocate a slice and fill it by `Clone`ing elements from an existing slice.
1938    ///
1939    /// # Errors
1940    /// Errors if the allocation fails.
1941    ///
1942    /// # Examples
1943    /// ```
1944    /// # use bump_scope::Bump;
1945    /// # let bump: Bump = Bump::try_new()?;
1946    /// let allocated = bump.try_alloc_slice_clone(&[String::from("a"), String::from("b")])?;
1947    /// assert_eq!(allocated, [String::from("a"), String::from("b")]);
1948    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1949    /// ```
1950    #[inline(always)]
1951    pub fn try_alloc_slice_clone<T: Clone>(&self, slice: &[T]) -> Result<BumpBox<'_, [T]>, AllocError> {
1952        self.as_scope().try_alloc_slice_clone(slice)
1953    }
1954
1955    /// Allocate a slice and fill it with elements by cloning `value`.
1956    ///
1957    /// # Panics
1958    /// Panics if the allocation fails.
1959    ///
1960    /// # Examples
1961    /// ```
1962    /// # use bump_scope::Bump;
1963    /// # let bump: Bump = Bump::new();
1964    /// let allocated = bump.alloc_slice_fill(3, "ho");
1965    /// assert_eq!(allocated, ["ho", "ho", "ho"]);
1966    /// ```
1967    #[inline(always)]
1968    #[cfg(feature = "panic-on-alloc")]
1969    pub fn alloc_slice_fill<T: Clone>(&self, len: usize, value: T) -> BumpBox<'_, [T]> {
1970        self.as_scope().alloc_slice_fill(len, value)
1971    }
1972
1973    /// Allocate a slice and fill it with elements by cloning `value`.
1974    ///
1975    /// # Errors
1976    /// Errors if the allocation fails.
1977    ///
1978    /// # Examples
1979    /// ```
1980    /// # use bump_scope::Bump;
1981    /// # let bump: Bump = Bump::try_new()?;
1982    /// let allocated = bump.try_alloc_slice_fill(3, "ho")?;
1983    /// assert_eq!(allocated, ["ho", "ho", "ho"]);
1984    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1985    /// ```
1986    #[inline(always)]
1987    pub fn try_alloc_slice_fill<T: Clone>(&self, len: usize, value: T) -> Result<BumpBox<'_, [T]>, AllocError> {
1988        self.as_scope().try_alloc_slice_fill(len, value)
1989    }
1990
1991    /// Allocates a slice by fill it with elements returned by calling a closure repeatedly.
1992    ///
1993    /// This method uses a closure to create new values. If you'd rather
1994    /// [`Clone`] a given value, use [`alloc_slice_fill`](Self::alloc_slice_fill). If you want to use the [`Default`]
1995    /// trait to generate values, you can pass [`Default::default`] as the
1996    /// argument.
1997    ///
1998    /// # Panics
1999    /// Panics if the allocation fails.
2000    ///
2001    /// # Examples
2002    /// ```
2003    /// # use bump_scope::Bump;
2004    /// # let bump: Bump = Bump::new();
2005    /// let allocated = bump.alloc_slice_fill_with::<i32>(3, Default::default);
2006    /// assert_eq!(allocated, [0, 0, 0]);
2007    /// ```
2008    #[inline(always)]
2009    #[cfg(feature = "panic-on-alloc")]
2010    pub fn alloc_slice_fill_with<T>(&self, len: usize, f: impl FnMut() -> T) -> BumpBox<'_, [T]> {
2011        self.as_scope().alloc_slice_fill_with(len, f)
2012    }
2013
2014    /// Allocates a slice by fill it with elements returned by calling a closure repeatedly.
2015    ///
2016    /// This method uses a closure to create new values. If you'd rather
2017    /// [`Clone`] a given value, use [`try_alloc_slice_fill`](Self::try_alloc_slice_fill). If you want to use the [`Default`]
2018    /// trait to generate values, you can pass [`Default::default`] as the
2019    /// argument.
2020    ///
2021    /// # Errors
2022    /// Errors if the allocation fails.
2023    ///
2024    /// # Examples
2025    /// ```
2026    /// # use bump_scope::Bump;
2027    /// # let bump: Bump = Bump::try_new()?;
2028    /// let allocated = bump.try_alloc_slice_fill_with::<i32>(3, Default::default)?;
2029    /// assert_eq!(allocated, [0, 0, 0]);
2030    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2031    /// ```
2032    #[inline(always)]
2033    pub fn try_alloc_slice_fill_with<T>(&self, len: usize, f: impl FnMut() -> T) -> Result<BumpBox<'_, [T]>, AllocError> {
2034        self.as_scope().try_alloc_slice_fill_with(len, f)
2035    }
2036
2037    /// Allocate a `str`.
2038    ///
2039    /// # Panics
2040    /// Panics if the allocation fails.
2041    ///
2042    /// # Examples
2043    /// ```
2044    /// # use bump_scope::Bump;
2045    /// # let bump: Bump = Bump::new();
2046    /// let allocated = bump.alloc_str("Hello, world!");
2047    /// assert_eq!(allocated, "Hello, world!");
2048    /// ```
2049    #[inline(always)]
2050    #[cfg(feature = "panic-on-alloc")]
2051    pub fn alloc_str(&self, src: &str) -> BumpBox<'_, str> {
2052        self.as_scope().alloc_str(src)
2053    }
2054
2055    /// Allocate a `str`.
2056    ///
2057    /// # Errors
2058    /// Errors if the allocation fails.
2059    ///
2060    /// # Examples
2061    /// ```
2062    /// # use bump_scope::Bump;
2063    /// # let bump: Bump = Bump::try_new()?;
2064    /// let allocated = bump.try_alloc_str("Hello, world!")?;
2065    /// assert_eq!(allocated, "Hello, world!");
2066    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2067    /// ```
2068    #[inline(always)]
2069    pub fn try_alloc_str(&self, src: &str) -> Result<BumpBox<'_, str>, AllocError> {
2070        self.as_scope().try_alloc_str(src)
2071    }
2072
2073    /// Allocate a `str` from format arguments.
2074    ///
2075    /// If you have a `&mut self` you can use [`alloc_fmt_mut`](Self::alloc_fmt_mut)
2076    /// instead for better performance.
2077    ///
2078    /// # Panics
2079    /// Panics if the allocation fails.
2080    ///
2081    /// This technically also panics if the `fmt()` implementation returned an Error,
2082    /// but since [`fmt()` implementors should only error when writing to the stream fails](core::fmt::Error),
2083    /// that should be equivalent to an allocation failure.
2084    ///
2085    /// # Examples
2086    /// ```
2087    /// # use bump_scope::Bump;
2088    /// # let bump: Bump = Bump::new();
2089    /// let one = 1;
2090    /// let two = 2;
2091    /// let string = bump.alloc_fmt(format_args!("{one} + {two} = {}", one + two));
2092    ///
2093    /// assert_eq!(string, "1 + 2 = 3");
2094    /// ```
2095    #[inline(always)]
2096    #[cfg(feature = "panic-on-alloc")]
2097    pub fn alloc_fmt(&self, args: fmt::Arguments) -> BumpBox<'_, str> {
2098        self.as_scope().alloc_fmt(args)
2099    }
2100
2101    /// Allocate a `str` from format arguments.
2102    ///
2103    /// If you have a `&mut self` you can use [`try_alloc_fmt_mut`](Self::try_alloc_fmt_mut)
2104    /// instead for better performance.
2105    ///
2106    /// # Errors
2107    /// Errors if the allocation fails.
2108    ///
2109    /// This technically also errors if the `fmt()` implementation returned an Error,
2110    /// but since [`fmt()` implementors should only error when writing to the stream fails](core::fmt::Error),
2111    /// that should be equivalent to an allocation failure.
2112    ///
2113    /// # Examples
2114    /// ```
2115    /// # use bump_scope::Bump;
2116    /// # let bump: Bump = Bump::try_new()?;
2117    /// let one = 1;
2118    /// let two = 2;
2119    /// let string = bump.try_alloc_fmt(format_args!("{one} + {two} = {}", one + two))?;
2120    ///
2121    /// assert_eq!(string, "1 + 2 = 3");
2122    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2123    /// ```
2124    #[inline(always)]
2125    pub fn try_alloc_fmt(&self, args: fmt::Arguments) -> Result<BumpBox<'_, str>, AllocError> {
2126        self.as_scope().try_alloc_fmt(args)
2127    }
2128
2129    /// Allocate a `str` from format arguments.
2130    ///
2131    /// This function is designed as a performance improvement over [`alloc_fmt`](Self::alloc_fmt).
2132    /// By taking `self` as `&mut`, it can use the entire remaining chunk space as the capacity
2133    /// for the temporary string buffer used for the allocation. As a result, that string buffer rarely needs to grow.
2134    ///
2135    /// # Panics
2136    /// Panics if the allocation fails.
2137    ///
2138    /// This technically also panics if the `fmt()` implementation returned an Error,
2139    /// but since [`fmt()` implementors should only error when writing to the stream fails](core::fmt::Error),
2140    /// that should be equivalent to an allocation failure.
2141    ///
2142    /// # Examples
2143    /// ```
2144    /// # use bump_scope::Bump;
2145    /// # let mut bump: Bump = Bump::new();
2146    /// let one = 1;
2147    /// let two = 2;
2148    /// let string = bump.alloc_fmt_mut(format_args!("{one} + {two} = {}", one + two));
2149    ///
2150    /// assert_eq!(string, "1 + 2 = 3");
2151    /// ```
2152    #[inline(always)]
2153    #[cfg(feature = "panic-on-alloc")]
2154    pub fn alloc_fmt_mut(&mut self, args: fmt::Arguments) -> BumpBox<'_, str> {
2155        self.as_mut_scope().alloc_fmt_mut(args)
2156    }
2157
2158    /// Allocate a `str` from format arguments.
2159    ///
2160    /// This function is designed as a performance improvement over [`try_alloc_fmt`](Self::try_alloc_fmt).
2161    /// By taking `self` as `&mut`, it can use the entire remaining chunk space as the capacity
2162    /// for the temporary string buffer used for the allocation. As a result, that string buffer rarely needs to grow.
2163    ///
2164    /// # Errors
2165    /// Errors if the allocation fails.
2166    ///
2167    /// This technically also errors if the `fmt()` implementation returned an Error,
2168    /// but since [`fmt()` implementors should only error when writing to the stream fails](core::fmt::Error),
2169    /// that should be equivalent to an allocation failure.
2170    ///
2171    /// # Examples
2172    /// ```
2173    /// # use bump_scope::Bump;
2174    /// # let mut bump: Bump = Bump::try_new()?;
2175    /// let one = 1;
2176    /// let two = 2;
2177    /// let string = bump.try_alloc_fmt_mut(format_args!("{one} + {two} = {}", one + two))?;
2178    ///
2179    /// assert_eq!(string, "1 + 2 = 3");
2180    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2181    /// ```
2182    #[inline(always)]
2183    pub fn try_alloc_fmt_mut(&mut self, args: fmt::Arguments) -> Result<BumpBox<'_, str>, AllocError> {
2184        self.as_mut_scope().try_alloc_fmt_mut(args)
2185    }
2186
2187    /// Allocate a `CStr`.
2188    ///
2189    /// # Panics
2190    /// Panics if the allocation fails.
2191    ///
2192    /// # Examples
2193    /// ```
2194    /// # use bump_scope::Bump;
2195    /// # let bump: Bump = Bump::new();
2196    /// let allocated = bump.alloc_cstr(c"Hello, world!");
2197    /// assert_eq!(allocated, c"Hello, world!");
2198    /// ```
2199    #[inline(always)]
2200    #[cfg(feature = "panic-on-alloc")]
2201    pub fn alloc_cstr(&self, src: &CStr) -> &CStr {
2202        self.as_scope().alloc_cstr(src)
2203    }
2204
2205    /// Allocate a `CStr`.
2206    ///
2207    /// # Errors
2208    /// Errors if the allocation fails.
2209    ///
2210    /// # Examples
2211    /// ```
2212    /// # use bump_scope::Bump;
2213    /// # let bump: Bump = Bump::try_new()?;
2214    /// let allocated = bump.try_alloc_cstr(c"Hello, world!")?;
2215    /// assert_eq!(allocated, c"Hello, world!");
2216    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2217    /// ```
2218    #[inline(always)]
2219    pub fn try_alloc_cstr(&self, src: &CStr) -> Result<&CStr, AllocError> {
2220        self.as_scope().try_alloc_cstr(src)
2221    }
2222
2223    /// Allocate a `CStr` from a `str`.
2224    ///
2225    /// If `src` contains a `'\0'` then the `CStr` will stop at the first `'\0'`.
2226    ///
2227    /// # Panics
2228    /// Panics if the allocation fails.
2229    ///
2230    /// # Examples
2231    /// ```
2232    /// # use bump_scope::Bump;
2233    /// # let bump: Bump = Bump::new();
2234    /// let allocated = bump.alloc_cstr_from_str("Hello, world!");
2235    /// assert_eq!(allocated, c"Hello, world!");
2236    ///
2237    /// let allocated = bump.alloc_cstr_from_str("abc\0def");
2238    /// assert_eq!(allocated, c"abc");
2239    /// ```
2240    #[inline(always)]
2241    #[cfg(feature = "panic-on-alloc")]
2242    pub fn alloc_cstr_from_str(&self, src: &str) -> &CStr {
2243        self.as_scope().alloc_cstr_from_str(src)
2244    }
2245
2246    /// Allocate a `CStr` from a `str`.
2247    ///
2248    /// If `src` contains a `'\0'` then the `CStr` will stop at the first `'\0'`.
2249    ///
2250    /// # Errors
2251    /// Errors if the allocation fails.
2252    ///
2253    /// # Examples
2254    /// ```
2255    /// # use bump_scope::Bump;
2256    /// # let bump: Bump = Bump::try_new()?;
2257    /// let allocated = bump.try_alloc_cstr_from_str("Hello, world!")?;
2258    /// assert_eq!(allocated, c"Hello, world!");
2259    ///
2260    /// let allocated = bump.try_alloc_cstr_from_str("abc\0def")?;
2261    /// assert_eq!(allocated, c"abc");
2262    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2263    /// ```
2264    #[inline(always)]
2265    pub fn try_alloc_cstr_from_str(&self, src: &str) -> Result<&CStr, AllocError> {
2266        self.as_scope().try_alloc_cstr_from_str(src)
2267    }
2268    /// Allocate a `CStr` from format arguments.
2269    ///
2270    /// If the string contains a `'\0'` then the `CStr` will stop at the first `'\0'`.
2271    ///
2272    /// If you have a `&mut self` you can use [`alloc_cstr_fmt_mut`](Self::alloc_cstr_fmt_mut)
2273    /// instead for better performance.
2274    ///
2275    /// # Panics
2276    /// Panics if the allocation fails.
2277    ///
2278    /// This technically also panics if the `fmt()` implementation returned an Error,
2279    /// but since [`fmt()` implementors should only error when writing to the stream fails](core::fmt::Error),
2280    /// that should be equivalent to an allocation failure.
2281    ///
2282    /// # Examples
2283    /// ```
2284    /// # use bump_scope::Bump;
2285    /// # let bump: Bump = Bump::new();
2286    /// let one = 1;
2287    /// let two = 2;
2288    /// let string = bump.alloc_cstr_fmt(format_args!("{one} + {two} = {}", one + two));
2289    /// assert_eq!(string, c"1 + 2 = 3");
2290    ///
2291    /// let one = bump.alloc_cstr_fmt(format_args!("{one}\0{two}"));
2292    /// assert_eq!(one, c"1");
2293    /// ```
2294    #[inline(always)]
2295    #[cfg(feature = "panic-on-alloc")]
2296    pub fn alloc_cstr_fmt(&self, args: fmt::Arguments) -> &CStr {
2297        self.as_scope().alloc_cstr_fmt(args)
2298    }
2299
2300    /// Allocate a `CStr` from format arguments.
2301    ///
2302    /// If the string contains a `'\0'` then the `CStr` will stop at the first `'\0'`.
2303    ///
2304    /// If you have a `&mut self` you can use [`try_alloc_cstr_fmt_mut`](Self::try_alloc_cstr_fmt_mut)
2305    /// instead for better performance.
2306    ///
2307    /// # Errors
2308    /// Errors if the allocation fails.
2309    ///
2310    /// This technically also errors if the `fmt()` implementation returned an Error,
2311    /// but since [`fmt()` implementors should only error when writing to the stream fails](core::fmt::Error),
2312    /// that should be equivalent to an allocation failure.
2313    ///
2314    /// # Examples
2315    /// ```
2316    /// # use bump_scope::Bump;
2317    /// # let bump: Bump = Bump::try_new()?;
2318    /// let one = 1;
2319    /// let two = 2;
2320    /// let string = bump.try_alloc_cstr_fmt(format_args!("{one} + {two} = {}", one + two))?;
2321    /// assert_eq!(string, c"1 + 2 = 3");
2322    ///
2323    /// let one = bump.try_alloc_cstr_fmt(format_args!("{one}\0{two}"))?;
2324    /// assert_eq!(one, c"1");
2325    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2326    /// ```
2327    #[inline(always)]
2328    pub fn try_alloc_cstr_fmt(&self, args: fmt::Arguments) -> Result<&CStr, AllocError> {
2329        self.as_scope().try_alloc_cstr_fmt(args)
2330    }
2331
2332    /// Allocate a `CStr` from format arguments.
2333    ///
2334    /// If the string contains a `'\0'` then the `CStr` will stop at the first `'\0'`.
2335    ///
2336    /// This function is designed as a performance improvement over [`alloc_cstr_fmt`](Self::alloc_cstr_fmt).
2337    /// By taking `self` as `&mut`, it can use the entire remaining chunk space as the capacity
2338    /// for the temporary string buffer used for the allocation. As a result, that string buffer rarely needs to grow.
2339    ///
2340    /// # Panics
2341    /// Panics if the allocation fails.
2342    ///
2343    /// This technically also panics if the `fmt()` implementation returned an Error,
2344    /// but since [`fmt()` implementors should only error when writing to the stream fails](core::fmt::Error),
2345    /// that should be equivalent to an allocation failure.
2346    ///
2347    /// # Examples
2348    /// ```
2349    /// # use bump_scope::Bump;
2350    /// # let mut bump: Bump = Bump::new();
2351    /// let one = 1;
2352    /// let two = 2;
2353    /// let string = bump.alloc_cstr_fmt_mut(format_args!("{one} + {two} = {}", one + two));
2354    /// assert_eq!(string, c"1 + 2 = 3");
2355    ///
2356    /// let one = bump.alloc_cstr_fmt_mut(format_args!("{one}\0{two}"));
2357    /// assert_eq!(one, c"1");
2358    /// ```
2359    #[inline(always)]
2360    #[cfg(feature = "panic-on-alloc")]
2361    pub fn alloc_cstr_fmt_mut(&mut self, args: fmt::Arguments) -> &CStr {
2362        self.as_mut_scope().alloc_cstr_fmt_mut(args)
2363    }
2364
2365    /// Allocate a `CStr` from format arguments.
2366    ///
2367    /// If the string contains a `'\0'` then the `CStr` will stop at the first `'\0'`.
2368    ///
2369    /// This function is designed as a performance improvement over [`try_alloc_cstr_fmt`](Self::try_alloc_cstr_fmt).
2370    /// By taking `self` as `&mut`, it can use the entire remaining chunk space as the capacity
2371    /// for the temporary string buffer used for the allocation. As a result, that string buffer rarely needs to grow.
2372    ///
2373    /// # Errors
2374    /// Errors if the allocation fails.
2375    ///
2376    /// This technically also errors if the `fmt()` implementation returned an Error,
2377    /// but since [`fmt()` implementors should only error when writing to the stream fails](core::fmt::Error),
2378    /// that should be equivalent to an allocation failure.
2379    ///
2380    /// # Examples
2381    /// ```
2382    /// # use bump_scope::Bump;
2383    /// # let mut bump: Bump = Bump::try_new()?;
2384    /// let one = 1;
2385    /// let two = 2;
2386    /// let string = bump.try_alloc_cstr_fmt_mut(format_args!("{one} + {two} = {}", one + two))?;
2387    /// assert_eq!(string, c"1 + 2 = 3");
2388    ///
2389    /// let one = bump.try_alloc_cstr_fmt_mut(format_args!("{one}\0{two}"))?;
2390    /// assert_eq!(one, c"1");
2391    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2392    /// ```
2393    #[inline(always)]
2394    pub fn try_alloc_cstr_fmt_mut(&mut self, args: fmt::Arguments) -> Result<&CStr, AllocError> {
2395        self.as_mut_scope().try_alloc_cstr_fmt_mut(args)
2396    }
2397
2398    /// Allocate elements of an iterator into a slice.
2399    ///
2400    /// If you have an `impl ExactSizeIterator` then you can use [`alloc_iter_exact`] instead for better performance.
2401    ///
2402    /// If `iter` is not an `ExactSizeIterator` but you have a `&mut self` you can still get somewhat better performance by using [`alloc_iter_mut`].
2403    ///
2404    /// [`alloc_iter_exact`]: Self::alloc_iter_exact
2405    /// [`alloc_iter_mut`]: Self::alloc_iter_mut
2406    ///
2407    /// # Panics
2408    /// Panics if the allocation fails.
2409    ///
2410    /// # Examples
2411    /// ```
2412    /// # use bump_scope::Bump;
2413    /// # let bump: Bump = Bump::new();
2414    /// let slice = bump.alloc_iter([1, 2, 3]);
2415    /// assert_eq!(slice, [1, 2, 3]);
2416    /// ```
2417    #[inline(always)]
2418    #[cfg(feature = "panic-on-alloc")]
2419    pub fn alloc_iter<T>(&self, iter: impl IntoIterator<Item = T>) -> BumpBox<'_, [T]> {
2420        self.as_scope().alloc_iter(iter)
2421    }
2422
2423    /// Allocate elements of an iterator into a slice.
2424    ///
2425    /// If you have an `impl ExactSizeIterator` then you can use [`try_alloc_iter_exact`] instead for better performance.
2426    ///
2427    /// If `iter` is not an `ExactSizeIterator` but you have a `&mut self` you can still get somewhat better performance by using [`try_alloc_iter_mut`].
2428    ///
2429    /// [`try_alloc_iter_exact`]: Self::try_alloc_iter_exact
2430    /// [`try_alloc_iter_mut`]: Self::try_alloc_iter_mut
2431    ///
2432    /// # Errors
2433    /// Errors if the allocation fails.
2434    ///
2435    /// # Examples
2436    /// ```
2437    /// # use bump_scope::Bump;
2438    /// # let bump: Bump = Bump::try_new()?;
2439    /// let slice = bump.try_alloc_iter([1, 2, 3])?;
2440    /// assert_eq!(slice, [1, 2, 3]);
2441    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2442    /// ```
2443    #[inline(always)]
2444    pub fn try_alloc_iter<T>(&self, iter: impl IntoIterator<Item = T>) -> Result<BumpBox<'_, [T]>, AllocError> {
2445        self.as_scope().try_alloc_iter(iter)
2446    }
2447
2448    /// Allocate elements of an `ExactSizeIterator` into a slice.
2449    ///
2450    /// # Panics
2451    /// Panics if the allocation fails.
2452    ///
2453    /// # Examples
2454    /// ```
2455    /// # use bump_scope::Bump;
2456    /// # let bump: Bump = Bump::new();
2457    /// let slice = bump.alloc_iter_exact([1, 2, 3]);
2458    /// assert_eq!(slice, [1, 2, 3]);
2459    /// ```
2460    #[inline(always)]
2461    #[cfg(feature = "panic-on-alloc")]
2462    pub fn alloc_iter_exact<T, I>(&self, iter: impl IntoIterator<Item = T, IntoIter = I>) -> BumpBox<'_, [T]>
2463    where
2464        I: ExactSizeIterator<Item = T>,
2465    {
2466        self.as_scope().alloc_iter_exact(iter)
2467    }
2468
2469    /// Allocate elements of an `ExactSizeIterator` into a slice.
2470    ///
2471    /// # Errors
2472    /// Errors if the allocation fails.
2473    ///
2474    /// # Examples
2475    /// ```
2476    /// # use bump_scope::Bump;
2477    /// # let bump: Bump = Bump::try_new()?;
2478    /// let slice = bump.try_alloc_iter_exact([1, 2, 3])?;
2479    /// assert_eq!(slice, [1, 2, 3]);
2480    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2481    /// ```
2482    #[inline(always)]
2483    pub fn try_alloc_iter_exact<T, I>(
2484        &self,
2485        iter: impl IntoIterator<Item = T, IntoIter = I>,
2486    ) -> Result<BumpBox<'_, [T]>, AllocError>
2487    where
2488        I: ExactSizeIterator<Item = T>,
2489    {
2490        self.as_scope().try_alloc_iter_exact(iter)
2491    }
2492
2493    /// Allocate elements of an iterator into a slice.
2494    ///
2495    /// This function is designed as a performance improvement over [`alloc_iter`](Self::alloc_iter).
2496    /// By taking `self` as `&mut`, it can use the entire remaining chunk space as the capacity
2497    /// for the temporary vector used for the allocation. As a result, that vector rarely needs to grow.
2498    ///
2499    /// When bumping downwards, prefer [`alloc_iter_mut_rev`](Self::alloc_iter_mut_rev) instead.
2500    ///
2501    /// # Panics
2502    /// Panics if the allocation fails.
2503    ///
2504    /// # Examples
2505    /// ```
2506    /// # use bump_scope::Bump;
2507    /// # let mut bump: Bump = Bump::new();
2508    /// let slice = bump.alloc_iter_mut([1, 2, 3]);
2509    /// assert_eq!(slice, [1, 2, 3]);
2510    /// ```
2511    #[inline(always)]
2512    #[cfg(feature = "panic-on-alloc")]
2513    pub fn alloc_iter_mut<T>(&mut self, iter: impl IntoIterator<Item = T>) -> BumpBox<'_, [T]> {
2514        self.as_mut_scope().alloc_iter_mut(iter)
2515    }
2516
2517    /// Allocate elements of an iterator into a slice.
2518    ///
2519    /// This function is designed as a performance improvement over [`try_alloc_iter`](Self::try_alloc_iter).
2520    /// By taking `self` as `&mut`, it can use the entire remaining chunk space as the capacity
2521    /// for the temporary vector used for the allocation. As a result, that vector rarely needs to grow.
2522    ///
2523    /// When bumping downwards, prefer [`alloc_iter_mut_rev`](Self::alloc_iter_mut_rev) instead.
2524    ///
2525    /// # Errors
2526    /// Errors if the allocation fails.
2527    ///
2528    /// # Examples
2529    /// ```
2530    /// # use bump_scope::Bump;
2531    /// # let mut bump: Bump = Bump::try_new()?;
2532    /// let slice = bump.try_alloc_iter_mut([1, 2, 3])?;
2533    /// assert_eq!(slice, [1, 2, 3]);
2534    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2535    /// ```
2536    #[inline(always)]
2537    pub fn try_alloc_iter_mut<T>(&mut self, iter: impl IntoIterator<Item = T>) -> Result<BumpBox<'_, [T]>, AllocError> {
2538        self.as_mut_scope().try_alloc_iter_mut(iter)
2539    }
2540
2541    /// Allocate elements of an iterator into a slice in reverse order.
2542    ///
2543    /// Compared to [`alloc_iter_mut`] this function is more performant
2544    /// for downwards bumping allocators as the allocation for the vector can be shrunk in place
2545    /// without any `ptr::copy`.
2546    ///
2547    /// The reverse is true when upwards allocating. In that case it's better to use [`alloc_iter_mut`] to prevent
2548    /// the `ptr::copy`.
2549    ///
2550    /// [`alloc_iter_mut`]: Self::alloc_iter_mut
2551    ///
2552    /// # Panics
2553    /// Panics if the allocation fails.
2554    ///
2555    /// # Examples
2556    /// ```
2557    /// # use bump_scope::Bump;
2558    /// # let mut bump: Bump = Bump::new();
2559    /// let slice = bump.alloc_iter_mut_rev([1, 2, 3]);
2560    /// assert_eq!(slice, [3, 2, 1]);
2561    /// ```
2562    #[inline(always)]
2563    #[cfg(feature = "panic-on-alloc")]
2564    pub fn alloc_iter_mut_rev<T>(&mut self, iter: impl IntoIterator<Item = T>) -> BumpBox<'_, [T]> {
2565        self.as_mut_scope().alloc_iter_mut_rev(iter)
2566    }
2567
2568    /// Allocate elements of an iterator into a slice in reverse order.
2569    ///
2570    /// Compared to [`try_alloc_iter_mut`] this function is more performant
2571    /// for downwards bumping allocators as the allocation for the vector can be shrunk in place
2572    /// without any `ptr::copy`.
2573    ///
2574    /// The reverse is true when upwards allocating. In that case it's better to use [`try_alloc_iter_mut`] to prevent
2575    /// the `ptr::copy`.
2576    ///
2577    /// [`try_alloc_iter_mut`]: Self::try_alloc_iter_mut
2578    ///
2579    /// # Errors
2580    /// Errors if the allocation fails.
2581    ///
2582    /// # Examples
2583    /// ```
2584    /// # use bump_scope::Bump;
2585    /// # let mut bump: Bump = Bump::try_new()?;
2586    /// let slice = bump.try_alloc_iter_mut_rev([1, 2, 3])?;
2587    /// assert_eq!(slice, [3, 2, 1]);
2588    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2589    /// ```
2590    #[inline(always)]
2591    pub fn try_alloc_iter_mut_rev<T>(&mut self, iter: impl IntoIterator<Item = T>) -> Result<BumpBox<'_, [T]>, AllocError> {
2592        self.as_mut_scope().try_alloc_iter_mut_rev(iter)
2593    }
2594
2595    /// Allocate an uninitialized object.
2596    ///
2597    /// You can safely initialize the object with [`init`](BumpBox::init) or unsafely with [`assume_init`](BumpBox::assume_init).
2598    ///
2599    /// # Panics
2600    /// Panics if the allocation fails.
2601    ///
2602    /// # Examples
2603    /// Safely:
2604    /// ```
2605    /// # use bump_scope::Bump;
2606    /// # let bump: Bump = Bump::new();
2607    /// let uninit = bump.alloc_uninit();
2608    ///
2609    /// let five = uninit.init(5);
2610    ///
2611    /// assert_eq!(*five, 5)
2612    /// ```
2613    ///
2614    /// Unsafely:
2615    /// ```
2616    /// # use bump_scope::Bump;
2617    /// # let bump: Bump = Bump::new();
2618    /// let mut uninit = bump.alloc_uninit();
2619    ///
2620    /// let five = unsafe {
2621    ///     uninit.write(5);
2622    ///     uninit.assume_init()
2623    /// };
2624    ///
2625    /// assert_eq!(*five, 5)
2626    /// ```
2627    #[inline(always)]
2628    #[cfg(feature = "panic-on-alloc")]
2629    pub fn alloc_uninit<T>(&self) -> BumpBox<'_, MaybeUninit<T>> {
2630        self.as_scope().alloc_uninit()
2631    }
2632
2633    /// Allocate an uninitialized object.
2634    ///
2635    /// You can safely initialize the object with [`init`](BumpBox::init) or unsafely with [`assume_init`](BumpBox::assume_init).
2636    ///
2637    /// # Errors
2638    /// Errors if the allocation fails.
2639    ///
2640    /// # Examples
2641    /// Safely:
2642    /// ```
2643    /// # use bump_scope::Bump;
2644    /// # let bump: Bump = Bump::new();
2645    /// let uninit = bump.try_alloc_uninit()?;
2646    ///
2647    /// let five = uninit.init(5);
2648    ///
2649    /// assert_eq!(*five, 5);
2650    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2651    /// ```
2652    ///
2653    /// Unsafely:
2654    /// ```
2655    /// # use bump_scope::Bump;
2656    /// # let bump: Bump = Bump::try_new()?;
2657    /// let mut uninit = bump.try_alloc_uninit()?;
2658    ///
2659    /// let five = unsafe {
2660    ///     uninit.write(5);
2661    ///     uninit.assume_init()
2662    /// };
2663    ///
2664    /// assert_eq!(*five, 5);
2665    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2666    /// ```
2667    #[inline(always)]
2668    pub fn try_alloc_uninit<T>(&self) -> Result<BumpBox<'_, MaybeUninit<T>>, AllocError> {
2669        self.as_scope().try_alloc_uninit()
2670    }
2671
2672    /// Allocate an uninitialized object slice.
2673    ///
2674    /// You can safely initialize the object with
2675    /// [`init_fill`](BumpBox::init_fill),
2676    /// [`init_fill_with`](BumpBox::init_fill_with),
2677    /// [`init_copy`](BumpBox::init_copy),
2678    /// [`init_clone`](BumpBox::init_clone),
2679    /// [`init_zeroed`](crate::zerocopy_08::InitZeroed::init_zeroed) or unsafely with
2680    /// [`assume_init`](BumpBox::assume_init).
2681    ///
2682    /// # Panics
2683    /// Panics if the allocation fails.
2684    ///
2685    /// # Examples
2686    /// Safely:
2687    /// ```
2688    /// # use bump_scope::Bump;
2689    /// # let bump: Bump = Bump::new();
2690    /// let uninit = bump.alloc_uninit_slice(3);
2691    ///
2692    /// let values = uninit.init_copy(&[1, 2, 3]);
2693    ///
2694    /// assert_eq!(values, [1, 2, 3])
2695    /// ```
2696    ///
2697    /// Unsafely:
2698    /// ```
2699    /// # use bump_scope::Bump;
2700    /// # let bump: Bump = Bump::new();
2701    /// let mut uninit = bump.alloc_uninit_slice(3);
2702    ///
2703    /// let values = unsafe {
2704    ///     uninit[0].write(1);
2705    ///     uninit[1].write(2);
2706    ///     uninit[2].write(3);
2707    ///
2708    ///     uninit.assume_init()
2709    /// };
2710    ///
2711    /// assert_eq!(values, [1, 2, 3]);
2712    /// ```
2713    #[inline(always)]
2714    #[cfg(feature = "panic-on-alloc")]
2715    pub fn alloc_uninit_slice<T>(&self, len: usize) -> BumpBox<'_, [MaybeUninit<T>]> {
2716        self.as_scope().alloc_uninit_slice(len)
2717    }
2718
2719    /// Allocate an uninitialized object slice.
2720    ///
2721    /// You can safely initialize the object with
2722    /// [`init_fill`](BumpBox::init_fill),
2723    /// [`init_fill_with`](BumpBox::init_fill_with),
2724    /// [`init_copy`](BumpBox::init_copy),
2725    /// [`init_clone`](BumpBox::init_clone),
2726    /// [`init_zeroed`](crate::zerocopy_08::InitZeroed::init_zeroed) or unsafely with
2727    /// [`assume_init`](BumpBox::assume_init).
2728    ///
2729    /// # Errors
2730    /// Errors if the allocation fails.
2731    ///
2732    /// # Examples
2733    /// Safely:
2734    /// ```
2735    /// # use bump_scope::Bump;
2736    /// # let bump: Bump = Bump::new();
2737    /// let uninit = bump.try_alloc_uninit_slice(3)?;
2738    ///
2739    /// let values = uninit.init_copy(&[1, 2, 3]);
2740    ///
2741    /// assert_eq!(values, [1, 2, 3]);
2742    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2743    /// ```
2744    ///
2745    /// Unsafely:
2746    /// ```
2747    /// # use bump_scope::Bump;
2748    /// # let bump: Bump = Bump::try_new()?;
2749    /// let mut uninit = bump.try_alloc_uninit_slice(3)?;
2750    ///
2751    /// let values = unsafe {
2752    ///     uninit[0].write(1);
2753    ///     uninit[1].write(2);
2754    ///     uninit[2].write(3);
2755    ///
2756    ///     uninit.assume_init()
2757    /// };
2758    ///
2759    /// assert_eq!(values, [1, 2, 3]);
2760    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2761    /// ```
2762    #[inline(always)]
2763    pub fn try_alloc_uninit_slice<T>(&self, len: usize) -> Result<BumpBox<'_, [MaybeUninit<T>]>, AllocError> {
2764        self.as_scope().try_alloc_uninit_slice(len)
2765    }
2766
2767    /// Allocate an uninitialized object slice.
2768    ///
2769    /// You can safely initialize the object with
2770    /// [`init_fill`](BumpBox::init_fill),
2771    /// [`init_fill_with`](BumpBox::init_fill_with),
2772    /// [`init_copy`](BumpBox::init_copy),
2773    /// [`init_clone`](BumpBox::init_clone),
2774    /// [`init_zeroed`](crate::zerocopy_08::InitZeroed::init_zeroed) or unsafely with
2775    /// [`assume_init`](BumpBox::assume_init).
2776    ///
2777    /// This is just like [`alloc_uninit_slice`](Self::alloc_uninit_slice) but uses a `slice` to provide the `len`.
2778    /// This avoids a check for a valid layout. The elements of `slice` are irrelevant.
2779    ///
2780    /// # Panics
2781    /// Panics if the allocation fails.
2782    ///
2783    /// # Examples
2784    /// ```
2785    /// # use bump_scope::Bump;
2786    /// # let bump: Bump = Bump::new();
2787    /// let slice = &[1, 2, 3];
2788    /// let uninit_slice = bump.alloc_uninit_slice_for(slice);
2789    /// assert_eq!(uninit_slice.len(), 3);
2790    /// ```
2791    #[inline(always)]
2792    #[cfg(feature = "panic-on-alloc")]
2793    pub fn alloc_uninit_slice_for<T>(&self, slice: &[T]) -> BumpBox<'_, [MaybeUninit<T>]> {
2794        self.as_scope().alloc_uninit_slice_for(slice)
2795    }
2796
2797    /// Allocate an uninitialized object slice.
2798    ///
2799    /// You can safely initialize the object with
2800    /// [`init_fill`](BumpBox::init_fill),
2801    /// [`init_fill_with`](BumpBox::init_fill_with),
2802    /// [`init_copy`](BumpBox::init_copy),
2803    /// [`init_clone`](BumpBox::init_clone),
2804    /// [`init_zeroed`](crate::zerocopy_08::InitZeroed::init_zeroed) or unsafely with
2805    /// [`assume_init`](BumpBox::assume_init).
2806    ///
2807    /// This is just like [`try_alloc_uninit_slice`](Self::try_alloc_uninit_slice) but uses a `slice` to provide the `len`.
2808    /// This avoids a check for a valid layout. The elements of `slice` are irrelevant.
2809    ///
2810    /// # Errors
2811    /// Errors if the allocation fails.
2812    ///
2813    /// # Examples
2814    /// ```
2815    /// # use bump_scope::Bump;
2816    /// # let bump: Bump = Bump::try_new()?;
2817    /// let slice = &[1, 2, 3];
2818    /// let uninit_slice = bump.try_alloc_uninit_slice_for(slice)?;
2819    /// assert_eq!(uninit_slice.len(), 3);
2820    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2821    /// ```
2822    #[inline(always)]
2823    pub fn try_alloc_uninit_slice_for<T>(&self, slice: &[T]) -> Result<BumpBox<'_, [MaybeUninit<T>]>, AllocError> {
2824        self.as_scope().try_alloc_uninit_slice_for(slice)
2825    }
2826
2827    /// Allocate a [`FixedBumpVec`] with the given `capacity`.
2828    ///
2829    /// # Panics
2830    /// Panics if the allocation fails.
2831    ///
2832    /// # Examples
2833    /// ```
2834    /// # use bump_scope::Bump;
2835    /// # let bump: Bump = Bump::new();
2836    /// # #[expect(deprecated)]
2837    /// let mut values = bump.alloc_fixed_vec(3);
2838    /// values.push(1);
2839    /// values.push(2);
2840    /// values.push(3);
2841    /// assert_eq!(values, [1, 2, 3])
2842    /// ```
2843    #[doc(hidden)]
2844    #[deprecated = "use `FixedBumpVec::with_capacity_in()` instead"]
2845    #[inline(always)]
2846    #[cfg(feature = "panic-on-alloc")]
2847    pub fn alloc_fixed_vec<T>(&self, capacity: usize) -> FixedBumpVec<'_, T> {
2848        #[expect(deprecated)]
2849        self.as_scope().alloc_fixed_vec(capacity)
2850    }
2851
2852    /// Allocate a [`FixedBumpVec`] with the given `capacity`.
2853    ///
2854    /// # Errors
2855    /// Errors if the allocation fails.
2856    ///
2857    /// # Examples
2858    /// ```
2859    /// # use bump_scope::Bump;
2860    /// # let bump: Bump = Bump::try_new()?;
2861    /// # #[expect(deprecated)]
2862    /// let mut values = bump.try_alloc_fixed_vec(3)?;
2863    /// values.push(1);
2864    /// values.push(2);
2865    /// values.push(3);
2866    /// assert_eq!(values, [1, 2, 3]);
2867    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2868    /// ```
2869    #[doc(hidden)]
2870    #[deprecated = "use `FixedBumpVec::try_with_capacity_in()` instead"]
2871    #[inline(always)]
2872    pub fn try_alloc_fixed_vec<T>(&self, capacity: usize) -> Result<FixedBumpVec<'_, T>, AllocError> {
2873        #[expect(deprecated)]
2874        self.as_scope().try_alloc_fixed_vec(capacity)
2875    }
2876
2877    /// Allocate a [`FixedBumpString`] with the given `capacity` in bytes.
2878    ///
2879    /// # Panics
2880    /// Panics if the allocation fails.
2881    ///
2882    /// # Examples
2883    /// ```
2884    /// # use bump_scope::Bump;
2885    /// # let bump: Bump = Bump::new();
2886    /// # #[expect(deprecated)]
2887    /// let mut string = bump.alloc_fixed_string(13);
2888    /// string.push_str("Hello,");
2889    /// string.push_str(" world!");
2890    /// assert_eq!(string, "Hello, world!");
2891    /// ```
2892    #[doc(hidden)]
2893    #[deprecated = "use `FixedBumpString::with_capacity_in()` instead"]
2894    #[inline(always)]
2895    #[cfg(feature = "panic-on-alloc")]
2896    pub fn alloc_fixed_string(&self, capacity: usize) -> FixedBumpString<'_> {
2897        #[expect(deprecated)]
2898        self.as_scope().alloc_fixed_string(capacity)
2899    }
2900
2901    /// Allocate a [`FixedBumpString`] with the given `capacity` in bytes.
2902    ///
2903    /// # Errors
2904    /// Errors if the allocation fails.
2905    ///
2906    /// # Examples
2907    /// ```
2908    /// # use bump_scope::Bump;
2909    /// # let bump: Bump = Bump::try_new()?;
2910    /// # #[expect(deprecated)]
2911    /// let mut string = bump.try_alloc_fixed_string(13)?;
2912    /// string.push_str("Hello,");
2913    /// string.push_str(" world!");
2914    /// assert_eq!(string, "Hello, world!");
2915    /// # Ok::<(), bump_scope::alloc::AllocError>(())
2916    /// ```
2917    #[doc(hidden)]
2918    #[deprecated = "use `FixedBumpString::try_with_capacity_in()` instead"]
2919    #[inline(always)]
2920    pub fn try_alloc_fixed_string(&self, capacity: usize) -> Result<FixedBumpString<'_>, AllocError> {
2921        #[expect(deprecated)]
2922        self.as_scope().try_alloc_fixed_string(capacity)
2923    }
2924
2925    /// Allocates memory as described by the given `Layout`.
2926    ///
2927    /// # Panics
2928    /// Panics if the allocation fails.
2929    #[inline(always)]
2930    #[cfg(feature = "panic-on-alloc")]
2931    pub fn alloc_layout(&self, layout: Layout) -> NonNull<u8> {
2932        self.as_scope().alloc_layout(layout)
2933    }
2934
2935    /// Allocates memory as described by the given `Layout`.
2936    ///
2937    /// # Errors
2938    /// Errors if the allocation fails.
2939    #[inline(always)]
2940    pub fn try_alloc_layout(&self, layout: Layout) -> Result<NonNull<u8>, AllocError> {
2941        self.as_scope().try_alloc_layout(layout)
2942    }
2943
2944    /// Drops an allocated value and attempts to free its memory.
2945    ///
2946    /// The memory can only be freed if this is the last allocation.
2947    ///
2948    /// # Examples
2949    /// ```
2950    /// # use bump_scope::Bump;
2951    /// # let bump: Bump = Bump::new();
2952    /// let boxed = bump.alloc(3i32);
2953    /// assert_eq!(bump.stats().allocated(), 4);
2954    /// bump.dealloc(boxed);
2955    /// assert_eq!(bump.stats().allocated(), 0);
2956    /// ```
2957    #[inline(always)]
2958    pub fn dealloc<T: ?Sized>(&self, boxed: BumpBox<T>) {
2959        self.as_scope().dealloc(boxed);
2960    }
2961
2962    /// Reserves capacity for at least `additional` more bytes to be bump allocated.
2963    /// The bump allocator may reserve more space to avoid frequent reallocations.
2964    /// After calling `reserve_bytes`, <code>self.[stats](Self::stats)().[remaining](Stats::remaining)()</code> will be greater than or equal to
2965    /// `additional`. Does nothing if the capacity is already sufficient.
2966    ///
2967    /// Note that these additional bytes are not necessarily in one contiguous region but
2968    /// might be spread out among many chunks.
2969    ///
2970    /// # Panics
2971    /// Panics if the allocation fails.
2972    ///
2973    /// # Examples
2974    /// ```
2975    /// # use bump_scope::{Bump};
2976    /// let bump: Bump = Bump::new();
2977    /// assert!(bump.stats().capacity() < 4096);
2978    ///
2979    /// bump.reserve_bytes(4096);
2980    /// assert!(bump.stats().capacity() >= 4096);
2981    /// ```
2982    #[inline(always)]
2983    #[cfg(feature = "panic-on-alloc")]
2984    pub fn reserve_bytes(&self, additional: usize) {
2985        self.as_scope().reserve_bytes(additional);
2986    }
2987
2988    /// Reserves capacity for at least `additional` more bytes to be bump allocated.
2989    /// The bump allocator may reserve more space to avoid frequent reallocations.
2990    /// After calling `reserve_bytes`, <code>self.[stats](Self::stats)().[remaining](Stats::remaining)()</code> will be greater than or equal to
2991    /// `additional`. Does nothing if the capacity is already sufficient.
2992    ///
2993    /// # Errors
2994    /// Errors if the allocation fails.
2995    ///
2996    /// # Examples
2997    /// ```
2998    /// # use bump_scope::Bump;
2999    /// let bump: Bump = Bump::try_new()?;
3000    /// assert!(bump.stats().capacity() < 4096);
3001    ///
3002    /// bump.try_reserve_bytes(4096)?;
3003    /// assert!(bump.stats().capacity() >= 4096);
3004    /// # Ok::<(), bump_scope::alloc::AllocError>(())
3005    /// ```
3006    #[inline(always)]
3007    pub fn try_reserve_bytes(&self, additional: usize) -> Result<(), AllocError> {
3008        self.as_scope().try_reserve_bytes(additional)
3009    }
3010
3011    /// Allocates the result of `f` in the bump allocator, then moves `E` out of it and deallocates the space it took up.
3012    ///
3013    /// This can be more performant than allocating `T` after the fact, as `Result<T, E>` may be constructed in the bump allocators memory instead of on the stack and then copied over.
3014    ///
3015    /// There is also [`alloc_try_with_mut`](Self::alloc_try_with_mut), optimized for a mutable reference.
3016    ///
3017    /// # Panics
3018    /// Panics if the allocation fails.
3019    ///
3020    /// # Examples
3021    #[cfg_attr(feature = "nightly-tests", doc = "```")]
3022    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
3023    /// # #![feature(offset_of_enum)]
3024    /// # use core::mem::offset_of;
3025    /// # use bump_scope::Bump;
3026    /// # let bump: Bump = Bump::new();
3027    /// let result = bump.alloc_try_with(|| -> Result<i32, i32> { Ok(123) });
3028    /// assert_eq!(result.unwrap(), 123);
3029    /// assert_eq!(bump.stats().allocated(), offset_of!(Result<i32, i32>, Ok.0) + size_of::<i32>());
3030    /// ```
3031    #[cfg_attr(feature = "nightly-tests", doc = "```")]
3032    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
3033    /// # use bump_scope::Bump;
3034    /// # let bump: Bump = Bump::new();
3035    /// let result = bump.alloc_try_with(|| -> Result<i32, i32> { Err(123) });
3036    /// assert_eq!(result.unwrap_err(), 123);
3037    /// assert_eq!(bump.stats().allocated(), 0);
3038    /// ```
3039    #[inline(always)]
3040    #[cfg(feature = "panic-on-alloc")]
3041    #[expect(clippy::missing_errors_doc)]
3042    pub fn alloc_try_with<T, E>(&self, f: impl FnOnce() -> Result<T, E>) -> Result<BumpBox<'_, T>, E> {
3043        self.as_scope().alloc_try_with(f)
3044    }
3045
3046    /// Allocates the result of `f` in the bump allocator, then moves `E` out of it and deallocates the space it took up.
3047    ///
3048    /// This can be more performant than allocating `T` after the fact, as `Result<T, E>` may be constructed in the bump allocators memory instead of on the stack and then copied over.
3049    ///
3050    /// There is also [`try_alloc_try_with_mut`](Self::try_alloc_try_with_mut), optimized for a mutable reference.
3051    ///
3052    /// # Errors
3053    /// Errors if the allocation fails.
3054    ///
3055    /// # Examples
3056    #[cfg_attr(feature = "nightly-tests", doc = "```")]
3057    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
3058    /// # #![feature(offset_of_enum)]
3059    /// # use core::mem::offset_of;
3060    /// # use bump_scope::Bump;
3061    /// # let bump: Bump = Bump::try_new()?;
3062    /// let result = bump.try_alloc_try_with(|| -> Result<i32, i32> { Ok(123) })?;
3063    /// assert_eq!(result.unwrap(), 123);
3064    /// assert_eq!(bump.stats().allocated(), offset_of!(Result<i32, i32>, Ok.0) + size_of::<i32>());
3065    /// # Ok::<(), bump_scope::alloc::AllocError>(())
3066    /// ```
3067    #[cfg_attr(feature = "nightly-tests", doc = "```")]
3068    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
3069    /// # use bump_scope::Bump;
3070    /// # let bump: Bump = Bump::try_new()?;
3071    /// let result = bump.try_alloc_try_with(|| -> Result<i32, i32> { Err(123) })?;
3072    /// assert_eq!(result.unwrap_err(), 123);
3073    /// assert_eq!(bump.stats().allocated(), 0);
3074    /// # Ok::<(), bump_scope::alloc::AllocError>(())
3075    /// ```
3076    #[inline(always)]
3077    pub fn try_alloc_try_with<T, E>(
3078        &self,
3079        f: impl FnOnce() -> Result<T, E>,
3080    ) -> Result<Result<BumpBox<'_, T>, E>, AllocError> {
3081        self.as_scope().try_alloc_try_with(f)
3082    }
3083
3084    /// Allocates the result of `f` in the bump allocator, then moves `E` out of it and deallocates the space it took up.
3085    ///
3086    /// This can be more performant than allocating `T` after the fact, as `Result<T, E>` may be constructed in the bump allocators memory instead of on the stack and then copied over.
3087    ///
3088    /// This is just like [`alloc_try_with`](Self::alloc_try_with), but optimized for a mutable reference.
3089    ///
3090    /// # Panics
3091    /// Panics if the allocation fails.
3092    ///
3093    /// # Examples
3094    #[cfg_attr(feature = "nightly-tests", doc = "```")]
3095    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
3096    /// # #![feature(offset_of_enum)]
3097    /// # use core::mem::offset_of;
3098    /// # use bump_scope::Bump;
3099    /// # let mut bump: Bump = Bump::new();
3100    /// let result = bump.alloc_try_with_mut(|| -> Result<i32, i32> { Ok(123) });
3101    /// assert_eq!(result.unwrap(), 123);
3102    /// assert_eq!(bump.stats().allocated(), offset_of!(Result<i32, i32>, Ok.0) + size_of::<i32>());
3103    /// ```
3104    #[cfg_attr(feature = "nightly-tests", doc = "```")]
3105    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
3106    /// # use bump_scope::Bump;
3107    /// # let mut bump: Bump = Bump::new();
3108    /// let result = bump.alloc_try_with_mut(|| -> Result<i32, i32> { Err(123) });
3109    /// assert_eq!(result.unwrap_err(), 123);
3110    /// assert_eq!(bump.stats().allocated(), 0);
3111    /// ```
3112    #[inline(always)]
3113    #[cfg(feature = "panic-on-alloc")]
3114    #[expect(clippy::missing_errors_doc)]
3115    pub fn alloc_try_with_mut<T, E>(&mut self, f: impl FnOnce() -> Result<T, E>) -> Result<BumpBox<'_, T>, E> {
3116        self.as_mut_scope().alloc_try_with_mut(f)
3117    }
3118
3119    /// Allocates the result of `f` in the bump allocator, then moves `E` out of it and deallocates the space it took up.
3120    ///
3121    /// This can be more performant than allocating `T` after the fact, as `Result<T, E>` may be constructed in the bump allocators memory instead of on the stack and then copied over.
3122    ///
3123    /// This is just like [`try_alloc_try_with`](Self::try_alloc_try_with), but optimized for a mutable reference.
3124    ///
3125    /// # Errors
3126    /// Errors if the allocation fails.
3127    ///
3128    /// # Examples
3129    #[cfg_attr(feature = "nightly-tests", doc = "```")]
3130    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
3131    /// # #![feature(offset_of_enum)]
3132    /// # use core::mem::offset_of;
3133    /// # use bump_scope::Bump;
3134    /// # let mut bump: Bump = Bump::try_new()?;
3135    /// let result = bump.try_alloc_try_with_mut(|| -> Result<i32, i32> { Ok(123) })?;
3136    /// assert_eq!(result.unwrap(), 123);
3137    /// assert_eq!(bump.stats().allocated(), offset_of!(Result<i32, i32>, Ok.0) + size_of::<i32>());
3138    /// # Ok::<(), bump_scope::alloc::AllocError>(())
3139    /// ```
3140    #[cfg_attr(feature = "nightly-tests", doc = "```")]
3141    #[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
3142    /// # use bump_scope::Bump;
3143    /// # let mut bump: Bump = Bump::try_new()?;
3144    /// let result = bump.try_alloc_try_with_mut(|| -> Result<i32, i32> { Err(123) })?;
3145    /// assert_eq!(result.unwrap_err(), 123);
3146    /// assert_eq!(bump.stats().allocated(), 0);
3147    /// # Ok::<(), bump_scope::alloc::AllocError>(())
3148    /// ```
3149    #[inline(always)]
3150    pub fn try_alloc_try_with_mut<T, E>(
3151        &mut self,
3152        f: impl FnOnce() -> Result<T, E>,
3153    ) -> Result<Result<BumpBox<'_, T>, E>, AllocError> {
3154        self.as_mut_scope().try_alloc_try_with_mut(f)
3155    }
3156}