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