Skip to main content

bump_scope/
bump_box.rs

1use core::{
2    any::Any,
3    borrow::{Borrow, BorrowMut},
4    cmp::Ordering,
5    fmt::{Debug, Display},
6    hash::{Hash, Hasher},
7    marker::PhantomData,
8    mem::{self, ManuallyDrop, MaybeUninit},
9    ops::{self, Deref, DerefMut, Index, IndexMut, Range, RangeBounds},
10    ptr::{self, NonNull},
11    slice, str,
12};
13
14#[cfg(feature = "nightly-fn-traits")]
15use core::{alloc::Layout, marker::Tuple};
16
17#[cfg(feature = "std")]
18use alloc_crate::{string::String, vec::Vec};
19
20#[cfg(feature = "alloc")]
21#[expect(unused_imports)]
22use alloc_crate::boxed::Box;
23
24use crate::{
25    FromUtf8Error, NoDrop, SizedTypeProperties,
26    alloc::BoxLike,
27    owned_slice::{self, OwnedSlice, TakeOwnedSlice},
28    owned_str,
29    polyfill::{self, non_null, pointer, transmute_mut},
30    set_len_on_drop_by_ptr::SetLenOnDropByPtr,
31    traits::BumpAllocatorTypedScope,
32};
33
34mod raw;
35mod slice_initializer;
36
37pub(crate) use raw::RawBumpBox;
38pub(crate) use slice_initializer::BumpBoxSliceInitializer;
39
40/// A pointer type that uniquely owns a bump allocation of type `T`. This type is returned whenever a bump allocation is made.
41///
42/// You can turn a `BumpBox` into a reference with [`into_ref`] and [`into_mut`] and into a [`Box`] with [`into_box`].
43///
44/// Unlike `Box`, `BumpBox` cannot implement `Clone` or free the allocated space on drop,
45/// as it does not store its allocator. It's essentially just an owned reference.
46///
47/// A `BumpBox` can be deallocated using [`Bump(Scope)::dealloc`](crate::Bump::dealloc).
48///
49/// ## Additional methods
50/// - `BumpBox<[T]>` provides methods from `Vec<T>` like
51///   [`pop`](Self::pop),
52///   [`clear`](Self::clear),
53///   [`truncate`](Self::truncate),
54///   [`remove`](Self::remove),
55///   [`swap_remove`](Self::swap_remove),
56///   [`retain`](Self::retain),
57///   [`drain`](Self::drain),
58///   [`extract_if`](Self::extract_if),
59///   [`dedup`](Self::dedup),
60///   [`split_off`](Self::split_off),
61///   slice methods but with owned semantics like
62///   [`split_at`](Self::split_at),
63///   <code>split_{[first](Self::split_first), [last](Self::split_last)}</code>
64///   <code>split_off_{[first](Self::split_off_first), [last](Self::split_off_last)}</code>
65///   and additional methods like
66///   [`partition`](Self::partition) and [`map_in_place`](Self::map_in_place).
67/// - `BumpBox<str>` provides methods from `String` like
68///   <code>[from_utf8](Self::from_utf8)([_unchecked](Self::from_utf8_unchecked))</code>,
69///   [`into_boxed_bytes`](Self::into_boxed_bytes),
70///   [`as_mut_bytes`](Self::as_mut_bytes),
71///   [`pop`](Self::pop),
72///   [`truncate`](Self::truncate),
73///   [`clear`](Self::clear),
74///   [`remove`](Self::remove),
75///   [`retain`](Self::retain),
76///   [`drain`](Self::drain) and
77///   [`split_off`](Self::split_off).
78/// - `BumpBox<MaybeUninit<T>>` provides [`init`](Self::init) and [`assume_init`](Self::assume_init)
79/// - `BumpBox<[MaybeUninit<T>]>` provides <code>init_{[fill](Self::init_fill), [fill_with](Self::init_fill_with), [fill_iter](Self::init_fill_iter), [copy](Self::init_copy), [clone](Self::init_clone), [move](Self::init_move)}</code>
80/// - `BumpBox<MaybeUninit<T>>` and `BumpBox<[MaybeUninit<T>]>` provide `init_zeroed` via an extension trait, either
81///   [`zerocopy_08::InitZeroed`](crate::zerocopy_08::InitZeroed::init_zeroed) or
82///   [`bytemuck::InitZeroed`](crate::bytemuck::InitZeroed::init_zeroed).
83///
84/// ## Api differences
85///
86/// `BumpBox<[T]>` and `BumpBox<str>` mirror the api of vectors and strings respectively.
87/// As such, methods like `as_ptr` and `as_mut_ptr` return a pointer to the start of the slice
88/// instead of a slice pointer. To get a pointer to the boxed content `T` of `BumpBox<T>`,
89/// use [`as_raw`](Self::as_raw) instead.
90///
91/// Unlike `Box<T>`, `BumpBox<T>` has some methods that are implemented for all `T`.
92/// Care is taken to not overwrite methods of `T` by only adding methods that start with
93/// `into_`. By convention `into_*` methods consume the type, so if `T` has an `into_*`
94/// method, then that method would not be callable by dereferencing the `BumpBox<T>` anyway.
95///
96/// ## No pinning
97///
98/// There is no way to safely pin a `BumpBox` in the general case.
99/// The [*drop guarantee*] of `Pin` requires the value to be dropped before its memory is reused.
100/// `Bump(Scope)` has api that frees memory so we'd need to drop the pinned value.
101/// But there is no way to ensure that a value is dropped in an async context.
102/// <details>
103/// <summary>Example of an unsound pin macro implementation.</summary>
104///
105/// We define a `bump_box_pin` macro that turns a `BumpBox<T>` into a `Pin<&mut T>`. This is not sound in async code.
106/// Here the memory `Foo(1)` is allocated at is reused by `Foo(2)` without dropping `Foo(1)` first which violates the drop guarantee.
107///
108/// ```
109/// # use bump_scope::{Bump, BumpBox};
110/// # use std::{mem, task::{Context, Poll}, pin::Pin, future::Future};
111/// #
112/// # #[must_use = "futures do nothing unless you `.await` or poll them"]
113/// # struct YieldNow(bool);
114/// #
115/// # impl Future for YieldNow {
116/// #     type Output = ();
117/// #
118/// #     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
119/// #         if !self.0 {
120/// #             self.0 = true;
121/// #             cx.waker().wake_by_ref();
122/// #             Poll::Pending
123/// #         } else {
124/// #             Poll::Ready(())
125/// #         }
126/// #     }
127/// # }
128/// #
129/// # fn yield_now() -> YieldNow {
130/// #     YieldNow(false)
131/// # }
132/// #
133/// macro_rules! bump_box_pin {
134///     ($name:ident) => {
135///         let mut boxed: BumpBox<_> = $name;
136///         let $name = unsafe { Pin::new_unchecked(&mut *boxed) };
137///     };
138/// }
139///
140/// struct Foo(i32);
141///
142/// impl Drop for Foo {
143///     fn drop(&mut self) {
144///         println!("dropped Foo({}) at {:?}", self.0, self as *const Foo);
145///     }
146/// }
147///
148/// fn use_pinned(_foo: Pin<&mut Foo>) {}
149///
150/// # #[expect(dead_code)]
151/// fn violate_drop_guarantee(cx: &mut Context) {
152///     let mut bump: Bump = Bump::new();
153///
154///     let mut future = Box::pin(async {
155///         let foo = bump.alloc(Foo(1));
156///         println!("created Foo({}) at {:?}", foo.0, &*foo as *const Foo);
157///         bump_box_pin!(foo);
158///         println!("pinned Foo({}) at {:?}", foo.0, &*foo as *const Foo);
159///         yield_now().await;
160///         use_pinned(foo);
161///     });
162///
163///     assert_eq!(future.as_mut().poll(cx), Poll::Pending);
164///     mem::forget(future);
165///
166///     bump.reset();
167///     let foo = bump.alloc(Foo(2));
168///     println!("created Foo({}) at {:?}", foo.0, &*foo as *const Foo);
169/// }
170/// ```
171/// This will print something like:
172/// ```text
173/// created Foo(1) at 0x78a4f4000d30
174/// pinned  Foo(1) at 0x78a4f4000d30
175/// created Foo(2) at 0x78a4f4000d30
176/// dropped Foo(2) at 0x78a4f4000d30
177/// ```
178/// </details>
179///
180/// [`into_ref`]: Self::into_ref
181/// [`into_mut`]: BumpBox::into_mut
182/// [`into_box`]: BumpBox::into_box
183/// [`leak`]: BumpBox::leak
184/// [`Box`]: alloc_crate::boxed::Box
185/// [*drop guarantee*]: https://doc.rust-lang.org/std/pin/index.html#subtle-details-and-the-drop-guarantee
186#[repr(transparent)]
187pub struct BumpBox<'a, T: ?Sized> {
188    ptr: NonNull<T>,
189
190    /// First field marks the lifetime.
191    /// Second field marks ownership over T. (<https://doc.rust-lang.org/nomicon/phantom-data.html#generic-parameters-and-drop-checking>)
192    marker: PhantomData<(&'a (), T)>,
193}
194
195/// Allows unsizing to be performed on `T` of `BumpBox<T>`.
196///
197/// This macro is required to unsize the pointee of a `BumpBox` on stable rust.
198///
199/// On nightly and when the feature "nightly-coerce-unsized" is enabled, `BumpBox` implements `CoerceUnsized` so `T` will coerce just like with [`Box`].
200///
201/// # Examples
202/// ```
203/// use bump_scope::{Bump, BumpBox, unsize_bump_box};
204/// use core::any::Any;
205///
206/// let bump: Bump = Bump::new();
207///
208/// let sized_box: BumpBox<[i32; 3]> = bump.alloc([1, 2, 3]);
209/// let unsized_box_slice: BumpBox<[i32]> = unsize_bump_box!(sized_box);
210///
211/// let sized_box: BumpBox<[i32; 3]> = bump.alloc([1, 2, 3]);
212/// let unsized_box_dyn: BumpBox<dyn Any> = unsize_bump_box!(sized_box);
213/// #
214/// # _ = unsized_box_slice;
215/// # _ = unsized_box_dyn;
216/// ```
217/// On nightly with the feature "nightly-coerce-unsized":
218#[cfg_attr(feature = "nightly-coerce-unsized", doc = "```")]
219#[cfg_attr(not(feature = "nightly-coerce-unsized"), doc = "```ignore")]
220/// use bump_scope::{Bump, BumpBox};
221/// use core::any::Any;
222///
223/// let bump: Bump = Bump::new();
224///
225/// let sized_box: BumpBox<[i32; 3]> = bump.alloc([1, 2, 3]);
226/// let unsized_box_slice: BumpBox<[i32]> = sized_box;
227///
228/// let sized_box: BumpBox<[i32; 3]> = bump.alloc([1, 2, 3]);
229/// let unsized_box_dyn: BumpBox<dyn Any> = sized_box;
230/// #
231/// # _ = unsized_box_slice;
232/// # _ = unsized_box_dyn;
233/// ```
234#[macro_export]
235macro_rules! unsize_bump_box {
236    ($boxed:expr) => {{
237        let (ptr, lt) = $crate::private::bump_box_into_raw_with_lifetime($boxed);
238        let ptr: $crate::private::core::ptr::NonNull<_> = ptr;
239        unsafe { $crate::private::bump_box_from_raw_with_lifetime(ptr, lt) }
240    }};
241}
242
243unsafe impl<T: ?Sized + Send> Send for BumpBox<'_, T> {}
244unsafe impl<T: ?Sized + Sync> Sync for BumpBox<'_, T> {}
245
246impl<T> BumpBox<'_, T> {
247    #[must_use]
248    #[inline(always)]
249    pub(crate) fn zst(value: T) -> Self {
250        assert!(T::IS_ZST);
251        mem::forget(value);
252        Self {
253            ptr: NonNull::dangling(),
254            marker: PhantomData,
255        }
256    }
257
258    #[must_use]
259    #[inline(always)]
260    pub(crate) fn zst_uninit() -> BumpBox<'static, MaybeUninit<T>> {
261        assert!(T::IS_ZST);
262        BumpBox {
263            ptr: NonNull::dangling(),
264            marker: PhantomData,
265        }
266    }
267}
268
269impl<'a, T: ?Sized + NoDrop> BumpBox<'a, T> {
270    /// Turns this `BumpBox<T>` into `&T` that is live for this bump scope.
271    /// This is only available for [`NoDrop`] types so you don't omit dropping a value for which it matters.
272    ///
273    /// `!NoDrop` types can still be turned into references via [`leak`](BumpBox::leak).
274    #[must_use]
275    #[inline(always)]
276    pub fn into_ref(self) -> &'a T {
277        self.into_mut()
278    }
279
280    /// Turns this `BumpBox<T>` into `&mut T` that is live for this bump scope.
281    /// This is only available for [`NoDrop`] types so you don't omit dropping a value for which it matters.
282    ///
283    /// `!NoDrop` types can still be turned into references via [`leak`](BumpBox::leak).
284    #[must_use]
285    #[inline(always)]
286    pub fn into_mut(self) -> &'a mut T {
287        Self::leak(self)
288    }
289}
290
291impl<'a, T: ?Sized> BumpBox<'a, T> {
292    #[must_use]
293    #[inline(always)]
294    pub(crate) const fn ptr(&self) -> NonNull<T> {
295        self.ptr
296    }
297
298    #[must_use]
299    #[inline(always)]
300    pub(crate) unsafe fn mut_ptr(&mut self) -> &mut NonNull<T> {
301        &mut self.ptr
302    }
303
304    /// Turns this `BumpBox<T>` into `Box<T>`. The bump `allocator` is not required to be
305    /// the allocator this box was allocated in.
306    ///
307    /// Unlike `BumpBox`, `Box` implements `Clone` and frees space iff it is the last allocation:
308    #[cfg_attr(feature = "allocator-api2-04", doc = "```")]
309    #[cfg_attr(not(feature = "allocator-api2-04"), doc = "```ignore")]
310    /// # use bump_scope::Bump;
311    /// # use allocator_api2_04::boxed::Box;
312    /// # let bump: Bump = Bump::new();
313    /// let a: Box<_, _> = bump.alloc(3i32).into_box(&bump);
314    /// let b = a.clone();
315    /// assert_eq!(a, b);
316    /// drop(b);
317    /// drop(a);
318    /// assert_eq!(bump.stats().allocated(), 0);
319    /// ```
320    #[must_use]
321    #[inline(always)]
322    pub fn into_box<A, B>(self, allocator: A) -> B
323    where
324        A: BumpAllocatorTypedScope<'a>,
325        B: BoxLike<T = T, A = A>,
326    {
327        let ptr = BumpBox::into_raw(self).as_ptr();
328
329        // SAFETY: bump might not be the allocator self was allocated with;
330        // that's fine though because a `BumpAllocatorCore` allows deallocate calls
331        // from allocations that don't belong to it
332        unsafe { B::from_raw_in(ptr, allocator) }
333    }
334
335    /// Turns this `BumpBox<T>` into `&mut T` that is live for this bump scope.
336    /// `T` won't be dropped which may leak resources.
337    ///
338    /// If `T` is [`NoDrop`], prefer to call [`into_mut`](BumpBox::into_mut) to signify that nothing gets leaked.
339    ///
340    /// # Examples
341    ///
342    /// ```
343    /// # use bump_scope::{Bump, BumpBox};
344    /// # let bump: Bump = Bump::new();
345    /// #
346    /// let boxed_slice_of_slices: BumpBox<[&mut [i32]]> = bump.alloc_iter_exact((0..3).map(|_| {
347    ///     bump.alloc_slice_fill_with(3, Default::default).into_mut()
348    /// }));
349    ///
350    /// // `&mut T` don't implement `NoDrop` currently because a blanket implementation
351    /// // for `&mut T` would conflict with the blanket implementation for `T: Copy`
352    /// // (see https://github.com/rust-lang/rust/issues/149650)
353    /// // so we need to use `leak`
354    /// let slice_of_slices: &mut [&mut [i32]] = BumpBox::leak(boxed_slice_of_slices);
355    /// # _ = slice_of_slices;
356    /// ```
357    #[inline(always)]
358    #[expect(clippy::must_use_candidate)]
359    pub fn leak(boxed: Self) -> &'a mut T {
360        unsafe { BumpBox::into_raw(boxed).as_mut() }
361    }
362
363    /// Returns a `NonNull` pointer to the `BumpBox`'s contents.
364    ///
365    /// The caller must ensure that the `BumpBox` outlives the pointer this
366    /// function returns, or else it will end up dangling.
367    ///
368    /// This method guarantees that for the purpose of the aliasing model, this method
369    /// does not materialize a reference to the underlying memory, and thus the returned pointer
370    /// will remain valid when mixed with other calls to [`as_raw`] and [`into_raw`].
371    /// Note that calling other methods that materialize references to the memory
372    /// may still invalidate this pointer.
373    /// See the example below for how this guarantee can be used.
374    ///
375    /// # Examples
376    ///
377    /// Due to the aliasing guarantee, the following code is legal:
378    ///
379    /// ```rust
380    /// # use bump_scope::{Bump, BumpBox};
381    /// # let bump: Bump = Bump::new();
382    ///
383    /// unsafe {
384    ///     let b = bump.alloc(0);
385    ///     let ptr1 = BumpBox::as_raw(&b);
386    ///     ptr1.write(1);
387    ///     let ptr2 = BumpBox::as_raw(&b);
388    ///     ptr2.write(2);
389    ///     // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
390    ///     ptr1.write(3);
391    /// }
392    /// ```
393    ///
394    /// [`as_raw`]: Self::as_raw
395    /// [`into_raw`]: Self::into_raw
396    #[inline]
397    #[must_use]
398    pub const fn as_raw(b: &Self) -> NonNull<T> {
399        b.ptr
400    }
401
402    /// Consumes the `BumpBox`, returning a wrapped raw pointer.
403    ///
404    /// The pointer will be properly aligned and non-null. It is only valid for the lifetime `'a`.
405    ///
406    /// After calling this function, the caller is responsible for dropping the
407    /// value previously managed by the `BumpBox`. The easiest way to do this is to `p.drop_in_place()`.
408    ///
409    /// You can turn this pointer back into a `BumpBox` with [`BumpBox::from_raw`].
410    ///
411    /// # Examples
412    /// Manually dropping `T`:
413    /// ```
414    /// use bump_scope::{Bump, BumpBox};
415    /// let bump: Bump = Bump::new();
416    /// let x = bump.alloc(String::from("Hello"));
417    /// let p = BumpBox::into_raw(x);
418    /// unsafe { p.drop_in_place() }
419    /// ```
420    #[inline(always)]
421    #[must_use = "use `leak` if you don't make use of the pointer"]
422    pub fn into_raw(self) -> NonNull<T> {
423        ManuallyDrop::new(self).ptr
424    }
425
426    /// Constructs a `BumpBox` from a raw pointer.
427    ///
428    /// After calling this function, the pointed to value is owned by the resulting `BumpBox`.
429    /// Specifically, the `BumpBox` destructor will call the destructor of `T`.
430    /// For this to be safe, the pointer must point to a valid `T` for the lifetime of `'a`.
431    ///
432    /// # Safety
433    /// - `ptr` must point to a valid value for the lifetime `'a`
434    ///
435    /// # Examples
436    ///
437    /// Recreate a `BumpBox` which was previously converted to a raw pointer
438    /// using [`BumpBox::into_raw`]:
439    /// ```
440    /// use bump_scope::{Bump, BumpBox};
441    /// use core::ptr::NonNull;
442    ///
443    /// unsafe fn from_raw_in<'a, T>(ptr: NonNull<T>, _bump: &'a Bump) -> BumpBox<'a, T> {
444    ///     BumpBox::from_raw(ptr)
445    /// }
446    ///
447    /// let bump: Bump = Bump::new();
448    /// let x = bump.alloc(String::from("Hello"));
449    /// let ptr = BumpBox::into_raw(x);
450    /// let x = unsafe { from_raw_in(ptr, &bump) };
451    /// assert_eq!(x.as_str(), "Hello");
452    /// drop(x);
453    /// ```
454    /// Manually create a `BumpBox` from scratch by using the bump allocator:
455    /// ```
456    /// use bump_scope::{Bump, BumpBox, alloc::Allocator};
457    /// use core::alloc::Layout;
458    /// use core::ptr::NonNull;
459    ///
460    /// unsafe fn from_raw_in<'a, T>(ptr: NonNull<T>, _bump: &'a Bump) -> BumpBox<'a, T> {
461    ///     unsafe { BumpBox::from_raw(ptr) }
462    /// }
463    ///
464    /// let bump: Bump = Bump::new();
465    ///
466    /// let five = unsafe {
467    ///     let ptr = bump.allocate(Layout::new::<i32>()).unwrap().cast::<i32>();
468    ///     // In general .write is required to avoid attempting to destruct
469    ///     // the (uninitialized) previous contents of `ptr`, though for this
470    ///     // simple example `*ptr = 5` would have worked as well.
471    ///     ptr.write(5);
472    ///     from_raw_in(ptr, &bump)
473    /// };
474    ///
475    /// assert_eq!(*five, 5);
476    /// ```
477    #[must_use]
478    #[inline(always)]
479    pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
480        Self {
481            ptr,
482            marker: PhantomData,
483        }
484    }
485}
486
487impl<'a, T> BumpBox<'a, T> {
488    /// Consumes the `BumpBox`, returning the wrapped value.
489    ///
490    /// # Examples
491    ///
492    /// ```
493    /// # use bump_scope::Bump;
494    /// # let bump: Bump = Bump::new();
495    /// let c = bump.alloc(5);
496    /// assert_eq!(c.into_inner(), 5);
497    /// ```
498    #[must_use]
499    #[inline(always)]
500    pub fn into_inner(self) -> T {
501        unsafe { self.into_raw().read() }
502    }
503
504    /// Converts a `BumpBox<T>` into a `BumpBox<[T]>`
505    ///
506    /// This conversion happens in place.
507    #[must_use]
508    #[inline(always)]
509    pub fn into_boxed_slice(self) -> BumpBox<'a, [T]> {
510        unsafe {
511            let ptr = self.into_raw();
512            let ptr = NonNull::slice_from_raw_parts(ptr, 1);
513            BumpBox::from_raw(ptr)
514        }
515    }
516}
517
518impl<'a> BumpBox<'a, str> {
519    /// Empty str.
520    pub const EMPTY_STR: Self = unsafe { BumpBox::from_utf8_unchecked(BumpBox::<[u8]>::EMPTY) };
521
522    /// Converts a `BumpBox<[u8]>` to a `BumpBox<str>`.
523    ///
524    /// A string ([`BumpBox<str>`]) is made of bytes ([`u8`]), and a vector of bytes
525    /// ([`BumpBox<[u8]>`]) is made of bytes, so this function converts between the
526    /// two. Not all byte slices are valid `BumpBox<str>`s, however: `BumpBox<str>`
527    /// requires that it is valid UTF-8. `from_utf8()` checks to ensure that
528    /// the bytes are valid UTF-8, and then does the conversion.
529    ///
530    /// If you are sure that the byte slice is valid UTF-8, and you don't want
531    /// to incur the overhead of the validity check, there is an unsafe version
532    /// of this function, [`from_utf8_unchecked`], which has the same behavior
533    /// but skips the check.
534    ///
535    /// This method will take care to not copy the vector, for efficiency's
536    /// sake.
537    ///
538    /// If you need a [`&str`] instead of a `BumpBox<str>`, consider
539    /// [`str::from_utf8`].
540    ///
541    /// The inverse of this method is [`into_boxed_bytes`].
542    ///
543    /// # Errors
544    ///
545    /// Returns [`Err`] if the slice is not UTF-8 with a description as to why the
546    /// provided bytes are not UTF-8. The vector you moved in is also included.
547    ///
548    /// # Examples
549    ///
550    /// Basic usage:
551    /// ```
552    /// # use bump_scope::{Bump, BumpBox};
553    /// # let bump: Bump = Bump::new();
554    /// // some bytes, in a vector
555    /// let sparkle_heart = bump.alloc_slice_copy(&[240, 159, 146, 150]);
556    ///
557    /// // We know these bytes are valid, so we'll use `unwrap()`.
558    /// let sparkle_heart = BumpBox::from_utf8(sparkle_heart).unwrap();
559    ///
560    /// assert_eq!(sparkle_heart, "💖");
561    /// ```
562    ///
563    /// Incorrect bytes:
564    /// ```
565    /// # use bump_scope::{Bump, BumpBox};
566    /// # let bump: Bump = Bump::new();
567    /// // some invalid bytes, in a vector
568    /// let sparkle_heart = bump.alloc_slice_copy(&[0, 159, 146, 150]);
569    ///
570    /// assert!(BumpBox::from_utf8(sparkle_heart).is_err());
571    /// ```
572    ///
573    /// [`from_utf8_unchecked`]: Self::from_utf8_unchecked
574    /// [`&str`]: prim@str "&str"
575    /// [`into_boxed_bytes`]: Self::into_boxed_bytes
576    pub const fn from_utf8(bytes: BumpBox<'a, [u8]>) -> Result<Self, FromUtf8Error<BumpBox<'a, [u8]>>> {
577        match str::from_utf8(bytes.as_slice()) {
578            // SAFETY: `BumpBox<[u8]>` and `BumpBox<str>` have the same representation;
579            // only the invariant that the bytes are utf8 is different.
580            Ok(_) => Ok(unsafe { mem::transmute(bytes) }),
581            Err(error) => Err(FromUtf8Error::new(error, bytes)),
582        }
583    }
584
585    /// Converts a vector of bytes to a `BumpString` without checking that the
586    /// string contains valid UTF-8.
587    ///
588    /// See the safe version, [`from_utf8`](Self::from_utf8), for more details.
589    ///
590    /// # Safety
591    ///
592    /// The bytes passed in must be valid UTF-8.
593    ///
594    /// # Examples
595    ///
596    /// ```
597    /// # use bump_scope::{Bump, BumpBox};
598    /// # let bump: Bump = Bump::new();
599    /// // some bytes, in a vector
600    /// let sparkle_heart = bump.alloc_slice_copy(&[240, 159, 146, 150]);
601    ///
602    /// let sparkle_heart = unsafe {
603    ///     BumpBox::from_utf8_unchecked(sparkle_heart)
604    /// };
605    ///
606    /// assert_eq!(sparkle_heart, "💖");
607    /// ```
608    #[must_use]
609    pub const unsafe fn from_utf8_unchecked(bytes: BumpBox<'a, [u8]>) -> Self {
610        debug_assert!(str::from_utf8(bytes.as_slice()).is_ok());
611
612        // SAFETY: `BumpBox<[u8]>` and `BumpBox<str>` have the same representation;
613        // only the invariant that the bytes are utf8 is different.
614        unsafe { mem::transmute(bytes) }
615    }
616
617    /// Converts a `BumpBox<str>` into a `BumpBox<[u8]>`.
618    #[inline]
619    #[must_use]
620    pub fn into_boxed_bytes(self) -> BumpBox<'a, [u8]> {
621        BumpBox {
622            ptr: non_null::str_bytes(self.ptr),
623            marker: PhantomData,
624        }
625    }
626
627    /// Returns a mutable reference to the bytes of this string.
628    ///
629    /// # Safety
630    ///
631    /// This function is unsafe because the returned `&mut BumpBox<[u8]>` allows writing
632    /// bytes which are not valid UTF-8. If this constraint is violated, using
633    /// the original `BumpBox<str>` after dropping the `&mut BumpBox<[u8]>` may violate memory
634    /// safety, as `BumpBox<str>`s must be valid UTF-8.
635    #[must_use]
636    #[inline(always)]
637    pub unsafe fn as_mut_bytes(&mut self) -> &mut BumpBox<'a, [u8]> {
638        unsafe {
639            // SAFETY: `BumpBox<[u8]>` and `BumpBox<str>` have the same representation;
640            // only the invariant that the bytes are utf8 is different.
641            transmute_mut(self)
642        }
643    }
644
645    /// Returns the number of bytes in the string, also referred to
646    /// as its 'length'.
647    #[must_use]
648    #[inline(always)]
649    pub const fn len(&self) -> usize {
650        non_null::str_len(self.ptr)
651    }
652
653    /// Returns `true` if the slice contains no elements.
654    #[must_use]
655    #[inline(always)]
656    pub const fn is_empty(&self) -> bool {
657        self.len() == 0
658    }
659
660    #[track_caller]
661    pub(crate) fn assert_char_boundary(&self, index: usize) {
662        #[cold]
663        #[track_caller]
664        #[inline(never)]
665        fn assert_failed() {
666            panic!("index is not on a char boundary")
667        }
668
669        if !self.is_char_boundary(index) {
670            assert_failed();
671        }
672    }
673
674    /// Splits the string into two by removing the specified range.
675    ///
676    /// This method does not allocate and does not change the order of the elements.
677    ///
678    /// # Panics
679    ///
680    /// Panics if the starting point or end point do not lie on a [`char`] boundary, or if they're out of bounds.
681    ///
682    /// # Complexity
683    ///
684    /// This operation takes `O(1)` time if either the range starts at 0, ends at `len`, or is empty.
685    /// Otherwise it takes `O(min(end, len - start))` time.
686    ///
687    /// # Examples
688    ///
689    /// ```
690    /// # use bump_scope::Bump;
691    /// # let bump: Bump = Bump::new();
692    /// let mut string = bump.alloc_str("foobarbazqux");
693    ///
694    /// let foo = string.split_off(..3);
695    /// assert_eq!(foo, "foo");
696    /// assert_eq!(string, "barbazqux");
697    ///
698    /// let qux = string.split_off(6..);
699    /// assert_eq!(qux, "qux");
700    /// assert_eq!(string, "barbaz");
701    ///
702    /// let rb = string.split_off(2..4);
703    /// assert_eq!(rb, "rb");
704    /// assert_eq!(string, "baaz");
705    ///
706    /// let rest = string.split_off(..);
707    /// assert_eq!(rest, "baaz");
708    /// assert_eq!(string, "");
709    /// ```
710    #[inline]
711    #[expect(clippy::return_self_not_must_use)]
712    pub fn split_off(&mut self, range: impl RangeBounds<usize>) -> Self {
713        let len = self.len();
714        let ops::Range { start, end } = polyfill::slice::range(range, ..len);
715        let ptr = non_null::as_non_null_ptr(non_null::str_bytes(self.ptr));
716
717        if end == len {
718            self.assert_char_boundary(start);
719
720            let lhs = NonNull::slice_from_raw_parts(ptr, start);
721            let rhs = NonNull::slice_from_raw_parts(unsafe { ptr.add(start) }, len - start);
722
723            self.ptr = non_null::str_from_utf8(lhs);
724            return unsafe { BumpBox::from_raw(non_null::str_from_utf8(rhs)) };
725        }
726
727        if start == 0 {
728            self.assert_char_boundary(end);
729
730            let lhs = NonNull::slice_from_raw_parts(ptr, end);
731            let rhs = NonNull::slice_from_raw_parts(unsafe { ptr.add(end) }, len - end);
732
733            self.ptr = non_null::str_from_utf8(rhs);
734            return unsafe { BumpBox::from_raw(non_null::str_from_utf8(lhs)) };
735        }
736
737        if start == end {
738            return BumpBox::EMPTY_STR;
739        }
740
741        self.assert_char_boundary(start);
742        self.assert_char_boundary(end);
743
744        let head_len = start;
745        let tail_len = len - end;
746
747        let range_len = end - start;
748        let remaining_len = len - range_len;
749
750        unsafe {
751            if head_len < tail_len {
752                // move the range of elements to split off to the start
753                self.as_mut_bytes().get_unchecked_mut(..end).rotate_right(range_len);
754
755                let lhs = NonNull::slice_from_raw_parts(ptr, range_len);
756                let rhs = NonNull::slice_from_raw_parts(ptr.add(range_len), remaining_len);
757
758                let lhs = non_null::str_from_utf8(lhs);
759                let rhs = non_null::str_from_utf8(rhs);
760
761                self.ptr = rhs;
762
763                BumpBox::from_raw(lhs)
764            } else {
765                // move the range of elements to split off to the end
766                self.as_mut_bytes().get_unchecked_mut(start..).rotate_left(range_len);
767
768                let lhs = NonNull::slice_from_raw_parts(ptr, remaining_len);
769                let rhs = NonNull::slice_from_raw_parts(ptr.add(remaining_len), range_len);
770
771                let lhs = non_null::str_from_utf8(lhs);
772                let rhs = non_null::str_from_utf8(rhs);
773
774                self.ptr = lhs;
775
776                BumpBox::from_raw(rhs)
777            }
778        }
779    }
780
781    /// Removes the last character from the string buffer and returns it.
782    ///
783    /// Returns [`None`] if this string is empty.
784    ///
785    /// # Examples
786    ///
787    /// ```
788    /// # use bump_scope::Bump;
789    /// # let bump: Bump = Bump::new();
790    /// let mut s = bump.alloc_str("abč");
791    ///
792    /// assert_eq!(s.pop(), Some('č'));
793    /// assert_eq!(s.pop(), Some('b'));
794    /// assert_eq!(s.pop(), Some('a'));
795    ///
796    /// assert_eq!(s.pop(), None);
797    /// ```
798    #[inline]
799    pub fn pop(&mut self) -> Option<char> {
800        let ch = self.chars().next_back()?;
801        let new_len = self.len() - ch.len_utf8();
802        unsafe {
803            self.set_len(new_len);
804        }
805        Some(ch)
806    }
807
808    /// Shortens this string to the specified length.
809    ///
810    /// If `new_len` is greater than or equal to the string's current length, this has no
811    /// effect.
812    ///
813    /// Note that this method has no effect on the allocated capacity
814    /// of the string
815    ///
816    /// # Panics
817    ///
818    /// Panics if `new_len` does not lie on a [`char`] boundary.
819    ///
820    /// # Examples
821    ///
822    /// ```
823    /// # use bump_scope::Bump;
824    /// # let bump: Bump = Bump::new();
825    /// let mut s = bump.alloc_str("hello");
826    ///
827    /// s.truncate(2);
828    ///
829    /// assert_eq!(s, "he");
830    /// ```
831    #[inline]
832    pub fn truncate(&mut self, new_len: usize) {
833        if new_len <= self.len() {
834            self.assert_char_boundary(new_len);
835            unsafe { self.as_mut_bytes().truncate(new_len) }
836        }
837    }
838
839    /// Truncates this string, removing all contents.
840    ///
841    /// # Examples
842    ///
843    /// ```
844    /// # use bump_scope::Bump;
845    /// # let bump: Bump = Bump::new();
846    /// let mut str = bump.alloc_str("hello");
847    /// str.clear();
848    /// assert!(str.is_empty());
849    /// ```
850    #[inline(always)]
851    pub fn clear(&mut self) {
852        unsafe {
853            self.set_len(0);
854        }
855    }
856
857    /// Returns a raw pointer to the str, or a dangling raw pointer
858    /// valid for zero sized reads.
859    #[inline]
860    #[must_use]
861    pub fn as_ptr(&self) -> *const u8 {
862        // We shadow the str method of the same name to avoid going through
863        // `deref`, which creates an intermediate reference.
864        self.ptr.as_ptr().cast()
865    }
866
867    /// Returns an unsafe mutable pointer to str, or a dangling
868    /// raw pointer valid for zero sized reads.
869    #[inline]
870    pub fn as_mut_ptr(&mut self) -> *mut u8 {
871        // We shadow the str method of the same name to avoid going through
872        // `deref_mut`, which creates an intermediate reference.
873        self.ptr.as_ptr().cast()
874    }
875
876    /// Returns a `NonNull` pointer to the string's buffer, or a dangling
877    /// `NonNull` pointer valid for zero sized reads if the vector didn't allocate.
878    ///
879    /// The caller must ensure that the string outlives the pointer this
880    /// function returns, or else it will end up dangling.
881    /// Modifying the string may cause its buffer to be reallocated,
882    /// which would also make any pointers to it invalid.
883    ///
884    /// This method guarantees that for the purpose of the aliasing model, this method
885    /// does not materialize a reference to the underlying slice, and thus the returned pointer
886    /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
887    /// and [`as_non_null`].
888    /// Note that calling other methods that materialize references to the slice,
889    /// or references to specific elements you are planning on accessing through this pointer,
890    /// may still invalidate this pointer.
891    /// See the example below for how this guarantee can be used.
892    ///
893    /// # Examples
894    ///
895    /// Due to the aliasing guarantee, the following code is legal:
896    ///
897    /// ```
898    /// # use bump_scope::Bump;
899    /// # let bump: Bump = Bump::new();
900    /// unsafe {
901    ///     let v = bump.alloc_str("a");
902    ///     let ptr1 = v.as_non_null();
903    ///     ptr1.write(b'b');
904    ///     let ptr2 = v.as_non_null();
905    ///     ptr2.write(b'c');
906    ///     // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
907    ///     ptr1.write(b'd');
908    /// }
909    /// ```
910    ///
911    /// [`as_mut_ptr`]: Self::as_mut_ptr
912    /// [`as_ptr`]: Self::as_ptr
913    /// [`as_non_null`]: Self::as_non_null
914    #[must_use]
915    #[inline(always)]
916    pub const fn as_non_null(&self) -> NonNull<u8> {
917        self.ptr.cast()
918    }
919
920    #[inline(always)]
921    pub(crate) unsafe fn set_ptr(&mut self, new_ptr: NonNull<u8>) {
922        self.ptr = non_null::str_from_utf8(NonNull::slice_from_raw_parts(new_ptr, self.len()));
923    }
924
925    /// Forces the length of the string to `new_len`.
926    ///
927    /// This is a low-level operation that maintains none of the normal
928    /// invariants of the type. Normally changing the length of a boxed slice
929    /// is done using one of the safe operations instead, such as
930    /// [`truncate`] or [`clear`].
931    ///
932    /// [`truncate`]: Self::truncate
933    /// [`clear`]: Self::clear
934    ///
935    /// # Safety
936    ///
937    /// - `new_len` must be less than or equal to the `capacity` (capacity is not tracked by this type).
938    /// - `new_len` must lie on a `char` boundary
939    /// - The elements at `old_len..new_len` must be initialized.
940    #[inline]
941    pub unsafe fn set_len(&mut self, new_len: usize) {
942        let ptr = self.ptr.cast::<u8>();
943        let bytes = NonNull::slice_from_raw_parts(ptr, new_len);
944        self.ptr = non_null::str_from_utf8(bytes);
945    }
946
947    /// Removes a [`char`] from this string at a byte position and returns it.
948    ///
949    /// This is an *O*(*n*) operation, as it requires copying every element in the
950    /// buffer.
951    ///
952    /// # Panics
953    ///
954    /// Panics if `idx` is larger than or equal to the string's length,
955    /// or if it does not lie on a [`char`] boundary.
956    ///
957    /// # Examples
958    ///
959    /// ```
960    /// # use bump_scope::Bump;
961    /// # let bump: Bump = Bump::new();
962    /// let mut s = bump.alloc_str("abç");
963    ///
964    /// assert_eq!(s.remove(0), 'a');
965    /// assert_eq!(s.remove(1), 'ç');
966    /// assert_eq!(s.remove(0), 'b');
967    /// ```
968    #[inline]
969    pub fn remove(&mut self, idx: usize) -> char {
970        let Some(ch) = self[idx..].chars().next() else {
971            panic!("cannot remove a char from the end of a string");
972        };
973
974        let next = idx + ch.len_utf8();
975        let len = self.len();
976        unsafe {
977            ptr::copy(self.as_ptr().add(next), self.as_mut_ptr().add(idx), len - next);
978            self.set_len(len - (next - idx));
979        }
980        ch
981    }
982
983    /// Retains only the characters specified by the predicate.
984    ///
985    /// In other words, remove all characters `c` such that `f(c)` returns `false`.
986    /// This method operates in place, visiting each character exactly once in the
987    /// original order, and preserves the order of the retained characters.
988    ///
989    /// # Examples
990    ///
991    /// ```
992    /// # use bump_scope::Bump;
993    /// # let bump: Bump = Bump::new();
994    /// let mut s = bump.alloc_str("f_o_ob_ar");
995    ///
996    /// s.retain(|c| c != '_');
997    ///
998    /// assert_eq!(s, "foobar");
999    /// ```
1000    ///
1001    /// Because the elements are visited exactly once in the original order,
1002    /// external state may be used to decide which elements to keep.
1003    ///
1004    /// ```
1005    /// # use bump_scope::Bump;
1006    /// # let bump: Bump = Bump::new();
1007    /// let mut s = bump.alloc_str("abcde");
1008    /// let keep = [false, true, true, false, true];
1009    /// let mut iter = keep.iter();
1010    /// s.retain(|_| *iter.next().unwrap());
1011    /// assert_eq!(s, "bce");
1012    /// ```
1013    #[inline]
1014    pub fn retain<F>(&mut self, mut f: F)
1015    where
1016        F: FnMut(char) -> bool,
1017    {
1018        struct SetLenOnDrop<'b, 'a> {
1019            s: &'b mut BumpBox<'a, str>,
1020            idx: usize,
1021            del_bytes: usize,
1022        }
1023
1024        impl Drop for SetLenOnDrop<'_, '_> {
1025            fn drop(&mut self) {
1026                let new_len = self.idx - self.del_bytes;
1027                debug_assert!(new_len <= self.s.len());
1028                unsafe { self.s.set_len(new_len) };
1029            }
1030        }
1031
1032        let len = self.len();
1033        let mut guard = SetLenOnDrop {
1034            s: self,
1035            idx: 0,
1036            del_bytes: 0,
1037        };
1038
1039        while guard.idx < len {
1040            let ch =
1041                // SAFETY: `guard.idx` is positive-or-zero and less that len so the `get_unchecked`
1042                // is in bound. `self` is valid UTF-8 like string and the returned slice starts at
1043                // a unicode code point so the `Chars` always return one character.
1044                unsafe { guard.s.get_unchecked(guard.idx..len).chars().next().unwrap_unchecked() };
1045            let ch_len = ch.len_utf8();
1046
1047            if !f(ch) {
1048                guard.del_bytes += ch_len;
1049            } else if guard.del_bytes > 0 {
1050                // SAFETY: `guard.idx` is in bound and `guard.del_bytes` represent the number of
1051                // bytes that are erased from the string so the resulting `guard.idx -
1052                // guard.del_bytes` always represent a valid unicode code point.
1053                //
1054                // `guard.del_bytes` >= `ch.len_utf8()`, so taking a slice with `ch.len_utf8()` len
1055                // is safe.
1056                ch.encode_utf8(unsafe {
1057                    slice::from_raw_parts_mut(guard.s.as_mut_ptr().add(guard.idx - guard.del_bytes), ch.len_utf8())
1058                });
1059            }
1060
1061            // Point idx to the next char
1062            guard.idx += ch_len;
1063        }
1064
1065        drop(guard);
1066    }
1067
1068    /// Removes the specified range from the string in bulk, returning all
1069    /// removed characters as an iterator.
1070    ///
1071    /// The returned iterator keeps a mutable borrow on the string to optimize
1072    /// its implementation.
1073    ///
1074    /// # Panics
1075    ///
1076    /// Panics if the starting point or end point do not lie on a [`char`]
1077    /// boundary, or if they're out of bounds.
1078    ///
1079    /// # Leaking
1080    ///
1081    /// If the returned iterator goes out of scope without being dropped (due to
1082    /// [`core::mem::forget`], for example), the string may still contain a copy
1083    /// of any drained characters, or may have lost characters arbitrarily,
1084    /// including characters outside the range.
1085    ///
1086    /// # Examples
1087    ///
1088    /// Basic usage:
1089    ///
1090    /// ```
1091    /// # use bump_scope::Bump;
1092    /// # let bump: Bump = Bump::new();
1093    /// let mut s = bump.alloc_str("α is alpha, β is beta");
1094    /// let beta_offset = s.find('β').unwrap_or(s.len());
1095    ///
1096    /// // Remove the range up until the β from the string
1097    /// let t: String = s.drain(..beta_offset).collect();
1098    /// assert_eq!(t, "α is alpha, ");
1099    /// assert_eq!(s, "β is beta");
1100    ///
1101    /// // A full range clears the string, like `clear()` does
1102    /// s.drain(..);
1103    /// assert_eq!(s, "");
1104    /// ```
1105    pub fn drain<R>(&mut self, range: R) -> owned_str::Drain<'_>
1106    where
1107        R: RangeBounds<usize>,
1108    {
1109        // Memory safety
1110        //
1111        // The String version of Drain does not have the memory safety issues
1112        // of the vector version. The data is just plain bytes.
1113        // Because the range removal happens in Drop, if the Drain iterator is leaked,
1114        // the removal will not happen.
1115        let Range { start, end } = polyfill::slice::range(range, ..self.len());
1116        self.assert_char_boundary(start);
1117        self.assert_char_boundary(end);
1118
1119        // Take out two simultaneous borrows. The &mut String won't be accessed
1120        // until iteration is over, in Drop.
1121        let self_ptr = unsafe { NonNull::new_unchecked(ptr::from_mut(self)) };
1122        // SAFETY: `slice::range` and `is_char_boundary` do the appropriate bounds checks.
1123        let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
1124
1125        owned_str::Drain {
1126            start,
1127            end,
1128            iter: chars_iter,
1129            string: self_ptr,
1130        }
1131    }
1132}
1133
1134impl<'a, T: Sized> BumpBox<'a, MaybeUninit<T>> {
1135    /// Initializes `self` with `value`.
1136    ///
1137    /// # Examples
1138    ///
1139    /// ```
1140    /// # use bump_scope::Bump;
1141    /// # let bump: Bump = Bump::new();
1142    /// let uninit = bump.alloc_uninit();
1143    /// let init = uninit.init(1);
1144    /// assert_eq!(*init, 1);
1145    /// ```
1146    #[must_use]
1147    #[inline(always)]
1148    pub fn init(mut self, value: T) -> BumpBox<'a, T> {
1149        self.as_mut().write(value);
1150        unsafe { self.assume_init() }
1151    }
1152
1153    /// # Safety
1154    ///
1155    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized state. Calling this when the content is not yet fully initialized causes immediate undefined behavior.
1156    ///
1157    /// See [`MaybeUninit::assume_init`].
1158    #[must_use]
1159    #[inline(always)]
1160    pub unsafe fn assume_init(self) -> BumpBox<'a, T> {
1161        unsafe {
1162            let ptr = BumpBox::into_raw(self);
1163            BumpBox::from_raw(ptr.cast())
1164        }
1165    }
1166}
1167
1168impl<'a, T: Sized> BumpBox<'a, [MaybeUninit<T>]> {
1169    #[must_use]
1170    #[inline(always)]
1171    pub(crate) fn uninit_zst_slice(len: usize) -> Self {
1172        assert!(T::IS_ZST);
1173        Self {
1174            ptr: NonNull::slice_from_raw_parts(NonNull::dangling(), len),
1175            marker: PhantomData,
1176        }
1177    }
1178
1179    /// Initializes `self` by filling it with elements by cloning `value`.
1180    ///
1181    /// # Examples
1182    ///
1183    /// ```
1184    /// # use bump_scope::Bump;
1185    /// # let bump: Bump = Bump::new();
1186    /// let uninit = bump.alloc_uninit_slice(10);
1187    /// let init = uninit.init_fill(1);
1188    /// assert_eq!(init, [1; 10]);
1189    /// ```
1190    #[must_use]
1191    #[inline(always)]
1192    pub fn init_fill(self, value: T) -> BumpBox<'a, [T]>
1193    where
1194        T: Clone,
1195    {
1196        unsafe {
1197            let len = self.len();
1198
1199            if len != 0 {
1200                let mut initializer = self.initializer();
1201
1202                for _ in 0..(len - 1) {
1203                    initializer.push_unchecked(value.clone());
1204                }
1205
1206                initializer.push_unchecked(value);
1207                initializer.into_init_unchecked()
1208            } else {
1209                BumpBox::default()
1210            }
1211        }
1212    }
1213
1214    /// Initializes `self` by filling it with elements returned by calling a closure repeatedly.
1215    ///
1216    /// This method uses a closure to create new values. If you'd rather
1217    /// [`Clone`] a given value, use [`init_fill`](Self::init_fill). If you want to use the [`Default`]
1218    /// trait to generate values, you can pass [`Default::default`] as the
1219    /// argument.
1220    ///
1221    /// # Examples
1222    ///
1223    /// ```
1224    /// # use bump_scope::Bump;
1225    /// # let bump: Bump = Bump::new();
1226    /// let uninit = bump.alloc_uninit_slice(10);
1227    /// let init = uninit.init_fill_with(Default::default);
1228    /// assert_eq!(init, [0; 10]);
1229    /// ```
1230    #[must_use]
1231    #[inline]
1232    pub fn init_fill_with(self, mut f: impl FnMut() -> T) -> BumpBox<'a, [T]> {
1233        let mut initializer = self.initializer();
1234
1235        while !initializer.is_full() {
1236            initializer.push_with(&mut f);
1237        }
1238
1239        initializer.into_init()
1240    }
1241
1242    /// Initializes `self` by filling it with elements returned from an iterator.
1243    ///
1244    /// # Panics
1245    ///
1246    /// This function will panic if the iterator runs out of items before the slice is filled.
1247    ///
1248    /// # Examples
1249    ///
1250    /// ```
1251    /// # use bump_scope::Bump;
1252    /// # let bump: Bump = Bump::new();
1253    /// let uninit = bump.alloc_uninit_slice(5);
1254    /// let init = uninit.init_fill_iter(['a', 'b'].iter().copied().cycle());
1255    /// assert_eq!(init, ['a', 'b', 'a', 'b', 'a']);
1256    /// ```
1257    #[must_use]
1258    #[inline]
1259    pub fn init_fill_iter(self, mut iter: impl Iterator<Item = T>) -> BumpBox<'a, [T]> {
1260        #[cold]
1261        #[inline(never)]
1262        #[track_caller]
1263        fn iter_ran_out() -> ! {
1264            panic!("iterator ran out of items to fill the slice with");
1265        }
1266
1267        let mut initializer = self.initializer();
1268
1269        while !initializer.is_full() {
1270            match iter.next() {
1271                Some(item) => {
1272                    initializer.push(item);
1273                }
1274                None => iter_ran_out(),
1275            }
1276        }
1277
1278        initializer.into_init()
1279    }
1280
1281    /// Initializes `self` by copying the elements from `slice` into `self`.
1282    ///
1283    /// The length of `slice` must be the same as `self`.
1284    ///
1285    /// # Panics
1286    ///
1287    /// This function will panic if the two slices have different lengths.
1288    ///
1289    /// # Examples
1290    ///
1291    /// ```
1292    /// # use bump_scope::Bump;
1293    /// # let bump: Bump = Bump::new();
1294    /// let uninit = bump.alloc_uninit_slice(3);
1295    ///
1296    /// let slice = &[
1297    ///     "foo",
1298    ///     "bar",
1299    ///     "baz",
1300    /// ];
1301    ///
1302    /// let init = uninit.init_copy(slice);
1303    ///
1304    /// assert_eq!(&*init, &["foo", "bar", "baz"]);
1305    /// ```
1306    #[must_use]
1307    #[inline]
1308    pub fn init_copy(mut self, slice: &[T]) -> BumpBox<'a, [T]>
1309    where
1310        T: Copy,
1311    {
1312        self.copy_from_slice(as_uninit_slice(slice));
1313        unsafe { self.assume_init() }
1314    }
1315
1316    /// Initializes `self` by cloning the elements from `slice` into `self`.
1317    ///
1318    /// The length of `slice` must be the same as `self`.
1319    ///
1320    /// # Panics
1321    ///
1322    /// This function will panic if the two slices have different lengths.
1323    ///
1324    /// # Examples
1325    ///
1326    /// ```
1327    /// # use bump_scope::Bump;
1328    /// # let bump: Bump = Bump::new();
1329    /// let uninit = bump.alloc_uninit_slice(3);
1330    ///
1331    /// let slice = &[
1332    ///     String::from("foo"),
1333    ///     String::from("bar"),
1334    ///     String::from("baz"),
1335    /// ];
1336    ///
1337    /// let init = uninit.init_clone(slice);
1338    ///
1339    /// assert_eq!(&*init, &["foo", "bar", "baz"]);
1340    /// ```
1341    #[must_use]
1342    #[inline]
1343    pub fn init_clone(self, slice: &[T]) -> BumpBox<'a, [T]>
1344    where
1345        T: Clone,
1346    {
1347        assert_eq!(slice.len(), self.len());
1348
1349        let mut initializer = self.initializer();
1350
1351        // SAFETY: we asserted that the lengths are the same
1352        unsafe {
1353            for value in slice {
1354                initializer.push_unchecked(value.clone());
1355            }
1356
1357            initializer.into_init_unchecked()
1358        }
1359    }
1360
1361    /// Initializes `self` by moving the elements from `slice` into `self`.
1362    ///
1363    /// The length of `slice` must be the same as `self`.
1364    ///
1365    /// # Panics
1366    ///
1367    /// This function will panic if the two slices have different lengths.
1368    ///
1369    /// # Examples
1370    ///
1371    /// ```
1372    /// # use bump_scope::Bump;
1373    /// # let bump: Bump = Bump::new();
1374    /// let uninit = bump.alloc_uninit_slice(3);
1375    ///
1376    /// let vec = vec![
1377    ///     String::from("foo"),
1378    ///     String::from("bar"),
1379    ///     String::from("baz"),
1380    /// ];
1381    ///
1382    /// let init = uninit.init_move(vec);
1383    ///
1384    /// assert_eq!(&*init, &["foo", "bar", "baz"]);
1385    /// ```
1386    #[inline]
1387    #[must_use]
1388    pub fn init_move(mut self, owned_slice: impl OwnedSlice<Item = T>) -> BumpBox<'a, [T]> {
1389        let mut owned_slice = owned_slice.into_take_owned_slice();
1390        let slice = NonNull::from(owned_slice.owned_slice_ref());
1391
1392        assert_eq!(slice.len(), self.len());
1393
1394        // SAFETY: we asserted that the lengths are the same
1395        unsafe {
1396            let src = slice.cast::<T>().as_ptr();
1397            let dst = self.as_mut_ptr().cast::<T>();
1398            ptr::copy_nonoverlapping(src, dst, slice.len());
1399
1400            owned_slice.take_owned_slice();
1401            self.assume_init()
1402        }
1403    }
1404
1405    #[must_use]
1406    #[inline]
1407    pub(crate) fn initializer(self) -> BumpBoxSliceInitializer<'a, T> {
1408        BumpBoxSliceInitializer::new(self)
1409    }
1410
1411    /// # Safety
1412    ///
1413    /// It is up to the caller to guarantee that each `MaybeUninit<T>` really is in an initialized state. Calling this when the content is not yet fully initialized causes immediate undefined behavior.
1414    ///
1415    /// See [`MaybeUninit::assume_init`].
1416    #[must_use]
1417    #[inline(always)]
1418    pub unsafe fn assume_init(self) -> BumpBox<'a, [T]> {
1419        let ptr = BumpBox::into_raw(self);
1420
1421        unsafe {
1422            let ptr = NonNull::new_unchecked(ptr.as_ptr() as _);
1423            BumpBox::from_raw(ptr)
1424        }
1425    }
1426}
1427
1428impl<'a, T> BumpBox<'a, [T]> {
1429    /// Empty slice.
1430    pub const EMPTY: Self = Self {
1431        ptr: NonNull::slice_from_raw_parts(NonNull::dangling(), 0),
1432        marker: PhantomData,
1433    };
1434
1435    #[must_use]
1436    #[inline(always)]
1437    pub(crate) fn zst_slice_clone(slice: &[T]) -> Self
1438    where
1439        T: Clone,
1440    {
1441        assert!(T::IS_ZST);
1442        BumpBox::uninit_zst_slice(slice.len()).init_clone(slice)
1443    }
1444
1445    #[must_use]
1446    #[inline(always)]
1447    pub(crate) fn zst_slice_fill(len: usize, value: T) -> Self
1448    where
1449        T: Clone,
1450    {
1451        assert!(T::IS_ZST);
1452        if len == 0 {
1453            drop(value);
1454            BumpBox::EMPTY
1455        } else {
1456            for _ in 1..len {
1457                mem::forget(value.clone());
1458            }
1459
1460            mem::forget(value);
1461            unsafe { BumpBox::zst_slice_from_len(len) }
1462        }
1463    }
1464
1465    #[must_use]
1466    #[inline(always)]
1467    pub(crate) fn zst_slice_fill_with(len: usize, f: impl FnMut() -> T) -> Self {
1468        assert!(T::IS_ZST);
1469        BumpBox::uninit_zst_slice(len).init_fill_with(f)
1470    }
1471
1472    /// Creates `T` values from nothing!
1473    #[must_use]
1474    #[inline(always)]
1475    pub(crate) unsafe fn zst_slice_from_len(len: usize) -> Self {
1476        assert!(T::IS_ZST);
1477        Self {
1478            ptr: NonNull::slice_from_raw_parts(NonNull::dangling(), len),
1479            marker: PhantomData,
1480        }
1481    }
1482
1483    /// Returns the number of elements in the slice, also referred to
1484    /// as its 'length'.
1485    #[must_use]
1486    #[inline(always)]
1487    pub const fn len(&self) -> usize {
1488        self.ptr.len()
1489    }
1490
1491    /// Returns `true` if the slice contains no elements.
1492    #[must_use]
1493    #[inline(always)]
1494    pub const fn is_empty(&self) -> bool {
1495        self.len() == 0
1496    }
1497
1498    /// Removes the last element from a slice and returns it, or [`None`] if it
1499    /// is empty.
1500    #[inline(always)]
1501    pub fn pop(&mut self) -> Option<T> {
1502        if self.is_empty() {
1503            None
1504        } else {
1505            unsafe {
1506                self.set_len(self.len() - 1);
1507                let ptr = self.as_ptr().add(self.len());
1508                Some(ptr.read())
1509            }
1510        }
1511    }
1512
1513    /// Clears the slice, removing all values.
1514    ///
1515    /// # Examples
1516    ///
1517    /// ```
1518    /// # use bump_scope::Bump;
1519    /// # let bump: Bump = Bump::new();
1520    /// let mut slice = bump.alloc_slice_copy(&[1, 2, 3]);
1521    /// slice.clear();
1522    /// assert!(slice.is_empty());
1523    /// ```
1524    #[inline(always)]
1525    pub fn clear(&mut self) {
1526        let elems: NonNull<[T]> = self.ptr;
1527
1528        // SAFETY:
1529        // - Setting `self.len` before calling `drop_in_place` means that,
1530        //   if an element's `Drop` impl panics, the vector's `Drop` impl will
1531        //   do nothing (leaking the rest of the elements) instead of dropping
1532        //   some twice.
1533        unsafe {
1534            self.set_len(0);
1535            elems.drop_in_place();
1536        }
1537    }
1538
1539    /// Shortens the slice, keeping the first `len` elements and dropping
1540    /// the rest.
1541    ///
1542    /// If `len` is greater than the slice's current length, this has no
1543    /// effect.
1544    ///
1545    /// The [`drain`] method can emulate `truncate`, but causes the excess
1546    /// elements to be returned instead of dropped.
1547    ///
1548    /// Note that this method has no effect on the allocated capacity
1549    /// of the vector.
1550    ///
1551    /// # Examples
1552    ///
1553    /// Truncating a five element vector to two elements:
1554    ///
1555    /// ```
1556    /// # use bump_scope::Bump;
1557    /// # let bump: Bump = Bump::new();
1558    /// let mut slice = bump.alloc_slice_copy(&[1, 2, 3, 4, 5]);
1559    /// slice.truncate(2);
1560    /// assert_eq!(slice, [1, 2]);
1561    /// ```
1562    ///
1563    /// No truncation occurs when `len` is greater than the slice's current
1564    /// length:
1565    ///
1566    /// ```
1567    /// # use bump_scope::Bump;
1568    /// # let bump: Bump = Bump::new();
1569    /// let mut slice = bump.alloc_slice_copy(&[1, 2, 3]);
1570    /// slice.truncate(8);
1571    /// assert_eq!(slice, [1, 2, 3]);
1572    /// ```
1573    ///
1574    /// Truncating when `len == 0` is equivalent to calling the [`clear`]
1575    /// method.
1576    ///
1577    /// ```
1578    /// # use bump_scope::Bump;
1579    /// # let bump: Bump = Bump::new();
1580    /// let mut slice = bump.alloc_slice_copy(&[1, 2, 3]);
1581    /// slice.truncate(0);
1582    /// assert_eq!(slice, []);
1583    /// ```
1584    ///
1585    /// [`clear`]: Self::clear
1586    /// [`drain`]: Self::drain
1587    pub fn truncate(&mut self, len: usize) {
1588        unsafe { non_null::truncate(&mut self.ptr, len) }
1589    }
1590
1591    /// Extracts a slice containing the entire boxed slice.
1592    ///
1593    /// Equivalent to `&s[..]`.
1594    #[must_use]
1595    #[inline(always)]
1596    pub const fn as_slice(&self) -> &[T] {
1597        unsafe { &*self.ptr.as_ptr().cast_const() }
1598    }
1599
1600    /// Extracts a mutable slice containing the entire boxed slice.
1601    ///
1602    /// Equivalent to `&mut s[..]`.
1603    #[must_use]
1604    #[inline(always)]
1605    pub fn as_mut_slice(&mut self) -> &mut [T] {
1606        unsafe { self.ptr.as_mut() }
1607    }
1608
1609    /// Returns a raw pointer to the slice, or a dangling raw pointer
1610    /// valid for zero sized reads.
1611    #[inline]
1612    #[must_use]
1613    pub fn as_ptr(&self) -> *const T {
1614        // We shadow the slice method of the same name to avoid going through
1615        // `deref`, which creates an intermediate reference.
1616        self.ptr.as_ptr().cast()
1617    }
1618
1619    /// Returns an unsafe mutable pointer to slice, or a dangling
1620    /// raw pointer valid for zero sized reads.
1621    #[inline]
1622    pub fn as_mut_ptr(&mut self) -> *mut T {
1623        // We shadow the slice method of the same name to avoid going through
1624        // `deref_mut`, which creates an intermediate reference.
1625        self.ptr.as_ptr().cast()
1626    }
1627
1628    /// Returns a `NonNull` pointer to the vector's buffer, or a dangling
1629    /// `NonNull` pointer valid for zero sized reads if the vector didn't allocate.
1630    ///
1631    /// The caller must ensure that the vector outlives the pointer this
1632    /// function returns, or else it will end up dangling.
1633    /// Modifying the vector may cause its buffer to be reallocated,
1634    /// which would also make any pointers to it invalid.
1635    ///
1636    /// This method guarantees that for the purpose of the aliasing model, this method
1637    /// does not materialize a reference to the underlying slice, and thus the returned pointer
1638    /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
1639    /// and [`as_non_null`].
1640    /// Note that calling other methods that materialize references to the slice,
1641    /// or references to specific elements you are planning on accessing through this pointer,
1642    /// may still invalidate this pointer.
1643    /// See the example below for how this guarantee can be used.
1644    ///
1645    /// # Examples
1646    ///
1647    /// Due to the aliasing guarantee, the following code is legal:
1648    ///
1649    /// ```
1650    /// # use bump_scope::Bump;
1651    /// # let bump: Bump = Bump::new();
1652    /// unsafe {
1653    ///     let v = bump.alloc_slice_copy(&[0]);
1654    ///     let ptr1 = v.as_non_null();
1655    ///     ptr1.write(1);
1656    ///     let ptr2 = v.as_non_null();
1657    ///     ptr2.write(2);
1658    ///     // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
1659    ///     ptr1.write(3);
1660    /// }
1661    /// ```
1662    ///
1663    /// [`as_mut_ptr`]: Self::as_mut_ptr
1664    /// [`as_ptr`]: Self::as_ptr
1665    /// [`as_non_null`]: Self::as_non_null
1666    #[must_use]
1667    #[inline(always)]
1668    pub const fn as_non_null(&self) -> NonNull<T> {
1669        self.ptr.cast()
1670    }
1671
1672    #[inline(always)]
1673    pub(crate) unsafe fn set_ptr(&mut self, new_ptr: NonNull<T>) {
1674        non_null::set_ptr(&mut self.ptr, new_ptr);
1675    }
1676
1677    /// Forces the length of the slice to `new_len`.
1678    ///
1679    /// This is a low-level operation that maintains none of the normal
1680    /// invariants of the type. Normally changing the length of a boxed slice
1681    /// is done using one of the safe operations instead, such as
1682    /// [`truncate`] or [`clear`].
1683    ///
1684    /// [`truncate`]: Self::truncate
1685    /// [`clear`]: Self::clear
1686    ///
1687    /// # Safety
1688    ///
1689    /// - `new_len` must be less than or equal to the `capacity` (capacity is not tracked by this type).
1690    /// - The elements at `old_len..new_len` must be initialized.
1691    #[inline]
1692    pub unsafe fn set_len(&mut self, new_len: usize) {
1693        non_null::set_len(&mut self.ptr, new_len);
1694    }
1695
1696    #[inline]
1697    pub(crate) unsafe fn inc_len(&mut self, amount: usize) {
1698        unsafe { self.set_len(self.len() + amount) };
1699    }
1700
1701    #[inline]
1702    pub(crate) unsafe fn dec_len(&mut self, amount: usize) {
1703        unsafe { self.set_len(self.len() - amount) };
1704    }
1705
1706    #[inline(always)]
1707    pub(crate) unsafe fn set_len_on_drop(&mut self) -> SetLenOnDropByPtr<'_, T> {
1708        SetLenOnDropByPtr::new(&mut self.ptr)
1709    }
1710
1711    /// Removes and returns the element at position `index` within the vector,
1712    /// shifting all elements after it to the left.
1713    ///
1714    /// Note: Because this shifts over the remaining elements, it has a
1715    /// worst-case performance of *O*(*n*). If you don't need the order of elements
1716    /// to be preserved, use [`swap_remove`] instead.
1717    ///
1718    /// # Panics
1719    /// Panics if `index` is out of bounds.
1720    ///
1721    /// [`swap_remove`]: Self::swap_remove
1722    ///
1723    /// # Examples
1724    ///
1725    /// ```
1726    /// # use bump_scope::Bump;
1727    /// # let bump: Bump = Bump::new();
1728    /// let mut v = bump.alloc_slice_copy(&[1, 2, 3]);
1729    /// assert_eq!(v.remove(1), 2);
1730    /// assert_eq!(v, [1, 3]);
1731    /// ```
1732    #[track_caller]
1733    pub fn remove(&mut self, index: usize) -> T {
1734        #[cold]
1735        #[inline(never)]
1736        #[track_caller]
1737        fn assert_failed(index: usize, len: usize) -> ! {
1738            panic!("removal index (is {index}) should be < len (is {len})");
1739        }
1740
1741        if index >= self.len() {
1742            assert_failed(index, self.len());
1743        }
1744
1745        unsafe {
1746            let start = self.as_mut_ptr();
1747            let value_ptr = start.add(index);
1748
1749            // copy it out, unsafely having a copy of the value on
1750            // the stack and in the vector at the same time
1751            let value = value_ptr.read();
1752
1753            // shift everything to fill in that spot
1754            if index != self.len() {
1755                let len = self.len() - index - 1;
1756                value_ptr.add(1).copy_to(value_ptr, len);
1757            }
1758
1759            self.dec_len(1);
1760            value
1761        }
1762    }
1763
1764    /// Removes an element from the vector and returns it.
1765    ///
1766    /// The removed element is replaced by the last element of the vector.
1767    ///
1768    /// This does not preserve ordering, but is *O*(1).
1769    /// If you need to preserve the element order, use [`remove`] instead.
1770    ///
1771    /// # Panics
1772    /// Panics if `index` is out of bounds.
1773    ///
1774    /// [`remove`]: Self::remove
1775    ///
1776    /// # Examples
1777    ///
1778    /// ```
1779    /// # use bump_scope::Bump;
1780    /// # let bump: Bump = Bump::new();
1781    /// let mut v = bump.alloc_slice_copy(&["foo", "bar", "baz", "qux"]);
1782    ///
1783    /// assert_eq!(v.swap_remove(1), "bar");
1784    /// assert_eq!(v, ["foo", "qux", "baz"]);
1785    ///
1786    /// assert_eq!(v.swap_remove(0), "foo");
1787    /// assert_eq!(v, ["baz", "qux"]);
1788    /// ```
1789    #[inline]
1790    pub fn swap_remove(&mut self, index: usize) -> T {
1791        #[cold]
1792        #[inline(never)]
1793        #[track_caller]
1794        fn assert_failed(index: usize, len: usize) -> ! {
1795            panic!("swap_remove index (is {index}) should be < len (is {len})");
1796        }
1797
1798        if index >= self.len() {
1799            assert_failed(index, self.len());
1800        }
1801
1802        unsafe {
1803            // We replace self[index] with the last element. Note that if the
1804            // bounds check above succeeds there must be a last element (which
1805            // can be self[index] itself).
1806
1807            let start = self.as_mut_ptr();
1808            let value_ptr = start.add(index);
1809            let value = value_ptr.read();
1810            self.dec_len(1);
1811
1812            start.add(self.len()).copy_to(value_ptr, 1);
1813            value
1814        }
1815    }
1816    /// Splits the vector into two by removing the specified range.
1817    ///
1818    /// This method does not allocate and does not change the order of the elements.
1819    ///
1820    /// # Panics
1821    ///
1822    /// Panics if the starting point is greater than the end point or if the end point is greater than the length of the vector.
1823    ///
1824    /// # Complexity
1825    ///
1826    /// This operation takes `O(1)` time if either the range starts at 0, ends at `len`, or is empty.
1827    /// Otherwise it takes `O(min(end, len - start))` time.
1828    ///
1829    /// # Examples
1830    ///
1831    /// ```
1832    /// # use bump_scope::Bump;
1833    /// # let bump: Bump = Bump::new();
1834    /// let mut slice = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6, 7, 8]);
1835    ///
1836    /// let front = slice.split_off(..2);
1837    /// assert_eq!(front, [1, 2]);
1838    /// assert_eq!(slice, [3, 4, 5, 6, 7, 8]);
1839    ///
1840    /// let back = slice.split_off(4..);
1841    /// assert_eq!(back, [7, 8]);
1842    /// assert_eq!(slice, [3, 4, 5, 6]);
1843    ///
1844    /// let middle = slice.split_off(1..3);
1845    /// assert_eq!(middle, [4, 5]);
1846    /// assert_eq!(slice, [3, 6]);
1847    ///
1848    /// let rest = slice.split_off(..);
1849    /// assert_eq!(rest, [3, 6]);
1850    /// assert_eq!(slice, []);
1851    /// ```
1852    #[inline]
1853    #[expect(clippy::return_self_not_must_use)]
1854    pub fn split_off(&mut self, range: impl RangeBounds<usize>) -> Self {
1855        let len = self.len();
1856        let ops::Range { start, end } = polyfill::slice::range(range, ..len);
1857        let ptr = non_null::as_non_null_ptr(self.ptr);
1858
1859        if T::IS_ZST {
1860            let range_len = end - start;
1861            let remaining_len = len - range_len;
1862
1863            unsafe {
1864                self.set_len(remaining_len);
1865                return BumpBox::zst_slice_from_len(range_len);
1866            }
1867        }
1868
1869        if end == len {
1870            let lhs = NonNull::slice_from_raw_parts(ptr, start);
1871            let rhs = NonNull::slice_from_raw_parts(unsafe { ptr.add(start) }, len - start);
1872
1873            self.ptr = lhs;
1874            return unsafe { BumpBox::from_raw(rhs) };
1875        }
1876
1877        if start == 0 {
1878            let lhs = NonNull::slice_from_raw_parts(ptr, end);
1879            let rhs = NonNull::slice_from_raw_parts(unsafe { ptr.add(end) }, len - end);
1880
1881            self.ptr = rhs;
1882            return unsafe { BumpBox::from_raw(lhs) };
1883        }
1884
1885        if start == end {
1886            return BumpBox::EMPTY;
1887        }
1888
1889        let head_len = start;
1890        let tail_len = len - end;
1891
1892        let range_len = end - start;
1893        let remaining_len = len - range_len;
1894
1895        unsafe {
1896            if head_len < tail_len {
1897                // move the range of elements to split off to the start
1898                self.as_mut_slice().get_unchecked_mut(..end).rotate_right(range_len);
1899
1900                let lhs = NonNull::slice_from_raw_parts(ptr, range_len);
1901                let rhs = NonNull::slice_from_raw_parts(ptr.add(range_len), remaining_len);
1902
1903                self.ptr = rhs;
1904
1905                BumpBox::from_raw(lhs)
1906            } else {
1907                // move the range of elements to split off to the end
1908                self.as_mut_slice().get_unchecked_mut(start..).rotate_left(range_len);
1909
1910                let lhs = NonNull::slice_from_raw_parts(ptr, remaining_len);
1911                let rhs = NonNull::slice_from_raw_parts(ptr.add(remaining_len), range_len);
1912
1913                self.ptr = lhs;
1914
1915                BumpBox::from_raw(rhs)
1916            }
1917        }
1918    }
1919
1920    /// Removes the first element of the slice and returns it.
1921    ///
1922    /// Returns `None` if the slice is empty.
1923    ///
1924    /// # Examples
1925    ///
1926    /// ```
1927    /// # use bump_scope::Bump;
1928    /// # let bump: Bump = Bump::new();
1929    /// let mut slice = bump.alloc_slice_move([
1930    ///     String::from("foo"),
1931    ///     String::from("bar"),
1932    ///     String::from("baz"),
1933    /// ]);
1934    ///
1935    /// let first = slice.split_off_first().unwrap();
1936    ///
1937    /// assert_eq!(&*first, "foo");
1938    /// assert_eq!(&*slice, ["bar", "baz"]);
1939    /// ```
1940    #[inline]
1941    #[must_use]
1942    pub fn split_off_first(&mut self) -> Option<BumpBox<'a, T>> {
1943        let (first, rest) = mem::take(self).split_first()?;
1944        *self = rest;
1945        Some(first)
1946    }
1947
1948    /// Removes the last element of the slice and returns it.
1949    ///
1950    /// Returns `None` if the slice is empty.
1951    ///
1952    /// # Examples
1953    ///
1954    /// ```
1955    /// # use bump_scope::Bump;
1956    /// # let bump: Bump = Bump::new();
1957    /// let mut slice = bump.alloc_slice_move([
1958    ///     String::from("foo"),
1959    ///     String::from("bar"),
1960    ///     String::from("baz"),
1961    /// ]);
1962    ///
1963    /// let last = slice.split_off_last().unwrap();
1964    ///
1965    /// assert_eq!(&*last, "baz");
1966    /// assert_eq!(&*slice, ["foo", "bar"]);
1967    /// ```
1968    #[inline]
1969    #[must_use]
1970    pub fn split_off_last(&mut self) -> Option<BumpBox<'a, T>> {
1971        let (last, rest) = mem::take(self).split_last()?;
1972        *self = rest;
1973        Some(last)
1974    }
1975
1976    /// Divides one slice into two at an index.
1977    ///
1978    /// The first will contain all indices from `[0, mid)` (excluding
1979    /// the index `mid` itself) and the second will contain all
1980    /// indices from `[mid, len)` (excluding the index `len` itself).
1981    ///
1982    /// # Panics
1983    ///
1984    /// Panics if `mid > len`.
1985    ///
1986    /// # Examples
1987    ///
1988    /// ```
1989    /// # use bump_scope::Bump;
1990    /// # let bump: Bump = Bump::new();
1991    /// #
1992    /// let v = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6]);
1993    ///
1994    /// {
1995    ///    let (left, right) = v.split_at(0);
1996    ///    assert_eq!(left, []);
1997    ///    assert_eq!(right, [1, 2, 3, 4, 5, 6]);
1998    /// }
1999    ///
2000    /// let v = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6]);
2001    ///
2002    /// {
2003    ///     let (left, right) = v.split_at(2);
2004    ///     assert_eq!(left, [1, 2]);
2005    ///     assert_eq!(right, [3, 4, 5, 6]);
2006    /// }
2007    ///
2008    /// let v = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6]);
2009    ///
2010    /// {
2011    ///     let (left, right) = v.split_at(6);
2012    ///     assert_eq!(left, [1, 2, 3, 4, 5, 6]);
2013    ///     assert_eq!(right, []);
2014    /// }
2015    /// ```
2016    #[inline]
2017    #[must_use]
2018    pub fn split_at(self, at: usize) -> (Self, Self) {
2019        #[cold]
2020        #[inline(never)]
2021        #[track_caller]
2022        fn assert_failed(at: usize, len: usize) -> ! {
2023            panic!("`at` split index (is {at}) should be <= len (is {len})");
2024        }
2025
2026        if at > self.len() {
2027            assert_failed(at, self.len());
2028        }
2029
2030        // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
2031        // fulfills the requirements of `split_at_unchecked`.
2032        unsafe { self.split_at_unchecked(at) }
2033    }
2034
2035    /// Divides one slice into two at an index, without doing bounds checking.
2036    ///
2037    /// The first will contain all indices from `[0, mid)` (excluding
2038    /// the index `mid` itself) and the second will contain all
2039    /// indices from `[mid, len)` (excluding the index `len` itself).
2040    ///
2041    /// For a safe alternative see [`split_at`].
2042    ///
2043    /// # Safety
2044    ///
2045    /// Calling this method with an out-of-bounds index is *[undefined behavior]*
2046    /// even if the resulting reference is not used. The caller has to ensure that
2047    /// `0 <= mid <= self.len()`.
2048    ///
2049    /// [`split_at`]: Self::split_at
2050    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2051    ///
2052    /// # Examples
2053    ///
2054    /// ```
2055    /// # use bump_scope::Bump;
2056    /// # let bump: Bump = Bump::new();
2057    /// #
2058    /// let v = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6]);
2059    ///
2060    /// unsafe {
2061    ///    let (left, right) = v.split_at_unchecked(0);
2062    ///    assert_eq!(left, []);
2063    ///    assert_eq!(right, [1, 2, 3, 4, 5, 6]);
2064    /// }
2065    ///
2066    /// let v = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6]);
2067    ///
2068    /// unsafe {
2069    ///     let (left, right) = v.split_at_unchecked(2);
2070    ///     assert_eq!(left, [1, 2]);
2071    ///     assert_eq!(right, [3, 4, 5, 6]);
2072    /// }
2073    ///
2074    /// let v = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6]);
2075    ///
2076    /// unsafe {
2077    ///     let (left, right) = v.split_at_unchecked(6);
2078    ///     assert_eq!(left, [1, 2, 3, 4, 5, 6]);
2079    ///     assert_eq!(right, []);
2080    /// }
2081    /// ```
2082    #[inline]
2083    #[must_use]
2084    pub unsafe fn split_at_unchecked(self, mid: usize) -> (Self, Self) {
2085        unsafe {
2086            let this = ManuallyDrop::new(self);
2087
2088            let len = this.len();
2089            let ptr = this.ptr.cast::<T>();
2090
2091            debug_assert!(
2092                mid <= len,
2093                "slice::split_at_unchecked requires the index to be within the slice"
2094            );
2095
2096            (
2097                Self::from_raw(NonNull::slice_from_raw_parts(ptr, mid)),
2098                Self::from_raw(NonNull::slice_from_raw_parts(ptr.add(mid), len - mid)),
2099            )
2100        }
2101    }
2102
2103    /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
2104    ///
2105    /// # Examples
2106    ///
2107    /// ```
2108    /// # use bump_scope::Bump;
2109    /// # let bump: Bump = Bump::new();
2110    /// let x = bump.alloc_slice_move([
2111    ///     String::from("foo"),
2112    ///     String::from("bar"),
2113    ///     String::from("baz"),
2114    /// ]);
2115    ///
2116    /// if let Some((first, rest)) = x.split_first() {
2117    ///     assert_eq!(&*first, "foo");
2118    ///     assert_eq!(&*rest, ["bar", "baz"]);
2119    /// }
2120    /// ```
2121    #[inline]
2122    #[must_use]
2123    pub fn split_first(self) -> Option<(BumpBox<'a, T>, BumpBox<'a, [T]>)> {
2124        let this = ManuallyDrop::new(self);
2125
2126        if this.is_empty() {
2127            return None;
2128        }
2129
2130        unsafe {
2131            let ptr = this.ptr.cast::<T>();
2132            let len = this.len();
2133
2134            Some((
2135                BumpBox::from_raw(ptr),
2136                BumpBox::from_raw(NonNull::slice_from_raw_parts(ptr.add(1), len - 1)),
2137            ))
2138        }
2139    }
2140
2141    /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
2142    ///
2143    /// # Examples
2144    ///
2145    /// ```
2146    /// # use bump_scope::Bump;
2147    /// # let bump: Bump = Bump::new();
2148    /// let x = bump.alloc_slice_move([
2149    ///     String::from("foo"),
2150    ///     String::from("bar"),
2151    ///     String::from("baz"),
2152    /// ]);
2153    ///
2154    /// if let Some((last, rest)) = x.split_last() {
2155    ///     assert_eq!(&*last, "baz");
2156    ///     assert_eq!(&*rest, ["foo", "bar"]);
2157    /// }
2158    /// ```
2159    #[inline]
2160    #[must_use]
2161    pub fn split_last(self) -> Option<(BumpBox<'a, T>, BumpBox<'a, [T]>)> {
2162        let this = ManuallyDrop::new(self);
2163
2164        if this.is_empty() {
2165            return None;
2166        }
2167
2168        unsafe {
2169            let ptr = this.ptr.cast::<T>();
2170            let len_minus_one = this.len() - 1;
2171
2172            Some((
2173                BumpBox::from_raw(ptr.add(len_minus_one)),
2174                BumpBox::from_raw(NonNull::slice_from_raw_parts(ptr, len_minus_one)),
2175            ))
2176        }
2177    }
2178
2179    /// Merges two contiguous slices into one.
2180    ///
2181    /// # Panics
2182    ///
2183    /// Panics if `self` and `other` are not contiguous.
2184    /// Panics if `T` is a zero-sized type and adding the lengths overflows.
2185    ///
2186    /// # Examples
2187    ///
2188    /// Split and merge back together.
2189    /// ```
2190    /// # use bump_scope::Bump;
2191    /// # let bump: Bump = Bump::new();
2192    /// #
2193    /// let v = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6]);
2194    ///
2195    /// let (left, right) = v.split_at(3);
2196    /// assert_eq!(left, [1, 2, 3]);
2197    /// assert_eq!(right, [4, 5, 6]);
2198    ///
2199    /// let merged = left.merge(right);
2200    /// assert_eq!(merged, [1, 2, 3, 4, 5, 6]);
2201    /// ```
2202    #[inline]
2203    #[must_use]
2204    pub fn merge(self, other: Self) -> Self {
2205        #[cold]
2206        #[inline(never)]
2207        #[track_caller]
2208        fn assert_failed_zst() -> ! {
2209            panic!("adding the lengths overflowed");
2210        }
2211
2212        #[cold]
2213        #[inline(never)]
2214        #[track_caller]
2215        fn assert_failed() -> ! {
2216            panic!("the two slices are not contiguous");
2217        }
2218
2219        if T::IS_ZST {
2220            let Some(len) = self.len().checked_add(other.len()) else {
2221                assert_failed_zst()
2222            };
2223
2224            let _ = self.into_raw();
2225            let _ = other.into_raw();
2226
2227            unsafe { Self::zst_slice_from_len(len) }
2228        } else {
2229            if self.as_ptr_range().end != other.as_ptr() {
2230                assert_failed();
2231            }
2232
2233            let lhs = self.into_raw();
2234            let rhs = other.into_raw();
2235
2236            let ptr = non_null::as_non_null_ptr(lhs);
2237
2238            // This can't overflow.
2239            // - Two slices can only be contiguous if they are part of the same chunk.
2240            // - The size of a chunk is representable as `usize`.
2241            let len = lhs.len() + rhs.len();
2242
2243            let slice = NonNull::slice_from_raw_parts(ptr, len);
2244
2245            unsafe { Self::from_raw(slice) }
2246        }
2247    }
2248
2249    /// Retains only the elements specified by the predicate, passing a mutable reference to it.
2250    ///
2251    /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
2252    /// This method operates in place, visiting each element exactly once in the
2253    /// original order, and preserves the order of the retained elements.
2254    ///
2255    /// # Examples
2256    ///
2257    /// ```
2258    /// # use bump_scope::Bump;
2259    /// # let bump: Bump = Bump::new();
2260    /// #
2261    /// let mut slice = bump.alloc_slice_copy(&[1, 2, 3, 4]);
2262    ///
2263    /// slice.retain(|x| if *x <= 3 {
2264    ///     *x += 1;
2265    ///     true
2266    /// } else {
2267    ///     false
2268    /// });
2269    ///
2270    /// assert_eq!(slice, [2, 3, 4]);
2271    /// ```
2272    #[expect(clippy::pedantic)]
2273    pub fn retain<F>(&mut self, mut f: F)
2274    where
2275        F: FnMut(&mut T) -> bool,
2276    {
2277        let original_len = self.len();
2278        // Avoid double drop if the drop guard is not executed,
2279        // since we may make some holes during the process.
2280        unsafe { self.set_len(0) };
2281
2282        // Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked]
2283        //      |<-              processed len   ->| ^- next to check
2284        //                  |<-  deleted cnt     ->|
2285        //      |<-              original_len                          ->|
2286        // Kept: Elements which predicate returns true on.
2287        // Hole: Moved or dropped element slot.
2288        // Unchecked: Unchecked valid elements.
2289        //
2290        // This drop guard will be invoked when predicate or `drop` of element panicked.
2291        // It shifts unchecked elements to cover holes and `set_len` to the correct length.
2292        // In cases when predicate and `drop` never panic, it will be optimized out.
2293        struct BackshiftOnDrop<'b, 'a, T> {
2294            v: &'b mut BumpBox<'a, [T]>,
2295            processed_len: usize,
2296            deleted_cnt: usize,
2297            original_len: usize,
2298        }
2299
2300        impl<T> Drop for BackshiftOnDrop<'_, '_, T> {
2301            fn drop(&mut self) {
2302                if self.deleted_cnt > 0 {
2303                    // SAFETY: Trailing unchecked items must be valid since we never touch them.
2304                    unsafe {
2305                        ptr::copy(
2306                            self.v.as_ptr().add(self.processed_len),
2307                            self.v.as_mut_ptr().add(self.processed_len - self.deleted_cnt),
2308                            self.original_len - self.processed_len,
2309                        );
2310                    }
2311                }
2312                // SAFETY: After filling holes, all items are in contiguous memory.
2313                unsafe {
2314                    self.v.set_len(self.original_len - self.deleted_cnt);
2315                }
2316            }
2317        }
2318
2319        let mut g = BackshiftOnDrop {
2320            v: self,
2321            processed_len: 0,
2322            deleted_cnt: 0,
2323            original_len,
2324        };
2325
2326        fn process_loop<F, T, const DELETED: bool>(original_len: usize, f: &mut F, g: &mut BackshiftOnDrop<'_, '_, T>)
2327        where
2328            F: FnMut(&mut T) -> bool,
2329        {
2330            while g.processed_len != original_len {
2331                // SAFETY: Unchecked element must be valid.
2332                let cur = unsafe { &mut *g.v.ptr.as_ptr().cast::<T>().add(g.processed_len) };
2333                if !f(cur) {
2334                    // Advance early to avoid double drop if `drop_in_place` panicked.
2335                    g.processed_len += 1;
2336                    g.deleted_cnt += 1;
2337                    // SAFETY: We never touch this element again after dropped.
2338                    unsafe { ptr::drop_in_place(cur) };
2339                    // We already advanced the counter.
2340                    if DELETED {
2341                        continue;
2342                    } else {
2343                        break;
2344                    }
2345                }
2346                if DELETED {
2347                    // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
2348                    // We use copy for move, and never touch this element again.
2349                    unsafe {
2350                        let hole_slot = g.v.ptr.as_ptr().cast::<T>().add(g.processed_len - g.deleted_cnt);
2351                        ptr::copy_nonoverlapping(cur, hole_slot, 1);
2352                    }
2353                }
2354                g.processed_len += 1;
2355            }
2356        }
2357
2358        // Stage 1: Nothing was deleted.
2359        process_loop::<F, T, false>(original_len, &mut f, &mut g);
2360
2361        // Stage 2: Some elements were deleted.
2362        process_loop::<F, T, true>(original_len, &mut f, &mut g);
2363
2364        // All item are processed. This can be optimized to `set_len` by LLVM.
2365        drop(g);
2366    }
2367
2368    /// Removes the specified range from the slice in bulk, returning all
2369    /// removed elements as an iterator. If the iterator is dropped before
2370    /// being fully consumed, it drops the remaining removed elements.
2371    ///
2372    /// The returned iterator keeps a mutable borrow on the slice to optimize
2373    /// its implementation.
2374    ///
2375    /// # Panics
2376    ///
2377    /// Panics if the starting point is greater than the end point or if
2378    /// the end point is greater than the length of the vector.
2379    ///
2380    /// # Leaking
2381    ///
2382    /// If the returned iterator goes out of scope without being dropped (due to
2383    /// [`mem::forget`], for example), the vector may have lost and leaked
2384    /// elements arbitrarily, including elements outside the range.
2385    ///
2386    /// # Examples
2387    ///
2388    /// ```
2389    /// # use bump_scope::Bump;
2390    /// # let bump: Bump = Bump::new();
2391    /// #
2392    /// let mut v = bump.alloc_slice_copy(&[1, 2, 3]);
2393    /// let u = bump.alloc_iter(v.drain(1..));
2394    /// assert_eq!(v, [1]);
2395    /// assert_eq!(u, [2, 3]);
2396    ///
2397    /// // A full range clears the slice, like `clear()` does
2398    /// v.drain(..);
2399    /// assert_eq!(v, []);
2400    /// ```
2401    pub fn drain<R>(&mut self, range: R) -> owned_slice::Drain<'_, T>
2402    where
2403        R: RangeBounds<usize>,
2404    {
2405        owned_slice::Drain::new(self, range)
2406    }
2407
2408    /// Creates an iterator which uses a closure to determine if an element should be removed.
2409    ///
2410    /// If the closure returns true, then the element is removed and yielded.
2411    /// If the closure returns false, the element will remain in the slice and will not be yielded
2412    /// by the iterator.
2413    ///
2414    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
2415    /// or the iteration short-circuits, then the remaining elements will be retained.
2416    /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
2417    ///
2418    /// Using this method is equivalent to the following code:
2419    ///
2420    /// ```
2421    /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
2422    /// # use bump_scope::Bump;
2423    /// # let bump: Bump = Bump::new();
2424    /// # let mut slice = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6]);
2425    /// let mut i = 0;
2426    /// while i < slice.len() {
2427    ///     if some_predicate(&mut slice[i]) {
2428    ///         let val = slice.remove(i);
2429    ///         // your code here
2430    ///         # _ = val;
2431    ///     } else {
2432    ///         i += 1;
2433    ///     }
2434    /// }
2435    ///
2436    /// # assert_eq!(slice, [1, 4, 5]);
2437    /// ```
2438    ///
2439    /// But `extract_if` is easier to use. `extract_if` is also more efficient,
2440    /// because it can backshift the elements of the array in bulk.
2441    ///
2442    /// Note that `extract_if` also lets you mutate every element in the filter closure,
2443    /// regardless of whether you choose to keep or remove it.
2444    ///
2445    /// # Examples
2446    ///
2447    /// Splitting an array into evens and odds, reusing the original allocation:
2448    ///
2449    /// ```
2450    /// # use bump_scope::Bump;
2451    /// # let bump: Bump = Bump::new();
2452    /// let mut numbers = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]);
2453    ///
2454    /// let evens = bump.alloc_iter(numbers.extract_if(|x| *x % 2 == 0));
2455    /// let odds = numbers;
2456    ///
2457    /// assert_eq!(evens, [2, 4, 6, 8, 14]);
2458    /// assert_eq!(odds, [1, 3, 5, 9, 11, 13, 15]);
2459    /// ```
2460    ///
2461    /// [`retain`]: Self::retain
2462    pub fn extract_if<F>(&mut self, filter: F) -> owned_slice::ExtractIf<'_, T, F>
2463    where
2464        F: FnMut(&mut T) -> bool,
2465    {
2466        owned_slice::ExtractIf::new(self, filter)
2467    }
2468
2469    /// Removes consecutive repeated elements in the slice according to the
2470    /// [`PartialEq`] trait implementation.
2471    ///
2472    /// If the slice is sorted, this removes all duplicates.
2473    ///
2474    /// # Examples
2475    ///
2476    /// ```
2477    /// # use bump_scope::Bump;
2478    /// # let bump: Bump = Bump::new();
2479    /// let mut slice = bump.alloc_slice_copy(&[1, 2, 2, 3, 2]);
2480    ///
2481    /// slice.dedup();
2482    ///
2483    /// assert_eq!(slice, [1, 2, 3, 2]);
2484    /// ```
2485    #[inline]
2486    pub fn dedup(&mut self)
2487    where
2488        T: PartialEq,
2489    {
2490        self.dedup_by(|a, b| a == b);
2491    }
2492
2493    /// Removes all but the first of consecutive elements in the slice that resolve to the same
2494    /// key.
2495    ///
2496    /// If the slice is sorted, this removes all duplicates.
2497    ///
2498    /// # Examples
2499    ///
2500    /// ```
2501    /// # use bump_scope::Bump;
2502    /// # let bump: Bump = Bump::new();
2503    /// let mut slice = bump.alloc_slice_copy(&[10, 20, 21, 30, 20]);
2504    ///
2505    /// slice.dedup_by_key(|i| *i / 10);
2506    ///
2507    /// assert_eq!(slice, [10, 20, 30, 20]);
2508    /// ```
2509    #[inline]
2510    pub fn dedup_by_key<F, K>(&mut self, mut key: F)
2511    where
2512        F: FnMut(&mut T) -> K,
2513        K: PartialEq,
2514    {
2515        self.dedup_by(|a, b| key(a) == key(b));
2516    }
2517
2518    /// Removes all but the first of consecutive elements in the vector satisfying a given equality
2519    /// relation.
2520    ///
2521    /// The `same_bucket` function is passed references to two elements from the vector and
2522    /// must determine if the elements compare equal. The elements are passed in opposite order
2523    /// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is removed.
2524    ///
2525    /// If the vector is sorted, this removes all duplicates.
2526    ///
2527    /// # Examples
2528    ///
2529    /// ```
2530    /// # use bump_scope::Bump;
2531    /// # let bump: Bump = Bump::new();
2532    /// let mut slice = bump.alloc_slice_copy(&["foo", "bar", "Bar", "baz", "bar"]);
2533    ///
2534    /// slice.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
2535    ///
2536    /// assert_eq!(slice, ["foo", "bar", "baz", "bar"]);
2537    /// ```
2538    pub fn dedup_by<F>(&mut self, mut same_bucket: F)
2539    where
2540        F: FnMut(&mut T, &mut T) -> bool,
2541    {
2542        let len = self.len();
2543        if len <= 1 {
2544            return;
2545        }
2546
2547        /* INVARIANT: vec.len() > read >= write > write-1 >= 0 */
2548        struct FillGapOnDrop<'b, 'a, T> {
2549            /* Offset of the element we want to check if it is duplicate */
2550            read: usize,
2551
2552            /* Offset of the place where we want to place the non-duplicate
2553             * when we find it. */
2554            write: usize,
2555
2556            /* The Vec that would need correction if `same_bucket` panicked */
2557            boxed: &'b mut BumpBox<'a, [T]>,
2558        }
2559
2560        impl<T> Drop for FillGapOnDrop<'_, '_, T> {
2561            fn drop(&mut self) {
2562                /* This code gets executed when `same_bucket` panics */
2563
2564                /* SAFETY: invariant guarantees that `read - write`
2565                 * and `len - read` never overflow and that the copy is always
2566                 * in-bounds. */
2567                unsafe {
2568                    let ptr = self.boxed.as_mut_ptr();
2569                    let len = self.boxed.len();
2570
2571                    /* How many items were left when `same_bucket` panicked.
2572                     * Basically vec[read..].len() */
2573                    let items_left = len.wrapping_sub(self.read);
2574
2575                    /* Pointer to first item in vec[write..write+items_left] slice */
2576                    let dropped_ptr = ptr.add(self.write);
2577                    /* Pointer to first item in vec[read..] slice */
2578                    let valid_ptr = ptr.add(self.read);
2579
2580                    /* Copy `vec[read..]` to `vec[write..write+items_left]`.
2581                     * The slices can overlap, so `copy_nonoverlapping` cannot be used */
2582                    ptr::copy(valid_ptr, dropped_ptr, items_left);
2583
2584                    /* How many items have been already dropped
2585                     * Basically vec[read..write].len() */
2586                    let dropped = self.read.wrapping_sub(self.write);
2587
2588                    self.boxed.set_len(len - dropped);
2589                }
2590            }
2591        }
2592
2593        let mut gap = FillGapOnDrop {
2594            read: 1,
2595            write: 1,
2596            boxed: self,
2597        };
2598        let ptr = gap.boxed.as_mut_ptr();
2599
2600        /* Drop items while going through Vec, it should be more efficient than
2601         * doing slice partition_dedup + truncate */
2602
2603        /* SAFETY: Because of the invariant, read_ptr, prev_ptr and write_ptr
2604         * are always in-bounds and read_ptr never aliases prev_ptr */
2605        unsafe {
2606            while gap.read < len {
2607                let read_ptr = ptr.add(gap.read);
2608                let prev_ptr = ptr.add(gap.write.wrapping_sub(1));
2609
2610                if same_bucket(&mut *read_ptr, &mut *prev_ptr) {
2611                    // Increase `gap.read` now since the drop may panic.
2612                    gap.read += 1;
2613                    /* We have found duplicate, drop it in-place */
2614                    ptr::drop_in_place(read_ptr);
2615                } else {
2616                    let write_ptr = ptr.add(gap.write);
2617
2618                    /* Because `read_ptr` can be equal to `write_ptr`, we either
2619                     * have to use `copy` or conditional `copy_nonoverlapping`.
2620                     * Looks like the first option is faster. */
2621                    ptr::copy(read_ptr, write_ptr, 1);
2622
2623                    /* We have filled that place, so go further */
2624                    gap.write += 1;
2625                    gap.read += 1;
2626                }
2627            }
2628
2629            /* Technically we could let `gap` clean up with its Drop, but
2630             * when `same_bucket` is [guaranteed allocated]o not panic, this bloats a little
2631             * the codegen, so we just do it manually */
2632            gap.boxed.set_len(gap.write);
2633            mem::forget(gap);
2634        }
2635    }
2636
2637    /// Consumes `self`, creating two boxed slices from it.
2638    ///
2639    /// The predicate passed to `partition()` can return `true`, or `false`.
2640    /// `partition()` returns a pair, all of the elements for which it returned
2641    /// `true`, and all of the elements for which it returned `false`.
2642    ///
2643    /// See also [`is_partitioned()`] and [`partition_in_place()`].
2644    ///
2645    /// [`is_partitioned()`]: Iterator::is_partitioned
2646    /// [`partition_in_place()`]: Iterator::partition_in_place
2647    ///
2648    /// # Examples
2649    ///
2650    /// Basic usage:
2651    ///
2652    /// ```
2653    /// # use bump_scope::Bump;
2654    /// # let bump: Bump = Bump::new();
2655    /// let slice = bump.alloc_slice_copy(&[1, 2, 3, 4, 5, 6, 7]);
2656    ///
2657    /// let (even, odd) = slice.partition(|n| n % 2 == 0);
2658    ///
2659    /// assert!(even.iter().all(|n| n % 2 == 0));
2660    /// assert!(odd.iter().all(|n| n % 2 != 0));
2661    /// ```
2662    pub fn partition<F>(mut self, f: F) -> (Self, Self)
2663    where
2664        F: FnMut(&T) -> bool,
2665    {
2666        let index = polyfill::iter::partition_in_place(self.iter_mut(), f);
2667        self.split_at(index)
2668    }
2669
2670    /// Returns a boxed slice of the same size as `self`, with function `f` applied to each element in order.
2671    ///
2672    /// This function only compiles when `U`s size and alignment is less or equal to `T`'s or if `U` has a size of 0.
2673    ///
2674    /// # Examples
2675    /// Mapping to a type with an equal alignment and size:
2676    /// ```
2677    /// # use bump_scope::{Bump};
2678    /// # use core::num::NonZero;
2679    /// # let bump: Bump = Bump::new();
2680    /// let a = bump.alloc_slice_copy(&[0, 1, 2]);
2681    /// let b = a.map_in_place(NonZero::new);
2682    /// assert_eq!(format!("{b:?}"), "[None, Some(1), Some(2)]");
2683    /// ```
2684    ///
2685    /// Mapping to a type with a smaller alignment and size:
2686    /// ```
2687    /// # use bump_scope::{Bump, BumpBox};
2688    /// # let bump: Bump = Bump::new();
2689    /// let a: BumpBox<[u32]> = bump.alloc_slice_copy(&[0, 1, 2]);
2690    /// let b: BumpBox<[u16]> = a.map_in_place(|i| i as u16);
2691    /// assert_eq!(b, [0, 1, 2]);
2692    /// ```
2693    ///
2694    /// Mapping to a type with a greater alignment won't compile:
2695    /// ```compile_fail,E0080
2696    /// # use bump_scope::{Bump, BumpBox};
2697    /// # let bump: Bump = Bump::new();
2698    /// let a: BumpBox<[[u8; 4]]> = bump.alloc_slice_copy(&[[0, 1, 2, 3]]);
2699    /// let b: BumpBox<[u32]> = a.map_in_place(u32::from_le_bytes);
2700    /// # _ = b;
2701    /// ```
2702    ///
2703    /// Mapping to a type with a greater size won't compile:
2704    /// ```compile_fail,E0080
2705    /// # use bump_scope::{Bump, BumpBox};
2706    /// # let bump: Bump = Bump::new();
2707    /// let a: BumpBox<[u32]> = bump.alloc_slice_copy(&[42]);
2708    /// let b: BumpBox<[[u32; 2]]> = a.map_in_place(|i| [i; 2]);
2709    /// # _ = b;
2710    /// ```
2711    pub fn map_in_place<U>(self, mut f: impl FnMut(T) -> U) -> BumpBox<'a, [U]> {
2712        assert_in_place_mappable!(T, U);
2713
2714        if U::IS_ZST {
2715            return BumpBox::uninit_zst_slice(self.len()).init_fill_iter(self.into_iter().map(f));
2716        }
2717
2718        struct DropGuard<T, U> {
2719            ptr: NonNull<T>,
2720            end: *mut T,
2721            src: *mut T,
2722            dst: *mut U,
2723        }
2724
2725        impl<T, U> Drop for DropGuard<T, U> {
2726            fn drop(&mut self) {
2727                unsafe {
2728                    // drop `T`s
2729                    let drop_ptr = self.src.add(1);
2730                    let drop_len = pointer::offset_from_unsigned(self.end, drop_ptr);
2731                    ptr::slice_from_raw_parts_mut(drop_ptr, drop_len).drop_in_place();
2732
2733                    // drop `U`s
2734                    let drop_ptr = self.ptr.cast::<U>().as_ptr();
2735                    let drop_len = pointer::offset_from_unsigned(self.dst, drop_ptr);
2736                    ptr::slice_from_raw_parts_mut(drop_ptr, drop_len).drop_in_place();
2737                }
2738            }
2739        }
2740
2741        let slice = self.into_raw();
2742        let ptr = slice.cast::<T>();
2743        let len = slice.len();
2744
2745        unsafe {
2746            let mut guard = DropGuard::<T, U> {
2747                ptr,
2748                end: ptr.as_ptr().add(len),
2749                src: ptr.as_ptr(),
2750                dst: ptr.as_ptr().cast::<U>(),
2751            };
2752
2753            while guard.src < guard.end {
2754                let src_value = guard.src.read();
2755                let dst_value = f(src_value);
2756                guard.dst.write(dst_value);
2757                guard.src = guard.src.add(1);
2758                guard.dst = guard.dst.add(1);
2759            }
2760
2761            mem::forget(guard);
2762
2763            BumpBox::from_raw(NonNull::slice_from_raw_parts(ptr.cast(), len))
2764        }
2765    }
2766}
2767
2768impl<'a, T, const N: usize> BumpBox<'a, [[T; N]]> {
2769    /// Takes a `BumpBox<[[T; N]]>` and flattens it into a `BumpBox<[T]>`.
2770    ///
2771    /// # Panics
2772    ///
2773    /// Panics if the length of the resulting slice would overflow a `usize`.
2774    ///
2775    /// This is only possible when flattening a slice of arrays of zero-sized
2776    /// types, and thus tends to be irrelevant in practice. If
2777    /// `size_of::<T>() > 0`, this will never panic.
2778    ///
2779    /// # Examples
2780    ///
2781    /// ```
2782    /// # use bump_scope::Bump;
2783    /// # let bump: Bump = Bump::new();
2784    /// #
2785    /// let mut slice = bump.alloc_slice_copy(&[[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
2786    /// assert_eq!(slice.pop(), Some([7, 8, 9]));
2787    ///
2788    /// let mut flattened = slice.into_flattened();
2789    /// assert_eq!(flattened.pop(), Some(6));
2790    /// ```
2791    #[must_use]
2792    pub fn into_flattened(self) -> BumpBox<'a, [T]> {
2793        let ptr = self.into_raw();
2794        let len = ptr.len();
2795
2796        let new_len = if T::IS_ZST {
2797            len.checked_mul(N).expect("slice len overflow")
2798        } else {
2799            // SAFETY:
2800            // - `len * N` cannot overflow because the allocation is already in
2801            // the address space.
2802            // - Each `[T; N]` has `N` valid elements, so there are `len * N`
2803            // valid elements in the allocation.
2804            unsafe { len.unchecked_mul(N) }
2805        };
2806
2807        unsafe { BumpBox::from_raw(NonNull::slice_from_raw_parts(ptr.cast(), new_len)) }
2808    }
2809}
2810
2811impl<'a> BumpBox<'a, dyn Any> {
2812    /// Attempt to downcast the box to a concrete type.
2813    #[inline(always)]
2814    #[expect(clippy::missing_errors_doc)]
2815    pub fn downcast<T: Any>(self) -> Result<BumpBox<'a, T>, Self> {
2816        if self.is::<T>() {
2817            Ok(unsafe { self.downcast_unchecked() })
2818        } else {
2819            Err(self)
2820        }
2821    }
2822
2823    /// Downcasts the box to a concrete type.
2824    ///
2825    /// For a safe alternative see [`downcast`].
2826    ///
2827    /// # Safety
2828    ///
2829    /// The contained value must be of type `T`. Calling this method
2830    /// with the incorrect type is *undefined behavior*.
2831    ///
2832    /// [`downcast`]: Self::downcast
2833    #[must_use]
2834    #[inline(always)]
2835    pub unsafe fn downcast_unchecked<T: Any>(self) -> BumpBox<'a, T> {
2836        debug_assert!(self.is::<T>());
2837        unsafe { BumpBox::from_raw(BumpBox::into_raw(self).cast()) }
2838    }
2839}
2840
2841impl<'a> BumpBox<'a, dyn Any + Send> {
2842    /// Attempt to downcast the box to a concrete type.
2843    #[expect(clippy::missing_errors_doc)]
2844    #[inline(always)]
2845    pub fn downcast<T: Any>(self) -> Result<BumpBox<'a, T>, Self> {
2846        if self.is::<T>() {
2847            Ok(unsafe { self.downcast_unchecked() })
2848        } else {
2849            Err(self)
2850        }
2851    }
2852
2853    /// Downcasts the box to a concrete type.
2854    ///
2855    /// For a safe alternative see [`downcast`].
2856    ///
2857    /// # Safety
2858    ///
2859    /// The contained value must be of type `T`. Calling this method
2860    /// with the incorrect type is *undefined behavior*.
2861    ///
2862    /// [`downcast`]: Self::downcast
2863    #[must_use]
2864    #[inline(always)]
2865    pub unsafe fn downcast_unchecked<T: Any>(self) -> BumpBox<'a, T> {
2866        debug_assert!(self.is::<T>());
2867        unsafe { BumpBox::from_raw(BumpBox::into_raw(self).cast()) }
2868    }
2869}
2870
2871impl<'a> BumpBox<'a, dyn Any + Send + Sync> {
2872    /// Attempt to downcast the box to a concrete type.
2873    #[expect(clippy::missing_errors_doc)]
2874    #[inline(always)]
2875    pub fn downcast<T: Any>(self) -> Result<BumpBox<'a, T>, Self> {
2876        if self.is::<T>() {
2877            Ok(unsafe { self.downcast_unchecked() })
2878        } else {
2879            Err(self)
2880        }
2881    }
2882
2883    /// Downcasts the box to a concrete type.
2884    ///
2885    /// For a safe alternative see [`downcast`].
2886    ///
2887    /// # Safety
2888    ///
2889    /// The contained value must be of type `T`. Calling this method
2890    /// with the incorrect type is *undefined behavior*.
2891    ///
2892    /// [`downcast`]: Self::downcast
2893    #[must_use]
2894    #[inline(always)]
2895    pub unsafe fn downcast_unchecked<T: Any>(self) -> BumpBox<'a, T> {
2896        debug_assert!(self.is::<T>());
2897        unsafe { BumpBox::from_raw(BumpBox::into_raw(self).cast()) }
2898    }
2899}
2900
2901// just like std's Rc and Arc this implements Unpin,
2902// at time of writing Box does not implement Unpin unconditionally, but that is probably an oversight
2903// see https://github.com/rust-lang/rust/pull/118634
2904impl<T: ?Sized> Unpin for BumpBox<'_, T> {}
2905
2906#[cfg(feature = "nightly-coerce-unsized")]
2907impl<'a, T, U> core::ops::CoerceUnsized<BumpBox<'a, U>> for BumpBox<'a, T>
2908where
2909    T: ?Sized + core::marker::Unsize<U>,
2910    U: ?Sized,
2911{
2912}
2913
2914#[cfg(feature = "nightly-dropck-eyepatch")]
2915unsafe impl<#[may_dangle] T: ?Sized> Drop for BumpBox<'_, T> {
2916    #[inline(always)]
2917    fn drop(&mut self) {
2918        unsafe { self.ptr.drop_in_place() }
2919    }
2920}
2921
2922#[cfg(not(feature = "nightly-dropck-eyepatch"))]
2923impl<T: ?Sized> Drop for BumpBox<'_, T> {
2924    #[inline(always)]
2925    fn drop(&mut self) {
2926        unsafe { self.ptr.drop_in_place() }
2927    }
2928}
2929
2930impl<T> NoDrop for BumpBox<'_, T> where T: NoDrop {}
2931
2932impl<T: ?Sized> Deref for BumpBox<'_, T> {
2933    type Target = T;
2934
2935    #[inline(always)]
2936    fn deref(&self) -> &Self::Target {
2937        unsafe { self.ptr.as_ref() }
2938    }
2939}
2940
2941impl<T: ?Sized> DerefMut for BumpBox<'_, T> {
2942    #[inline(always)]
2943    fn deref_mut(&mut self) -> &mut Self::Target {
2944        unsafe { self.ptr.as_mut() }
2945    }
2946}
2947
2948impl<T: ?Sized> AsRef<T> for BumpBox<'_, T> {
2949    #[inline(always)]
2950    fn as_ref(&self) -> &T {
2951        self
2952    }
2953}
2954
2955impl<T: ?Sized> AsMut<T> for BumpBox<'_, T> {
2956    #[inline(always)]
2957    fn as_mut(&mut self) -> &mut T {
2958        self
2959    }
2960}
2961
2962impl<T: ?Sized> Borrow<T> for BumpBox<'_, T> {
2963    #[inline(always)]
2964    fn borrow(&self) -> &T {
2965        self
2966    }
2967}
2968
2969impl<T: ?Sized> BorrowMut<T> for BumpBox<'_, T> {
2970    #[inline(always)]
2971    fn borrow_mut(&mut self) -> &mut T {
2972        self
2973    }
2974}
2975
2976impl<T: ?Sized + Debug> Debug for BumpBox<'_, T> {
2977    #[inline(always)]
2978    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2979        T::fmt(self, f)
2980    }
2981}
2982
2983impl<T: ?Sized + Display> Display for BumpBox<'_, T> {
2984    #[inline(always)]
2985    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2986        T::fmt(self, f)
2987    }
2988}
2989
2990impl<T> Default for BumpBox<'_, [T]> {
2991    #[inline(always)]
2992    fn default() -> Self {
2993        unsafe { Self::from_raw(NonNull::from(&mut [])) }
2994    }
2995}
2996
2997impl Default for BumpBox<'_, str> {
2998    #[inline(always)]
2999    fn default() -> Self {
3000        unsafe { Self::from_raw(NonNull::from(core::str::from_utf8_unchecked_mut(&mut []))) }
3001    }
3002}
3003
3004impl<'b, T: ?Sized + PartialEq> PartialEq<BumpBox<'b, T>> for BumpBox<'_, T> {
3005    #[inline(always)]
3006    fn eq(&self, other: &BumpBox<'b, T>) -> bool {
3007        T::eq(self, other)
3008    }
3009
3010    #[inline(always)]
3011    fn ne(&self, other: &BumpBox<'b, T>) -> bool {
3012        T::ne(self, other)
3013    }
3014}
3015
3016impl<T: ?Sized + PartialEq> PartialEq<T> for BumpBox<'_, T> {
3017    #[inline(always)]
3018    fn eq(&self, other: &T) -> bool {
3019        T::eq(self, other)
3020    }
3021
3022    #[inline(always)]
3023    fn ne(&self, other: &T) -> bool {
3024        T::ne(self, other)
3025    }
3026}
3027
3028impl<T: ?Sized + PartialEq> PartialEq<&T> for BumpBox<'_, T> {
3029    #[inline(always)]
3030    fn eq(&self, other: &&T) -> bool {
3031        T::eq(self, other)
3032    }
3033
3034    #[inline(always)]
3035    fn ne(&self, other: &&T) -> bool {
3036        T::ne(self, other)
3037    }
3038}
3039
3040impl<T: ?Sized + PartialEq> PartialEq<&mut T> for BumpBox<'_, T> {
3041    #[inline(always)]
3042    fn eq(&self, other: &&mut T) -> bool {
3043        T::eq(self, other)
3044    }
3045
3046    #[inline(always)]
3047    fn ne(&self, other: &&mut T) -> bool {
3048        T::ne(self, other)
3049    }
3050}
3051
3052impl<'a, T, U> PartialEq<BumpBox<'a, [U]>> for [T]
3053where
3054    T: PartialEq<U>,
3055{
3056    #[inline(always)]
3057    fn eq(&self, other: &BumpBox<'a, [U]>) -> bool {
3058        <[T] as PartialEq<[U]>>::eq(self, other)
3059    }
3060
3061    #[inline(always)]
3062    fn ne(&self, other: &BumpBox<'a, [U]>) -> bool {
3063        <[T] as PartialEq<[U]>>::ne(self, other)
3064    }
3065}
3066
3067impl<'a, T, U> PartialEq<BumpBox<'a, [U]>> for &[T]
3068where
3069    T: PartialEq<U>,
3070{
3071    #[inline(always)]
3072    fn eq(&self, other: &BumpBox<'a, [U]>) -> bool {
3073        <[T] as PartialEq<[U]>>::eq(self, other)
3074    }
3075
3076    #[inline(always)]
3077    fn ne(&self, other: &BumpBox<'a, [U]>) -> bool {
3078        <[T] as PartialEq<[U]>>::ne(self, other)
3079    }
3080}
3081
3082impl<'a, T, U> PartialEq<BumpBox<'a, [U]>> for &mut [T]
3083where
3084    T: PartialEq<U>,
3085{
3086    #[inline(always)]
3087    fn eq(&self, other: &BumpBox<'a, [U]>) -> bool {
3088        <[T] as PartialEq<[U]>>::eq(self, other)
3089    }
3090
3091    #[inline(always)]
3092    fn ne(&self, other: &BumpBox<'a, [U]>) -> bool {
3093        <[T] as PartialEq<[U]>>::ne(self, other)
3094    }
3095}
3096
3097impl<T: PartialEq, const N: usize> PartialEq<[T; N]> for BumpBox<'_, [T]> {
3098    #[inline(always)]
3099    fn eq(&self, other: &[T; N]) -> bool {
3100        <[T]>::eq(self, other)
3101    }
3102
3103    #[inline(always)]
3104    fn ne(&self, other: &[T; N]) -> bool {
3105        <[T]>::ne(self, other)
3106    }
3107}
3108
3109impl<'b, T: ?Sized + PartialOrd> PartialOrd<BumpBox<'b, T>> for BumpBox<'_, T> {
3110    #[inline(always)]
3111    fn partial_cmp(&self, other: &BumpBox<'b, T>) -> Option<Ordering> {
3112        T::partial_cmp(self, other)
3113    }
3114    #[inline(always)]
3115    fn lt(&self, other: &BumpBox<'b, T>) -> bool {
3116        T::lt(self, other)
3117    }
3118    #[inline(always)]
3119    fn le(&self, other: &BumpBox<'b, T>) -> bool {
3120        T::le(self, other)
3121    }
3122    #[inline(always)]
3123    fn ge(&self, other: &BumpBox<'b, T>) -> bool {
3124        T::ge(self, other)
3125    }
3126    #[inline(always)]
3127    fn gt(&self, other: &BumpBox<'b, T>) -> bool {
3128        T::gt(self, other)
3129    }
3130}
3131
3132impl<'a, T: ?Sized + Ord> Ord for BumpBox<'a, T> {
3133    #[inline(always)]
3134    fn cmp(&self, other: &BumpBox<'a, T>) -> Ordering {
3135        T::cmp(self, other)
3136    }
3137}
3138
3139impl<T: ?Sized + Eq> Eq for BumpBox<'_, T> {}
3140
3141impl<T: ?Sized + Hash> Hash for BumpBox<'_, T> {
3142    #[inline(always)]
3143    fn hash<H: Hasher>(&self, state: &mut H) {
3144        T::hash(self, state);
3145    }
3146}
3147
3148impl<T: ?Sized + Hasher> Hasher for BumpBox<'_, T> {
3149    #[inline(always)]
3150    fn finish(&self) -> u64 {
3151        T::finish(self)
3152    }
3153    #[inline(always)]
3154    fn write(&mut self, bytes: &[u8]) {
3155        T::write(self, bytes);
3156    }
3157    #[inline(always)]
3158    fn write_u8(&mut self, i: u8) {
3159        T::write_u8(self, i);
3160    }
3161    #[inline(always)]
3162    fn write_u16(&mut self, i: u16) {
3163        T::write_u16(self, i);
3164    }
3165    #[inline(always)]
3166    fn write_u32(&mut self, i: u32) {
3167        T::write_u32(self, i);
3168    }
3169    #[inline(always)]
3170    fn write_u64(&mut self, i: u64) {
3171        T::write_u64(self, i);
3172    }
3173    #[inline(always)]
3174    fn write_u128(&mut self, i: u128) {
3175        T::write_u128(self, i);
3176    }
3177    #[inline(always)]
3178    fn write_usize(&mut self, i: usize) {
3179        T::write_usize(self, i);
3180    }
3181    #[inline(always)]
3182    fn write_i8(&mut self, i: i8) {
3183        T::write_i8(self, i);
3184    }
3185    #[inline(always)]
3186    fn write_i16(&mut self, i: i16) {
3187        T::write_i16(self, i);
3188    }
3189    #[inline(always)]
3190    fn write_i32(&mut self, i: i32) {
3191        T::write_i32(self, i);
3192    }
3193    #[inline(always)]
3194    fn write_i64(&mut self, i: i64) {
3195        T::write_i64(self, i);
3196    }
3197    #[inline(always)]
3198    fn write_i128(&mut self, i: i128) {
3199        T::write_i128(self, i);
3200    }
3201    #[inline(always)]
3202    fn write_isize(&mut self, i: isize) {
3203        T::write_isize(self, i);
3204    }
3205}
3206
3207#[cfg(feature = "alloc")]
3208impl<'a> Extend<BumpBox<'a, str>> for alloc_crate::string::String {
3209    #[inline(always)]
3210    fn extend<T: IntoIterator<Item = BumpBox<'a, str>>>(&mut self, iter: T) {
3211        iter.into_iter().for_each(move |s| self.push_str(&s));
3212    }
3213}
3214
3215impl<'a, T> IntoIterator for BumpBox<'a, [T]> {
3216    type Item = T;
3217    type IntoIter = owned_slice::IntoIter<'a, T>;
3218
3219    #[inline(always)]
3220    fn into_iter(self) -> Self::IntoIter {
3221        let this = ManuallyDrop::new(self);
3222        unsafe { owned_slice::IntoIter::new(this.ptr) }
3223    }
3224}
3225
3226impl<'b, T> IntoIterator for &'b BumpBox<'_, [T]> {
3227    type Item = &'b T;
3228    type IntoIter = slice::Iter<'b, T>;
3229
3230    #[inline(always)]
3231    fn into_iter(self) -> Self::IntoIter {
3232        <[T]>::iter(self)
3233    }
3234}
3235
3236impl<'b, T> IntoIterator for &'b mut BumpBox<'_, [T]> {
3237    type Item = &'b mut T;
3238    type IntoIter = slice::IterMut<'b, T>;
3239
3240    #[inline(always)]
3241    fn into_iter(self) -> Self::IntoIter {
3242        <[T]>::iter_mut(self)
3243    }
3244}
3245
3246impl<I, T: Index<I>> Index<I> for BumpBox<'_, T> {
3247    type Output = <T as Index<I>>::Output;
3248
3249    #[inline]
3250    fn index(&self, index: I) -> &Self::Output {
3251        <T as Index<I>>::index(self, index)
3252    }
3253}
3254
3255impl<I, T: IndexMut<I>> IndexMut<I> for BumpBox<'_, T> {
3256    #[inline]
3257    fn index_mut(&mut self, index: I) -> &mut Self::Output {
3258        <T as IndexMut<I>>::index_mut(self, index)
3259    }
3260}
3261
3262#[cfg(feature = "std")]
3263impl<T: ?Sized + std::io::Read> std::io::Read for BumpBox<'_, T> {
3264    #[inline(always)]
3265    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
3266        T::read(self, buf)
3267    }
3268
3269    #[inline(always)]
3270    fn read_vectored(&mut self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result<usize> {
3271        T::read_vectored(self, bufs)
3272    }
3273
3274    #[inline(always)]
3275    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
3276        T::read_to_end(self, buf)
3277    }
3278
3279    #[inline(always)]
3280    fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize> {
3281        T::read_to_string(self, buf)
3282    }
3283
3284    #[inline(always)]
3285    fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
3286        T::read_exact(self, buf)
3287    }
3288}
3289
3290#[cfg(feature = "std")]
3291impl<T: ?Sized + std::io::Write> std::io::Write for BumpBox<'_, T> {
3292    #[inline(always)]
3293    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
3294        T::write(self, buf)
3295    }
3296
3297    #[inline(always)]
3298    fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
3299        T::write_vectored(self, bufs)
3300    }
3301
3302    #[inline(always)]
3303    fn flush(&mut self) -> std::io::Result<()> {
3304        T::flush(self)
3305    }
3306
3307    #[inline(always)]
3308    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
3309        T::write_all(self, buf)
3310    }
3311
3312    #[inline(always)]
3313    fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> std::io::Result<()> {
3314        T::write_fmt(self, fmt)
3315    }
3316}
3317
3318#[cfg(feature = "std")]
3319impl<T: ?Sized + std::io::Seek> std::io::Seek for BumpBox<'_, T> {
3320    #[inline(always)]
3321    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
3322        T::seek(self, pos)
3323    }
3324
3325    #[inline(always)]
3326    fn stream_position(&mut self) -> std::io::Result<u64> {
3327        T::stream_position(self)
3328    }
3329}
3330
3331#[cfg(feature = "std")]
3332impl<T: ?Sized + std::io::BufRead> std::io::BufRead for BumpBox<'_, T> {
3333    #[inline(always)]
3334    fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
3335        T::fill_buf(self)
3336    }
3337
3338    #[inline(always)]
3339    fn consume(&mut self, amt: usize) {
3340        T::consume(self, amt);
3341    }
3342
3343    #[inline(always)]
3344    fn read_until(&mut self, byte: u8, buf: &mut std::vec::Vec<u8>) -> std::io::Result<usize> {
3345        T::read_until(self, byte, buf)
3346    }
3347
3348    #[inline(always)]
3349    fn read_line(&mut self, buf: &mut std::string::String) -> std::io::Result<usize> {
3350        T::read_line(self, buf)
3351    }
3352}
3353
3354#[cfg(feature = "nightly-fn-traits")]
3355impl<Args: Tuple, F: FnOnce<Args> + ?Sized> FnOnce<Args> for BumpBox<'_, F> {
3356    type Output = <F as FnOnce<Args>>::Output;
3357
3358    extern "rust-call" fn call_once(self, args: Args) -> Self::Output {
3359        use alloc_crate::{
3360            alloc::{AllocError, Allocator},
3361            boxed::Box,
3362        };
3363
3364        struct NoopAllocator;
3365
3366        // SAFETY:
3367        // An allocator that always fails allocation and does nothing on deallocation
3368        // satisfies the safety invariants.
3369        unsafe impl Allocator for NoopAllocator {
3370            fn allocate(&self, _layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
3371                Err(AllocError)
3372            }
3373
3374            unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) {}
3375        }
3376
3377        let ptr = self.into_raw().as_ptr();
3378
3379        // SAFETY:
3380        // The allocator will only be used to call `deallocate` which does nothing
3381        // just like the `BumpBox` would do no deallocation on drop.
3382        //
3383        // The `Box` or its allocator do not encode the lifetime of the `BumpBox` but
3384        // it's fine here because it only lives in this function.
3385        unsafe {
3386            let boxed = Box::from_raw_in(ptr, NoopAllocator);
3387            <Box<F, NoopAllocator> as FnOnce<Args>>::call_once(boxed, args)
3388        }
3389    }
3390}
3391
3392#[cfg(feature = "nightly-fn-traits")]
3393impl<Args: Tuple, F: FnMut<Args> + ?Sized> FnMut<Args> for BumpBox<'_, F> {
3394    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output {
3395        <F as FnMut<Args>>::call_mut(self, args)
3396    }
3397}
3398
3399#[cfg(feature = "nightly-fn-traits")]
3400impl<Args: Tuple, F: Fn<Args> + ?Sized> Fn<Args> for BumpBox<'_, F> {
3401    extern "rust-call" fn call(&self, args: Args) -> Self::Output {
3402        <F as Fn<Args>>::call(self, args)
3403    }
3404}
3405
3406#[inline(always)]
3407fn as_uninit_slice<T>(slice: &[T]) -> &[MaybeUninit<T>] {
3408    unsafe { &*(ptr::from_ref(slice) as *const [MaybeUninit<T>]) }
3409}
3410
3411macro_rules! assert_in_place_mappable {
3412    ($src:ty, $dst:ty) => {
3413        let _assert = AssertInPlaceMappable::<$src, $dst>::ASSERT;
3414    };
3415}
3416
3417// False positive; i need `pub(self)` to forward declare it.
3418// Useless attribute is needed for msrv clippy.
3419#[expect(clippy::useless_attribute)]
3420#[expect(clippy::needless_pub_self)]
3421pub(self) use assert_in_place_mappable;
3422
3423struct AssertInPlaceMappable<Src, Dst>(PhantomData<(Src, Dst)>);
3424
3425impl<Src, Dst> AssertInPlaceMappable<Src, Dst> {
3426    const ASSERT: () = assert!(
3427        Dst::IS_ZST || (Src::ALIGN >= Dst::ALIGN && Src::SIZE >= Dst::SIZE),
3428        "`map_in_place` only compiles when `U`s size and alignment is less or equal to `T`'s or if `U` has a size of 0"
3429    );
3430}
3431
3432const _: () = {
3433    #[repr(align(1024))]
3434    struct AlignedZst;
3435    assert_in_place_mappable!(u32, u32);
3436    assert_in_place_mappable!(u32, Option<core::num::NonZeroU32>);
3437    assert_in_place_mappable!(u32, [u8; 4]);
3438    assert_in_place_mappable!(u32, [u16; 2]);
3439    assert_in_place_mappable!(u32, ());
3440    assert_in_place_mappable!(u32, AlignedZst);
3441    assert_in_place_mappable!((), ());
3442    assert_in_place_mappable!((), AlignedZst);
3443};