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