bump_scope/bump_vec.rs
1use core::{
2 alloc::Layout,
3 borrow::{Borrow, BorrowMut},
4 fmt::Debug,
5 hash::Hash,
6 iter,
7 marker::PhantomData,
8 mem::{ManuallyDrop, MaybeUninit},
9 ops::{Deref, DerefMut, Index, IndexMut, RangeBounds},
10 panic::{RefUnwindSafe, UnwindSafe},
11 ptr::{self, NonNull},
12 slice::SliceIndex,
13};
14
15use crate::{
16 BumpAllocatorExt, BumpAllocatorScopeExt, BumpBox, ErrorBehavior, FixedBumpVec, NoDrop, SizedTypeProperties,
17 alloc::AllocError,
18 destructure::destructure,
19 min_non_zero_cap,
20 owned_slice::{self, OwnedSlice, TakeOwnedSlice},
21 polyfill::{hint::likely, non_null, pointer, slice},
22 raw_fixed_bump_vec::RawFixedBumpVec,
23};
24
25#[cfg(feature = "panic-on-alloc")]
26use crate::panic_on_error;
27
28mod drain;
29mod into_iter;
30mod splice;
31
32pub use into_iter::IntoIter;
33
34#[cfg(feature = "panic-on-alloc")]
35pub(crate) use drain::Drain;
36
37#[cfg(feature = "panic-on-alloc")]
38pub use splice::Splice;
39
40/// This is like [`vec!`](alloc_crate::vec!) but allocates inside a bump allocator, returning a [`BumpVec`].
41///
42/// `$bump` can be any type that implements [`BumpAllocatorExt`].
43///
44/// # Panics
45/// If used without `try`, panics on allocation failure.
46///
47/// # Errors
48/// If used with `try`, errors on allocation failure.
49///
50/// # Examples
51///
52/// There are three forms of this macro:
53///
54/// - Create an empty [`BumpVec`]:
55/// ```
56/// # use bump_scope::{Bump, bump_vec, BumpVec};
57/// # let bump: Bump = Bump::new();
58/// let vec: BumpVec<i32, _> = bump_vec![in &bump];
59/// assert!(vec.is_empty());
60/// ```
61///
62/// - Create a [`BumpVec`] containing a given list of elements:
63///
64/// ```
65/// # use bump_scope::{Bump, bump_vec};
66/// # let bump: Bump = Bump::new();
67/// let vec = bump_vec![in ≎ 1, 2, 3];
68/// assert_eq!(vec[0], 1);
69/// assert_eq!(vec[1], 2);
70/// assert_eq!(vec[2], 3);
71/// ```
72///
73/// - Create a [`BumpVec`] from a given element and size:
74///
75/// ```
76/// # use bump_scope::{Bump, bump_vec};
77/// # let bump: Bump = Bump::new();
78/// let vec = bump_vec![in ≎ 1; 3];
79/// assert_eq!(vec, [1, 1, 1]);
80/// ```
81///
82/// Note that unlike array expressions this syntax supports all elements
83/// which implement [`Clone`] and the number of elements doesn't have to be
84/// a constant.
85///
86/// This will use `clone` to duplicate an expression, so one should be careful
87/// using this with types having a nonstandard `Clone` implementation. For
88/// example, `bump_vec![in ≎ Rc::new(1); 5]` will create a vector of five references
89/// to the same boxed integer value, not five references pointing to independently
90/// boxed integers.
91///
92/// Also, note that `bump_vec![in ≎ expr; 0]` is allowed, and produces an empty vector.
93/// This will still evaluate `expr`, however, and immediately drop the resulting value, so
94/// be mindful of side effects.
95#[macro_export]
96macro_rules! bump_vec {
97 [in $bump:expr] => {
98 $crate::BumpVec::new_in($bump)
99 };
100 [in $bump:expr; $($values:expr),* $(,)?] => {
101 $crate::__bump_vec_panic_on_alloc![in $bump; $($values),*]
102 };
103 [in $bump:expr; $value:expr; $count:expr] => {
104 $crate::__bump_vec_panic_on_alloc![in $bump; $value; $count]
105 };
106 [try in $bump:expr] => {
107 Ok::<_, $crate::alloc::AllocError>($crate::BumpVec::new_in($bump))
108 };
109 [try in $bump:expr; $($values:expr),* $(,)?] => {
110 $crate::BumpVec::try_from_owned_slice_in([$($values),*], $bump)
111 };
112 [try in $bump:expr; $value:expr; $count:expr] => {
113 $crate::BumpVec::try_from_elem_in($value, $count, $bump)
114 };
115}
116
117#[doc(hidden)]
118#[macro_export]
119#[cfg(feature = "panic-on-alloc")]
120macro_rules! __bump_vec_panic_on_alloc {
121 [in $bump:expr; $($values:expr),* $(,)?] => {
122 $crate::BumpVec::from_owned_slice_in([$($values),*], $bump)
123 };
124 [in $bump:expr; $value:expr; $count:expr] => {
125 $crate::BumpVec::from_elem_in($value, $count, $bump)
126 };
127}
128
129#[doc(hidden)]
130#[macro_export]
131#[cfg(not(feature = "panic-on-alloc"))]
132macro_rules! __bump_vec_panic_on_alloc {
133 [in $bump:expr; $($values:expr),* $(,)?] => {
134 compile_error!(
135 concat!("the potentially panicking api of `bump_vec!` is not available\n\
136 help: enable `bump-scope`'s \"panic-on-alloc\" feature or use `try`:\n\
137 `bump_vec![try in ",
138 stringify!($bump),
139 "; ",
140 stringify!($($values),*),
141 "]`"
142 ))
143 };
144 [in $bump:expr; $value:expr; $count:expr] => {
145 compile_error!(
146 concat!("the potentially panicking api of `bump_vec!` is not available\n\
147 help: enable `bump-scope`'s \"panic-on-alloc\" feature or use `try`:\n\
148 `bump_vec![try in ",
149 stringify!($bump),
150 "; ",
151 stringify!($value),
152 "; ",
153 stringify!($count),
154 "]`"
155 ))
156 };
157}
158
159/// A bump allocated [`Vec`](alloc_crate::vec::Vec).
160///
161/// The main difference to `Vec` is that it can be turned into a slice that is live for this bump scope (`'a`).
162/// Such a slice can be live while entering new scopes.
163///
164/// This would not be possible with `Vec`:
165///
166/// ```
167/// # use bump_scope::{Bump, BumpVec};
168/// # let mut bump: Bump = Bump::new();
169/// let bump = bump.as_mut_scope();
170///
171/// let slice = {
172/// let mut vec = BumpVec::new_in(&*bump);
173///
174/// vec.push(1);
175/// vec.push(2);
176/// vec.push(3);
177///
178/// vec.into_slice()
179/// };
180///
181/// bump.scoped(|bump| {
182/// // allocate more things
183/// # _ = bump;
184/// });
185///
186/// assert_eq!(slice, [1, 2, 3]);
187/// ```
188///
189/// # Examples
190///
191/// This type can be used to allocate a slice, when `alloc_*` methods are too limiting:
192/// ```
193/// # use bump_scope::{Bump, BumpVec};
194/// # let bump: Bump = Bump::new();
195/// let mut vec = BumpVec::new_in(&bump);
196///
197/// vec.push(1);
198/// vec.push(2);
199/// vec.push(3);
200///
201/// let slice: &[i32] = vec.into_slice();
202///
203/// assert_eq!(slice, [1, 2, 3]);
204/// ```
205// `BumpString` and `BumpVec<u8>` have the same repr.
206#[repr(C)]
207pub struct BumpVec<T, A: BumpAllocatorExt> {
208 fixed: RawFixedBumpVec<T>,
209 allocator: A,
210}
211
212impl<T: UnwindSafe, A: BumpAllocatorExt + UnwindSafe> UnwindSafe for BumpVec<T, A> {}
213impl<T: RefUnwindSafe, A: BumpAllocatorExt + RefUnwindSafe> RefUnwindSafe for BumpVec<T, A> {}
214
215impl<T, A: BumpAllocatorExt> Deref for BumpVec<T, A> {
216 type Target = [T];
217
218 fn deref(&self) -> &Self::Target {
219 unsafe { self.fixed.cook_ref() }
220 }
221}
222
223impl<T, A: BumpAllocatorExt> DerefMut for BumpVec<T, A> {
224 fn deref_mut(&mut self) -> &mut Self::Target {
225 unsafe { self.fixed.cook_mut() }
226 }
227}
228
229impl<T, A: BumpAllocatorExt> BumpVec<T, A> {
230 /// # Safety
231 ///
232 /// Must only be called from the drop implementation and a call to this function
233 /// must be the only thing in that drop implementation.
234 #[inline]
235 unsafe fn drop_inner(&mut self) {
236 struct DropGuard<'a, T, A: BumpAllocatorExt>(&'a mut BumpVec<T, A>);
237
238 impl<T, A: BumpAllocatorExt> Drop for DropGuard<'_, T, A> {
239 fn drop(&mut self) {
240 // SAFETY:
241 // Calling `deallocate` with a dangling pointer is fine because
242 // - `layout.size()` will be `0` which will make it have no effect in the allocator
243 // - calling deallocate with a pointer not owned by this allocator is explicitly allowed; see `BumpAllocator`
244 unsafe {
245 let ptr = self.0.fixed.as_non_null().cast();
246 let layout = Layout::from_size_align_unchecked(self.0.fixed.capacity() * T::SIZE, T::ALIGN);
247 self.0.allocator.deallocate(ptr, layout);
248 }
249 }
250 }
251
252 let guard = DropGuard(self);
253
254 // destroy the remaining elements
255 guard.0.clear();
256
257 // now `guard` will be dropped and deallocate the memory
258 }
259}
260
261#[cfg(feature = "nightly-dropck-eyepatch")]
262unsafe impl<#[may_dangle] T, A: BumpAllocatorExt> Drop for BumpVec<T, A> {
263 #[inline]
264 fn drop(&mut self) {
265 unsafe { self.drop_inner() }
266 }
267}
268
269#[cfg(not(feature = "nightly-dropck-eyepatch"))]
270impl<T, A: BumpAllocatorExt> Drop for BumpVec<T, A> {
271 #[inline]
272 fn drop(&mut self) {
273 unsafe { self.drop_inner() }
274 }
275}
276
277impl<T, A: BumpAllocatorExt + Default> Default for BumpVec<T, A> {
278 fn default() -> Self {
279 Self::new_in(A::default())
280 }
281}
282
283#[cfg(feature = "panic-on-alloc")]
284impl<T: Clone, A: BumpAllocatorExt + Clone> Clone for BumpVec<T, A> {
285 fn clone(&self) -> Self {
286 let allocator = self.allocator.clone();
287 let ptr = allocator.allocate_slice::<MaybeUninit<T>>(self.len());
288 let slice = NonNull::slice_from_raw_parts(ptr, self.len());
289 let boxed = unsafe { BumpBox::from_raw(slice) };
290 let boxed = boxed.init_clone(self);
291 let fixed = FixedBumpVec::from_init(boxed);
292 let fixed = unsafe { RawFixedBumpVec::from_cooked(fixed) };
293 Self { fixed, allocator }
294 }
295}
296
297impl<T, A: BumpAllocatorExt> BumpVec<T, A> {
298 /// Constructs a new empty `BumpVec<T>`.
299 ///
300 /// The vector will not allocate until elements are pushed onto it.
301 ///
302 /// # Examples
303 /// ```
304 /// # use bump_scope::{Bump, BumpVec};
305 /// # let bump: Bump = Bump::new();
306 /// let vec = BumpVec::<i32, _>::new_in(&bump);
307 /// assert_eq!(vec.len(), 0);
308 /// assert_eq!(vec.capacity(), 0);
309 /// ```
310 #[inline]
311 pub const fn new_in(allocator: A) -> Self {
312 Self {
313 fixed: RawFixedBumpVec::EMPTY,
314 allocator,
315 }
316 }
317
318 /// Constructs a new empty vector with at least the specified capacity
319 /// in the provided bump allocator.
320 ///
321 /// The vector will be able to hold `capacity` elements without
322 /// reallocating. If `capacity` is 0, the vector will not allocate.
323 ///
324 /// It is important to note that although the returned vector has the
325 /// minimum *capacity* specified, the vector will have a zero *length*. For
326 /// an explanation of the difference between length and capacity, see
327 /// *[Capacity and reallocation]*.
328 ///
329 /// When `T` is a zero-sized type, there will be no allocation
330 /// and the capacity will always be `usize::MAX`.
331 ///
332 /// [Capacity and reallocation]: alloc_crate::vec::Vec#capacity-and-reallocation
333 ///
334 /// # Panics
335 /// Panics if the allocation fails.
336 ///
337 /// # Examples
338 /// ```
339 /// # use bump_scope::{Bump, BumpVec};
340 /// # let bump: Bump = Bump::new();
341 /// let mut vec = BumpVec::<i32, _>::with_capacity_in(10, &bump);
342 ///
343 /// // The vector contains no items, even though it has capacity for more
344 /// assert_eq!(vec.len(), 0);
345 /// assert!(vec.capacity() >= 10);
346 ///
347 /// // These are all done without reallocating...
348 /// for i in 0..10 {
349 /// vec.push(i);
350 /// }
351 /// assert_eq!(vec.len(), 10);
352 /// assert!(vec.capacity() >= 10);
353 ///
354 /// // ...but this may make the vector reallocate
355 /// vec.push(11);
356 /// assert_eq!(vec.len(), 11);
357 /// assert!(vec.capacity() >= 11);
358 ///
359 /// // A vector of a zero-sized type will always over-allocate, since no
360 /// // allocation is necessary
361 /// let vec_units = BumpVec::<(), _>::with_capacity_in(10, &bump);
362 /// assert_eq!(vec_units.capacity(), usize::MAX);
363 /// ```
364 #[must_use]
365 #[inline(always)]
366 #[cfg(feature = "panic-on-alloc")]
367 pub fn with_capacity_in(capacity: usize, allocator: A) -> Self {
368 panic_on_error(Self::generic_with_capacity_in(capacity, allocator))
369 }
370
371 /// Constructs a new empty vector with at least the specified capacity
372 /// in the provided bump allocator.
373 ///
374 /// The vector will be able to hold `capacity` elements without
375 /// reallocating. If `capacity` is 0, the vector will not allocate.
376 ///
377 /// It is important to note that although the returned vector has the
378 /// minimum *capacity* specified, the vector will have a zero *length*. For
379 /// an explanation of the difference between length and capacity, see
380 /// *[Capacity and reallocation]*.
381 ///
382 /// When `T` is a zero-sized type, there will be no allocation
383 /// and the capacity will always be `usize::MAX`.
384 ///
385 /// [Capacity and reallocation]: alloc_crate::vec::Vec#capacity-and-reallocation
386 ///
387 /// # Errors
388 /// Errors if the allocation fails.
389 ///
390 /// # Examples
391 /// ```
392 /// # use bump_scope::{Bump, BumpVec};
393 /// # let bump: Bump = Bump::try_new()?;
394 /// let mut vec = BumpVec::<i32, _>::try_with_capacity_in(10, &bump)?;
395 ///
396 /// // The vector contains no items, even though it has capacity for more
397 /// assert_eq!(vec.len(), 0);
398 /// assert!(vec.capacity() >= 10);
399 ///
400 /// // These are all done without reallocating...
401 /// for i in 0..10 {
402 /// vec.push(i);
403 /// }
404 /// assert_eq!(vec.len(), 10);
405 /// assert!(vec.capacity() >= 10);
406 ///
407 /// // ...but this may make the vector reallocate
408 /// vec.push(11);
409 /// assert_eq!(vec.len(), 11);
410 /// assert!(vec.capacity() >= 11);
411 ///
412 /// // A vector of a zero-sized type will always over-allocate, since no
413 /// // allocation is necessary
414 /// let vec_units = BumpVec::<(), _>::try_with_capacity_in(10, &bump)?;
415 /// assert_eq!(vec_units.capacity(), usize::MAX);
416 /// # Ok::<(), bump_scope::alloc::AllocError>(())
417 /// ```
418 #[inline(always)]
419 pub fn try_with_capacity_in(capacity: usize, allocator: A) -> Result<Self, AllocError> {
420 Self::generic_with_capacity_in(capacity, allocator)
421 }
422
423 #[inline]
424 pub(crate) fn generic_with_capacity_in<E: ErrorBehavior>(capacity: usize, allocator: A) -> Result<Self, E> {
425 if T::IS_ZST || capacity == 0 {
426 return Ok(Self {
427 fixed: RawFixedBumpVec::EMPTY,
428 allocator,
429 });
430 }
431
432 Ok(Self {
433 fixed: unsafe { RawFixedBumpVec::allocate(&allocator, capacity)? },
434 allocator,
435 })
436 }
437
438 /// Constructs a new `BumpVec<T>` and pushes `value` `count` times.
439 ///
440 /// # Panics
441 /// Panics if the allocation fails.
442 ///
443 /// # Examples
444 /// ```
445 /// # use bump_scope::{Bump, BumpVec};
446 /// # let bump: Bump = Bump::new();
447 /// let vec = BumpVec::from_elem_in("ho", 3, &bump);
448 /// assert_eq!(vec, ["ho", "ho", "ho"]);
449 /// ```
450 #[must_use]
451 #[inline(always)]
452 #[cfg(feature = "panic-on-alloc")]
453 pub fn from_elem_in(value: T, count: usize, allocator: A) -> Self
454 where
455 T: Clone,
456 {
457 panic_on_error(Self::generic_from_elem_in(value, count, allocator))
458 }
459
460 /// Constructs a new `BumpVec<T>` and pushes `value` `count` times.
461 ///
462 /// # Errors
463 /// Errors if the allocation fails.
464 ///
465 /// # Examples
466 /// ```
467 /// # use bump_scope::{Bump, BumpVec};
468 /// # let bump: Bump = Bump::try_new()?;
469 /// let vec = BumpVec::try_from_elem_in("ho", 3, &bump)?;
470 /// assert_eq!(vec, ["ho", "ho", "ho"]);
471 /// # Ok::<(), bump_scope::alloc::AllocError>(())
472 /// ```
473 #[inline(always)]
474 pub fn try_from_elem_in(value: T, count: usize, allocator: A) -> Result<Self, AllocError>
475 where
476 T: Clone,
477 {
478 Self::generic_from_elem_in(value, count, allocator)
479 }
480
481 #[inline]
482 pub(crate) fn generic_from_elem_in<E: ErrorBehavior>(value: T, count: usize, allocator: A) -> Result<Self, E>
483 where
484 T: Clone,
485 {
486 let mut vec = Self::generic_with_capacity_in(count, allocator)?;
487
488 unsafe {
489 if count != 0 {
490 for _ in 0..(count - 1) {
491 vec.push_with_unchecked(|| value.clone());
492 }
493
494 vec.push_with_unchecked(|| value);
495 }
496 }
497
498 Ok(vec)
499 }
500
501 /// Constructs a new `BumpVec<T>` from an [`OwnedSlice`].
502 ///
503 /// # Panics
504 /// Panics if the allocation fails.
505 ///
506 /// # Examples
507 /// ```
508 /// # use bump_scope::{Bump, BumpVec};
509 /// # let bump: Bump = Bump::new();
510 /// // by value
511 /// let a = BumpVec::from_owned_slice_in([1, 2], &bump);
512 /// let b = BumpVec::from_owned_slice_in(vec![3, 4], &bump);
513 /// let c = BumpVec::from_owned_slice_in(bump.alloc_iter(5..=6), &bump);
514 ///
515 /// // by mutable reference
516 /// let mut other = vec![7, 8];
517 /// let d = BumpVec::from_owned_slice_in(&mut other, &bump);
518 /// assert!(other.is_empty());
519 ///
520 /// assert_eq!(a, [1, 2]);
521 /// assert_eq!(b, [3, 4]);
522 /// assert_eq!(c, [5, 6]);
523 /// assert_eq!(d, [7, 8]);
524 /// ```
525 #[must_use]
526 #[inline(always)]
527 #[cfg(feature = "panic-on-alloc")]
528 pub fn from_owned_slice_in(owned_slice: impl OwnedSlice<Item = T>, allocator: A) -> Self {
529 panic_on_error(Self::generic_from_owned_slice_in(owned_slice, allocator))
530 }
531
532 /// Constructs a new `BumpVec<T>` from an [`OwnedSlice`].
533 ///
534 /// # Errors
535 /// Errors if the allocation fails.
536 ///
537 /// # Examples
538 /// ```
539 /// # use bump_scope::{Bump, BumpVec};
540 /// # let bump: Bump = Bump::new();
541 /// // by value
542 /// let a = BumpVec::try_from_owned_slice_in([1, 2], &bump)?;
543 /// let b = BumpVec::try_from_owned_slice_in(vec![3, 4], &bump)?;
544 /// let c = BumpVec::try_from_owned_slice_in(bump.alloc_iter(5..=6), &bump)?;
545 ///
546 /// // by mutable reference
547 /// let mut other = vec![7, 8];
548 /// let d = BumpVec::try_from_owned_slice_in(&mut other, &bump)?;
549 /// assert!(other.is_empty());
550 ///
551 /// assert_eq!(a, [1, 2]);
552 /// assert_eq!(b, [3, 4]);
553 /// assert_eq!(c, [5, 6]);
554 /// assert_eq!(d, [7, 8]);
555 /// # Ok::<(), bump_scope::alloc::AllocError>(())
556 /// ```
557 #[inline(always)]
558 pub fn try_from_owned_slice_in(owned_slice: impl OwnedSlice<Item = T>, allocator: A) -> Result<Self, AllocError> {
559 Self::generic_from_owned_slice_in(owned_slice, allocator)
560 }
561
562 #[inline]
563 pub(crate) fn generic_from_owned_slice_in<E: ErrorBehavior>(
564 owned_slice: impl OwnedSlice<Item = T>,
565 allocator: A,
566 ) -> Result<Self, E> {
567 let owned_slice = owned_slice.into_take_owned_slice();
568 let mut this = Self::generic_with_capacity_in(owned_slice.owned_slice_ref().len(), allocator)?;
569 this.generic_append(owned_slice)?;
570 Ok(this)
571 }
572
573 /// Constructs a new `BumpVec<T>` from a `[T; N]`.
574 ///
575 /// # Panics
576 /// Panics if the allocation fails.
577 #[doc(hidden)]
578 #[deprecated = "use `from_owned_slice_in` instead"]
579 #[must_use]
580 #[inline(always)]
581 #[cfg(feature = "panic-on-alloc")]
582 pub fn from_array_in<const N: usize>(array: [T; N], allocator: A) -> Self {
583 panic_on_error(Self::generic_from_array_in(array, allocator))
584 }
585
586 /// Constructs a new `BumpVec<T>` from a `[T; N]`.
587 ///
588 /// # Errors
589 /// Errors if the allocation fails.
590 #[doc(hidden)]
591 #[deprecated = "use `try_from_owned_slice_in` instead"]
592 #[inline(always)]
593 pub fn try_from_array_in<const N: usize>(array: [T; N], allocator: A) -> Result<Self, AllocError> {
594 Self::generic_from_array_in(array, allocator)
595 }
596
597 #[inline]
598 pub(crate) fn generic_from_array_in<E: ErrorBehavior, const N: usize>(array: [T; N], allocator: A) -> Result<Self, E> {
599 let array = ManuallyDrop::new(array);
600
601 if T::IS_ZST {
602 return Ok(Self {
603 fixed: unsafe { RawFixedBumpVec::new_zst(N) },
604 allocator,
605 });
606 }
607
608 if N == 0 {
609 return Ok(Self {
610 fixed: RawFixedBumpVec::EMPTY,
611 allocator,
612 });
613 }
614
615 let mut fixed = unsafe { RawFixedBumpVec::allocate(&allocator, N)? };
616
617 let src = array.as_ptr();
618 let dst = fixed.as_mut_ptr();
619
620 unsafe {
621 ptr::copy_nonoverlapping(src, dst, N);
622 fixed.set_len(N);
623 }
624
625 Ok(Self { fixed, allocator })
626 }
627
628 /// Create a new [`BumpVec`] whose elements are taken from an iterator and allocated in the given `bump`.
629 ///
630 /// This is behaviorally identical to [`FromIterator::from_iter`].
631 ///
632 /// If you have an `impl ExactSizeIterator` then you can use [`from_iter_exact_in`](Self::from_iter_exact_in) instead for better performance.
633 ///
634 /// # Panics
635 /// Panics if the allocation fails.
636 ///
637 /// # Examples
638 /// ```
639 /// # use bump_scope::{Bump, BumpVec};
640 /// # let bump: Bump = Bump::new();
641 /// let vec = BumpVec::from_iter_in([1, 2, 3], &bump);
642 /// assert_eq!(vec, [1, 2, 3]);
643 /// ```
644 #[must_use]
645 #[inline(always)]
646 #[cfg(feature = "panic-on-alloc")]
647 pub fn from_iter_in<I>(iter: I, allocator: A) -> Self
648 where
649 I: IntoIterator<Item = T>,
650 {
651 panic_on_error(Self::generic_from_iter_in(iter, allocator))
652 }
653
654 /// Create a new [`BumpVec`] whose elements are taken from an iterator and allocated in the given `bump`.
655 ///
656 /// This is behaviorally identical to [`FromIterator::from_iter`].
657 ///
658 /// If you have an `impl ExactSizeIterator` then you can use [`from_iter_exact_in`](Self::from_iter_exact_in) instead for better performance.
659 ///
660 /// # Errors
661 /// Errors if the allocation fails.
662 ///
663 /// # Examples
664 /// ```
665 /// # use bump_scope::{Bump, BumpVec};
666 /// # let bump: Bump = Bump::try_new()?;
667 /// let vec = BumpVec::try_from_iter_in([1, 2, 3], &bump)?;
668 /// assert_eq!(vec, [1, 2, 3]);
669 /// # Ok::<(), bump_scope::alloc::AllocError>(())
670 /// ```
671 #[inline(always)]
672 pub fn try_from_iter_in<I>(iter: I, allocator: A) -> Result<Self, AllocError>
673 where
674 I: IntoIterator<Item = T>,
675 {
676 Self::generic_from_iter_in(iter, allocator)
677 }
678
679 #[inline]
680 pub(crate) fn generic_from_iter_in<E: ErrorBehavior, I>(iter: I, allocator: A) -> Result<Self, E>
681 where
682 I: IntoIterator<Item = T>,
683 {
684 let iter = iter.into_iter();
685 let capacity = iter.size_hint().0;
686
687 let mut vec = Self::generic_with_capacity_in(capacity, allocator)?;
688
689 for value in iter {
690 vec.generic_push(value)?;
691 }
692
693 Ok(vec)
694 }
695
696 /// Create a new [`BumpVec`] whose elements are taken from an iterator and allocated in the given `bump`.
697 ///
698 /// This is just like [`from_iter_in`](Self::from_iter_in) but optimized for an [`ExactSizeIterator`].
699 ///
700 /// # Panics
701 /// Panics if the allocation fails.
702 ///
703 /// # Examples
704 /// ```
705 /// # use bump_scope::{Bump, BumpVec};
706 /// # let bump: Bump = Bump::new();
707 /// let vec = BumpVec::from_iter_exact_in([1, 2, 3], &bump);
708 /// assert_eq!(vec, [1, 2, 3]);
709 /// ```
710 #[must_use]
711 #[inline(always)]
712 #[cfg(feature = "panic-on-alloc")]
713 pub fn from_iter_exact_in<I>(iter: I, allocator: A) -> Self
714 where
715 I: IntoIterator<Item = T>,
716 I::IntoIter: ExactSizeIterator,
717 {
718 panic_on_error(Self::generic_from_iter_exact_in(iter, allocator))
719 }
720
721 /// Create a new [`BumpVec`] whose elements are taken from an iterator and allocated in the given `bump`.
722 ///
723 /// This is just like [`from_iter_in`](Self::from_iter_in) but optimized for an [`ExactSizeIterator`].
724 ///
725 /// # Errors
726 /// Errors if the allocation fails.
727 ///
728 /// # Examples
729 /// ```
730 /// # use bump_scope::{Bump, BumpVec};
731 /// # let bump: Bump = Bump::try_new()?;
732 /// let vec = BumpVec::try_from_iter_exact_in([1, 2, 3], &bump)?;
733 /// assert_eq!(vec, [1, 2, 3]);
734 /// # Ok::<(), bump_scope::alloc::AllocError>(())
735 /// ```
736 #[inline(always)]
737 pub fn try_from_iter_exact_in<I>(iter: I, allocator: A) -> Result<Self, AllocError>
738 where
739 I: IntoIterator<Item = T>,
740 I::IntoIter: ExactSizeIterator,
741 {
742 Self::generic_from_iter_exact_in(iter, allocator)
743 }
744
745 #[inline]
746 pub(crate) fn generic_from_iter_exact_in<E: ErrorBehavior, I>(iter: I, allocator: A) -> Result<Self, E>
747 where
748 I: IntoIterator<Item = T>,
749 I::IntoIter: ExactSizeIterator,
750 {
751 let mut iter = iter.into_iter();
752 let len = iter.len();
753
754 let mut vec = Self::generic_with_capacity_in(len, allocator)?;
755
756 while vec.len() != vec.capacity() {
757 match iter.next() {
758 // SAFETY: we checked above that `len != capacity`, so there is space
759 Some(value) => unsafe { vec.push_unchecked(value) },
760 None => break,
761 }
762 }
763
764 Ok(vec)
765 }
766
767 /// Returns the total number of elements the vector can hold without
768 /// reallocating.
769 ///
770 /// # Examples
771 ///
772 /// ```
773 /// # use bump_scope::{Bump, BumpVec};
774 /// # let bump: Bump = Bump::new();
775 /// let vec = BumpVec::<i32, _>::with_capacity_in(2048, &bump);
776 /// assert!(vec.capacity() >= 2048);
777 /// ```
778 #[must_use]
779 #[inline(always)]
780 pub const fn capacity(&self) -> usize {
781 self.fixed.capacity()
782 }
783
784 /// Returns the number of elements in the vector, also referred to
785 /// as its 'length'.
786 ///
787 /// # Examples
788 /// ```
789 /// # use bump_scope::{Bump, bump_vec};
790 /// # let bump: Bump = Bump::new();
791 /// let a = bump_vec![in ≎ 1, 2, 3];
792 /// assert_eq!(a.len(), 3);
793 /// ```
794 #[must_use]
795 #[inline(always)]
796 pub const fn len(&self) -> usize {
797 self.fixed.len()
798 }
799
800 /// Returns `true` if the vector contains no elements.
801 ///
802 /// # Examples
803 /// ```
804 /// # use bump_scope::{Bump, BumpVec};
805 /// # let bump: Bump = Bump::new();
806 /// let mut v = BumpVec::new_in(&bump);
807 /// assert!(v.is_empty());
808 ///
809 /// v.push(1);
810 /// assert!(!v.is_empty());
811 /// ```
812 #[must_use]
813 #[inline(always)]
814 pub const fn is_empty(&self) -> bool {
815 self.fixed.len() == 0
816 }
817
818 /// Splits the vector into two by removing the specified range.
819 ///
820 /// This method does not allocate and does not change the order of the elements.
821 ///
822 /// The excess capacity may end up in either vector.
823 /// This behavior is different from <code>Vec::[split_off](alloc_crate::vec::Vec::split_off)</code> which allocates a new vector for the split-off elements
824 /// so the original vector keeps its capacity.
825 /// If you rather want that behavior then you can write this instead:
826 /// ```
827 /// # use bump_scope::{Bump, BumpVec};
828 /// # let bump: Bump = Bump::new();
829 /// # let mut vec = BumpVec::from_owned_slice_in(['a', 'b', 'c', 'd', 'e'], &bump);
830 /// # let start = 1;
831 /// # let end = 4;
832 /// let mut other = BumpVec::new_in(*vec.allocator());
833 /// other.append(vec.drain(start..end));
834 /// # assert_eq!(vec, ['a', 'e']);
835 /// # assert_eq!(other, ['b', 'c', 'd']);
836 /// ```
837 ///
838 /// # Panics
839 ///
840 /// Panics if the starting point is greater than the end point or if the end point is greater than the length of the vector.
841 ///
842 /// # Complexity
843 ///
844 /// This operation takes `O(1)` time if either the range starts at 0, ends at `len`, or is empty.
845 /// Otherwise it takes `O(min(end, len - start))` time.
846 ///
847 /// # Examples
848 ///
849 /// ```
850 /// # use bump_scope::{Bump, BumpVec};
851 /// # let bump: Bump = Bump::new();
852 /// let mut vec = BumpVec::with_capacity_in(10, &bump);
853 /// vec.append([1, 2, 3, 4, 5, 6, 7, 8]);
854 ///
855 /// let front = vec.split_off(..2);
856 /// assert_eq!(front, [1, 2]);
857 /// assert_eq!(vec, [3, 4, 5, 6, 7, 8]);
858 ///
859 /// let back = vec.split_off(4..);
860 /// assert_eq!(back, [7, 8]);
861 /// assert_eq!(vec, [3, 4, 5, 6]);
862 ///
863 /// let middle = vec.split_off(1..3);
864 /// assert_eq!(middle, [4, 5]);
865 /// assert_eq!(vec, [3, 6]);
866 ///
867 /// let rest = vec.split_off(..);
868 /// assert_eq!(rest, [3, 6]);
869 /// assert_eq!(vec, []);
870 /// ```
871 #[inline]
872 #[expect(clippy::return_self_not_must_use)]
873 pub fn split_off(&mut self, range: impl RangeBounds<usize>) -> Self
874 where
875 A: Clone,
876 {
877 let other = unsafe { self.fixed.cook_mut() }.split_off(range);
878
879 Self {
880 fixed: unsafe { RawFixedBumpVec::from_cooked(other) },
881 allocator: self.allocator.clone(),
882 }
883 }
884
885 /// Removes the last element from a vector and returns it, or [`None`] if it
886 /// is empty.
887 ///
888 /// # Examples
889 /// ```
890 /// # use bump_scope::{Bump, bump_vec};
891 /// # let bump: Bump = Bump::new();
892 /// let mut vec = bump_vec![in ≎ 1, 2, 3];
893 /// assert_eq!(vec.pop(), Some(3));
894 /// assert_eq!(vec, [1, 2]);
895 /// ```
896 ///
897 /// # Time complexity
898 /// Takes *O*(1) time.
899 #[inline(always)]
900 pub fn pop(&mut self) -> Option<T> {
901 unsafe { self.fixed.cook_mut() }.pop()
902 }
903
904 /// Removes and returns the last element from a vector if the predicate
905 /// returns `true`, or [`None`] if the predicate returns false or the vector
906 /// is empty (the predicate will not be called in that case).
907 ///
908 /// # Examples
909 ///
910 /// ```
911 /// # use bump_scope::{Bump, bump_vec};
912 /// # let bump: Bump = Bump::new();
913 /// let mut vec = bump_vec![in ≎ 1, 2, 3, 4];
914 /// let pred = |x: &mut i32| *x % 2 == 0;
915 ///
916 /// assert_eq!(vec.pop_if(pred), Some(4));
917 /// assert_eq!(vec, [1, 2, 3]);
918 /// assert_eq!(vec.pop_if(pred), None);
919 /// ```
920 pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
921 let last = self.last_mut()?;
922 if predicate(last) { self.pop() } else { None }
923 }
924
925 /// Clears the vector, removing all values.
926 ///
927 /// # Examples
928 /// ```
929 /// # use bump_scope::{Bump, bump_vec};
930 /// # let bump: Bump = Bump::new();
931 /// let mut vec = bump_vec![in ≎ 1, 2, 3];
932 /// vec.clear();
933 /// assert!(vec.is_empty());
934 /// ```
935 #[inline(always)]
936 pub fn clear(&mut self) {
937 unsafe { self.fixed.cook_mut() }.clear();
938 }
939
940 /// Shortens the vector, keeping the first `len` elements and dropping
941 /// the rest.
942 ///
943 /// If `len` is greater than the vector's current length, this has no
944 /// effect.
945 ///
946 /// The [`drain`] method can emulate `truncate`, but causes the excess
947 /// elements to be returned instead of dropped.
948 ///
949 /// Note that this method has no effect on the allocated capacity
950 /// of the vector.
951 ///
952 /// # Examples
953 ///
954 /// Truncating a five element vector to two elements:
955 ///
956 /// ```
957 /// # use bump_scope::{Bump, bump_vec};
958 /// # let bump: Bump = Bump::new();
959 /// #
960 /// let mut vec = bump_vec![in ≎ 1, 2, 3, 4, 5];
961 /// vec.truncate(2);
962 /// assert_eq!(vec, [1, 2]);
963 /// ```
964 ///
965 /// No truncation occurs when `len` is greater than the vector's current
966 /// length:
967 ///
968 /// ```
969 /// # use bump_scope::{Bump, bump_vec};
970 /// # let bump: Bump = Bump::new();
971 /// #
972 /// let mut vec = bump_vec![in ≎ 1, 2, 3];
973 /// vec.truncate(8);
974 /// assert_eq!(vec, [1, 2, 3]);
975 /// ```
976 ///
977 /// Truncating when `len == 0` is equivalent to calling the [`clear`]
978 /// method.
979 ///
980 /// ```
981 /// # use bump_scope::{Bump, bump_vec};
982 /// # let bump: Bump = Bump::new();
983 /// #
984 /// let mut vec = bump_vec![in ≎ 1, 2, 3];
985 /// vec.truncate(0);
986 /// assert_eq!(vec, []);
987 /// ```
988 ///
989 /// [`clear`]: Self::clear
990 /// [`drain`]: Self::drain
991 pub fn truncate(&mut self, len: usize) {
992 unsafe { self.fixed.cook_mut() }.truncate(len);
993 }
994
995 /// Removes and returns the element at position `index` within the vector,
996 /// shifting all elements after it to the left.
997 ///
998 /// Note: Because this shifts over the remaining elements, it has a
999 /// worst-case performance of *O*(*n*). If you don't need the order of elements
1000 /// to be preserved, use [`swap_remove`] instead.
1001 ///
1002 /// # Panics
1003 /// Panics if `index` is out of bounds.
1004 ///
1005 /// [`swap_remove`]: Self::swap_remove
1006 /// # Examples
1007 /// ```
1008 /// # use bump_scope::{Bump, bump_vec};
1009 /// # let bump: Bump = Bump::new();
1010 /// let mut v = bump_vec![in ≎ 1, 2, 3];
1011 /// assert_eq!(v.remove(1), 2);
1012 /// assert_eq!(v, [1, 3]);
1013 /// ```
1014 #[track_caller]
1015 pub fn remove(&mut self, index: usize) -> T {
1016 unsafe { self.fixed.cook_mut() }.remove(index)
1017 }
1018
1019 /// Removes an element from the vector and returns it.
1020 ///
1021 /// The removed element is replaced by the last element of the vector.
1022 ///
1023 /// This does not preserve ordering, but is *O*(1).
1024 /// If you need to preserve the element order, use [`remove`] instead.
1025 ///
1026 /// # Panics
1027 /// Panics if `index` is out of bounds.
1028 ///
1029 /// [`remove`]: Self::remove
1030 /// # Examples
1031 /// ```
1032 /// # use bump_scope::{Bump, bump_vec};
1033 /// # let bump: Bump = Bump::new();
1034 /// #
1035 /// let mut v = bump_vec![in ≎ "foo", "bar", "baz", "qux"];
1036 ///
1037 /// assert_eq!(v.swap_remove(1), "bar");
1038 /// assert_eq!(v, ["foo", "qux", "baz"]);
1039 ///
1040 /// assert_eq!(v.swap_remove(0), "foo");
1041 /// assert_eq!(v, ["baz", "qux"]);
1042 /// ```
1043 #[inline]
1044 pub fn swap_remove(&mut self, index: usize) -> T {
1045 unsafe { self.fixed.cook_mut() }.swap_remove(index)
1046 }
1047
1048 /// Extracts a slice containing the entire vector.
1049 ///
1050 /// Equivalent to `&s[..]`.
1051 #[must_use]
1052 #[inline(always)]
1053 pub const fn as_slice(&self) -> &[T] {
1054 unsafe { self.fixed.cook_ref() }.as_slice()
1055 }
1056
1057 /// Extracts a mutable slice containing the entire vector.
1058 ///
1059 /// Equivalent to `&mut s[..]`.
1060 #[must_use]
1061 #[inline(always)]
1062 pub fn as_mut_slice(&mut self) -> &mut [T] {
1063 unsafe { self.fixed.cook_mut() }.as_mut_slice()
1064 }
1065
1066 /// Returns a raw pointer to the slice, or a dangling raw pointer
1067 /// valid for zero sized reads.
1068 #[inline]
1069 #[must_use]
1070 pub fn as_ptr(&self) -> *const T {
1071 self.fixed.as_ptr()
1072 }
1073
1074 /// Returns an unsafe mutable pointer to slice, or a dangling
1075 /// raw pointer valid for zero sized reads.
1076 #[inline]
1077 pub fn as_mut_ptr(&mut self) -> *mut T {
1078 self.fixed.as_mut_ptr()
1079 }
1080
1081 /// Returns a `NonNull` pointer to the vector's buffer, or a dangling
1082 /// `NonNull` pointer valid for zero sized reads if the vector didn't allocate.
1083 ///
1084 /// The caller must ensure that the vector outlives the pointer this
1085 /// function returns, or else it will end up dangling.
1086 /// Modifying the vector may cause its buffer to be reallocated,
1087 /// which would also make any pointers to it invalid.
1088 ///
1089 /// This method guarantees that for the purpose of the aliasing model, this method
1090 /// does not materialize a reference to the underlying slice, and thus the returned pointer
1091 /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
1092 /// and [`as_non_null`].
1093 /// Note that calling other methods that materialize references to the slice,
1094 /// or references to specific elements you are planning on accessing through this pointer,
1095 /// may still invalidate this pointer.
1096 /// See the second example below for how this guarantee can be used.
1097 ///
1098 /// # Examples
1099 ///
1100 /// ```
1101 /// # use bump_scope::{Bump, BumpVec};
1102 /// # let bump: Bump = Bump::new();
1103 /// // Allocate vector big enough for 4 elements.
1104 /// let size = 4;
1105 /// let mut x: BumpVec<i32, _> = BumpVec::with_capacity_in(size, &bump);
1106 /// let x_ptr = x.as_non_null();
1107 ///
1108 /// // Initialize elements via raw pointer writes, then set length.
1109 /// unsafe {
1110 /// for i in 0..size {
1111 /// x_ptr.add(i).write(i as i32);
1112 /// }
1113 /// x.set_len(size);
1114 /// }
1115 /// assert_eq!(&*x, &[0, 1, 2, 3]);
1116 /// ```
1117 ///
1118 /// Due to the aliasing guarantee, the following code is legal:
1119 ///
1120 /// ```
1121 /// # use bump_scope::{Bump, bump_vec};
1122 /// # let bump: Bump = Bump::new();
1123 /// unsafe {
1124 /// let v = bump_vec![in ≎ 0];
1125 /// let ptr1 = v.as_non_null();
1126 /// ptr1.write(1);
1127 /// let ptr2 = v.as_non_null();
1128 /// ptr2.write(2);
1129 /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
1130 /// ptr1.write(3);
1131 /// }
1132 /// ```
1133 ///
1134 /// [`as_mut_ptr`]: Self::as_mut_ptr
1135 /// [`as_ptr`]: Self::as_ptr
1136 /// [`as_non_null`]: Self::as_non_null
1137 #[must_use]
1138 #[inline(always)]
1139 pub const fn as_non_null(&self) -> NonNull<T> {
1140 self.fixed.as_non_null()
1141 }
1142
1143 /// Returns a `NonNull` pointer to the vector's buffer, or a dangling
1144 /// `NonNull` pointer valid for zero sized reads if the vector didn't allocate.
1145 #[doc(hidden)]
1146 #[deprecated = "renamed to `as_non_null`"]
1147 #[must_use]
1148 #[inline(always)]
1149 pub fn as_non_null_ptr(&self) -> NonNull<T> {
1150 self.fixed.as_non_null()
1151 }
1152
1153 /// Returns a `NonNull` pointer to the vector's buffer, or a dangling
1154 /// `NonNull` pointer valid for zero sized reads if the vector didn't allocate.
1155 #[doc(hidden)]
1156 #[deprecated = "too niche; compute this yourself if needed"]
1157 #[must_use]
1158 #[inline(always)]
1159 pub fn as_non_null_slice(&self) -> NonNull<[T]> {
1160 #[expect(deprecated)]
1161 self.fixed.as_non_null_slice()
1162 }
1163
1164 /// Appends an element to the back of the collection.
1165 ///
1166 /// # Safety
1167 /// Vector must not be full.
1168 #[inline(always)]
1169 pub unsafe fn push_unchecked(&mut self, value: T) {
1170 unsafe { self.fixed.cook_mut().push_unchecked(value) };
1171 }
1172
1173 /// Appends an element to the back of the collection.
1174 ///
1175 /// # Safety
1176 /// Vector must not be full.
1177 #[inline(always)]
1178 pub unsafe fn push_with_unchecked(&mut self, f: impl FnOnce() -> T) {
1179 unsafe { self.fixed.cook_mut().push_with_unchecked(f) };
1180 }
1181
1182 /// Forces the length of the vector to `new_len`.
1183 ///
1184 /// This is a low-level operation that maintains none of the normal
1185 /// invariants of the type. Normally changing the length of a vector
1186 /// is done using one of the safe operations instead, such as
1187 /// [`resize`], [`truncate`], [`extend`], or [`clear`].
1188 ///
1189 /// # Safety
1190 /// - `new_len` must be less than or equal to the [`capacity`].
1191 /// - The elements at `old_len..new_len` must be initialized.
1192 ///
1193 /// [`resize`]: Self::resize
1194 /// [`truncate`]: Self::truncate
1195 /// [`extend`]: Self::extend
1196 /// [`clear`]: Self::clear
1197 /// [`capacity`]: Self::capacity
1198 #[inline]
1199 pub unsafe fn set_len(&mut self, new_len: usize) {
1200 unsafe { self.fixed.set_len(new_len) };
1201 }
1202
1203 #[inline]
1204 pub(crate) unsafe fn inc_len(&mut self, amount: usize) {
1205 unsafe { self.fixed.cook_mut().inc_len(amount) };
1206 }
1207
1208 /// Appends an element to the back of a collection.
1209 ///
1210 /// # Panics
1211 /// Panics if the allocation fails.
1212 ///
1213 /// # Examples
1214 /// ```
1215 /// # use bump_scope::{bump_vec, Bump};
1216 /// # let bump: Bump = Bump::new();
1217 /// let mut vec = bump_vec![in ≎ 1, 2];
1218 /// vec.push(3);
1219 /// assert_eq!(vec, [1, 2, 3]);
1220 /// ```
1221 #[inline(always)]
1222 #[cfg(feature = "panic-on-alloc")]
1223 pub fn push(&mut self, value: T) {
1224 panic_on_error(self.generic_push(value));
1225 }
1226
1227 /// Appends an element to the back of a collection.
1228 ///
1229 /// # Errors
1230 /// Errors if the allocation fails.
1231 ///
1232 /// # Examples
1233 /// ```
1234 /// # use bump_scope::{bump_vec, Bump};
1235 /// # let bump: Bump = Bump::try_new()?;
1236 /// let mut vec = bump_vec![try in ≎ 1, 2]?;
1237 /// vec.try_push(3)?;
1238 /// assert_eq!(vec, [1, 2, 3]);
1239 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1240 /// ```
1241 #[inline(always)]
1242 pub fn try_push(&mut self, value: T) -> Result<(), AllocError> {
1243 self.generic_push(value)
1244 }
1245
1246 #[inline]
1247 pub(crate) fn generic_push<E: ErrorBehavior>(&mut self, value: T) -> Result<(), E> {
1248 self.generic_push_with(|| value)
1249 }
1250
1251 /// Reserves space for one more element, then calls `f`
1252 /// to produce the value that is appended.
1253 ///
1254 /// In some cases this could be more performant than `push(f())` because it
1255 /// permits the compiler to directly place `T` in the vector instead of
1256 /// constructing it on the stack and copying it over.
1257 ///
1258 /// # Panics
1259 /// Panics if the allocation fails.
1260 ///
1261 /// # Examples
1262 /// ```
1263 /// # use bump_scope::{Bump, bump_vec};
1264 /// # let bump: Bump = Bump::new();
1265 /// let mut vec = bump_vec![in ≎ 1, 2];
1266 /// vec.push_with(|| 3);
1267 /// assert_eq!(vec, [1, 2, 3]);
1268 /// ```
1269 #[inline(always)]
1270 #[cfg(feature = "panic-on-alloc")]
1271 pub fn push_with(&mut self, f: impl FnOnce() -> T) {
1272 panic_on_error(self.generic_push_with(f));
1273 }
1274
1275 /// Reserves space for one more element, then calls `f`
1276 /// to produce the value that is appended.
1277 ///
1278 /// In some cases this could be more performant than `push(f())` because it
1279 /// permits the compiler to directly place `T` in the vector instead of
1280 /// constructing it on the stack and copying it over.
1281 ///
1282 /// # Errors
1283 /// Errors if the allocation fails.
1284 ///
1285 /// # Examples
1286 /// ```
1287 /// # use bump_scope::{Bump, bump_vec};
1288 /// # let bump: Bump = Bump::new();
1289 /// let mut vec = bump_vec![in ≎ 1, 2];
1290 /// vec.try_push_with(|| 3)?;
1291 /// assert_eq!(vec, [1, 2, 3]);
1292 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1293 /// ```
1294 #[inline(always)]
1295 pub fn try_push_with(&mut self, f: impl FnOnce() -> T) -> Result<(), AllocError> {
1296 self.generic_push_with(f)
1297 }
1298
1299 #[inline]
1300 pub(crate) fn generic_push_with<E: ErrorBehavior>(&mut self, f: impl FnOnce() -> T) -> Result<(), E> {
1301 self.generic_reserve_one()?;
1302 unsafe {
1303 self.push_with_unchecked(f);
1304 }
1305 Ok(())
1306 }
1307
1308 /// Inserts an element at position `index` within the vector, shifting all elements after it to the right.
1309 ///
1310 /// # Panics
1311 /// Panics if the allocation fails.
1312 ///
1313 /// Panics if `index > len`.
1314 ///
1315 /// # Examples
1316 /// ```
1317 /// # use bump_scope::{Bump, bump_vec};
1318 /// # let bump: Bump = Bump::new();
1319 /// let mut vec = bump_vec![in ≎ 1, 2, 3];
1320 /// vec.insert(1, 4);
1321 /// assert_eq!(vec, [1, 4, 2, 3]);
1322 /// vec.insert(4, 5);
1323 /// assert_eq!(vec, [1, 4, 2, 3, 5]);
1324 /// ```
1325 #[inline(always)]
1326 #[cfg(feature = "panic-on-alloc")]
1327 pub fn insert(&mut self, index: usize, element: T) {
1328 panic_on_error(self.generic_insert(index, element));
1329 }
1330
1331 /// Inserts an element at position `index` within the vector, shifting all elements after it to the right.
1332 ///
1333 /// # Panics
1334 /// Panics if `index > len`.
1335 ///
1336 /// # Errors
1337 /// Errors if the allocation fails.
1338 ///
1339 /// # Examples
1340 /// ```
1341 /// # use bump_scope::{Bump, bump_vec};
1342 /// # let bump: Bump = Bump::try_new()?;
1343 /// let mut vec = bump_vec![try in ≎ 1, 2, 3]?;
1344 /// vec.try_insert(1, 4)?;
1345 /// assert_eq!(vec, [1, 4, 2, 3]);
1346 /// vec.try_insert(4, 5)?;
1347 /// assert_eq!(vec, [1, 4, 2, 3, 5]);
1348 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1349 /// ```
1350 #[inline(always)]
1351 pub fn try_insert(&mut self, index: usize, element: T) -> Result<(), AllocError> {
1352 self.generic_insert(index, element)
1353 }
1354
1355 #[inline]
1356 pub(crate) fn generic_insert<E: ErrorBehavior>(&mut self, index: usize, element: T) -> Result<(), E> {
1357 #[cold]
1358 #[track_caller]
1359 #[inline(never)]
1360 fn assert_failed(index: usize, len: usize) -> ! {
1361 panic!("insertion index (is {index}) should be <= len (is {len})");
1362 }
1363
1364 if index > self.len() {
1365 assert_failed(index, self.len());
1366 }
1367
1368 self.generic_reserve_one()?;
1369
1370 unsafe {
1371 let pos = self.as_mut_ptr().add(index);
1372
1373 if index != self.len() {
1374 let len = self.len() - index;
1375 ptr::copy(pos, pos.add(1), len);
1376 }
1377
1378 pos.write(element);
1379 self.inc_len(1);
1380 }
1381
1382 Ok(())
1383 }
1384
1385 /// Copies and appends all elements in a slice to the `BumpVec`.
1386 ///
1387 /// Iterates over the `slice`, copies each element, and then appends
1388 /// it to this `BumpVec`. The `slice` is traversed in-order.
1389 ///
1390 /// Note that this function is same as [`extend`] except that it is
1391 /// specialized to work with copyable slices instead.
1392 ///
1393 /// [`extend`]: Self::extend
1394 ///
1395 /// # Panics
1396 /// Panics if the allocation fails.
1397 ///
1398 /// # Examples
1399 /// ```
1400 /// # use bump_scope::{ Bump, bump_vec };
1401 /// # let bump: Bump = Bump::new();
1402 /// let mut vec = bump_vec![in ≎ 1];
1403 /// vec.extend_from_slice_copy(&[2, 3, 4]);
1404 /// assert_eq!(vec, [1, 2, 3, 4]);
1405 /// ```
1406 #[inline(always)]
1407 #[cfg(feature = "panic-on-alloc")]
1408 pub fn extend_from_slice_copy(&mut self, slice: &[T])
1409 where
1410 T: Copy,
1411 {
1412 panic_on_error(self.generic_extend_from_slice_copy(slice));
1413 }
1414
1415 /// Copies and appends all elements in a slice to the `BumpVec`.
1416 ///
1417 /// Iterates over the `slice`, copies each element, and then appends
1418 /// it to this `BumpVec`. The `slice` is traversed in-order.
1419 ///
1420 /// Note that this function is same as [`extend`] except that it is
1421 /// specialized to work with copyable slices instead.
1422 ///
1423 /// [`extend`]: Self::extend
1424 ///
1425 /// # Errors
1426 /// Errors if the allocation fails.
1427 ///
1428 /// # Examples
1429 /// ```
1430 /// # use bump_scope::{ Bump, bump_vec };
1431 /// # let bump: Bump = Bump::new();
1432 /// let mut vec = bump_vec![try in ≎ 1]?;
1433 /// vec.try_extend_from_slice_copy(&[2, 3, 4])?;
1434 /// assert_eq!(vec, [1, 2, 3, 4]);
1435 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1436 /// ```
1437 #[inline(always)]
1438 pub fn try_extend_from_slice_copy(&mut self, slice: &[T]) -> Result<(), AllocError>
1439 where
1440 T: Copy,
1441 {
1442 self.generic_extend_from_slice_copy(slice)
1443 }
1444
1445 #[inline]
1446 pub(crate) fn generic_extend_from_slice_copy<E: ErrorBehavior>(&mut self, slice: &[T]) -> Result<(), E>
1447 where
1448 T: Copy,
1449 {
1450 unsafe { self.extend_by_copy_nonoverlapping(slice) }
1451 }
1452
1453 /// Clones and appends all elements in a slice to the `BumpVec`.
1454 ///
1455 /// Iterates over the `slice`, clones each element, and then appends
1456 /// it to this `BumpVec`. The `slice` is traversed in-order.
1457 ///
1458 /// Note that this function is same as [`extend`] except that it is
1459 /// specialized to work with slices instead.
1460 ///
1461 /// [`extend`]: Self::extend
1462 ///
1463 /// # Panics
1464 /// Panics if the allocation fails.
1465 ///
1466 /// # Examples
1467 /// ```
1468 /// # use std::string::String;
1469 /// # use bump_scope::{ Bump, bump_vec };
1470 /// # let bump: Bump = Bump::new();
1471 /// let mut vec = bump_vec![in ≎ String::from("a")];
1472 /// vec.extend_from_slice_clone(&[String::from("b"), String::from("c")]);
1473 /// assert_eq!(vec, ["a", "b", "c"]);
1474 /// ```
1475 #[inline(always)]
1476 #[cfg(feature = "panic-on-alloc")]
1477 pub fn extend_from_slice_clone(&mut self, slice: &[T])
1478 where
1479 T: Clone,
1480 {
1481 panic_on_error(self.generic_extend_from_slice_clone(slice));
1482 }
1483
1484 /// Clones and appends all elements in a slice to the `BumpVec`.
1485 ///
1486 /// Iterates over the `slice`, clones each element, and then appends
1487 /// it to this `BumpVec`. The `slice` is traversed in-order.
1488 ///
1489 /// Note that this function is same as [`extend`] except that it is
1490 /// specialized to work with slices instead.
1491 ///
1492 /// [`extend`]: Self::extend
1493 ///
1494 /// # Errors
1495 /// Errors if the allocation fails.
1496 ///
1497 /// # Examples
1498 /// ```
1499 /// # use std::string::String;
1500 /// # use bump_scope::{ Bump, bump_vec };
1501 /// # let bump: Bump = Bump::new();
1502 /// let mut vec = bump_vec![try in ≎ String::from("a")]?;
1503 /// vec.try_extend_from_slice_clone(&[String::from("b"), String::from("c")])?;
1504 /// assert_eq!(vec, ["a", "b", "c"]);
1505 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1506 /// ```
1507 #[inline(always)]
1508 pub fn try_extend_from_slice_clone(&mut self, slice: &[T]) -> Result<(), AllocError>
1509 where
1510 T: Clone,
1511 {
1512 self.generic_extend_from_slice_clone(slice)
1513 }
1514
1515 #[inline]
1516 pub(crate) fn generic_extend_from_slice_clone<E: ErrorBehavior>(&mut self, slice: &[T]) -> Result<(), E>
1517 where
1518 T: Clone,
1519 {
1520 self.generic_reserve(slice.len())?;
1521
1522 unsafe {
1523 let mut pos = 0usize;
1524
1525 while likely(pos != slice.len()) {
1526 let elem = slice.get_unchecked(pos);
1527 self.push_unchecked(elem.clone());
1528 pos += 1;
1529 }
1530 }
1531
1532 Ok(())
1533 }
1534
1535 /// Copies elements from `src` range to the end of the vector.
1536 ///
1537 /// # Panics
1538 /// Panics if the allocation fails.
1539 ///
1540 /// Panics if the starting point is greater than the end point or if
1541 /// the end point is greater than the length of the vector.
1542 ///
1543 /// # Examples
1544 /// ```
1545 /// # use bump_scope::{Bump, bump_vec};
1546 /// # let bump: Bump = Bump::new();
1547 /// let mut vec = bump_vec![in ≎ 0, 1, 2, 3, 4];
1548 ///
1549 /// vec.extend_from_within_copy(2..);
1550 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1551 ///
1552 /// vec.extend_from_within_copy(..2);
1553 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1554 ///
1555 /// vec.extend_from_within_copy(4..8);
1556 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1557 /// ```
1558 #[inline(always)]
1559 #[cfg(feature = "panic-on-alloc")]
1560 pub fn extend_from_within_copy<R>(&mut self, src: R)
1561 where
1562 T: Copy,
1563 R: RangeBounds<usize>,
1564 {
1565 panic_on_error(self.generic_extend_from_within_copy(src));
1566 }
1567
1568 /// Copies elements from `src` range to the end of the vector.
1569 ///
1570 /// # Panics
1571 /// Panics if the starting point is greater than the end point or if
1572 /// the end point is greater than the length of the vector.
1573 ///
1574 /// # Errors
1575 /// Errors if the allocation fails.
1576 ///
1577 /// # Examples
1578 /// ```
1579 /// # use bump_scope::{Bump, bump_vec};
1580 /// # let bump: Bump = Bump::try_new()?;
1581 /// let mut vec = bump_vec![try in ≎ 0, 1, 2, 3, 4]?;
1582 ///
1583 /// vec.try_extend_from_within_copy(2..)?;
1584 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1585 ///
1586 /// vec.try_extend_from_within_copy(..2)?;
1587 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1588 ///
1589 /// vec.try_extend_from_within_copy(4..8)?;
1590 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1591 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1592 /// ```
1593 #[inline(always)]
1594 pub fn try_extend_from_within_copy<R>(&mut self, src: R) -> Result<(), AllocError>
1595 where
1596 T: Copy,
1597 R: RangeBounds<usize>,
1598 {
1599 self.generic_extend_from_within_copy(src)
1600 }
1601
1602 #[inline]
1603 pub(crate) fn generic_extend_from_within_copy<E: ErrorBehavior, R>(&mut self, src: R) -> Result<(), E>
1604 where
1605 T: Copy,
1606 R: RangeBounds<usize>,
1607 {
1608 let range = slice::range(src, ..self.len());
1609 let count = range.len();
1610
1611 self.generic_reserve(count)?;
1612
1613 // SAFETY:
1614 // - `slice::range` guarantees that the given range is valid for indexing self
1615 unsafe {
1616 let ptr = self.as_mut_ptr();
1617
1618 let src = ptr.add(range.start);
1619 let dst = ptr.add(self.len());
1620 ptr::copy_nonoverlapping(src, dst, count);
1621
1622 self.inc_len(count);
1623 Ok(())
1624 }
1625 }
1626
1627 /// Clones elements from `src` range to the end of the vector.
1628 ///
1629 /// # Panics
1630 /// Panics if the allocation fails.
1631 ///
1632 /// Panics if the starting point is greater than the end point or if
1633 /// the end point is greater than the length of the vector.
1634 ///
1635 /// # Examples
1636 /// ```
1637 /// # use bump_scope::{Bump, bump_vec};
1638 /// # let bump: Bump = Bump::new();
1639 /// let mut vec = bump_vec![in ≎ 0, 1, 2, 3, 4];
1640 ///
1641 /// vec.extend_from_within_clone(2..);
1642 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1643 ///
1644 /// vec.extend_from_within_clone(..2);
1645 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1646 ///
1647 /// vec.extend_from_within_clone(4..8);
1648 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1649 /// ```
1650 #[inline(always)]
1651 #[cfg(feature = "panic-on-alloc")]
1652 pub fn extend_from_within_clone<R>(&mut self, src: R)
1653 where
1654 T: Clone,
1655 R: RangeBounds<usize>,
1656 {
1657 panic_on_error(self.generic_extend_from_within_clone(src));
1658 }
1659
1660 /// Clones elements from `src` range to the end of the vector.
1661 ///
1662 /// # Panics
1663 /// Panics if the starting point is greater than the end point or if
1664 /// the end point is greater than the length of the vector.
1665 ///
1666 /// # Errors
1667 /// Errors if the allocation fails.
1668 ///
1669 /// # Examples
1670 /// ```
1671 /// # use bump_scope::{Bump, bump_vec};
1672 /// # let bump: Bump = Bump::try_new()?;
1673 /// let mut vec = bump_vec![try in ≎ 0, 1, 2, 3, 4]?;
1674 ///
1675 /// vec.try_extend_from_within_clone(2..)?;
1676 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1677 ///
1678 /// vec.try_extend_from_within_clone(..2)?;
1679 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1680 ///
1681 /// vec.try_extend_from_within_clone(4..8)?;
1682 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1683 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1684 /// ```
1685 #[inline(always)]
1686 pub fn try_extend_from_within_clone<R>(&mut self, src: R) -> Result<(), AllocError>
1687 where
1688 T: Clone,
1689 R: RangeBounds<usize>,
1690 {
1691 self.generic_extend_from_within_clone(src)
1692 }
1693
1694 #[inline]
1695 pub(crate) fn generic_extend_from_within_clone<E: ErrorBehavior, R>(&mut self, src: R) -> Result<(), E>
1696 where
1697 T: Clone,
1698 R: RangeBounds<usize>,
1699 {
1700 let range = slice::range(src, ..self.len());
1701 let count = range.len();
1702
1703 self.generic_reserve(count)?;
1704
1705 if T::IS_ZST {
1706 unsafe {
1707 // We can materialize ZST's from nothing.
1708 #[expect(clippy::uninit_assumed_init)]
1709 let fake = ManuallyDrop::new(MaybeUninit::<T>::uninit().assume_init());
1710
1711 for _ in 0..count {
1712 self.push_unchecked((*fake).clone());
1713 }
1714
1715 return Ok(());
1716 }
1717 }
1718
1719 // SAFETY:
1720 // - `slice::range` guarantees that the given range is valid for indexing self
1721 unsafe {
1722 let ptr = self.as_mut_ptr();
1723
1724 let mut src = ptr.add(range.start);
1725 let mut dst = ptr.add(self.len());
1726
1727 let src_end = src.add(count);
1728
1729 while src != src_end {
1730 dst.write((*src).clone());
1731
1732 src = src.add(1);
1733 dst = dst.add(1);
1734 self.inc_len(1);
1735 }
1736 }
1737
1738 Ok(())
1739 }
1740
1741 /// Reserves capacity for at least `additional` more elements to be inserted
1742 /// in the given `BumpVec<T>`. The collection may reserve more space to
1743 /// speculatively avoid frequent reallocations. After calling `reserve`,
1744 /// capacity will be greater than or equal to `self.len() + additional`.
1745 /// Does nothing if capacity is already sufficient.
1746 ///
1747 /// # Panics
1748 /// Panics if the allocation fails.
1749 ///
1750 /// # Examples
1751 /// ```
1752 /// # use bump_scope::{Bump, bump_vec};
1753 /// # let bump: Bump = Bump::new();
1754 /// let mut vec = bump_vec![in ≎ 1];
1755 /// vec.reserve(10);
1756 /// assert!(vec.capacity() >= 11);
1757 /// ```
1758 #[inline(always)]
1759 #[cfg(feature = "panic-on-alloc")]
1760 pub fn reserve(&mut self, additional: usize) {
1761 panic_on_error(self.generic_reserve(additional));
1762 }
1763
1764 /// Reserves capacity for at least `additional` more elements to be inserted
1765 /// in the given `BumpVec<T>`. The collection may reserve more space to
1766 /// speculatively avoid frequent reallocations. After calling `reserve`,
1767 /// capacity will be greater than or equal to `self.len() + additional`.
1768 /// Does nothing if capacity is already sufficient.
1769 ///
1770 /// # Errors
1771 /// Errors if the allocation fails.
1772 ///
1773 /// # Examples
1774 /// ```
1775 /// # use bump_scope::{Bump, bump_vec};
1776 /// # let bump: Bump = Bump::try_new()?;
1777 /// let mut vec = bump_vec![try in ≎ 1]?;
1778 /// vec.try_reserve(10)?;
1779 /// assert!(vec.capacity() >= 11);
1780 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1781 /// ```
1782 #[inline(always)]
1783 pub fn try_reserve(&mut self, additional: usize) -> Result<(), AllocError> {
1784 self.generic_reserve(additional)
1785 }
1786
1787 #[inline]
1788 pub(crate) fn generic_reserve<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
1789 if additional > (self.capacity() - self.len()) {
1790 self.generic_grow_amortized(additional)?;
1791 }
1792
1793 Ok(())
1794 }
1795
1796 /// Reserves the minimum capacity for at least `additional` more elements to
1797 /// be inserted in the given `BumpVec<T>`. Unlike [`reserve`], this will not
1798 /// deliberately over-allocate to speculatively avoid frequent allocations.
1799 /// After calling `reserve_exact`, capacity will be greater than or equal to
1800 /// `self.len() + additional`. Does nothing if the capacity is already
1801 /// sufficient.
1802 ///
1803 /// Note that the allocator may give the collection more space than it
1804 /// requests. Therefore, capacity cannot be relied upon to be precisely
1805 /// minimal. Prefer [`reserve`] if future insertions are expected.
1806 ///
1807 /// [`reserve`]: Self::reserve
1808 ///
1809 /// # Panics
1810 /// Panics if the allocation fails.
1811 ///
1812 /// # Examples
1813 /// ```
1814 /// # use bump_scope::{Bump, bump_vec};
1815 /// # let bump: Bump = Bump::new();
1816 /// let mut vec = bump_vec![in ≎ 1];
1817 /// vec.reserve_exact(10);
1818 /// assert!(vec.capacity() >= 11);
1819 /// ```
1820 #[inline(always)]
1821 #[cfg(feature = "panic-on-alloc")]
1822 pub fn reserve_exact(&mut self, additional: usize) {
1823 panic_on_error(self.generic_reserve_exact(additional));
1824 }
1825
1826 /// Reserves the minimum capacity for at least `additional` more elements to
1827 /// be inserted in the given `BumpVec<T>`. Unlike [`reserve`], this will not
1828 /// deliberately over-allocate to speculatively avoid frequent allocations.
1829 /// After calling `reserve_exact`, capacity will be greater than or equal to
1830 /// `self.len() + additional`. Does nothing if the capacity is already
1831 /// sufficient.
1832 ///
1833 /// Note that the allocator may give the collection more space than it
1834 /// requests. Therefore, capacity cannot be relied upon to be precisely
1835 /// minimal. Prefer [`reserve`] if future insertions are expected.
1836 ///
1837 /// [`reserve`]: Self::reserve
1838 ///
1839 /// # Errors
1840 /// Errors if the allocation fails.
1841 ///
1842 /// # Examples
1843 /// ```
1844 /// # use bump_scope::{Bump, bump_vec};
1845 /// # let bump: Bump = Bump::try_new()?;
1846 /// let mut vec = bump_vec![try in ≎ 1]?;
1847 /// vec.try_reserve_exact(10)?;
1848 /// assert!(vec.capacity() >= 11);
1849 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1850 /// ```
1851 #[inline(always)]
1852 pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), AllocError> {
1853 self.generic_reserve_exact(additional)
1854 }
1855
1856 #[inline]
1857 pub(crate) fn generic_reserve_exact<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
1858 if additional > (self.capacity() - self.len()) {
1859 self.generic_grow_exact(additional)?;
1860 }
1861
1862 Ok(())
1863 }
1864
1865 /// Resizes the `BumpVec` in-place so that `len` is equal to `new_len`.
1866 ///
1867 /// If `new_len` is greater than `len`, the `BumpVec` is extended by the
1868 /// difference, with each additional slot filled with `value`.
1869 /// If `new_len` is less than `len`, the `BumpVec` is simply truncated.
1870 ///
1871 /// This method requires `T` to implement [`Clone`],
1872 /// in order to be able to clone the passed value.
1873 /// If you need more flexibility (or want to rely on [`Default`] instead of
1874 /// [`Clone`]), use [`resize_with`].
1875 /// If you only need to resize to a smaller size, use [`truncate`].
1876 ///
1877 /// [`resize_with`]: Self::resize_with
1878 /// [`truncate`]: Self::truncate
1879 ///
1880 /// # Panics
1881 /// Panics if the allocation fails.
1882 ///
1883 /// # Examples
1884 /// ```
1885 /// # use bump_scope::{Bump, bump_vec};
1886 /// # let bump: Bump = Bump::new();
1887 /// let mut vec = bump_vec![in ≎ "hello"];
1888 /// vec.resize(3, "world");
1889 /// assert_eq!(vec, ["hello", "world", "world"]);
1890 /// drop(vec);
1891 ///
1892 /// let mut vec = bump_vec![in ≎ 1, 2, 3, 4];
1893 /// vec.resize(2, 0);
1894 /// assert_eq!(vec, [1, 2]);
1895 /// ```
1896 #[inline(always)]
1897 #[cfg(feature = "panic-on-alloc")]
1898 pub fn resize(&mut self, new_len: usize, value: T)
1899 where
1900 T: Clone,
1901 {
1902 panic_on_error(self.generic_resize(new_len, value));
1903 }
1904
1905 /// Resizes the `BumpVec` in-place so that `len` is equal to `new_len`.
1906 ///
1907 /// If `new_len` is greater than `len`, the `BumpVec` is extended by the
1908 /// difference, with each additional slot filled with `value`.
1909 /// If `new_len` is less than `len`, the `BumpVec` is simply truncated.
1910 ///
1911 /// This method requires `T` to implement [`Clone`],
1912 /// in order to be able to clone the passed value.
1913 /// If you need more flexibility (or want to rely on [`Default`] instead of
1914 /// [`Clone`]), use [`resize_with`].
1915 /// If you only need to resize to a smaller size, use [`truncate`].
1916 ///
1917 /// [`resize_with`]: Self::resize_with
1918 /// [`truncate`]: Self::truncate
1919 ///
1920 /// # Errors
1921 /// Errors if the allocation fails.
1922 ///
1923 /// # Examples
1924 /// ```
1925 /// # use bump_scope::{Bump, bump_vec};
1926 /// # let bump: Bump = Bump::try_new()?;
1927 /// let mut vec = bump_vec![try in ≎ "hello"]?;
1928 /// vec.try_resize(3, "world")?;
1929 /// assert_eq!(vec, ["hello", "world", "world"]);
1930 /// drop(vec);
1931 ///
1932 /// let mut vec = bump_vec![try in ≎ 1, 2, 3, 4]?;
1933 /// vec.try_resize(2, 0)?;
1934 /// assert_eq!(vec, [1, 2]);
1935 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1936 /// ```
1937 #[inline(always)]
1938 pub fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), AllocError>
1939 where
1940 T: Clone,
1941 {
1942 self.generic_resize(new_len, value)
1943 }
1944
1945 #[inline]
1946 pub(crate) fn generic_resize<E: ErrorBehavior>(&mut self, new_len: usize, value: T) -> Result<(), E>
1947 where
1948 T: Clone,
1949 {
1950 let len = self.len();
1951
1952 if new_len > len {
1953 self.extend_with(new_len - len, value)
1954 } else {
1955 self.truncate(new_len);
1956 Ok(())
1957 }
1958 }
1959
1960 /// Resizes the `BumpVec` in-place so that `len` is equal to `new_len`.
1961 ///
1962 /// If `new_len` is greater than `len`, the `BumpVec` is extended by the
1963 /// difference, with each additional slot filled with the result of
1964 /// calling the closure `f`. The return values from `f` will end up
1965 /// in the `BumpVec` in the order they have been generated.
1966 ///
1967 /// If `new_len` is less than `len`, the `BumpVec` is simply truncated.
1968 ///
1969 /// This method uses a closure to create new values on every push. If
1970 /// you'd rather [`Clone`] a given value, use [`BumpVec::resize`]. If you
1971 /// want to use the [`Default`] trait to generate values, you can
1972 /// pass [`Default::default`] as the second argument.
1973 ///
1974 /// # Panics
1975 /// Panics if the allocation fails.
1976 ///
1977 /// # Examples
1978 /// ```
1979 /// # use bump_scope::{Bump, bump_vec};
1980 /// # let bump: Bump = Bump::new();
1981 /// let mut vec = bump_vec![in ≎ 1, 2, 3];
1982 /// vec.resize_with(5, Default::default);
1983 /// assert_eq!(vec, [1, 2, 3, 0, 0]);
1984 /// drop(vec);
1985 ///
1986 /// let mut vec = bump_vec![in &bump];
1987 /// let mut p = 1;
1988 /// vec.resize_with(4, || { p *= 2; p });
1989 /// assert_eq!(vec, [2, 4, 8, 16]);
1990 /// ```
1991 #[inline(always)]
1992 #[cfg(feature = "panic-on-alloc")]
1993 pub fn resize_with<F>(&mut self, new_len: usize, f: F)
1994 where
1995 F: FnMut() -> T,
1996 {
1997 panic_on_error(self.generic_resize_with(new_len, f));
1998 }
1999
2000 /// Resizes the `BumpVec` in-place so that `len` is equal to `new_len`.
2001 ///
2002 /// If `new_len` is greater than `len`, the `BumpVec` is extended by the
2003 /// difference, with each additional slot filled with the result of
2004 /// calling the closure `f`. The return values from `f` will end up
2005 /// in the `BumpVec` in the order they have been generated.
2006 ///
2007 /// If `new_len` is less than `len`, the `BumpVec` is simply truncated.
2008 ///
2009 /// This method uses a closure to create new values on every push. If
2010 /// you'd rather [`Clone`] a given value, use [`BumpVec::resize`]. If you
2011 /// want to use the [`Default`] trait to generate values, you can
2012 /// pass [`Default::default`] as the second argument.
2013 ///
2014 /// # Errors
2015 /// Errors if the allocation fails.
2016 ///
2017 /// # Examples
2018 /// ```
2019 /// # use bump_scope::{Bump, bump_vec};
2020 /// # let bump: Bump = Bump::try_new()?;
2021 /// let mut vec = bump_vec![try in ≎ 1, 2, 3]?;
2022 /// vec.try_resize_with(5, Default::default)?;
2023 /// assert_eq!(vec, [1, 2, 3, 0, 0]);
2024 /// drop(vec);
2025 ///
2026 /// let mut vec = bump_vec![try in &bump]?;
2027 /// let mut p = 1;
2028 /// vec.try_resize_with(4, || { p *= 2; p })?;
2029 /// assert_eq!(vec, [2, 4, 8, 16]);
2030 /// # Ok::<(), bump_scope::alloc::AllocError>(())
2031 /// ```
2032 #[inline(always)]
2033 pub fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), AllocError>
2034 where
2035 F: FnMut() -> T,
2036 {
2037 self.generic_resize_with(new_len, f)
2038 }
2039
2040 #[inline]
2041 pub(crate) fn generic_resize_with<E: ErrorBehavior, F>(&mut self, new_len: usize, f: F) -> Result<(), E>
2042 where
2043 F: FnMut() -> T,
2044 {
2045 let len = self.len();
2046 if new_len > len {
2047 unsafe { self.extend_trusted(iter::repeat_with(f).take(new_len - len)) }
2048 } else {
2049 self.truncate(new_len);
2050 Ok(())
2051 }
2052 }
2053
2054 /// Moves all the elements of `other` into `self`, leaving `other` empty.
2055 ///
2056 /// # Panics
2057 /// Panics if the allocation fails.
2058 ///
2059 /// # Examples
2060 /// ```
2061 /// # use bump_scope::{Bump, BumpVec};
2062 /// # let bump: Bump = Bump::new();
2063 /// let mut vec = BumpVec::new_in(&bump);
2064 ///
2065 /// // append by value
2066 /// vec.append([1, 2]);
2067 /// vec.append(vec![3, 4]);
2068 /// vec.append(bump.alloc_iter(5..=6));
2069 ///
2070 /// // append by mutable reference
2071 /// let mut other = vec![7, 8];
2072 /// vec.append(&mut other);
2073 ///
2074 /// assert_eq!(other, []);
2075 /// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]);
2076 /// ```
2077 #[inline(always)]
2078 #[cfg(feature = "panic-on-alloc")]
2079 pub fn append(&mut self, other: impl OwnedSlice<Item = T>) {
2080 panic_on_error(self.generic_append(other));
2081 }
2082
2083 /// Moves all the elements of `other` into `self`, leaving `other` empty.
2084 ///
2085 /// # Errors
2086 /// Errors if the allocation fails.
2087 ///
2088 /// # Examples
2089 /// ```
2090 /// # use bump_scope::{Bump, BumpVec};
2091 /// # let bump: Bump = Bump::new();
2092 /// let mut vec = BumpVec::new_in(&bump);
2093 ///
2094 /// // append by value
2095 /// vec.try_append([1, 2])?;
2096 /// vec.try_append(vec![3, 4])?;
2097 /// vec.try_append(bump.alloc_iter(5..=6))?;
2098 ///
2099 /// // append by mutable reference
2100 /// let mut other = vec![7, 8];
2101 /// vec.try_append(&mut other)?;
2102 ///
2103 /// assert_eq!(other, []);
2104 /// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]);
2105 /// # Ok::<(), bump_scope::alloc::AllocError>(())
2106 /// ```
2107 #[inline(always)]
2108 pub fn try_append(&mut self, other: impl OwnedSlice<Item = T>) -> Result<(), AllocError> {
2109 self.generic_append(other)
2110 }
2111
2112 #[inline]
2113 pub(crate) fn generic_append<E: ErrorBehavior>(&mut self, other: impl OwnedSlice<Item = T>) -> Result<(), E> {
2114 unsafe {
2115 let mut owned_slice = other.into_take_owned_slice();
2116
2117 let slice = NonNull::from(owned_slice.owned_slice_ref());
2118 self.generic_reserve(slice.len())?;
2119
2120 let src = slice.cast::<T>().as_ptr();
2121 let dst = self.as_mut_ptr().add(self.len());
2122 ptr::copy_nonoverlapping(src, dst, slice.len());
2123
2124 owned_slice.take_owned_slice();
2125 self.inc_len(slice.len());
2126 Ok(())
2127 }
2128 }
2129
2130 /// Returns a vector of the same size as `self`, with function `f` applied to each element in order.
2131 ///
2132 /// Compared to `from_iter_in(into_iter().map(f), ...)` this method has the advantage that it can reuse the existing allocation.
2133 ///
2134 /// # Panics
2135 /// Panics if the allocation fails. An allocation only occurs when the alignment or size of `U` is greater than that of `T`.
2136 ///
2137 /// # Examples
2138 /// Mapping to a type with an equal alignment and size (no allocation):
2139 /// ```
2140 /// # use bump_scope::{Bump, BumpVec};
2141 /// # use core::num::NonZero;
2142 /// # let bump: Bump = Bump::new();
2143 /// let a = BumpVec::from_iter_exact_in([0, 1, 2], &bump);
2144 /// let b = a.map(NonZero::new);
2145 /// assert_eq!(format!("{b:?}"), "[None, Some(1), Some(2)]");
2146 /// ```
2147 ///
2148 /// Mapping to a type with a smaller alignment and size (no allocation, capacity may grow):
2149 /// ```
2150 /// # use bump_scope::{Bump, BumpVec};
2151 /// # let bump: Bump = Bump::new();
2152 /// let vec_a: BumpVec<u32, _> = BumpVec::from_iter_in([1, 2, 3, 4], &bump);
2153 /// assert_eq!(vec_a.capacity(), 4);
2154 /// assert_eq!(bump.stats().allocated(), 4 * 4);
2155 ///
2156 /// let vec_b: BumpVec<u16, _> = vec_a.map(|i| i as u16);
2157 /// assert_eq!(vec_b.capacity(), 8);
2158 /// assert_eq!(bump.stats().allocated(), 4 * 4);
2159 /// ```
2160 ///
2161 /// Mapping to a type with a higher alignment or size is equivalent to
2162 /// calling `from_iter_in(into_iter().map(f), ...)`:
2163 /// ```
2164 /// # use bump_scope::{Bump, BumpVec};
2165 /// # let bump: Bump = Bump::new();
2166 /// let vec_a: BumpVec<u16, _> = BumpVec::from_iter_in([1, 2, 3, 4], &bump);
2167 /// assert_eq!(vec_a.capacity(), 4);
2168 /// assert_eq!(bump.stats().allocated(), 4 * 2);
2169 ///
2170 /// let vec_b: BumpVec<u32, _> = vec_a.map(|i| i as u32);
2171 /// assert_eq!(vec_b.capacity(), 4);
2172 /// assert_eq!(bump.stats().allocated(), 4 * 2 + 4 * 4);
2173 /// ```
2174 #[inline(always)]
2175 #[cfg(feature = "panic-on-alloc")]
2176 pub fn map<U>(self, f: impl FnMut(T) -> U) -> BumpVec<U, A>
2177 where
2178 A: Clone,
2179 {
2180 panic_on_error(self.generic_map(f))
2181 }
2182
2183 /// Returns a vector of the same size as `self`, with function `f` applied to each element in order.
2184 ///
2185 /// Compared to `try_from_iter_in(into_iter().map(f), ...)` this method has the advantage that it can reuse the existing allocation.
2186 ///
2187 /// # Errors
2188 /// Errors if the allocation fails. An allocation can only occurs when the alignment or size of `U` is greater than that of `T`.
2189 ///
2190 /// # Examples
2191 /// Mapping to a type with an equal alignment and size (no allocation):
2192 /// ```
2193 /// # use bump_scope::{Bump, BumpVec};
2194 /// # use core::num::NonZero;
2195 /// # let bump: Bump = Bump::try_new()?;
2196 /// let a = BumpVec::try_from_iter_exact_in([0, 1, 2], &bump)?;
2197 /// let b = a.try_map(NonZero::new)?;
2198 /// assert_eq!(format!("{b:?}"), "[None, Some(1), Some(2)]");
2199 /// # Ok::<(), bump_scope::alloc::AllocError>(())
2200 /// ```
2201 ///
2202 /// Mapping to a type with a smaller alignment and size (no allocation, capacity may grow):
2203 /// ```
2204 /// # use bump_scope::{Bump, BumpVec};
2205 /// # let bump: Bump = Bump::try_new()?;
2206 /// let vec_a: BumpVec<u32, _> = BumpVec::try_from_iter_in([1, 2, 3, 4], &bump)?;
2207 /// assert_eq!(vec_a.capacity(), 4);
2208 /// assert_eq!(bump.stats().allocated(), 4 * 4);
2209 ///
2210 /// let vec_b: BumpVec<u16, _> = vec_a.try_map(|i| i as u16)?;
2211 /// assert_eq!(vec_b.capacity(), 8);
2212 /// assert_eq!(bump.stats().allocated(), 4 * 4);
2213 /// # Ok::<(), bump_scope::alloc::AllocError>(())
2214 /// ```
2215 ///
2216 /// Mapping to a type with a higher alignment or size is equivalent to
2217 /// calling `try_from_iter_in(into_iter().map(f), ...)`:
2218 /// ```
2219 /// # use bump_scope::{Bump, BumpVec};
2220 /// # let bump: Bump = Bump::try_new()?;
2221 /// let vec_a: BumpVec<u16, _> = BumpVec::try_from_iter_in([1, 2, 3, 4], &bump)?;
2222 /// assert_eq!(vec_a.capacity(), 4);
2223 /// assert_eq!(bump.stats().allocated(), 4 * 2);
2224 ///
2225 /// let vec_b: BumpVec<u32, _> = vec_a.try_map(|i| i as u32)?;
2226 /// assert_eq!(vec_b.capacity(), 4);
2227 /// assert_eq!(bump.stats().allocated(), 4 * 2 + 4 * 4);
2228 /// # Ok::<(), bump_scope::alloc::AllocError>(())
2229 /// ```
2230 #[inline(always)]
2231 pub fn try_map<U>(self, f: impl FnMut(T) -> U) -> Result<BumpVec<U, A>, AllocError>
2232 where
2233 A: Clone,
2234 {
2235 self.generic_map(f)
2236 }
2237
2238 #[inline]
2239 fn generic_map<B: ErrorBehavior, U>(self, mut f: impl FnMut(T) -> U) -> Result<BumpVec<U, A>, B>
2240 where
2241 A: Clone,
2242 {
2243 if !T::IS_ZST && !U::IS_ZST && T::ALIGN >= U::ALIGN && T::SIZE >= U::SIZE {
2244 struct DropGuard<T, U, A: BumpAllocatorExt> {
2245 ptr: NonNull<T>,
2246 cap: usize,
2247 end: *mut T,
2248 src: *mut T,
2249 dst: *mut U,
2250 allocator: A,
2251 }
2252
2253 impl<T, U, A: BumpAllocatorExt> DropGuard<T, U, A> {
2254 fn into_allocator(self) -> A {
2255 destructure!(let Self { allocator } = self);
2256 allocator
2257 }
2258 }
2259
2260 impl<T, U, A: BumpAllocatorExt> Drop for DropGuard<T, U, A> {
2261 fn drop(&mut self) {
2262 unsafe {
2263 // drop `T`s
2264 let drop_ptr = self.src.add(1);
2265 let drop_len = pointer::offset_from_unsigned(self.end, drop_ptr);
2266 ptr::slice_from_raw_parts_mut(drop_ptr, drop_len).drop_in_place();
2267
2268 // drop `U`s
2269 let drop_ptr = self.ptr.as_ptr().cast::<U>();
2270 let drop_len = pointer::offset_from_unsigned(self.dst, drop_ptr);
2271 ptr::slice_from_raw_parts_mut(drop_ptr, drop_len).drop_in_place();
2272
2273 // deallocate memory block (for additional safety notes see `Self::drop::DropGuard::drop`)
2274 let layout = Layout::from_size_align_unchecked(self.cap * T::SIZE, T::ALIGN);
2275 self.allocator.deallocate(self.ptr.cast(), layout);
2276 }
2277 }
2278 }
2279
2280 destructure!(let Self { fixed, allocator } = self);
2281 let cap = fixed.capacity();
2282 let slice = unsafe { fixed.cook() }.into_boxed_slice().into_raw();
2283 let ptr = slice.cast::<T>();
2284 let len = slice.len();
2285
2286 unsafe {
2287 let mut guard = DropGuard::<T, U, A> {
2288 ptr,
2289 cap,
2290 end: ptr.as_ptr().add(len),
2291 src: ptr.as_ptr(),
2292 dst: ptr.as_ptr().cast(),
2293 allocator,
2294 };
2295
2296 while guard.src < guard.end {
2297 let src_value = guard.src.read();
2298 let dst_value = f(src_value);
2299 guard.dst.write(dst_value);
2300 guard.src = guard.src.add(1);
2301 guard.dst = guard.dst.add(1);
2302 }
2303
2304 let allocator = guard.into_allocator();
2305 let new_cap = (cap * T::SIZE) / U::SIZE;
2306
2307 Ok(BumpVec {
2308 fixed: RawFixedBumpVec::from_raw_parts(NonNull::slice_from_raw_parts(ptr.cast(), len), new_cap),
2309 allocator,
2310 })
2311 }
2312 } else {
2313 // fallback
2314 let allocator = self.allocator.clone();
2315 Ok(BumpVec::generic_from_iter_exact_in(self.into_iter().map(f), allocator)?)
2316 }
2317 }
2318
2319 /// Returns a vector of the same size as `self`, with function `f` applied to each element in order.
2320 ///
2321 /// 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.
2322 ///
2323 /// # Examples
2324 /// Mapping to a type with an equal alignment and size:
2325 /// ```
2326 /// # use bump_scope::{Bump, BumpVec};
2327 /// # use core::num::NonZero;
2328 /// # let bump: Bump = Bump::new();
2329 /// let a = BumpVec::from_iter_exact_in([0, 1, 2], &bump);
2330 /// let b = a.map_in_place(NonZero::new);
2331 /// assert_eq!(format!("{b:?}"), "[None, Some(1), Some(2)]");
2332 /// ```
2333 ///
2334 /// Mapping to a type with a smaller alignment and size:
2335 /// ```
2336 /// # use bump_scope::{Bump, BumpVec};
2337 /// # let bump: Bump = Bump::new();
2338 /// let a: BumpVec<u32, _> = BumpVec::from_iter_exact_in([0, 1, 2], &bump);
2339 /// assert_eq!(a.capacity(), 3);
2340 ///
2341 /// let b: BumpVec<u16, _> = a.map_in_place(|i| i as u16);
2342 /// assert_eq!(b.capacity(), 6);
2343 ///
2344 /// assert_eq!(b, [0, 1, 2]);
2345 /// ```
2346 ///
2347 /// Mapping to a type with a greater alignment or size won't compile:
2348 /// ```compile_fail,E0080
2349 /// # use bump_scope::{Bump, BumpVec};
2350 /// # let bump: Bump = Bump::new();
2351 /// let a: BumpVec<u16, _> = BumpVec::from_iter_exact_in([0, 1, 2], &bump);
2352 /// let b: BumpVec<u32, _> = a.map_in_place(|i| i as u32);
2353 /// # _ = b;
2354 /// ```
2355 ///
2356 /// Mapping to a type with a greater size won't compile:
2357 /// ```compile_fail,E0080
2358 /// # use bump_scope::{Bump, BumpVec};
2359 /// # let bump: Bump = Bump::new();
2360 /// let a: BumpVec<u32, _> = BumpVec::from_iter_exact_in([42], &bump);
2361 /// let b: BumpVec<[u32; 2], _> = a.map_in_place(|i| [i; 2]);
2362 /// # _ = b;
2363 /// ```
2364 pub fn map_in_place<U>(self, f: impl FnMut(T) -> U) -> BumpVec<U, A> {
2365 destructure!(let Self { fixed, allocator } = self);
2366
2367 // `FixedBumpVec::map_in_place` handles dropping `T`s and `U`s on panic.
2368 // What is left to do is deallocating the memory.
2369
2370 struct DropGuard<T, A: BumpAllocatorExt> {
2371 ptr: NonNull<T>,
2372 cap: usize,
2373 allocator: A,
2374 }
2375
2376 impl<T, A: BumpAllocatorExt> DropGuard<T, A> {
2377 fn into_allocator(self) -> A {
2378 destructure!(let Self { allocator } = self);
2379 allocator
2380 }
2381 }
2382
2383 impl<T, A: BumpAllocatorExt> Drop for DropGuard<T, A> {
2384 fn drop(&mut self) {
2385 unsafe {
2386 let layout = Layout::from_size_align_unchecked(self.cap * T::SIZE, T::ALIGN);
2387 self.allocator.deallocate(self.ptr.cast(), layout);
2388 }
2389 }
2390 }
2391
2392 let guard = DropGuard::<T, _> {
2393 ptr: fixed.as_non_null(),
2394 cap: fixed.capacity(),
2395 allocator,
2396 };
2397
2398 let fixed = unsafe { RawFixedBumpVec::from_cooked(fixed.cook().map_in_place(f)) };
2399 let allocator = guard.into_allocator();
2400
2401 BumpVec { fixed, allocator }
2402 }
2403
2404 /// Creates a splicing iterator that replaces the specified range in the vector
2405 /// with the given `replace_with` iterator and yields the removed items.
2406 /// `replace_with` does not need to be the same length as `range`.
2407 ///
2408 /// `range` is removed even if the iterator is not consumed until the end.
2409 ///
2410 /// It is unspecified how many elements are removed from the vector
2411 /// if the `Splice` value is leaked.
2412 ///
2413 /// The input iterator `replace_with` is only consumed when the `Splice` value is dropped.
2414 ///
2415 /// This is optimal if:
2416 ///
2417 /// * The tail (elements in the vector after `range`) is empty,
2418 /// * or `replace_with` yields fewer or equal elements than `range`’s length
2419 /// * or the lower bound of its `size_hint()` is exact.
2420 ///
2421 /// Otherwise, a temporary vector is allocated and the tail is moved twice.
2422 ///
2423 /// # Panics
2424 ///
2425 /// Panics if the starting point is greater than the end point or if
2426 /// the end point is greater than the length of the vector.
2427 ///
2428 /// # Examples
2429 ///
2430 /// ```
2431 /// # use bump_scope::{Bump, bump_vec};
2432 /// # let bump: Bump = Bump::new();
2433 /// let mut v = bump_vec![in ≎ 1, 2, 3, 4];
2434 /// let new = [7, 8, 9];
2435 /// let u = bump.alloc_iter(v.splice(1..3, new));
2436 /// assert_eq!(v, [1, 7, 8, 9, 4]);
2437 /// assert_eq!(u, [2, 3]);
2438 /// ```
2439 #[cfg(feature = "panic-on-alloc")]
2440 #[inline]
2441 pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter, A>
2442 where
2443 R: RangeBounds<usize>,
2444 I: IntoIterator<Item = T>,
2445 {
2446 // Memory safety
2447 //
2448 // When the Drain is first created, it shortens the length of
2449 // the source vector to make sure no uninitialized or moved-from elements
2450 // are accessible at all if the Drain's destructor never gets to run.
2451 //
2452 // Drain will ptr::read out the values to remove.
2453 // When finished, remaining tail of the vec is copied back to cover
2454 // the hole, and the vector length is restored to the new length.
2455
2456 use core::ops::Range;
2457 let len = self.len();
2458 let Range { start, end } = slice::range(range, ..len);
2459
2460 let drain = unsafe {
2461 // set self.vec length's to start, to be safe in case Drain is leaked
2462 self.set_len(start);
2463 let range_slice = slice::from_raw_parts(self.as_ptr().add(start), end - start);
2464
2465 Drain {
2466 tail_start: end,
2467 tail_len: len - end,
2468 iter: range_slice.iter(),
2469 vec: NonNull::from(self),
2470 }
2471 };
2472
2473 Splice {
2474 drain,
2475 replace_with: replace_with.into_iter(),
2476 }
2477 }
2478
2479 /// Like [`reserve`] but allows you to provide a different `len`.
2480 ///
2481 /// This helps with algorithms from the standard library that make use of
2482 /// `RawVec::reserve` which behaves the same.
2483 ///
2484 /// # Safety
2485 ///
2486 /// - `len` must be less than or equal to `self.capacity()`
2487 ///
2488 /// [`reserve`]: Self::reserve
2489 #[inline(always)]
2490 #[cfg(feature = "panic-on-alloc")]
2491 pub(crate) unsafe fn buf_reserve(&mut self, len: usize, additional: usize) {
2492 unsafe {
2493 if additional > (self.capacity() - len) {
2494 panic_on_error(self.generic_grow_amortized_buf(len, additional));
2495 }
2496 }
2497 }
2498
2499 /// Extend the vector by `n` clones of value.
2500 fn extend_with<B: ErrorBehavior>(&mut self, n: usize, value: T) -> Result<(), B>
2501 where
2502 T: Clone,
2503 {
2504 self.generic_reserve(n)?;
2505 unsafe {
2506 self.fixed.cook_mut().extend_with_unchecked(n, value);
2507 }
2508 Ok(())
2509 }
2510
2511 #[inline(always)]
2512 unsafe fn extend_by_copy_nonoverlapping<E: ErrorBehavior>(&mut self, other: *const [T]) -> Result<(), E> {
2513 unsafe {
2514 let len = other.len();
2515 self.generic_reserve(len)?;
2516
2517 let src = other.cast::<T>();
2518 let dst = self.as_mut_ptr().add(self.len());
2519 ptr::copy_nonoverlapping(src, dst, len);
2520
2521 self.inc_len(len);
2522 Ok(())
2523 }
2524 }
2525
2526 #[inline]
2527 fn generic_reserve_one<E: ErrorBehavior>(&mut self) -> Result<(), E> {
2528 if self.capacity() == self.len() {
2529 self.generic_grow_amortized::<E>(1)?;
2530 }
2531
2532 Ok(())
2533 }
2534
2535 #[cold]
2536 #[inline(never)]
2537 fn generic_grow_amortized<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
2538 if T::IS_ZST {
2539 // This function is only called after we checked that the current capacity is not
2540 // sufficient. When `T::IS_ZST` the capacity is `usize::MAX`, so it can't grow.
2541 return Err(E::capacity_overflow());
2542 }
2543
2544 let Some(required_cap) = self.len().checked_add(additional) else {
2545 return Err(E::capacity_overflow())?;
2546 };
2547
2548 let new_cap = self.capacity().checked_mul(2).unwrap_or(required_cap).max(required_cap);
2549 let new_cap = new_cap.max(min_non_zero_cap(T::SIZE));
2550
2551 unsafe { self.generic_grow_to(new_cap) }
2552 }
2553
2554 /// Like [`reserve`] but allows you to provide a different `len`.
2555 ///
2556 /// This is only used for [`buf_reserve`], read its documentation for more.
2557 ///
2558 /// # Safety
2559 ///
2560 /// - `len` must be less than or equal to `self.capacity()`
2561 ///
2562 /// [`reserve`]: Self::reserve
2563 /// [`buf_reserve`]: Self::buf_reserve
2564 #[cold]
2565 #[inline(never)]
2566 #[cfg(feature = "panic-on-alloc")]
2567 unsafe fn generic_grow_amortized_buf<E: ErrorBehavior>(&mut self, len: usize, additional: usize) -> Result<(), E> {
2568 if T::IS_ZST {
2569 // This function is only called after we checked that the current capacity is not
2570 // sufficient. When `T::IS_ZST` the capacity is `usize::MAX`, so it can't grow.
2571 return Err(E::capacity_overflow());
2572 }
2573
2574 let Some(required_cap) = len.checked_add(additional) else {
2575 return Err(E::capacity_overflow())?;
2576 };
2577
2578 // This guarantees exponential growth. The doubling cannot overflow
2579 // because `capacity <= isize::MAX` and the type of `capacity` is usize;
2580 let new_cap = (self.capacity() * 2).max(required_cap).max(min_non_zero_cap(T::SIZE));
2581
2582 unsafe { self.generic_grow_to(new_cap) }
2583 }
2584
2585 #[cold]
2586 #[inline(never)]
2587 fn generic_grow_exact<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
2588 if T::IS_ZST {
2589 // This function is only called after we checked that the current capacity is not
2590 // sufficient. When `T::IS_ZST` the capacity is `usize::MAX`, so it can't grow.
2591 return Err(E::capacity_overflow());
2592 }
2593
2594 let Some(required_cap) = self.len().checked_add(additional) else {
2595 return Err(E::capacity_overflow())?;
2596 };
2597
2598 unsafe { self.generic_grow_to(required_cap) }
2599 }
2600
2601 /// # Safety
2602 ///
2603 /// `new_capacity` must be greater than the current capacity.
2604 unsafe fn generic_grow_to<E: ErrorBehavior>(&mut self, new_capacity: usize) -> Result<(), E> {
2605 unsafe {
2606 let new_cap = new_capacity;
2607
2608 if self.capacity() == 0 {
2609 self.fixed = RawFixedBumpVec::allocate(&self.allocator, new_cap)?;
2610 return Ok(());
2611 }
2612
2613 let old_ptr = self.as_non_null().cast();
2614
2615 let old_size = self.capacity() * T::SIZE; // we already allocated that amount so this can't overflow
2616 let Some(new_size) = new_cap.checked_mul(T::SIZE) else {
2617 return Err(E::capacity_overflow());
2618 };
2619
2620 let old_layout = Layout::from_size_align_unchecked(old_size, T::ALIGN);
2621 let Ok(new_layout) = Layout::from_size_align(new_size, T::ALIGN) else {
2622 return Err(E::capacity_overflow());
2623 };
2624
2625 let new_ptr = match self.allocator.grow(old_ptr, old_layout, new_layout) {
2626 Ok(ok) => ok.cast(),
2627 Err(_) => return Err(E::allocation(new_layout)),
2628 };
2629
2630 self.fixed.set_ptr(new_ptr);
2631 self.fixed.set_cap(new_cap);
2632
2633 Ok(())
2634 }
2635 }
2636
2637 /// Shrinks the capacity of the vector as much as possible.
2638 ///
2639 /// This will also free space for future bump allocations if and only if this is the most recent allocation.
2640 ///
2641 /// # Examples
2642 /// ```
2643 /// # use bump_scope::{Bump, BumpVec};
2644 /// # let bump: Bump = Bump::new();
2645 /// let mut vec = BumpVec::with_capacity_in(10, &bump);
2646 /// vec.extend([1, 2, 3]);
2647 /// assert!(vec.capacity() == 10);
2648 /// assert_eq!(bump.stats().allocated(), 10 * 4);
2649 /// vec.shrink_to_fit();
2650 /// assert!(vec.capacity() == 3);
2651 /// assert_eq!(bump.stats().allocated(), 3 * 4);
2652 /// ```
2653 pub fn shrink_to_fit(&mut self) {
2654 let Self { fixed, allocator } = self;
2655
2656 let old_ptr = fixed.as_non_null();
2657 let old_len = fixed.capacity();
2658 let new_len = fixed.len();
2659
2660 unsafe {
2661 if let Some(new_ptr) = allocator.shrink_slice(old_ptr, old_len, new_len) {
2662 fixed.set_ptr(new_ptr);
2663 fixed.set_cap(new_len);
2664 }
2665 }
2666 }
2667
2668 /// # Safety
2669 ///
2670 /// `iterator` must satisfy the invariants of nightly's `TrustedLen`.
2671 unsafe fn extend_trusted<B: ErrorBehavior>(&mut self, iterator: impl Iterator<Item = T>) -> Result<(), B> {
2672 unsafe {
2673 let (low, high) = iterator.size_hint();
2674 if let Some(additional) = high {
2675 debug_assert_eq!(
2676 low,
2677 additional,
2678 "TrustedLen iterator's size hint is not exact: {:?}",
2679 (low, high)
2680 );
2681
2682 self.generic_reserve(additional)?;
2683
2684 let ptr = self.as_mut_ptr();
2685 let mut local_len = self.fixed.set_len_on_drop();
2686
2687 iterator.for_each(move |element| {
2688 let dst = ptr.add(local_len.current_len());
2689
2690 ptr::write(dst, element);
2691 // Since the loop executes user code which can panic we have to update
2692 // the length every step to correctly drop what we've written.
2693 // NB can't overflow since we would have had to alloc the address space
2694 local_len.increment_len(1);
2695 });
2696
2697 Ok(())
2698 } else {
2699 // Per TrustedLen contract a `None` upper bound means that the iterator length
2700 // truly exceeds usize::MAX, which would eventually lead to a capacity overflow anyway.
2701 // Since the other branch already panics eagerly (via `reserve()`) we do the same here.
2702 // This avoids additional codegen for a fallback code path which would eventually
2703 // panic anyway.
2704 Err(B::capacity_overflow())
2705 }
2706 }
2707 }
2708
2709 /// Retains only the elements specified by the predicate, passing a mutable reference to it.
2710 ///
2711 /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
2712 /// This method operates in place, visiting each element exactly once in the
2713 /// original order, and preserves the order of the retained elements.
2714 ///
2715 /// # Examples
2716 ///
2717 /// ```
2718 /// # use bump_scope::{Bump, bump_vec};
2719 /// # let bump: Bump = Bump::new();
2720 /// #
2721 /// let mut vec = bump_vec![in ≎ 1, 2, 3, 4];
2722 ///
2723 /// vec.retain(|x| if *x <= 3 {
2724 /// *x += 1;
2725 /// true
2726 /// } else {
2727 /// false
2728 /// });
2729 ///
2730 /// assert_eq!(vec, [2, 3, 4]);
2731 /// ```
2732 #[expect(clippy::pedantic)]
2733 pub fn retain<F>(&mut self, f: F)
2734 where
2735 F: FnMut(&mut T) -> bool,
2736 {
2737 unsafe { self.fixed.cook_mut() }.retain(f)
2738 }
2739
2740 /// Removes the specified range from the vector in bulk, returning all
2741 /// removed elements as an iterator. If the iterator is dropped before
2742 /// being fully consumed, it drops the remaining removed elements.
2743 ///
2744 /// The returned iterator keeps a mutable borrow on the vector to optimize
2745 /// its implementation.
2746 ///
2747 /// # Panics
2748 ///
2749 /// Panics if the starting point is greater than the end point or if
2750 /// the end point is greater than the length of the vector.
2751 ///
2752 /// # Leaking
2753 ///
2754 /// If the returned iterator goes out of scope without being dropped (due to
2755 /// [`mem::forget`](core::mem::forget), for example), the vector may have lost and leaked
2756 /// elements arbitrarily, including elements outside the range.
2757 ///
2758 /// # Examples
2759 ///
2760 /// ```
2761 /// # use bump_scope::{Bump, bump_vec};
2762 /// # let bump: Bump = Bump::new();
2763 /// let mut v = bump_vec![in ≎ 1, 2, 3];
2764 /// let u = bump.alloc_iter(v.drain(1..));
2765 /// assert_eq!(v, [1]);
2766 /// assert_eq!(u, [2, 3]);
2767 ///
2768 /// // A full range clears the vector, like `clear()` does
2769 /// v.drain(..);
2770 /// assert_eq!(v, []);
2771 /// ```
2772 pub fn drain<R>(&mut self, range: R) -> owned_slice::Drain<'_, T>
2773 where
2774 R: RangeBounds<usize>,
2775 {
2776 unsafe { self.fixed.cook_mut() }.drain(range)
2777 }
2778
2779 /// Creates an iterator which uses a closure to determine if an element should be removed.
2780 ///
2781 /// If the closure returns true, then the element is removed and yielded.
2782 /// If the closure returns false, the element will remain in the vector and will not be yielded
2783 /// by the iterator.
2784 ///
2785 /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
2786 /// or the iteration short-circuits, then the remaining elements will be retained.
2787 /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
2788 ///
2789 /// Using this method is equivalent to the following code:
2790 ///
2791 /// ```
2792 /// # use bump_scope::{Bump, bump_vec};
2793 /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
2794 /// # let bump: Bump = Bump::new();
2795 /// # let mut vec = bump_vec![in ≎ 1, 2, 3, 4, 5, 6];
2796 /// let mut i = 0;
2797 /// while i < vec.len() {
2798 /// if some_predicate(&mut vec[i]) {
2799 /// let val = vec.remove(i);
2800 /// // your code here
2801 /// # _ = val;
2802 /// } else {
2803 /// i += 1;
2804 /// }
2805 /// }
2806 ///
2807 /// # assert_eq!(vec, [1, 4, 5]);
2808 /// ```
2809 ///
2810 /// But `extract_if` is easier to use. `extract_if` is also more efficient,
2811 /// because it can backshift the elements of the array in bulk.
2812 ///
2813 /// Note that `extract_if` also lets you mutate every element in the filter closure,
2814 /// regardless of whether you choose to keep or remove it.
2815 ///
2816 /// # Examples
2817 ///
2818 /// Splitting an array into evens and odds, reusing the original allocation:
2819 ///
2820 /// ```
2821 /// # use bump_scope::{Bump, bump_vec};
2822 /// # let bump: Bump = Bump::new();
2823 /// let mut numbers = bump_vec![in ≎ 1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
2824 ///
2825 /// let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
2826 /// let odds = numbers;
2827 ///
2828 /// assert_eq!(evens, [2, 4, 6, 8, 14]);
2829 /// assert_eq!(odds, [1, 3, 5, 9, 11, 13, 15]);
2830 /// ```
2831 ///
2832 /// [`retain`]: Self::retain
2833 pub fn extract_if<F>(&mut self, filter: F) -> owned_slice::ExtractIf<'_, T, F>
2834 where
2835 F: FnMut(&mut T) -> bool,
2836 {
2837 unsafe { self.fixed.cook_mut() }.extract_if(filter)
2838 }
2839
2840 /// Removes consecutive repeated elements in the vector according to the
2841 /// [`PartialEq`] trait implementation.
2842 ///
2843 /// If the vector is sorted, this removes all duplicates.
2844 ///
2845 /// # Examples
2846 ///
2847 /// ```
2848 /// # use bump_scope::{Bump, bump_vec};
2849 /// # let bump: Bump = Bump::new();
2850 /// let mut vec = bump_vec![in ≎ 1, 2, 2, 3, 2];
2851 ///
2852 /// vec.dedup();
2853 ///
2854 /// assert_eq!(vec, [1, 2, 3, 2]);
2855 /// ```
2856 #[inline]
2857 pub fn dedup(&mut self)
2858 where
2859 T: PartialEq,
2860 {
2861 unsafe { self.fixed.cook_mut() }.dedup();
2862 }
2863
2864 /// Removes all but the first of consecutive elements in the vector that resolve to the same
2865 /// key.
2866 ///
2867 /// If the vector is sorted, this removes all duplicates.
2868 ///
2869 /// # Examples
2870 ///
2871 /// ```
2872 /// # use bump_scope::{Bump, bump_vec};
2873 /// # let bump: Bump = Bump::new();
2874 /// let mut vec = bump_vec![in ≎ 10, 20, 21, 30, 20];
2875 ///
2876 /// vec.dedup_by_key(|i| *i / 10);
2877 ///
2878 /// assert_eq!(vec, [10, 20, 30, 20]);
2879 /// ```
2880 #[inline]
2881 pub fn dedup_by_key<F, K>(&mut self, key: F)
2882 where
2883 F: FnMut(&mut T) -> K,
2884 K: PartialEq,
2885 {
2886 unsafe { self.fixed.cook_mut() }.dedup_by_key(key);
2887 }
2888
2889 /// Removes all but the first of consecutive elements in the vector satisfying a given equality
2890 /// relation.
2891 ///
2892 /// The `same_bucket` function is passed references to two elements from the vector and
2893 /// must determine if the elements compare equal. The elements are passed in opposite order
2894 /// from their order in the vector, so if `same_bucket(a, b)` returns `true`, `a` is removed.
2895 ///
2896 /// If the vector is sorted, this removes all duplicates.
2897 ///
2898 /// # Examples
2899 ///
2900 /// ```
2901 /// # use bump_scope::{Bump, bump_vec};
2902 /// # let bump: Bump = Bump::new();
2903 /// let mut vec = bump_vec![in ≎ "foo", "bar", "Bar", "baz", "bar"];
2904 ///
2905 /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
2906 ///
2907 /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
2908 /// ```
2909 pub fn dedup_by<F>(&mut self, same_bucket: F)
2910 where
2911 F: FnMut(&mut T, &mut T) -> bool,
2912 {
2913 unsafe { self.fixed.cook_mut() }.dedup_by(same_bucket);
2914 }
2915
2916 /// Returns the remaining spare capacity of the vector as a slice of
2917 /// `MaybeUninit<T>`.
2918 ///
2919 /// The returned slice can be used to fill the vector with data (e.g. by
2920 /// reading from a file) before marking the data as initialized using the
2921 /// [`set_len`] method.
2922 ///
2923 /// [`set_len`]: Self::set_len
2924 ///
2925 /// # Examples
2926 ///
2927 /// ```
2928 /// # use bump_scope::{Bump, BumpVec};
2929 /// # let bump: Bump = Bump::new();
2930 /// // Allocate vector big enough for 10 elements.
2931 /// let mut v = BumpVec::with_capacity_in(10, &bump);
2932 ///
2933 /// // Fill in the first 3 elements.
2934 /// let uninit = v.spare_capacity_mut();
2935 /// uninit[0].write(0);
2936 /// uninit[1].write(1);
2937 /// uninit[2].write(2);
2938 ///
2939 /// // Mark the first 3 elements of the vector as being initialized.
2940 /// unsafe {
2941 /// v.set_len(3);
2942 /// }
2943 ///
2944 /// assert_eq!(&v, &[0, 1, 2]);
2945 /// ```
2946 #[inline]
2947 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
2948 // Note:
2949 // This method is not implemented in terms of `split_at_spare_mut`,
2950 // to prevent invalidation of pointers to the buffer.
2951 unsafe {
2952 slice::from_raw_parts_mut(
2953 self.as_mut_ptr().add(self.len()).cast::<MaybeUninit<T>>(),
2954 self.capacity() - self.len(),
2955 )
2956 }
2957 }
2958
2959 /// Returns vector content as a slice of `T`, along with the remaining spare
2960 /// capacity of the vector as a slice of `MaybeUninit<T>`.
2961 ///
2962 /// The returned spare capacity slice can be used to fill the vector with data
2963 /// (e.g. by reading from a file) before marking the data as initialized using
2964 /// the [`set_len`] method.
2965 ///
2966 /// [`set_len`]: Self::set_len
2967 ///
2968 /// Note that this is a low-level API, which should be used with care for
2969 /// optimization purposes. If you need to append data to a `BumpVec`
2970 /// you can use [`push`], [`extend`], `extend_from_slice`[`_copy`](BumpVec::extend_from_slice_copy)`/`[`_clone`](BumpVec::extend_from_within_clone),
2971 /// `extend_from_within`[`_copy`](BumpVec::extend_from_within_copy)`/`[`_clone`](BumpVec::extend_from_within_clone), [`insert`], [`resize`] or
2972 /// [`resize_with`], depending on your exact needs.
2973 ///
2974 /// [`push`]: Self::push
2975 /// [`extend`]: Self::extend
2976 /// [`insert`]: Self::insert
2977 /// [`append`]: Self::append
2978 /// [`resize`]: Self::resize
2979 /// [`resize_with`]: Self::resize_with
2980 #[inline]
2981 pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]) {
2982 let ptr = self.as_mut_ptr();
2983
2984 // SAFETY:
2985 // - `ptr` is guaranteed to be valid for `self.len` elements
2986 // - but the allocation extends out to `self.buf.capacity()` elements, possibly
2987 // uninitialized
2988 let spare_ptr = unsafe { ptr.add(self.len()) };
2989 let spare_ptr = spare_ptr.cast::<MaybeUninit<T>>();
2990 let spare_len = self.capacity() - self.len();
2991
2992 // SAFETY:
2993 // - `ptr` is guaranteed to be valid for `self.len` elements
2994 // - `spare_ptr` is pointing one element past the buffer, so it doesn't overlap with `initialized`
2995 unsafe {
2996 let initialized = slice::from_raw_parts_mut(ptr, self.len());
2997 let spare = slice::from_raw_parts_mut(spare_ptr, spare_len);
2998
2999 (initialized, spare)
3000 }
3001 }
3002
3003 /// Returns a reference to the allocator.
3004 #[must_use]
3005 #[inline(always)]
3006 pub fn allocator(&self) -> &A {
3007 &self.allocator
3008 }
3009
3010 /// Returns a type which provides statistics about the memory usage of the bump allocator.
3011 ///
3012 /// This is equivalent to calling `.allocator().stats()`.
3013 /// This merely exists for api parity with `Mut*` collections which can't have a `allocator` method.
3014 #[must_use]
3015 #[inline(always)]
3016 pub fn allocator_stats(&self) -> A::Stats<'_> {
3017 self.allocator.stats()
3018 }
3019}
3020
3021impl<'a, T, A: BumpAllocatorScopeExt<'a>> BumpVec<T, A> {
3022 /// Turns this `BumpVec<T>` into a `FixedBumpVec<T>`.
3023 ///
3024 /// This retains the unused capacity unlike <code>[into_](Self::into_slice)([boxed_](Self::into_boxed_slice))[slice](Self::into_slice)</code>.
3025 #[must_use]
3026 #[inline(always)]
3027 pub fn into_fixed_vec(self) -> FixedBumpVec<'a, T> {
3028 self.into_parts().0
3029 }
3030
3031 /// Turns this `BumpVec<T>` into a `BumpBox<[T]>`.
3032 #[must_use]
3033 #[inline(always)]
3034 pub fn into_boxed_slice(mut self) -> BumpBox<'a, [T]> {
3035 self.shrink_to_fit();
3036 self.into_fixed_vec().into_boxed_slice()
3037 }
3038
3039 /// Turns this `BumpVec<T>` into a `&[T]` that is live for this bump scope.
3040 ///
3041 /// This is only available for [`NoDrop`] types so you don't omit dropping a value for which it matters.
3042 ///
3043 /// `!NoDrop` types can still be turned into slices via <code>BumpBox::[leak](BumpBox::leak)(vec.[into_boxed_slice](Self::into_boxed_slice)())</code>.
3044 #[must_use]
3045 #[inline(always)]
3046 pub fn into_slice(self) -> &'a mut [T]
3047 where
3048 [T]: NoDrop,
3049 {
3050 self.into_boxed_slice().into_mut()
3051 }
3052
3053 /// Creates a `BumpVec<T>` from its parts.
3054 ///
3055 /// The provided `bump` does not have to be the one the `fixed_vec` was allocated in.
3056 ///
3057 /// ```
3058 /// # use bump_scope::{Bump, FixedBumpVec, BumpVec};
3059 /// # let bump: Bump = Bump::new();
3060 /// let mut fixed_vec = FixedBumpVec::with_capacity_in(3, &bump);
3061 /// fixed_vec.push(1);
3062 /// fixed_vec.push(2);
3063 /// fixed_vec.push(3);
3064 /// let mut vec = BumpVec::from_parts(fixed_vec, &bump);
3065 /// vec.push(4);
3066 /// vec.push(5);
3067 /// assert_eq!(vec, [1, 2, 3, 4, 5]);
3068 /// ```
3069 #[must_use]
3070 #[inline(always)]
3071 pub fn from_parts(vec: FixedBumpVec<'a, T>, allocator: A) -> Self {
3072 Self {
3073 fixed: unsafe { RawFixedBumpVec::from_cooked(vec) },
3074 allocator,
3075 }
3076 }
3077
3078 /// Turns this `BumpVec<T>` into its parts.
3079 /// ```
3080 /// # use bump_scope::{Bump, BumpVec};
3081 /// # let bump: Bump = Bump::new();
3082 /// let mut vec = BumpVec::new_in(&bump);
3083 /// vec.reserve(10);
3084 /// vec.push(1);
3085 /// let fixed_vec = vec.into_parts().0;
3086 /// assert_eq!(fixed_vec.capacity(), 10);
3087 /// assert_eq!(fixed_vec, [1]);
3088 /// ```
3089 #[must_use]
3090 #[inline(always)]
3091 pub fn into_parts(self) -> (FixedBumpVec<'a, T>, A) {
3092 destructure!(let Self { fixed, allocator } = self);
3093 (unsafe { fixed.cook() }, allocator)
3094 }
3095}
3096
3097impl<T, const N: usize, A: BumpAllocatorExt> BumpVec<[T; N], A> {
3098 /// Takes a `BumpVec<[T; N]>` and flattens it into a `BumpVec<T>`.
3099 ///
3100 /// # Panics
3101 ///
3102 /// Panics if the length of the resulting vector would overflow a `usize`.
3103 ///
3104 /// This is only possible when flattening a vector of arrays of zero-sized
3105 /// types, and thus tends to be irrelevant in practice. If
3106 /// `size_of::<T>() > 0`, this will never panic.
3107 ///
3108 /// # Examples
3109 ///
3110 /// ```
3111 /// # use bump_scope::{Bump, bump_vec};
3112 /// # let bump: Bump = Bump::new();
3113 /// #
3114 /// let mut vec = bump_vec![in ≎ [1, 2, 3], [4, 5, 6], [7, 8, 9]];
3115 /// assert_eq!(vec.pop(), Some([7, 8, 9]));
3116 ///
3117 /// let mut flattened = vec.into_flattened();
3118 /// assert_eq!(flattened.pop(), Some(6));
3119 /// ```
3120 #[must_use]
3121 pub fn into_flattened(self) -> BumpVec<T, A> {
3122 destructure!(let Self { fixed, allocator } = self);
3123 let fixed = unsafe { RawFixedBumpVec::from_cooked(fixed.cook().into_flattened()) };
3124 BumpVec { fixed, allocator }
3125 }
3126}
3127
3128impl<T: Debug, A: BumpAllocatorExt> Debug for BumpVec<T, A> {
3129 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3130 Debug::fmt(self.as_slice(), f)
3131 }
3132}
3133
3134impl<T, A: BumpAllocatorExt, I: SliceIndex<[T]>> Index<I> for BumpVec<T, A> {
3135 type Output = I::Output;
3136
3137 #[inline(always)]
3138 fn index(&self, index: I) -> &Self::Output {
3139 Index::index(self.as_slice(), index)
3140 }
3141}
3142
3143impl<T, A: BumpAllocatorExt, I: SliceIndex<[T]>> IndexMut<I> for BumpVec<T, A> {
3144 #[inline(always)]
3145 fn index_mut(&mut self, index: I) -> &mut Self::Output {
3146 IndexMut::index_mut(self.as_mut_slice(), index)
3147 }
3148}
3149
3150#[cfg(feature = "panic-on-alloc")]
3151impl<T, A: BumpAllocatorExt> Extend<T> for BumpVec<T, A> {
3152 #[inline]
3153 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
3154 let iter = iter.into_iter();
3155
3156 self.reserve(iter.size_hint().0);
3157
3158 for value in iter {
3159 self.push(value);
3160 }
3161 }
3162}
3163
3164#[cfg(feature = "panic-on-alloc")]
3165impl<'t, T: Clone + 't, A: BumpAllocatorExt> Extend<&'t T> for BumpVec<T, A> {
3166 #[inline]
3167 fn extend<I: IntoIterator<Item = &'t T>>(&mut self, iter: I) {
3168 let iter = iter.into_iter();
3169
3170 self.reserve(iter.size_hint().0);
3171
3172 for value in iter {
3173 self.push(value.clone());
3174 }
3175 }
3176}
3177
3178impl<T, A: BumpAllocatorExt> IntoIterator for BumpVec<T, A> {
3179 type Item = T;
3180 type IntoIter = IntoIter<T, A>;
3181
3182 #[inline]
3183 fn into_iter(self) -> Self::IntoIter {
3184 unsafe {
3185 destructure!(let Self { fixed, allocator } = self);
3186
3187 let (slice, cap) = fixed.into_raw_parts();
3188 let begin = slice.cast::<T>();
3189
3190 let end = if T::IS_ZST {
3191 non_null::wrapping_byte_add(begin, slice.len())
3192 } else {
3193 begin.add(slice.len())
3194 };
3195
3196 IntoIter {
3197 buf: begin,
3198 cap,
3199
3200 ptr: begin,
3201 end,
3202
3203 allocator,
3204 marker: PhantomData,
3205 }
3206 }
3207 }
3208}
3209
3210impl<'c, T, A: BumpAllocatorExt> IntoIterator for &'c BumpVec<T, A> {
3211 type Item = &'c T;
3212 type IntoIter = slice::Iter<'c, T>;
3213
3214 #[inline(always)]
3215 fn into_iter(self) -> Self::IntoIter {
3216 self.as_slice().iter()
3217 }
3218}
3219
3220impl<'c, T, A: BumpAllocatorExt> IntoIterator for &'c mut BumpVec<T, A> {
3221 type Item = &'c mut T;
3222 type IntoIter = slice::IterMut<'c, T>;
3223
3224 #[inline(always)]
3225 fn into_iter(self) -> Self::IntoIter {
3226 self.as_mut_slice().iter_mut()
3227 }
3228}
3229
3230impl<T, A: BumpAllocatorExt> AsRef<[T]> for BumpVec<T, A> {
3231 #[inline(always)]
3232 fn as_ref(&self) -> &[T] {
3233 self
3234 }
3235}
3236
3237impl<T, A: BumpAllocatorExt> AsMut<[T]> for BumpVec<T, A> {
3238 #[inline(always)]
3239 fn as_mut(&mut self) -> &mut [T] {
3240 self
3241 }
3242}
3243
3244impl<T, A: BumpAllocatorExt> Borrow<[T]> for BumpVec<T, A> {
3245 #[inline(always)]
3246 fn borrow(&self) -> &[T] {
3247 self
3248 }
3249}
3250
3251impl<T, A: BumpAllocatorExt> BorrowMut<[T]> for BumpVec<T, A> {
3252 #[inline(always)]
3253 fn borrow_mut(&mut self) -> &mut [T] {
3254 self
3255 }
3256}
3257
3258impl<T: Hash, A: BumpAllocatorExt> Hash for BumpVec<T, A> {
3259 #[inline(always)]
3260 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
3261 self.as_slice().hash(state);
3262 }
3263}
3264
3265/// Returns [`ErrorKind::OutOfMemory`](std::io::ErrorKind::OutOfMemory) when allocations fail.
3266#[cfg(feature = "std")]
3267impl<A: BumpAllocatorExt> std::io::Write for BumpVec<u8, A> {
3268 #[inline(always)]
3269 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
3270 if self.try_extend_from_slice_copy(buf).is_err() {
3271 return Err(std::io::ErrorKind::OutOfMemory.into());
3272 }
3273
3274 Ok(buf.len())
3275 }
3276
3277 #[inline(always)]
3278 fn flush(&mut self) -> std::io::Result<()> {
3279 Ok(())
3280 }
3281
3282 #[inline]
3283 fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
3284 let len = bufs.iter().map(|b| b.len()).sum();
3285 self.try_reserve(len).map_err(|_| std::io::ErrorKind::OutOfMemory)?;
3286 for buf in bufs {
3287 self.try_extend_from_slice_copy(buf)
3288 .map_err(|_| std::io::ErrorKind::OutOfMemory)?;
3289 }
3290 Ok(len)
3291 }
3292
3293 #[inline(always)]
3294 fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
3295 if self.try_extend_from_slice_copy(buf).is_err() {
3296 return Err(std::io::ErrorKind::OutOfMemory.into());
3297 }
3298
3299 Ok(())
3300 }
3301}
3302
3303#[cfg(feature = "panic-on-alloc")]
3304impl<T, A: BumpAllocatorExt + Default> FromIterator<T> for BumpVec<T, A> {
3305 #[inline]
3306 #[track_caller]
3307 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
3308 Self::from_iter_in(iter, A::default())
3309 }
3310}