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