bump_scope/
fixed_bump_vec.rs

1use core::{
2    borrow::{Borrow, BorrowMut},
3    fmt::Debug,
4    hash::Hash,
5    iter,
6    mem::{ManuallyDrop, MaybeUninit},
7    ops::{self, Deref, DerefMut, Index, IndexMut, RangeBounds},
8    ptr::{self, NonNull},
9    slice::SliceIndex,
10};
11
12use crate::{
13    BumpAllocatorScopeExt, BumpBox, BumpVec, ErrorBehavior, NoDrop, SizedTypeProperties,
14    alloc::AllocError,
15    owned_slice::{self, OwnedSlice, TakeOwnedSlice},
16    polyfill::{self, hint::likely, non_null, pointer, slice},
17};
18
19#[cfg(feature = "panic-on-alloc")]
20use crate::panic_on_error;
21
22/// A type like [`BumpVec`] but with a fixed capacity.
23///
24/// It can be constructed using [`with_capacity_in`] or from a `BumpBox` via [`from_init`] or [`from_uninit`].
25///
26/// ## Using it like `BumpVec`
27///
28/// This type is also useful when you want a growing `BumpVec` but don't want to carry around a reference to
29/// the `Bump(Scope)`. You can use it this way by first converting it to a `BumpVec` using [`BumpVec::from_parts`],
30/// making your changes and then turning it back into a `FixedBumpVec` with [`BumpVec::into_fixed_vec`].
31///
32/// Not storing the `Bump(Scope)` allows you to call bump allocator methods that require `&mut`,
33/// like [`scoped`](crate::Bump::scoped).
34///
35/// # Examples
36/// ```
37/// # use bump_scope::{Bump, FixedBumpVec};
38/// # let bump: Bump = Bump::new();
39/// let mut vec = FixedBumpVec::with_capacity_in(3, &bump);
40///
41/// vec.push(1);
42/// vec.push(2);
43/// vec.push(3);
44///
45/// let slice: &[i32] = vec.into_slice();
46///
47/// assert_eq!(slice, [1, 2, 3]);
48/// ```
49///
50/// Growing it via `BumpVec`:
51///
52/// ```
53/// # use bump_scope::{Bump, BumpScope, BumpVec, FixedBumpVec};
54/// # type T = i32;
55/// struct MyBuilder<'a, 'b> {
56///     bump: &'b mut BumpScope<'a>,
57///     vec: FixedBumpVec<'a, T>,
58/// }
59///
60/// impl<'a, 'b> MyBuilder<'a, 'b> {
61///     fn push(&mut self, value: T) {
62///         let fixed_vec = core::mem::take(&mut self.vec);
63///         let mut vec = BumpVec::from_parts(fixed_vec, &mut *self.bump);
64///         vec.push(value);
65///         self.vec = vec.into_fixed_vec();
66///     }
67/// }
68///
69/// let mut bump: Bump = Bump::new();
70///
71/// let mut builder = MyBuilder {
72///     bump: bump.as_mut_scope(),
73///     vec: FixedBumpVec::new(),
74/// };
75///
76/// builder.push(1);
77/// assert_eq!(builder.vec, [1]);
78/// ```
79///
80/// [`with_capacity_in`]: Self::with_capacity_in
81/// [`from_uninit`]: Self::from_uninit
82/// [`from_init`]: Self::from_init
83// `FixedBumpString` and `FixedBumpVec<u8>` have the same repr.
84#[repr(C)]
85pub struct FixedBumpVec<'a, T> {
86    initialized: BumpBox<'a, [T]>,
87    capacity: usize,
88}
89
90unsafe impl<T: Send> Send for FixedBumpVec<'_, T> {}
91unsafe impl<T: Sync> Sync for FixedBumpVec<'_, T> {}
92
93impl<'a, T> FixedBumpVec<'a, T> {
94    #[doc(hidden)]
95    #[deprecated = "use `FixedBumpVec::new()` instead"]
96    /// Empty fixed vector.
97    pub const EMPTY: Self = Self {
98        initialized: BumpBox::EMPTY,
99        capacity: if T::IS_ZST { usize::MAX } else { 0 },
100    };
101
102    /// Constructs a new empty `FixedBumpVec<T>`.
103    ///
104    /// This will not allocate.
105    ///
106    /// # Examples
107    /// ```
108    /// # use bump_scope::FixedBumpVec;
109    /// let vec = FixedBumpVec::<i32>::new();
110    /// assert_eq!(vec.len(), 0);
111    /// assert_eq!(vec.capacity(), 0);
112    /// ```
113    #[inline]
114    #[must_use]
115    pub const fn new() -> Self {
116        Self {
117            initialized: BumpBox::EMPTY,
118            capacity: if T::IS_ZST { usize::MAX } else { 0 },
119        }
120    }
121
122    /// Constructs a new empty vector with the specified capacity
123    /// in the provided bump allocator.
124    ///
125    /// The vector will be able to hold `capacity` elements.
126    /// If `capacity` is 0, the vector will not allocate.
127    ///
128    /// When `T` is a zero-sized type, there will be no allocation
129    /// and the capacity will always be `usize::MAX`.
130    ///
131    /// # Panics
132    /// Panics if the allocation fails.
133    ///
134    /// # Examples
135    /// ```
136    /// # use bump_scope::{Bump, FixedBumpVec};
137    /// # let bump: Bump = Bump::new();
138    /// let mut vec = FixedBumpVec::<i32>::with_capacity_in(10, &bump);
139    ///
140    /// // The vector contains no items, even though it has capacity for more
141    /// assert_eq!(vec.len(), 0);
142    /// assert!(vec.capacity() == 10);
143    ///
144    /// // The vector has space for 10 items...
145    /// for i in 0..10 {
146    ///     vec.push(i);
147    /// }
148    ///
149    /// assert_eq!(vec.len(), 10);
150    /// assert!(vec.capacity() == 10);
151    ///
152    /// // ...but one more will not fit
153    /// assert!(vec.try_push(11).is_err());
154    ///
155    /// // A vector of a zero-sized type will always over-allocate, since no
156    /// // allocation is necessary
157    /// let vec_units = FixedBumpVec::<()>::with_capacity_in(10, &bump);
158    /// assert_eq!(vec_units.capacity(), usize::MAX);
159    /// ```
160    #[must_use]
161    #[inline(always)]
162    #[cfg(feature = "panic-on-alloc")]
163    pub fn with_capacity_in(capacity: usize, allocator: impl BumpAllocatorScopeExt<'a>) -> Self {
164        panic_on_error(Self::generic_with_capacity_in(capacity, allocator))
165    }
166
167    /// Constructs a new empty vector with the specified capacity
168    /// in the provided bump allocator.
169    ///
170    /// The vector will be able to hold `capacity` elements.
171    /// If `capacity` is 0, the vector will not allocate.
172    ///
173    /// When `T` is a zero-sized type, there will be no allocation
174    /// and the capacity will always be `usize::MAX`.
175    ///
176    /// # Errors
177    /// Errors if the allocation fails.
178    ///
179    /// # Examples
180    /// ```
181    /// # use bump_scope::{Bump, FixedBumpVec};
182    /// # let bump: Bump = Bump::new();
183    /// let mut vec = FixedBumpVec::<i32>::try_with_capacity_in(10, &bump)?;
184    ///
185    /// // The vector contains no items, even though it has capacity for more
186    /// assert_eq!(vec.len(), 0);
187    /// assert!(vec.capacity() == 10);
188    ///
189    /// // The vector has space for 10 items...
190    /// for i in 0..10 {
191    ///     vec.push(i);
192    /// }
193    /// assert_eq!(vec.len(), 10);
194    /// assert!(vec.capacity() == 10);
195    ///
196    /// // ...but one more will not fit
197    /// assert!(vec.try_push(11).is_err());
198    ///
199    /// // A vector of a zero-sized type will always over-allocate, since no
200    /// // allocation is necessary
201    /// let vec_units = FixedBumpVec::<()>::try_with_capacity_in(10, &bump)?;
202    /// assert_eq!(vec_units.capacity(), usize::MAX);
203    /// # Ok::<(), bump_scope::alloc::AllocError>(())
204    /// ```
205    #[inline(always)]
206    pub fn try_with_capacity_in(capacity: usize, allocator: impl BumpAllocatorScopeExt<'a>) -> Result<Self, AllocError> {
207        Self::generic_with_capacity_in(capacity, allocator)
208    }
209
210    #[inline]
211    pub(crate) fn generic_with_capacity_in<E: ErrorBehavior>(
212        capacity: usize,
213        allocator: impl BumpAllocatorScopeExt<'a>,
214    ) -> Result<Self, E> {
215        Ok(BumpVec::generic_with_capacity_in(capacity, allocator)?.into_fixed_vec())
216    }
217
218    /// Create a new [`FixedBumpVec`] whose elements are taken from an iterator and allocated in the given `bump`.
219    ///
220    /// This is behaviorally identical to [`FromIterator::from_iter`].
221    ///
222    /// If you have an `impl ExactSizeIterator` then you can use [`from_iter_exact_in`](Self::from_iter_exact_in) instead for better performance.
223    ///
224    /// # Panics
225    /// Panics if the allocation fails.
226    ///
227    /// # Examples
228    /// ```
229    /// # use bump_scope::{Bump, FixedBumpVec};
230    /// # let bump: Bump = Bump::new();
231    /// let vec = FixedBumpVec::from_iter_in([1, 2, 3], &bump);
232    /// assert_eq!(vec, [1, 2, 3]);
233    /// ```
234    #[must_use]
235    #[inline(always)]
236    #[cfg(feature = "panic-on-alloc")]
237    pub fn from_iter_in<I, A>(iter: I, allocator: A) -> Self
238    where
239        I: IntoIterator<Item = T>,
240        A: BumpAllocatorScopeExt<'a>,
241    {
242        panic_on_error(Self::generic_from_iter_in(iter, allocator))
243    }
244
245    /// Create a new [`FixedBumpVec`] whose elements are taken from an iterator and allocated in the given `bump`.
246    ///
247    /// This is behaviorally identical to [`FromIterator::from_iter`].
248    ///
249    /// If you have an `impl ExactSizeIterator` then you can use [`from_iter_exact_in`](Self::from_iter_exact_in) instead for better performance.
250    ///
251    /// # Errors
252    /// Errors if the allocation fails.
253    ///
254    /// # Examples
255    /// ```
256    /// # use bump_scope::{Bump, FixedBumpVec};
257    /// # let bump: Bump = Bump::try_new()?;
258    /// let vec = FixedBumpVec::try_from_iter_in([1, 2, 3], &bump)?;
259    /// assert_eq!(vec, [1, 2, 3]);
260    /// # Ok::<(), bump_scope::alloc::AllocError>(())
261    /// ```
262    #[inline(always)]
263    pub fn try_from_iter_in<I, A>(iter: I, allocator: A) -> Result<Self, AllocError>
264    where
265        I: IntoIterator<Item = T>,
266        A: BumpAllocatorScopeExt<'a>,
267    {
268        Self::generic_from_iter_in(iter, allocator)
269    }
270
271    #[inline]
272    pub(crate) fn generic_from_iter_in<E: ErrorBehavior, I, A>(iter: I, allocator: A) -> Result<Self, E>
273    where
274        I: IntoIterator<Item = T>,
275        A: BumpAllocatorScopeExt<'a>,
276    {
277        Ok(BumpVec::generic_from_iter_in(iter, allocator)?.into_fixed_vec())
278    }
279
280    /// Create a new [`FixedBumpVec`] whose elements are taken from an iterator and allocated in the given `bump`.
281    ///
282    /// This is just like [`from_iter_in`](Self::from_iter_in) but optimized for an [`ExactSizeIterator`].
283    ///
284    /// # Panics
285    /// Panics if the allocation fails.
286    ///
287    /// # Examples
288    /// ```
289    /// # use bump_scope::{Bump, FixedBumpVec};
290    /// # let bump: Bump = Bump::new();
291    /// let vec = FixedBumpVec::from_iter_exact_in([1, 2, 3], &bump);
292    /// assert_eq!(vec, [1, 2, 3]);
293    /// ```
294    #[must_use]
295    #[inline(always)]
296    #[cfg(feature = "panic-on-alloc")]
297    pub fn from_iter_exact_in<I, A>(iter: I, allocator: A) -> Self
298    where
299        I: IntoIterator<Item = T>,
300        I::IntoIter: ExactSizeIterator,
301        A: BumpAllocatorScopeExt<'a>,
302    {
303        panic_on_error(Self::generic_from_iter_exact_in(iter, allocator))
304    }
305
306    /// Create a new [`FixedBumpVec`] whose elements are taken from an iterator and allocated in the given `bump`.
307    ///
308    /// This is just like [`from_iter_in`](Self::from_iter_in) but optimized for an [`ExactSizeIterator`].
309    ///
310    /// # Errors
311    /// Errors if the allocation fails.
312    ///
313    /// # Examples
314    /// ```
315    /// # use bump_scope::{Bump, FixedBumpVec};
316    /// # let bump: Bump = Bump::try_new()?;
317    /// let vec = FixedBumpVec::try_from_iter_exact_in([1, 2, 3], &bump)?;
318    /// assert_eq!(vec, [1, 2, 3]);
319    /// # Ok::<(), bump_scope::alloc::AllocError>(())
320    /// ```
321    #[inline(always)]
322    pub fn try_from_iter_exact_in<I, A>(iter: I, allocator: A) -> Result<Self, AllocError>
323    where
324        I: IntoIterator<Item = T>,
325        I::IntoIter: ExactSizeIterator,
326        A: BumpAllocatorScopeExt<'a>,
327    {
328        Self::generic_from_iter_exact_in(iter, allocator)
329    }
330
331    #[inline]
332    pub(crate) fn generic_from_iter_exact_in<E: ErrorBehavior, I, A>(iter: I, allocator: A) -> Result<Self, E>
333    where
334        I: IntoIterator<Item = T>,
335        I::IntoIter: ExactSizeIterator,
336        A: BumpAllocatorScopeExt<'a>,
337    {
338        Ok(BumpVec::generic_from_iter_exact_in(iter, allocator)?.into_fixed_vec())
339    }
340
341    /// Turns a `BumpBox<[T]>` into a full `FixedBumpVec<T>`.
342    #[must_use]
343    pub fn from_init(initialized: BumpBox<'a, [T]>) -> Self {
344        let capacity = if T::IS_ZST { usize::MAX } else { initialized.len() };
345        Self { initialized, capacity }
346    }
347
348    /// Turns a `BumpBox<[MaybeUninit<T>]>` into a `FixedBumpVec<T>` with a length of `0`.
349    #[must_use]
350    pub fn from_uninit(uninitialized: BumpBox<'a, [MaybeUninit<T>]>) -> Self {
351        let uninitialized = uninitialized.into_raw();
352        let capacity = if T::IS_ZST { usize::MAX } else { uninitialized.len() };
353
354        let ptr = non_null::as_non_null_ptr(uninitialized).cast::<T>();
355        let initialized = unsafe { BumpBox::from_raw(NonNull::slice_from_raw_parts(ptr, 0)) };
356
357        Self { initialized, capacity }
358    }
359
360    /// Returns the total number of elements the vector can hold.
361    ///
362    /// # Examples
363    ///
364    /// ```
365    /// # use bump_scope::{Bump, FixedBumpVec};
366    /// # let bump: Bump = Bump::new();
367    /// let vec = FixedBumpVec::<i32>::with_capacity_in(2048, &bump);
368    /// assert_eq!(vec.capacity(), 2048);
369    /// ```
370    #[must_use]
371    #[inline(always)]
372    pub const fn capacity(&self) -> usize {
373        self.capacity
374    }
375
376    /// Returns the number of elements in the vector, also referred to
377    /// as its 'length'.
378    #[must_use]
379    #[inline(always)]
380    pub const fn len(&self) -> usize {
381        self.initialized.len()
382    }
383
384    /// Returns `true` if the vector contains no elements.
385    #[must_use]
386    #[inline(always)]
387    pub const fn is_empty(&self) -> bool {
388        self.initialized.is_empty()
389    }
390
391    /// Returns `true` if the vector has reached its capacity.
392    #[must_use]
393    #[inline(always)]
394    pub const fn is_full(&self) -> bool {
395        self.len() >= self.capacity
396    }
397
398    /// Turns this `FixedBumpVec<T>` into a `&[T]` that is live for this bump scope.
399    ///
400    /// This is only available for [`NoDrop`] types so you don't omit dropping a value for which it matters.
401    ///
402    /// `!NoDrop` types can still be turned into slices via <code>BumpBox::[leak](BumpBox::leak)(vec.[into_boxed_slice](Self::into_boxed_slice)())</code>.
403    #[must_use]
404    #[inline(always)]
405    pub fn into_slice(self) -> &'a mut [T]
406    where
407        [T]: NoDrop,
408    {
409        self.into_boxed_slice().into_mut()
410    }
411
412    /// Turns this `FixedBumpVec<T>` into a `BumpBox<[T]>`.
413    #[must_use]
414    #[inline(always)]
415    pub fn into_boxed_slice(self) -> BumpBox<'a, [T]> {
416        self.initialized
417    }
418
419    /// Turns this `FixedBumpVec<T>` into a `BumpVec<T>`.
420    #[must_use]
421    #[inline(always)]
422    pub fn into_vec<A: BumpAllocatorScopeExt<'a>>(self, allocator: A) -> BumpVec<T, A> {
423        BumpVec::from_parts(self, allocator)
424    }
425
426    /// Removes the last element from a vector and returns it, or [`None`] if it
427    /// is empty.
428    ///
429    /// # Examples
430    /// ```
431    /// # use bump_scope::{Bump, FixedBumpVec};
432    /// # let bump: Bump = Bump::new();
433    /// let mut vec = FixedBumpVec::with_capacity_in(3, &bump);
434    /// vec.append([1, 2, 3]);
435    /// assert_eq!(vec.pop(), Some(3));
436    /// assert_eq!(vec, [1, 2]);
437    /// ```
438    ///
439    /// # Time complexity
440    /// Takes *O*(1) time.
441    #[inline(always)]
442    pub fn pop(&mut self) -> Option<T> {
443        self.initialized.pop()
444    }
445
446    /// Removes and returns the last element from a vector if the predicate
447    /// returns `true`, or [`None`] if the predicate returns false or the vector
448    /// is empty (the predicate will not be called in that case).
449    ///
450    /// # Examples
451    ///
452    /// ```
453    /// # use bump_scope::{Bump, FixedBumpVec};
454    /// # let bump: Bump = Bump::new();
455    /// let mut vec = FixedBumpVec::<i32>::with_capacity_in(4, &bump);
456    /// vec.append([1, 2, 3, 4]);
457    /// let pred = |x: &mut i32| *x % 2 == 0;
458    ///
459    /// assert_eq!(vec.pop_if(pred), Some(4));
460    /// assert_eq!(vec, [1, 2, 3]);
461    /// assert_eq!(vec.pop_if(pred), None);
462    /// ```
463    pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
464        let last = self.last_mut()?;
465        if predicate(last) { self.pop() } else { None }
466    }
467
468    /// Clears the vector, removing all values.
469    ///
470    /// # Examples
471    /// ```
472    /// # use bump_scope::{Bump, FixedBumpVec};
473    /// # let bump: Bump = Bump::new();
474    /// let mut vec = FixedBumpVec::with_capacity_in(10, &bump);
475    /// vec.extend_from_slice_copy(&[1, 2, 3]);
476    /// vec.clear();
477    /// assert!(vec.is_empty());
478    /// ```
479    #[inline(always)]
480    pub fn clear(&mut self) {
481        self.initialized.clear();
482    }
483
484    /// Shortens the vector, keeping the first `len` elements and dropping
485    /// the rest.
486    ///
487    /// If `len` is greater than the vector's current length, this has no
488    /// effect.
489    ///
490    /// The [`drain`] method can emulate `truncate`, but causes the excess
491    /// elements to be returned instead of dropped.
492    ///
493    /// Note that this method has no effect on the allocated capacity
494    /// of the vector.
495    ///
496    /// # Examples
497    ///
498    /// Truncating a five element vector to two elements:
499    ///
500    /// ```
501    /// # use bump_scope::{Bump, FixedBumpVec};
502    /// # let bump: Bump = Bump::new();
503    /// let mut vec = FixedBumpVec::with_capacity_in(10, &bump);
504    /// vec.extend_from_slice_copy(&[1, 2, 3, 4, 5]);
505    /// vec.truncate(2);
506    /// assert_eq!(vec, [1, 2]);
507    /// ```
508    ///
509    /// No truncation occurs when `len` is greater than the vector's current
510    /// length:
511    ///
512    /// ```
513    /// # use bump_scope::{Bump, FixedBumpVec};
514    /// # let bump: Bump = Bump::new();
515    /// let mut vec = FixedBumpVec::with_capacity_in(10, &bump);
516    /// vec.extend_from_slice_copy(&[1, 2, 3]);
517    /// vec.truncate(8);
518    /// assert_eq!(vec, [1, 2, 3]);
519    /// ```
520    ///
521    /// Truncating when `len == 0` is equivalent to calling the [`clear`]
522    /// method.
523    ///
524    /// ```
525    /// # use bump_scope::{Bump, FixedBumpVec};
526    /// # let bump: Bump = Bump::new();
527    /// let mut vec = FixedBumpVec::with_capacity_in(10, &bump);
528    /// vec.extend_from_slice_copy(&[1, 2, 3]);
529    /// vec.truncate(0);
530    /// assert_eq!(vec, []);
531    /// ```
532    ///
533    /// [`clear`]: Self::clear
534    /// [`drain`]: Self::drain
535    pub fn truncate(&mut self, len: usize) {
536        self.initialized.truncate(len);
537    }
538
539    /// Removes and returns the element at position `index` within the vector,
540    /// shifting all elements after it to the left.
541    ///
542    /// Note: Because this shifts over the remaining elements, it has a
543    /// worst-case performance of *O*(*n*). If you don't need the order of elements
544    /// to be preserved, use [`swap_remove`] instead.
545    ///
546    /// # Panics
547    /// Panics if `index` is out of bounds.
548    ///
549    /// [`swap_remove`]: Self::swap_remove
550    ///
551    /// # Examples
552    /// ```
553    /// # use bump_scope::Bump;
554    /// # let bump: Bump = Bump::new();
555    /// let mut v = bump.alloc_slice_copy(&[1, 2, 3]);
556    /// assert_eq!(v.remove(1), 2);
557    /// assert_eq!(v, [1, 3]);
558    /// ```
559    #[inline(always)]
560    pub fn remove(&mut self, index: usize) -> T {
561        self.initialized.remove(index)
562    }
563
564    /// Extracts a slice containing the entire vector.
565    ///
566    /// Equivalent to `&s[..]`.
567    #[must_use]
568    #[inline(always)]
569    pub const fn as_slice(&self) -> &[T] {
570        self.initialized.as_slice()
571    }
572
573    /// Extracts a mutable slice containing the entire vector.
574    ///
575    /// Equivalent to `&mut s[..]`.
576    #[must_use]
577    #[inline(always)]
578    pub fn as_mut_slice(&mut self) -> &mut [T] {
579        self.initialized.as_mut_slice()
580    }
581
582    /// Returns a raw pointer to the slice, or a dangling raw pointer
583    /// valid for zero sized reads.
584    #[inline]
585    #[must_use]
586    pub fn as_ptr(&self) -> *const T {
587        self.initialized.as_ptr()
588    }
589
590    /// Returns an unsafe mutable pointer to the slice, or a dangling
591    /// raw pointer valid for zero sized reads.
592    #[inline]
593    pub fn as_mut_ptr(&mut self) -> *mut T {
594        self.initialized.as_mut_ptr()
595    }
596
597    /// Returns a `NonNull` pointer to the vector's buffer, or a dangling
598    /// `NonNull` pointer valid for zero sized reads if the vector didn't allocate.
599    ///
600    /// The caller must ensure that the vector outlives the pointer this
601    /// function returns, or else it will end up dangling.
602    /// Modifying the vector may cause its buffer to be reallocated,
603    /// which would also make any pointers to it invalid.
604    ///
605    /// This method guarantees that for the purpose of the aliasing model, this method
606    /// does not materialize a reference to the underlying slice, and thus the returned pointer
607    /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
608    /// and [`as_non_null`].
609    /// Note that calling other methods that materialize references to the slice,
610    /// or references to specific elements you are planning on accessing through this pointer,
611    /// may still invalidate this pointer.
612    /// See the second example below for how this guarantee can be used.
613    ///
614    /// # Examples
615    ///
616    /// ```
617    /// # use bump_scope::{Bump, FixedBumpVec};
618    /// # let bump: Bump = Bump::new();
619    /// // Allocate vector big enough for 4 elements.
620    /// let size = 4;
621    /// let mut x: FixedBumpVec<i32> = FixedBumpVec::with_capacity_in(size, &bump);
622    /// let x_ptr = x.as_non_null();
623    ///
624    /// // Initialize elements via raw pointer writes, then set length.
625    /// unsafe {
626    ///     for i in 0..size {
627    ///         x_ptr.add(i).write(i as i32);
628    ///     }
629    ///     x.set_len(size);
630    /// }
631    /// assert_eq!(&*x, &[0, 1, 2, 3]);
632    /// ```
633    ///
634    /// Due to the aliasing guarantee, the following code is legal:
635    ///
636    /// ```
637    /// # use bump_scope::{Bump, bump_vec};
638    /// # let bump: Bump = Bump::new();
639    /// unsafe {
640    ///     let v = bump_vec![in &bump; 0].into_fixed_vec();
641    ///     let ptr1 = v.as_non_null();
642    ///     ptr1.write(1);
643    ///     let ptr2 = v.as_non_null();
644    ///     ptr2.write(2);
645    ///     // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
646    ///     ptr1.write(3);
647    /// }
648    /// ```
649    ///
650    /// [`as_mut_ptr`]: Self::as_mut_ptr
651    /// [`as_ptr`]: Self::as_ptr
652    /// [`as_non_null`]: Self::as_non_null
653    #[must_use]
654    #[inline(always)]
655    pub const fn as_non_null(&self) -> NonNull<T> {
656        self.initialized.as_non_null()
657    }
658
659    /// Returns a raw nonnull pointer to the slice, or a dangling raw pointer
660    /// valid for zero sized reads.
661    #[doc(hidden)]
662    #[deprecated = "renamed to `as_non_null`"]
663    #[must_use]
664    #[inline(always)]
665    pub fn as_non_null_ptr(&self) -> NonNull<T> {
666        self.initialized.as_non_null()
667    }
668
669    /// Returns a raw nonnull pointer to the slice, or a dangling raw pointer
670    /// valid for zero sized reads.
671    #[doc(hidden)]
672    #[deprecated = "too niche; compute this yourself if needed"]
673    #[must_use]
674    #[inline(always)]
675    pub fn as_non_null_slice(&self) -> NonNull<[T]> {
676        #[expect(deprecated)]
677        self.initialized.as_non_null_slice()
678    }
679
680    #[inline(always)]
681    pub(crate) unsafe fn set_ptr(&mut self, new_ptr: NonNull<T>) {
682        unsafe { self.initialized.set_ptr(new_ptr) };
683    }
684
685    /// Forces the length of the vector to `new_len`.
686    ///
687    /// This is a low-level operation that maintains none of the normal
688    /// invariants of the type. Normally changing the length of a vector
689    /// is done using one of the safe operations instead, such as
690    /// [`truncate`] or [`clear`].
691    ///
692    /// # Safety
693    /// - `new_len` must be less than or equal to the [`capacity`].
694    /// - The elements at `old_len..new_len` must be initialized.
695    ///
696    /// [`truncate`]: Self::truncate
697    /// [`clear`]: Self::clear
698    /// [`capacity`]: Self::capacity
699    #[inline(always)]
700    pub unsafe fn set_len(&mut self, new_len: usize) {
701        unsafe { self.initialized.set_len(new_len) };
702    }
703
704    #[inline(always)]
705    pub(crate) unsafe fn set_cap(&mut self, new_cap: usize) {
706        self.capacity = new_cap;
707    }
708
709    #[inline]
710    pub(crate) unsafe fn inc_len(&mut self, amount: usize) {
711        unsafe {
712            self.initialized.inc_len(amount);
713        }
714    }
715
716    /// Removes an element from the vector and returns it.
717    ///
718    /// The removed element is replaced by the last element of the vector.
719    ///
720    /// This does not preserve ordering, but is *O*(1).
721    /// If you need to preserve the element order, use [`remove`] instead.
722    ///
723    /// # Panics
724    /// Panics if `index` is out of bounds.
725    ///
726    /// [`remove`]: Self::remove
727    ///
728    /// # Examples
729    /// ```
730    /// # use bump_scope::Bump;
731    /// # let bump: Bump = Bump::new();
732    /// #
733    /// let mut v = bump.alloc_slice_copy(&["foo", "bar", "baz", "qux"]);
734    ///
735    /// assert_eq!(v.swap_remove(1), "bar");
736    /// assert_eq!(v, ["foo", "qux", "baz"]);
737    ///
738    /// assert_eq!(v.swap_remove(0), "foo");
739    /// assert_eq!(v, ["baz", "qux"]);
740    /// ```
741    #[inline]
742    pub fn swap_remove(&mut self, index: usize) -> T {
743        self.initialized.swap_remove(index)
744    }
745
746    /// Splits the vector into two by removing the specified range.
747    ///
748    /// This method does not allocate and does not change the order of the elements.
749    ///
750    /// The excess capacity may end up in either vector.
751    /// 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
752    /// so the original vector keeps its capacity.
753    /// If you rather want that behavior then you can write this instead:
754    /// ```
755    /// # use bump_scope::{Bump, FixedBumpVec};
756    /// # let bump: Bump = Bump::new();
757    /// # let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
758    /// # vec.append([1, 2, 3, 4, 5]);
759    /// # let start = 1;
760    /// # let end = 4;
761    /// let mut other = FixedBumpVec::with_capacity_in(end - start, &bump);
762    /// other.append(vec.drain(start..end));
763    /// # assert_eq!(vec, [1, 5]);
764    /// # assert_eq!(other, [2, 3, 4]);
765    /// ```
766    ///
767    /// # Panics
768    ///
769    /// Panics if the starting point is greater than the end point or if the end point is greater than the length of the vector.
770    ///
771    /// # Complexity
772    ///
773    /// This operation takes `O(1)` time if either the range starts at 0, ends at `len`, or is empty.
774    /// Otherwise it takes `O(min(end, len - start))` time.
775    ///
776    /// # Examples
777    ///
778    /// ```
779    /// # use bump_scope::{Bump, FixedBumpVec};
780    /// # let bump: Bump = Bump::new();
781    /// let mut vec = FixedBumpVec::with_capacity_in(10, &bump);
782    /// vec.append([1, 2, 3, 4, 5, 6, 7, 8]);
783    ///
784    /// let front = vec.split_off(..2);
785    /// assert_eq!(front, [1, 2]);
786    /// assert_eq!(vec, [3, 4, 5, 6, 7, 8]);
787    ///
788    /// let back = vec.split_off(4..);
789    /// assert_eq!(back, [7, 8]);
790    /// assert_eq!(vec, [3, 4, 5, 6]);
791    ///
792    /// let middle = vec.split_off(1..3);
793    /// assert_eq!(middle, [4, 5]);
794    /// assert_eq!(vec, [3, 6]);
795    ///
796    /// let rest = vec.split_off(..);
797    /// assert_eq!(rest, [3, 6]);
798    /// assert_eq!(vec, []);
799    /// ```
800    #[inline]
801    #[expect(clippy::return_self_not_must_use)]
802    pub fn split_off(&mut self, range: impl RangeBounds<usize>) -> Self {
803        let len = self.len();
804        let ops::Range { start, end } = polyfill::slice::range(range, ..len);
805        let ptr = self.initialized.as_non_null();
806
807        unsafe {
808            if T::IS_ZST {
809                let range_len = end - start;
810                let remaining_len = len - range_len;
811
812                self.set_len(remaining_len);
813
814                return FixedBumpVec {
815                    initialized: BumpBox::zst_slice_from_len(range_len),
816                    capacity: usize::MAX,
817                };
818            }
819
820            if end == len {
821                let lhs = ptr;
822                let rhs = ptr.add(start);
823
824                let lhs_len = start;
825                let rhs_len = len - start;
826
827                let lhs_cap = start;
828                let rhs_cap = self.capacity - lhs_cap;
829
830                self.set_ptr(lhs);
831                self.set_len(lhs_len);
832                self.set_cap(lhs_cap);
833
834                return FixedBumpVec {
835                    initialized: BumpBox::from_raw(NonNull::slice_from_raw_parts(rhs, rhs_len)),
836                    capacity: rhs_cap,
837                };
838            }
839
840            if start == 0 {
841                let lhs = ptr;
842                let rhs = ptr.add(end);
843
844                let lhs_len = end;
845                let rhs_len = len - end;
846
847                let lhs_cap = end;
848                let rhs_cap = self.capacity - lhs_cap;
849
850                self.set_ptr(rhs);
851                self.set_len(rhs_len);
852                self.set_cap(rhs_cap);
853
854                return FixedBumpVec {
855                    initialized: BumpBox::from_raw(NonNull::slice_from_raw_parts(lhs, lhs_len)),
856                    capacity: lhs_cap,
857                };
858            }
859
860            if start == end {
861                return FixedBumpVec::new();
862            }
863
864            let head_len = start;
865            let tail_len = len - end;
866
867            let range_len = end - start;
868            let remaining_len = len - range_len;
869
870            if head_len < tail_len {
871                // move the range of elements to split off to the start
872                self.as_mut_slice().get_unchecked_mut(..end).rotate_right(range_len);
873
874                let lhs = ptr;
875                let rhs = ptr.add(range_len);
876
877                let lhs_len = range_len;
878                let rhs_len = remaining_len;
879
880                let lhs_cap = range_len;
881                let rhs_cap = self.capacity - lhs_cap;
882
883                self.set_ptr(rhs);
884                self.set_len(rhs_len);
885                self.set_cap(rhs_cap);
886
887                FixedBumpVec {
888                    initialized: BumpBox::from_raw(NonNull::slice_from_raw_parts(lhs, lhs_len)),
889                    capacity: lhs_cap,
890                }
891            } else {
892                // move the range of elements to split off to the end
893                self.as_mut_slice().get_unchecked_mut(start..).rotate_left(range_len);
894
895                let lhs = ptr;
896                let rhs = ptr.add(remaining_len);
897
898                let lhs_len = remaining_len;
899                let rhs_len = range_len;
900
901                let lhs_cap = remaining_len;
902                let rhs_cap = self.capacity - lhs_cap;
903
904                self.set_ptr(lhs);
905                self.set_len(lhs_len);
906                self.set_cap(lhs_cap);
907
908                FixedBumpVec {
909                    initialized: BumpBox::from_raw(NonNull::slice_from_raw_parts(rhs, rhs_len)),
910                    capacity: rhs_cap,
911                }
912            }
913        }
914    }
915
916    /// Appends an element to the back of a collection.
917    ///
918    /// # Panics
919    /// Panics if the vector does not have enough capacity.
920    ///
921    /// # Examples
922    /// ```
923    /// # use bump_scope::{Bump, FixedBumpVec};
924    /// # let bump: Bump = Bump::new();
925    /// let mut vec = FixedBumpVec::with_capacity_in(3, &bump);
926    /// vec.extend_from_slice_copy(&[1, 2]);
927    /// vec.push(3);
928    /// assert_eq!(vec, [1, 2, 3]);
929    /// ```
930    #[inline(always)]
931    #[cfg(feature = "panic-on-alloc")]
932    pub fn push(&mut self, value: T) {
933        panic_on_error(self.generic_push(value));
934    }
935
936    /// Appends an element to the back of a collection.
937    ///
938    /// # Errors
939    /// Errors if the vector does not have enough capacity.
940    ///
941    /// # Examples
942    /// ```
943    /// # use bump_scope::{Bump, FixedBumpVec};
944    /// # let bump: Bump = Bump::try_new()?;
945    /// let mut vec = FixedBumpVec::try_with_capacity_in(3, &bump)?;
946    /// vec.try_extend_from_slice_copy(&[1, 2])?;
947    /// vec.try_push(3)?;
948    /// assert_eq!(vec, [1, 2, 3]);
949    /// # Ok::<(), bump_scope::alloc::AllocError>(())
950    /// ```
951    #[inline(always)]
952    pub fn try_push(&mut self, value: T) -> Result<(), AllocError> {
953        self.generic_push(value)
954    }
955
956    #[inline]
957    pub(crate) fn generic_push<E: ErrorBehavior>(&mut self, value: T) -> Result<(), E> {
958        self.generic_push_with(|| value)
959    }
960
961    /// Reserves space for one more element, then calls `f`
962    /// to produce the value that is appended.
963    ///
964    /// In some cases this could be more performant than `push(f())` because it
965    /// permits the compiler to directly place `T` in the vector instead of
966    /// constructing it on the stack and copying it over.
967    ///
968    /// # Panics
969    /// Panics if the vector does not have enough capacity.
970    ///
971    /// # Examples
972    /// ```
973    /// # use bump_scope::{Bump, FixedBumpVec};
974    /// # let bump: Bump = Bump::new();
975    /// let mut vec = FixedBumpVec::with_capacity_in(3, &bump);
976    /// vec.append([1, 2]);
977    /// vec.push_with(|| 3);
978    /// assert_eq!(vec, [1, 2, 3]);
979    /// ```
980    #[inline(always)]
981    #[cfg(feature = "panic-on-alloc")]
982    pub fn push_with(&mut self, f: impl FnOnce() -> T) {
983        panic_on_error(self.generic_push_with(f));
984    }
985
986    /// Reserves space for one more element, then calls `f`
987    /// to produce the value that is appended.
988    ///
989    /// In some cases this could be more performant than `push(f())` because it
990    /// permits the compiler to directly place `T` in the vector instead of
991    /// constructing it on the stack and copying it over.
992    ///
993    /// # Errors
994    /// Errors if the vector does not have enough capacity.
995    ///
996    /// # Examples
997    /// ```
998    /// # use bump_scope::{Bump, FixedBumpVec};
999    /// # let bump: Bump = Bump::new();
1000    /// let mut vec = FixedBumpVec::try_with_capacity_in(3, &bump)?;
1001    /// vec.try_append([1, 2])?;
1002    /// vec.try_push_with(|| 3)?;
1003    /// assert_eq!(vec, [1, 2, 3]);
1004    ///
1005    /// let push_result = vec.try_push_with(|| unreachable!());
1006    /// assert!(push_result.is_err());
1007    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1008    /// ```
1009    #[inline(always)]
1010    pub fn try_push_with(&mut self, f: impl FnOnce() -> T) -> Result<(), AllocError> {
1011        self.generic_push_with(f)
1012    }
1013
1014    #[inline]
1015    pub(crate) fn generic_push_with<E: ErrorBehavior>(&mut self, f: impl FnOnce() -> T) -> Result<(), E> {
1016        self.generic_reserve_one()?;
1017        unsafe {
1018            self.push_with_unchecked(f);
1019        }
1020        Ok(())
1021    }
1022
1023    /// Inserts an element at position `index` within the vector, shifting all elements after it to the right.
1024    ///
1025    /// # Panics
1026    /// Panics if the vector does not have enough capacity.
1027    ///
1028    /// Panics if `index > len`.
1029    ///
1030    /// # Examples
1031    /// ```
1032    /// # use bump_scope::{Bump, FixedBumpVec};
1033    /// # let bump: Bump = Bump::new();
1034    /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
1035    /// vec.extend_from_slice_copy(&[1, 2, 3]);
1036    /// vec.insert(1, 4);
1037    /// assert_eq!(vec, [1, 4, 2, 3]);
1038    /// vec.insert(4, 5);
1039    /// assert_eq!(vec, [1, 4, 2, 3, 5]);
1040    /// ```
1041    #[inline(always)]
1042    #[cfg(feature = "panic-on-alloc")]
1043    pub fn insert(&mut self, index: usize, element: T) {
1044        panic_on_error(self.generic_insert(index, element));
1045    }
1046
1047    /// Inserts an element at position `index` within the vector, shifting all elements after it to the right.
1048    ///
1049    /// # Panics
1050    /// Panics if `index > len`.
1051    ///
1052    /// # Errors
1053    /// Errors if the vector does not have enough capacity.
1054    ///
1055    /// # Examples
1056    /// ```
1057    /// # use bump_scope::{Bump, FixedBumpVec};
1058    /// # let bump: Bump = Bump::try_new()?;
1059    /// let mut vec = FixedBumpVec::try_with_capacity_in(5, &bump)?;
1060    /// vec.try_extend_from_slice_copy(&[1, 2, 3])?;
1061    /// vec.try_insert(1, 4)?;
1062    /// assert_eq!(vec, [1, 4, 2, 3]);
1063    /// vec.try_insert(4, 5)?;
1064    /// assert_eq!(vec, [1, 4, 2, 3, 5]);
1065    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1066    /// ```
1067    #[inline(always)]
1068    pub fn try_insert(&mut self, index: usize, element: T) -> Result<(), AllocError> {
1069        self.generic_insert(index, element)
1070    }
1071
1072    #[inline]
1073    pub(crate) fn generic_insert<E: ErrorBehavior>(&mut self, index: usize, element: T) -> Result<(), E> {
1074        #[cold]
1075        #[track_caller]
1076        #[inline(never)]
1077        fn assert_failed(index: usize, len: usize) -> ! {
1078            panic!("insertion index (is {index}) should be <= len (is {len})");
1079        }
1080
1081        if index > self.len() {
1082            assert_failed(index, self.len());
1083        }
1084
1085        self.generic_reserve_one()?;
1086
1087        unsafe {
1088            let pos = self.as_mut_ptr().add(index);
1089
1090            if index != self.len() {
1091                let len = self.len() - index;
1092                ptr::copy(pos, pos.add(1), len);
1093            }
1094
1095            pos.write(element);
1096            self.inc_len(1);
1097        }
1098
1099        Ok(())
1100    }
1101
1102    /// Copies and appends all elements in a slice to the `FixedBumpVec`.
1103    ///
1104    /// Iterates over the `slice`, copies each element, and then appends
1105    /// it to this `FixedBumpVec`. The `slice` is traversed in-order.
1106    ///
1107    /// Note that this function is same as [`extend`] except that it is
1108    /// specialized to work with copyable slices instead.
1109    ///
1110    /// [`extend`]: Self::extend
1111    ///
1112    /// # Panics
1113    /// Panics if the vector does not have enough capacity.
1114    ///
1115    /// # Examples
1116    /// ```
1117    /// # use bump_scope::{ Bump, FixedBumpVec };
1118    /// # let bump: Bump = Bump::new();
1119    /// let mut vec = FixedBumpVec::with_capacity_in(4, &bump);
1120    /// vec.push(1);
1121    /// vec.extend_from_slice_copy(&[2, 3, 4]);
1122    /// assert_eq!(vec, [1, 2, 3, 4]);
1123    /// ```
1124    #[inline(always)]
1125    #[cfg(feature = "panic-on-alloc")]
1126    pub fn extend_from_slice_copy(&mut self, slice: &[T])
1127    where
1128        T: Copy,
1129    {
1130        panic_on_error(self.generic_extend_from_slice_copy(slice));
1131    }
1132
1133    /// Copies and appends all elements in a slice to the `FixedBumpVec`.
1134    ///
1135    /// Iterates over the `slice`, copies each element, and then appends
1136    /// it to this `FixedBumpVec`. The `slice` is traversed in-order.
1137    ///
1138    /// Note that this function is same as [`extend`] except that it is
1139    /// specialized to work with copyable slices instead.
1140    ///
1141    /// [`extend`]: Self::extend
1142    ///
1143    /// # Errors
1144    /// Errors if the vector does not have enough capacity.
1145    ///
1146    /// # Examples
1147    /// ```
1148    /// # use bump_scope::{ Bump, FixedBumpVec };
1149    /// # let bump: Bump = Bump::new();
1150    /// let mut vec = FixedBumpVec::try_with_capacity_in(4, &bump)?;
1151    /// vec.try_push(1)?;
1152    /// vec.try_extend_from_slice_copy(&[2, 3, 4])?;
1153    /// assert_eq!(vec, [1, 2, 3, 4]);
1154    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1155    /// ```
1156    #[inline(always)]
1157    pub fn try_extend_from_slice_copy(&mut self, slice: &[T]) -> Result<(), AllocError>
1158    where
1159        T: Copy,
1160    {
1161        self.generic_extend_from_slice_copy(slice)
1162    }
1163
1164    #[inline]
1165    pub(crate) fn generic_extend_from_slice_copy<E: ErrorBehavior>(&mut self, slice: &[T]) -> Result<(), E>
1166    where
1167        T: Copy,
1168    {
1169        unsafe { self.extend_by_copy_nonoverlapping(slice) }
1170    }
1171
1172    /// Clones and appends all elements in a slice to the `FixedBumpVec`.
1173    ///
1174    /// Iterates over the `slice`, clones each element, and then appends
1175    /// it to this `FixedBumpVec`. The `slice` is traversed in-order.
1176    ///
1177    /// Note that this function is same as [`extend`] except that it is
1178    /// specialized to work with slices instead.
1179    ///
1180    /// [`extend`]: Self::extend
1181    ///
1182    /// # Panics
1183    /// Panics if the vector does not have enough capacity.
1184    ///
1185    /// # Examples
1186    /// ```
1187    /// # use std::string::String;
1188    /// # use bump_scope::{ Bump, FixedBumpVec };
1189    /// # let bump: Bump = Bump::new();
1190    /// let mut vec = FixedBumpVec::with_capacity_in(3, &bump);
1191    /// vec.push(String::from("a"));
1192    /// vec.extend_from_slice_clone(&[String::from("b"), String::from("c")]);
1193    /// assert_eq!(vec, ["a", "b", "c"]);
1194    /// ```
1195    #[inline(always)]
1196    #[cfg(feature = "panic-on-alloc")]
1197    pub fn extend_from_slice_clone(&mut self, slice: &[T])
1198    where
1199        T: Clone,
1200    {
1201        panic_on_error(self.generic_extend_from_slice_clone(slice));
1202    }
1203
1204    /// Clones and appends all elements in a slice to the `FixedBumpVec`.
1205    ///
1206    /// Iterates over the `slice`, clones each element, and then appends
1207    /// it to this `FixedBumpVec`. The `slice` is traversed in-order.
1208    ///
1209    /// Note that this function is same as [`extend`] except that it is
1210    /// specialized to work with slices instead.
1211    ///
1212    /// [`extend`]: Self::extend
1213    ///
1214    /// # Errors
1215    /// Errors if the vector does not have enough capacity.
1216    ///
1217    /// # Examples
1218    /// ```
1219    /// # use std::string::String;
1220    /// # use bump_scope::{ Bump, FixedBumpVec };
1221    /// # let bump: Bump = Bump::new();
1222    /// let mut vec = FixedBumpVec::try_with_capacity_in(3, &bump)?;
1223    /// vec.try_push(String::from("a"))?;
1224    /// vec.try_extend_from_slice_clone(&[String::from("b"), String::from("c")])?;
1225    /// assert_eq!(vec, ["a", "b", "c"]);
1226    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1227    /// ```
1228    #[inline(always)]
1229    pub fn try_extend_from_slice_clone(&mut self, slice: &[T]) -> Result<(), AllocError>
1230    where
1231        T: Clone,
1232    {
1233        self.generic_extend_from_slice_clone(slice)
1234    }
1235
1236    #[inline]
1237    pub(crate) fn generic_extend_from_slice_clone<E: ErrorBehavior>(&mut self, slice: &[T]) -> Result<(), E>
1238    where
1239        T: Clone,
1240    {
1241        self.generic_reserve(slice.len())?;
1242
1243        unsafe {
1244            let mut pos = 0usize;
1245
1246            while likely(pos != slice.len()) {
1247                let elem = slice.get_unchecked(pos);
1248                self.push_unchecked(elem.clone());
1249                pos += 1;
1250            }
1251        }
1252
1253        Ok(())
1254    }
1255
1256    /// Copies elements from `src` range to the end of the vector.
1257    ///
1258    /// # Panics
1259    /// Panics if the vector does not have enough capacity.
1260    ///
1261    /// Panics if the starting point is greater than the end point or if
1262    /// the end point is greater than the length of the vector.
1263    ///
1264    /// # Examples
1265    /// ```
1266    /// # use bump_scope::{Bump, FixedBumpVec};
1267    /// # let bump: Bump = Bump::new();
1268    /// let mut vec = FixedBumpVec::with_capacity_in(100, &bump);
1269    /// vec.extend_from_slice_copy(&[0, 1, 2, 3, 4]);
1270    ///
1271    /// vec.extend_from_within_copy(2..);
1272    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1273    ///
1274    /// vec.extend_from_within_copy(..2);
1275    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1276    ///
1277    /// vec.extend_from_within_copy(4..8);
1278    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1279    /// ```
1280    #[inline(always)]
1281    #[cfg(feature = "panic-on-alloc")]
1282    pub fn extend_from_within_copy<R>(&mut self, src: R)
1283    where
1284        T: Copy,
1285        R: RangeBounds<usize>,
1286    {
1287        panic_on_error(self.generic_extend_from_within_copy(src));
1288    }
1289
1290    /// Copies elements from `src` range to the end of the vector.
1291    ///
1292    /// # Panics
1293    /// Panics if the starting point is greater than the end point or if
1294    /// the end point is greater than the length of the vector.
1295    ///
1296    /// # Errors
1297    /// Errors if the vector does not have enough capacity.
1298    ///
1299    /// # Examples
1300    /// ```
1301    /// # use bump_scope::{Bump, FixedBumpVec};
1302    /// # let bump: Bump = Bump::try_new()?;
1303    /// let mut vec = FixedBumpVec::try_with_capacity_in(100, &bump)?;
1304    /// vec.try_extend_from_slice_copy(&[0, 1, 2, 3, 4])?;
1305    ///
1306    /// vec.try_extend_from_within_copy(2..)?;
1307    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1308    ///
1309    /// vec.try_extend_from_within_copy(..2)?;
1310    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1311    ///
1312    /// vec.try_extend_from_within_copy(4..8)?;
1313    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1314    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1315    /// ```
1316    #[inline(always)]
1317    pub fn try_extend_from_within_copy<R>(&mut self, src: R) -> Result<(), AllocError>
1318    where
1319        T: Copy,
1320        R: RangeBounds<usize>,
1321    {
1322        self.generic_extend_from_within_copy(src)
1323    }
1324
1325    #[inline]
1326    pub(crate) fn generic_extend_from_within_copy<E: ErrorBehavior, R>(&mut self, src: R) -> Result<(), E>
1327    where
1328        T: Copy,
1329        R: RangeBounds<usize>,
1330    {
1331        let range = slice::range(src, ..self.len());
1332        let count = range.len();
1333
1334        self.generic_reserve(count)?;
1335
1336        // SAFETY:
1337        // - `slice::range` guarantees that the given range is valid for indexing self
1338        unsafe {
1339            let ptr = self.as_mut_ptr();
1340
1341            let src = ptr.add(range.start);
1342            let dst = ptr.add(self.len());
1343            ptr::copy_nonoverlapping(src, dst, count);
1344
1345            self.inc_len(count);
1346            Ok(())
1347        }
1348    }
1349
1350    /// Clones elements from `src` range to the end of the vector.
1351    ///
1352    /// # Panics
1353    /// Panics if the vector does not have enough capacity.
1354    ///
1355    /// Panics if the starting point is greater than the end point or if
1356    /// the end point is greater than the length of the vector.
1357    ///
1358    /// # Examples
1359    /// ```
1360    /// # use bump_scope::{Bump, FixedBumpVec};
1361    /// # let bump: Bump = Bump::new();
1362    /// let mut vec = FixedBumpVec::with_capacity_in(14, &bump);
1363    /// vec.extend_from_slice_copy(&[0, 1, 2, 3, 4]);
1364    ///
1365    /// vec.extend_from_within_clone(2..);
1366    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1367    ///
1368    /// vec.extend_from_within_clone(..2);
1369    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1370    ///
1371    /// vec.extend_from_within_clone(4..8);
1372    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1373    /// ```
1374    #[inline(always)]
1375    #[cfg(feature = "panic-on-alloc")]
1376    pub fn extend_from_within_clone<R>(&mut self, src: R)
1377    where
1378        T: Clone,
1379        R: RangeBounds<usize>,
1380    {
1381        panic_on_error(self.generic_extend_from_within_clone(src));
1382    }
1383
1384    /// Clones elements from `src` range to the end of the vector.
1385    ///
1386    /// # Panics
1387    /// Panics if the starting point is greater than the end point or if
1388    /// the end point is greater than the length of the vector.
1389    ///
1390    /// # Errors
1391    /// Errors if the vector does not have enough capacity.
1392    ///
1393    /// # Examples
1394    /// ```
1395    /// # use bump_scope::{Bump, FixedBumpVec};
1396    /// # let bump: Bump = Bump::try_new()?;
1397    /// let mut vec = FixedBumpVec::try_with_capacity_in(14, &bump)?;
1398    /// vec.try_extend_from_slice_copy(&[0, 1, 2, 3, 4])?;
1399    ///
1400    /// vec.try_extend_from_within_clone(2..)?;
1401    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1402    ///
1403    /// vec.try_extend_from_within_clone(..2)?;
1404    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1405    ///
1406    /// vec.try_extend_from_within_clone(4..8)?;
1407    /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1408    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1409    /// ```
1410    #[inline(always)]
1411    pub fn try_extend_from_within_clone<R>(&mut self, src: R) -> Result<(), AllocError>
1412    where
1413        T: Clone,
1414        R: RangeBounds<usize>,
1415    {
1416        self.generic_extend_from_within_clone(src)
1417    }
1418
1419    #[inline]
1420    pub(crate) fn generic_extend_from_within_clone<E: ErrorBehavior, R>(&mut self, src: R) -> Result<(), E>
1421    where
1422        T: Clone,
1423        R: RangeBounds<usize>,
1424    {
1425        let range = slice::range(src, ..self.len());
1426        let count = range.len();
1427
1428        self.generic_reserve(count)?;
1429
1430        if T::IS_ZST {
1431            unsafe {
1432                // We can materialize ZST's from nothing.
1433                #[expect(clippy::uninit_assumed_init)]
1434                let fake = ManuallyDrop::new(MaybeUninit::<T>::uninit().assume_init());
1435
1436                for _ in 0..count {
1437                    self.push_unchecked((*fake).clone());
1438                }
1439
1440                return Ok(());
1441            }
1442        }
1443
1444        // SAFETY:
1445        // - `slice::range` guarantees that the given range is valid for indexing self
1446        unsafe {
1447            let ptr = self.as_mut_ptr();
1448
1449            let mut src = ptr.add(range.start);
1450            let mut dst = ptr.add(self.len());
1451
1452            let src_end = src.add(count);
1453
1454            while src != src_end {
1455                dst.write((*src).clone());
1456
1457                src = src.add(1);
1458                dst = dst.add(1);
1459                self.inc_len(1);
1460            }
1461        }
1462
1463        Ok(())
1464    }
1465
1466    /// Checks if at least `additional` more elements can be inserted
1467    /// in the given `FixedBumpVec<T>` due to capacity.
1468    ///
1469    /// # Panics
1470    /// Panics if the vector does not have enough capacity.
1471    #[inline(always)]
1472    #[cfg(feature = "panic-on-alloc")]
1473    pub fn reserve(&mut self, additional: usize) {
1474        panic_on_error(self.generic_reserve(additional));
1475    }
1476
1477    /// Checks if at least `additional` more elements can be inserted
1478    /// in the given `FixedBumpVec<T>` due to capacity.
1479    ///
1480    /// # Errors
1481    /// Errors if the vector does not have enough capacity.
1482    #[inline(always)]
1483    pub fn try_reserve(&mut self, additional: usize) -> Result<(), AllocError> {
1484        self.generic_reserve(additional)
1485    }
1486
1487    #[inline]
1488    pub(crate) fn generic_reserve<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
1489        if additional > (self.capacity() - self.len()) {
1490            Err(E::fixed_size_vector_no_space(additional))
1491        } else {
1492            Ok(())
1493        }
1494    }
1495
1496    /// Resizes the `FixedBumpVec` in-place so that `len` is equal to `new_len`.
1497    ///
1498    /// If `new_len` is greater than `len`, the `FixedBumpVec` is extended by the
1499    /// difference, with each additional slot filled with `value`.
1500    /// If `new_len` is less than `len`, the `FixedBumpVec` is simply truncated.
1501    ///
1502    /// This method requires `T` to implement [`Clone`],
1503    /// in order to be able to clone the passed value.
1504    /// If you need more flexibility (or want to rely on [`Default`] instead of
1505    /// [`Clone`]), use [`resize_with`].
1506    /// If you only need to resize to a smaller size, use [`truncate`].
1507    ///
1508    /// [`resize_with`]: Self::resize_with
1509    /// [`truncate`]: Self::truncate
1510    ///
1511    /// # Panics
1512    /// Panics if the vector does not have enough capacity.
1513    ///
1514    /// # Examples
1515    /// ```
1516    /// # use bump_scope::{Bump, FixedBumpVec};
1517    /// # let bump: Bump = Bump::new();
1518    /// let mut vec = FixedBumpVec::with_capacity_in(10, &bump);
1519    /// vec.extend_from_slice_copy(&["hello"]);
1520    /// vec.resize(3, "world");
1521    /// assert_eq!(vec, ["hello", "world", "world"]);
1522    /// drop(vec);
1523    ///
1524    /// let mut vec = FixedBumpVec::with_capacity_in(10, &bump);
1525    /// vec.extend_from_slice_copy(&[1, 2, 3, 4]);
1526    /// vec.resize(2, 0);
1527    /// assert_eq!(vec, [1, 2]);
1528    /// ```
1529    #[inline(always)]
1530    #[cfg(feature = "panic-on-alloc")]
1531    pub fn resize(&mut self, new_len: usize, value: T)
1532    where
1533        T: Clone,
1534    {
1535        panic_on_error(self.generic_resize(new_len, value));
1536    }
1537
1538    /// Resizes the `FixedBumpVec` in-place so that `len` is equal to `new_len`.
1539    ///
1540    /// If `new_len` is greater than `len`, the `FixedBumpVec` is extended by the
1541    /// difference, with each additional slot filled with `value`.
1542    /// If `new_len` is less than `len`, the `FixedBumpVec` is simply truncated.
1543    ///
1544    /// This method requires `T` to implement [`Clone`],
1545    /// in order to be able to clone the passed value.
1546    /// If you need more flexibility (or want to rely on [`Default`] instead of
1547    /// [`Clone`]), use [`resize_with`].
1548    /// If you only need to resize to a smaller size, use [`truncate`].
1549    ///
1550    /// [`resize_with`]: Self::resize_with
1551    /// [`truncate`]: Self::truncate
1552    ///
1553    /// # Errors
1554    /// Errors if the vector does not have enough capacity.
1555    ///
1556    /// # Examples
1557    /// ```
1558    /// # use bump_scope::{Bump, FixedBumpVec};
1559    /// # let bump: Bump = Bump::try_new()?;
1560    /// let mut vec = FixedBumpVec::try_with_capacity_in(10, &bump)?;
1561    /// vec.try_extend_from_slice_copy(&["hello"])?;
1562    /// vec.try_resize(3, "world")?;
1563    /// assert_eq!(vec, ["hello", "world", "world"]);
1564    /// drop(vec);
1565    ///
1566    /// let mut vec = FixedBumpVec::try_with_capacity_in(10, &bump)?;
1567    /// vec.try_extend_from_slice_copy(&[1, 2, 3, 4])?;
1568    /// vec.try_resize(2, 0)?;
1569    /// assert_eq!(vec, [1, 2]);
1570    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1571    /// ```
1572    #[inline(always)]
1573    pub fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), AllocError>
1574    where
1575        T: Clone,
1576    {
1577        self.generic_resize(new_len, value)
1578    }
1579
1580    #[inline]
1581    pub(crate) fn generic_resize<E: ErrorBehavior>(&mut self, new_len: usize, value: T) -> Result<(), E>
1582    where
1583        T: Clone,
1584    {
1585        let len = self.len();
1586
1587        if new_len > len {
1588            self.extend_with(new_len - len, value)
1589        } else {
1590            self.truncate(new_len);
1591            Ok(())
1592        }
1593    }
1594
1595    /// Resizes the `FixedBumpVec` in-place so that `len` is equal to `new_len`.
1596    ///
1597    /// If `new_len` is greater than `len`, the `FixedBumpVec` is extended by the
1598    /// difference, with each additional slot filled with the result of
1599    /// calling the closure `f`. The return values from `f` will end up
1600    /// in the `FixedBumpVec` in the order they have been generated.
1601    ///
1602    /// If `new_len` is less than `len`, the `FixedBumpVec` is simply truncated.
1603    ///
1604    /// This method uses a closure to create new values on every push. If
1605    /// you'd rather [`Clone`] a given value, use [`FixedBumpVec::resize`]. If you
1606    /// want to use the [`Default`] trait to generate values, you can
1607    /// pass [`Default::default`] as the second argument.
1608    ///
1609    /// # Panics
1610    /// Panics if the vector does not have enough capacity.
1611    ///
1612    /// # Examples
1613    /// ```
1614    /// # use bump_scope::{Bump, FixedBumpVec};
1615    /// # let bump: Bump = Bump::new();
1616    /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
1617    /// vec.extend_from_slice_copy(&[1, 2, 3]);
1618    /// vec.resize_with(5, Default::default);
1619    /// assert_eq!(vec, [1, 2, 3, 0, 0]);
1620    /// drop(vec);
1621    ///
1622    /// let mut vec = FixedBumpVec::with_capacity_in(4, &bump);
1623    /// let mut p = 1;
1624    /// vec.resize_with(4, || { p *= 2; p });
1625    /// assert_eq!(vec, [2, 4, 8, 16]);
1626    /// ```
1627    #[inline(always)]
1628    #[cfg(feature = "panic-on-alloc")]
1629    pub fn resize_with<F>(&mut self, new_len: usize, f: F)
1630    where
1631        F: FnMut() -> T,
1632    {
1633        panic_on_error(self.generic_resize_with(new_len, f));
1634    }
1635
1636    /// Resizes the `FixedBumpVec` in-place so that `len` is equal to `new_len`.
1637    ///
1638    /// If `new_len` is greater than `len`, the `FixedBumpVec` is extended by the
1639    /// difference, with each additional slot filled with the result of
1640    /// calling the closure `f`. The return values from `f` will end up
1641    /// in the `FixedBumpVec` in the order they have been generated.
1642    ///
1643    /// If `new_len` is less than `len`, the `FixedBumpVec` is simply truncated.
1644    ///
1645    /// This method uses a closure to create new values on every push. If
1646    /// you'd rather [`Clone`] a given value, use [`FixedBumpVec::resize`]. If you
1647    /// want to use the [`Default`] trait to generate values, you can
1648    /// pass [`Default::default`] as the second argument.
1649    ///
1650    /// # Errors
1651    /// Errors if the vector does not have enough capacity.
1652    ///
1653    /// # Examples
1654    /// ```
1655    /// # use bump_scope::{Bump, FixedBumpVec};
1656    /// # let bump: Bump = Bump::try_new()?;
1657    /// let mut vec = FixedBumpVec::try_with_capacity_in(5, &bump)?;
1658    /// vec.try_extend_from_slice_copy(&[1, 2, 3])?;
1659    /// vec.try_resize_with(5, Default::default)?;
1660    /// assert_eq!(vec, [1, 2, 3, 0, 0]);
1661    /// drop(vec);
1662    ///
1663    /// let mut vec = FixedBumpVec::try_with_capacity_in(4, &bump)?;
1664    /// let mut p = 1;
1665    /// vec.try_resize_with(4, || { p *= 2; p })?;
1666    /// assert_eq!(vec, [2, 4, 8, 16]);
1667    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1668    /// ```
1669    #[inline(always)]
1670    pub fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), AllocError>
1671    where
1672        F: FnMut() -> T,
1673    {
1674        self.generic_resize_with(new_len, f)
1675    }
1676
1677    #[inline]
1678    pub(crate) fn generic_resize_with<E: ErrorBehavior, F>(&mut self, new_len: usize, f: F) -> Result<(), E>
1679    where
1680        F: FnMut() -> T,
1681    {
1682        let len = self.len();
1683        if new_len > len {
1684            unsafe { self.extend_trusted(iter::repeat_with(f).take(new_len - len)) }
1685        } else {
1686            self.truncate(new_len);
1687            Ok(())
1688        }
1689    }
1690
1691    /// Moves all the elements of `other` into `self`, leaving `other` empty.
1692    ///
1693    /// # Panics
1694    /// Panics if the vector does not have enough capacity.
1695    ///
1696    /// # Examples
1697    /// ```
1698    /// # use bump_scope::{Bump, FixedBumpVec};
1699    /// # let bump: Bump = Bump::new();
1700    /// let mut vec = FixedBumpVec::with_capacity_in(8, &bump);
1701    ///
1702    /// // append by value
1703    /// vec.append([1, 2]);
1704    /// vec.append(vec![3, 4]);
1705    /// vec.append(bump.alloc_iter(5..=6));
1706    ///
1707    /// // append by mutable reference
1708    /// let mut other = vec![7, 8];
1709    /// vec.append(&mut other);
1710    ///
1711    /// assert_eq!(other, []);
1712    /// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]);
1713    /// ```
1714    #[inline(always)]
1715    #[cfg(feature = "panic-on-alloc")]
1716    pub fn append(&mut self, other: impl OwnedSlice<Item = T>) {
1717        panic_on_error(self.generic_append(other));
1718    }
1719
1720    /// Moves all the elements of `other` into `self`, leaving `other` empty.
1721    ///
1722    /// # Errors
1723    /// Errors if the vector does not have enough capacity.
1724    ///
1725    /// # Examples
1726    /// ```
1727    /// # use bump_scope::{Bump, FixedBumpVec};
1728    /// # let bump: Bump = Bump::new();
1729    /// let mut vec = FixedBumpVec::try_with_capacity_in(8, &bump)?;
1730    ///
1731    /// // append by value
1732    /// vec.try_append([1, 2])?;
1733    /// vec.try_append(vec![3, 4])?;
1734    /// vec.try_append(bump.alloc_iter(5..=6))?;
1735    ///
1736    /// // append by mutable reference
1737    /// let mut other = vec![7, 8];
1738    /// vec.try_append(&mut other)?;
1739    ///
1740    /// assert_eq!(other, []);
1741    /// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]);
1742    /// # Ok::<(), bump_scope::alloc::AllocError>(())
1743    /// ```
1744    #[inline(always)]
1745    pub fn try_append(&mut self, other: impl OwnedSlice<Item = T>) -> Result<(), AllocError> {
1746        self.generic_append(other)
1747    }
1748
1749    #[inline]
1750    pub(crate) fn generic_append<E: ErrorBehavior>(&mut self, other: impl OwnedSlice<Item = T>) -> Result<(), E> {
1751        unsafe {
1752            let mut owned_slice = other.into_take_owned_slice();
1753
1754            let slice = NonNull::from(owned_slice.owned_slice_ref());
1755            self.generic_reserve(slice.len())?;
1756
1757            let src = slice.cast::<T>().as_ptr();
1758            let dst = self.as_mut_ptr().add(self.len());
1759            ptr::copy_nonoverlapping(src, dst, slice.len());
1760
1761            owned_slice.take_owned_slice();
1762            self.inc_len(slice.len());
1763            Ok(())
1764        }
1765    }
1766
1767    /// Returns a fixed vector of the same size as `self`, with function `f` applied to each element in order.
1768    ///
1769    /// 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.
1770    ///
1771    /// # Examples
1772    /// Mapping to a type with an equal alignment and size:
1773    /// ```
1774    /// # use bump_scope::{Bump, FixedBumpVec};
1775    /// # use core::num::NonZero;
1776    /// # let bump: Bump = Bump::new();
1777    /// let a = FixedBumpVec::from_iter_exact_in([0, 1, 2], &bump);
1778    /// let b = a.map_in_place(NonZero::new);
1779    /// assert_eq!(format!("{b:?}"), "[None, Some(1), Some(2)]");
1780    /// ```
1781    ///
1782    /// Mapping to a type with a smaller alignment and size:
1783    /// ```
1784    /// # use bump_scope::{Bump, FixedBumpVec};
1785    /// # let bump: Bump = Bump::new();
1786    /// let a: FixedBumpVec<u32> = FixedBumpVec::from_iter_exact_in([0, 1, 2], &bump);
1787    /// assert_eq!(a.capacity(), 3);
1788    ///
1789    /// let b: FixedBumpVec<u16> = a.map_in_place(|i| i as u16);
1790    /// assert_eq!(b.capacity(), 6);
1791    ///
1792    /// assert_eq!(b, [0, 1, 2]);
1793    /// ```
1794    ///
1795    /// Mapping to a type with a greater alignment won't compile:
1796    /// ```compile_fail,E0080
1797    /// # use bump_scope::{Bump, FixedBumpVec};
1798    /// # let bump: Bump = Bump::new();
1799    /// let a: FixedBumpVec<[u8; 4]> = FixedBumpVec::from_iter_exact_in([[0, 1, 2, 3]], &bump);
1800    /// let b: FixedBumpVec<u32> = a.map_in_place(u32::from_le_bytes);
1801    /// # _ = b;
1802    /// ```
1803    ///
1804    /// Mapping to a type with a greater size won't compile:
1805    /// ```compile_fail,E0080
1806    /// # use bump_scope::{Bump, FixedBumpVec};
1807    /// # let bump: Bump = Bump::new();
1808    /// let a: FixedBumpVec<u32> = FixedBumpVec::from_iter_exact_in([42], &bump);
1809    /// let b: FixedBumpVec<[u32; 2]> = a.map_in_place(|i| [i; 2]);
1810    /// # _ = b;
1811    /// ```
1812    pub fn map_in_place<U>(self, f: impl FnMut(T) -> U) -> FixedBumpVec<'a, U> {
1813        let Self { initialized, capacity } = self;
1814
1815        FixedBumpVec {
1816            initialized: initialized.map_in_place(f),
1817            capacity: if U::IS_ZST {
1818                usize::MAX
1819            } else {
1820                (capacity * T::SIZE) / U::SIZE
1821            },
1822        }
1823    }
1824
1825    /// Appends an element to the back of the collection.
1826    ///
1827    /// # Safety
1828    /// Vector must not be full.
1829    #[inline(always)]
1830    pub unsafe fn push_unchecked(&mut self, value: T) {
1831        unsafe {
1832            self.push_with_unchecked(|| value);
1833        }
1834    }
1835
1836    /// Appends an element to the back of the collection.
1837    ///
1838    /// # Safety
1839    /// Vector must not be full.
1840    #[inline(always)]
1841    pub unsafe fn push_with_unchecked(&mut self, f: impl FnOnce() -> T) {
1842        debug_assert!(!self.is_full());
1843
1844        unsafe {
1845            let ptr = self.as_mut_ptr().add(self.len());
1846            pointer::write_with(ptr, f);
1847            self.inc_len(1);
1848        }
1849    }
1850
1851    /// Extend the vector by `n` clones of value.
1852    fn extend_with<B: ErrorBehavior>(&mut self, n: usize, value: T) -> Result<(), B>
1853    where
1854        T: Clone,
1855    {
1856        self.generic_reserve(n)?;
1857        unsafe {
1858            self.extend_with_unchecked(n, value);
1859        }
1860        Ok(())
1861    }
1862
1863    /// Extend the vector by `n` clones of value.
1864    ///
1865    /// # Safety
1866    /// Capacity must be sufficient.
1867    pub(crate) unsafe fn extend_with_unchecked(&mut self, n: usize, value: T)
1868    where
1869        T: Clone,
1870    {
1871        unsafe {
1872            let mut ptr = self.as_mut_ptr().add(self.len());
1873
1874            // Use SetLenOnDrop to work around bug where compiler
1875            // might not realize the store through `ptr` through self.set_len()
1876            // don't alias.
1877            let mut local_len = self.initialized.set_len_on_drop();
1878
1879            // Write all elements except the last one
1880            for _ in 1..n {
1881                pointer::write_with(ptr, || value.clone());
1882                ptr = ptr.add(1);
1883
1884                // Increment the length in every step in case clone() panics
1885                local_len.increment_len(1);
1886            }
1887
1888            if n > 0 {
1889                // We can write the last element directly without cloning needlessly
1890                ptr.write(value);
1891                local_len.increment_len(1);
1892            }
1893
1894            // len set by scope guard
1895        }
1896    }
1897
1898    /// Retains only the elements specified by the predicate, passing a mutable reference to it.
1899    ///
1900    /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
1901    /// This method operates in place, visiting each element exactly once in the
1902    /// original order, and preserves the order of the retained elements.
1903    ///
1904    /// # Examples
1905    ///
1906    /// ```
1907    /// # use bump_scope::{Bump, FixedBumpVec};
1908    /// # let bump: Bump = Bump::new();
1909    /// #
1910    /// let mut vec = FixedBumpVec::with_capacity_in(4, &bump);
1911    /// vec.extend_from_slice_copy(&[1, 2, 3, 4]);
1912    ///
1913    /// vec.retain(|x| if *x <= 3 {
1914    ///     *x += 1;
1915    ///     true
1916    /// } else {
1917    ///     false
1918    /// });
1919    ///
1920    /// assert_eq!(vec, [2, 3, 4]);
1921    /// ```
1922    #[expect(clippy::pedantic)]
1923    pub fn retain<F>(&mut self, f: F)
1924    where
1925        F: FnMut(&mut T) -> bool,
1926    {
1927        self.initialized.retain(f)
1928    }
1929
1930    /// Removes the specified range from the vector in bulk, returning all
1931    /// removed elements as an iterator. If the iterator is dropped before
1932    /// being fully consumed, it drops the remaining removed elements.
1933    ///
1934    /// The returned iterator keeps a mutable borrow on the vector to optimize
1935    /// its implementation.
1936    ///
1937    /// # Panics
1938    ///
1939    /// Panics if the starting point is greater than the end point or if
1940    /// the end point is greater than the length of the vector.
1941    ///
1942    /// # Leaking
1943    ///
1944    /// If the returned iterator goes out of scope without being dropped (due to
1945    /// [`mem::forget`](core::mem::forget), for example), the vector may have lost and leaked
1946    /// elements arbitrarily, including elements outside the range.
1947    ///
1948    /// # Examples
1949    ///
1950    /// ```
1951    /// # use bump_scope::{Bump, FixedBumpVec};
1952    /// # let bump: Bump = Bump::new();
1953    /// #
1954    /// let mut v = FixedBumpVec::with_capacity_in(3, &bump);
1955    /// v.extend_from_slice_copy(&[1, 2, 3]);
1956    /// let u = bump.alloc_iter(v.drain(1..));
1957    /// assert_eq!(v, [1]);
1958    /// assert_eq!(u, [2, 3]);
1959    ///
1960    /// // A full range clears the vector, like `clear()` does
1961    /// v.drain(..);
1962    /// assert_eq!(v, []);
1963    /// ```
1964    pub fn drain<R>(&mut self, range: R) -> owned_slice::Drain<'_, T>
1965    where
1966        R: RangeBounds<usize>,
1967    {
1968        self.initialized.drain(range)
1969    }
1970
1971    /// Creates an iterator which uses a closure to determine if an element should be removed.
1972    ///
1973    /// If the closure returns true, then the element is removed and yielded.
1974    /// If the closure returns false, the element will remain in the vector and will not be yielded
1975    /// by the iterator.
1976    ///
1977    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
1978    /// or the iteration short-circuits, then the remaining elements will be retained.
1979    /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
1980    ///
1981    /// Using this method is equivalent to the following code:
1982    ///
1983    /// ```
1984    /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
1985    /// # use bump_scope::{Bump, FixedBumpVec};
1986    /// # let bump: Bump = Bump::new();
1987    /// # let mut vec = FixedBumpVec::with_capacity_in(6, &bump);
1988    /// # vec.extend_from_slice_copy(&[1, 2, 3, 4, 5, 6]);
1989    /// let mut i = 0;
1990    /// while i < vec.len() {
1991    ///     if some_predicate(&mut vec[i]) {
1992    ///         let val = vec.remove(i);
1993    ///         // your code here
1994    ///         # _ = val;
1995    ///     } else {
1996    ///         i += 1;
1997    ///     }
1998    /// }
1999    ///
2000    /// # assert_eq!(vec, [1, 4, 5]);
2001    /// ```
2002    ///
2003    /// But `extract_if` is easier to use. `extract_if` is also more efficient,
2004    /// because it can backshift the elements of the array in bulk.
2005    ///
2006    /// Note that `extract_if` also lets you mutate every element in the filter closure,
2007    /// regardless of whether you choose to keep or remove it.
2008    ///
2009    /// # Examples
2010    ///
2011    /// Splitting an array into evens and odds, reusing the original allocation:
2012    ///
2013    /// ```
2014    /// # use bump_scope::{Bump, FixedBumpVec};
2015    /// # let bump: Bump = Bump::new();
2016    /// let mut numbers = FixedBumpVec::with_capacity_in(16, &bump);
2017    /// numbers.extend_from_slice_copy(&[1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]);
2018    ///
2019    /// let evens = bump.alloc_iter(numbers.extract_if(|x| *x % 2 == 0));
2020    /// let odds = numbers;
2021    ///
2022    /// assert_eq!(evens, [2, 4, 6, 8, 14]);
2023    /// assert_eq!(odds, [1, 3, 5, 9, 11, 13, 15]);
2024    /// ```
2025    ///
2026    /// [`retain`]: Self::retain
2027    pub fn extract_if<F>(&mut self, filter: F) -> owned_slice::ExtractIf<'_, T, F>
2028    where
2029        F: FnMut(&mut T) -> bool,
2030    {
2031        self.initialized.extract_if(filter)
2032    }
2033
2034    /// Removes consecutive repeated elements in the vector according to the
2035    /// [`PartialEq`] trait implementation.
2036    ///
2037    /// If the vector is sorted, this removes all duplicates.
2038    ///
2039    /// # Examples
2040    ///
2041    /// ```
2042    /// # use bump_scope::{Bump, FixedBumpVec};
2043    /// # let bump: Bump = Bump::new();
2044    /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
2045    /// vec.extend_from_slice_copy(&[1, 2, 2, 3, 2]);
2046    ///
2047    /// vec.dedup();
2048    ///
2049    /// assert_eq!(vec, [1, 2, 3, 2]);
2050    /// ```
2051    #[inline]
2052    pub fn dedup(&mut self)
2053    where
2054        T: PartialEq,
2055    {
2056        self.initialized.dedup();
2057    }
2058
2059    /// Removes all but the first of consecutive elements in the vector that resolve to the same
2060    /// key.
2061    ///
2062    /// If the vector is sorted, this removes all duplicates.
2063    ///
2064    /// # Examples
2065    ///
2066    /// ```
2067    /// # use bump_scope::{Bump, FixedBumpVec};
2068    /// # let bump: Bump = Bump::new();
2069    /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
2070    /// vec.extend_from_slice_copy(&[10, 20, 21, 30, 20]);
2071    ///
2072    /// vec.dedup_by_key(|i| *i / 10);
2073    ///
2074    /// assert_eq!(vec, [10, 20, 30, 20]);
2075    /// ```
2076    #[inline]
2077    pub fn dedup_by_key<F, K>(&mut self, key: F)
2078    where
2079        F: FnMut(&mut T) -> K,
2080        K: PartialEq,
2081    {
2082        self.initialized.dedup_by_key(key);
2083    }
2084
2085    /// Removes all but the first of consecutive elements in the vector satisfying a given equality
2086    /// relation.
2087    ///
2088    /// The `same_bucket` function is passed references to two elements from the vector and
2089    /// must determine if the elements compare equal. The elements are passed in opposite order
2090    /// from their order in the vector, so if `same_bucket(a, b)` returns `true`, `a` is removed.
2091    ///
2092    /// If the vector is sorted, this removes all duplicates.
2093    ///
2094    /// # Examples
2095    ///
2096    /// ```
2097    /// # use bump_scope::{Bump, FixedBumpVec};
2098    /// # let bump: Bump = Bump::new();
2099    /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
2100    /// vec.extend_from_slice_copy(&["foo", "bar", "Bar", "baz", "bar"]);
2101    ///
2102    /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
2103    ///
2104    /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
2105    /// ```
2106    pub fn dedup_by<F>(&mut self, same_bucket: F)
2107    where
2108        F: FnMut(&mut T, &mut T) -> bool,
2109    {
2110        self.initialized.dedup_by(same_bucket);
2111    }
2112
2113    /// Returns the vector content as a boxed slice of `T`, along with the remaining spare
2114    /// capacity of the vector as a boxed slice of `MaybeUninit<T>`.
2115    #[inline]
2116    #[must_use]
2117    pub fn split_at_spare(self) -> (BumpBox<'a, [T]>, BumpBox<'a, [MaybeUninit<T>]>) {
2118        unsafe {
2119            let uninitialized_ptr = self
2120                .initialized
2121                .as_non_null()
2122                .add(self.initialized.len())
2123                .cast::<MaybeUninit<T>>();
2124            let uninitialized_len = self.capacity - self.len();
2125            let uninitialized = BumpBox::from_raw(NonNull::slice_from_raw_parts(uninitialized_ptr, uninitialized_len));
2126            (self.initialized, uninitialized)
2127        }
2128    }
2129
2130    #[inline(always)]
2131    pub(crate) fn into_raw_parts(self) -> (BumpBox<'a, [T]>, usize) {
2132        (self.initialized, self.capacity)
2133    }
2134
2135    #[inline(always)]
2136    pub(crate) unsafe fn from_raw_parts(initialized: BumpBox<'a, [T]>, capacity: usize) -> Self {
2137        Self { initialized, capacity }
2138    }
2139
2140    #[inline(always)]
2141    unsafe fn extend_by_copy_nonoverlapping<B: ErrorBehavior>(&mut self, other: *const [T]) -> Result<(), B> {
2142        unsafe {
2143            let len = other.len();
2144            self.generic_reserve(len)?;
2145
2146            let src = other.cast::<T>();
2147            let dst = self.as_mut_ptr().add(self.len());
2148            ptr::copy_nonoverlapping(src, dst, len);
2149
2150            self.inc_len(len);
2151            Ok(())
2152        }
2153    }
2154
2155    /// # Safety
2156    ///
2157    /// `iterator` must satisfy the invariants of nightly's `TrustedLen`.
2158    unsafe fn extend_trusted<B: ErrorBehavior>(&mut self, iterator: impl Iterator<Item = T>) -> Result<(), B> {
2159        unsafe {
2160            let (low, high) = iterator.size_hint();
2161            if let Some(additional) = high {
2162                debug_assert_eq!(
2163                    low,
2164                    additional,
2165                    "TrustedLen iterator's size hint is not exact: {:?}",
2166                    (low, high)
2167                );
2168
2169                self.generic_reserve(additional)?;
2170
2171                let ptr = self.as_mut_ptr();
2172                let mut local_len = self.initialized.set_len_on_drop();
2173
2174                iterator.for_each(move |element| {
2175                    let dst = ptr.add(local_len.current_len());
2176
2177                    ptr::write(dst, element);
2178                    // Since the loop executes user code which can panic we have to update
2179                    // the length every step to correctly drop what we've written.
2180                    // NB can't overflow since we would have had to alloc the address space
2181                    local_len.increment_len(1);
2182                });
2183
2184                Ok(())
2185            } else {
2186                // Per TrustedLen contract a `None` upper bound means that the iterator length
2187                // truly exceeds usize::MAX, which would eventually lead to a capacity overflow anyway.
2188                // Since the other branch already panics eagerly (via `reserve()`) we do the same here.
2189                // This avoids additional codegen for a fallback code path which would eventually
2190                // panic anyway.
2191                Err(B::fixed_size_vector_is_full())
2192            }
2193        }
2194    }
2195
2196    #[inline(always)]
2197    fn generic_reserve_one<B: ErrorBehavior>(&self) -> Result<(), B> {
2198        if self.is_full() {
2199            Err(B::fixed_size_vector_is_full())
2200        } else {
2201            Ok(())
2202        }
2203    }
2204}
2205
2206impl<'a, T, const N: usize> FixedBumpVec<'a, [T; N]> {
2207    /// Takes a `FixedBumpVec<[T; N]>` and flattens it into a `FixedBumpVec<T>`.
2208    ///
2209    /// # Panics
2210    ///
2211    /// Panics if the length of the resulting vector would overflow a `usize`.
2212    ///
2213    /// This is only possible when flattening a vector of arrays of zero-sized
2214    /// types, and thus tends to be irrelevant in practice. If
2215    /// `size_of::<T>() > 0`, this will never panic.
2216    ///
2217    /// # Examples
2218    ///
2219    /// ```
2220    /// # use bump_scope::{Bump, FixedBumpVec};
2221    /// # let bump: Bump = Bump::new();
2222    /// #
2223    /// let mut vec = FixedBumpVec::with_capacity_in(3, &bump);
2224    /// vec.append([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
2225    /// assert_eq!(vec.pop(), Some([7, 8, 9]));
2226    ///
2227    /// let mut flattened = vec.into_flattened();
2228    /// assert_eq!(flattened.pop(), Some(6));
2229    /// ```
2230    #[must_use]
2231    pub fn into_flattened(self) -> FixedBumpVec<'a, T> {
2232        let (initialized, cap) = self.into_raw_parts();
2233        let ptr = initialized.into_raw();
2234        let len = ptr.len();
2235
2236        let (new_len, new_cap) = if T::IS_ZST {
2237            (len.checked_mul(N).expect("vec len overflow"), usize::MAX)
2238        } else {
2239            // SAFETY:
2240            // - `cap * N` cannot overflow because the allocation is already in
2241            // the address space.
2242            // - Each `[T; N]` has `N` valid elements, so there are `len * N`
2243            // valid elements in the allocation.
2244            unsafe { (polyfill::usize::unchecked_mul(len, N), polyfill::usize::unchecked_mul(cap, N)) }
2245        };
2246
2247        // SAFETY:
2248        // - `ptr` was allocated by `self`
2249        // - `ptr` is well-aligned because `[T; N]` has the same alignment as `T`.
2250        // - `new_cap` refers to the same sized allocation as `cap` because
2251        // `new_cap * size_of::<T>()` == `cap * size_of::<[T; N]>()`
2252        // - `len` <= `cap`, so `len * N` <= `cap * N`.
2253        unsafe {
2254            let slice = NonNull::slice_from_raw_parts(ptr.cast(), new_len);
2255            let initialized = BumpBox::from_raw(slice);
2256            FixedBumpVec::from_raw_parts(initialized, new_cap)
2257        }
2258    }
2259}
2260
2261impl<T> Debug for FixedBumpVec<'_, T>
2262where
2263    T: Debug,
2264{
2265    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2266        self.initialized.fmt(f)
2267    }
2268}
2269
2270impl<T> Default for FixedBumpVec<'_, T> {
2271    fn default() -> Self {
2272        Self::new()
2273    }
2274}
2275
2276impl<T> Deref for FixedBumpVec<'_, T> {
2277    type Target = [T];
2278
2279    fn deref(&self) -> &Self::Target {
2280        &self.initialized
2281    }
2282}
2283
2284impl<T> DerefMut for FixedBumpVec<'_, T> {
2285    fn deref_mut(&mut self) -> &mut Self::Target {
2286        &mut self.initialized
2287    }
2288}
2289
2290impl<T, I: SliceIndex<[T]>> Index<I> for FixedBumpVec<'_, T> {
2291    type Output = I::Output;
2292
2293    #[inline(always)]
2294    fn index(&self, index: I) -> &Self::Output {
2295        Index::index(self.as_slice(), index)
2296    }
2297}
2298
2299impl<T, I: SliceIndex<[T]>> IndexMut<I> for FixedBumpVec<'_, T> {
2300    #[inline(always)]
2301    fn index_mut(&mut self, index: I) -> &mut Self::Output {
2302        IndexMut::index_mut(self.as_mut_slice(), index)
2303    }
2304}
2305
2306#[cfg(feature = "panic-on-alloc")]
2307impl<T> Extend<T> for FixedBumpVec<'_, T> {
2308    #[inline]
2309    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
2310        let iter = iter.into_iter();
2311
2312        self.reserve(iter.size_hint().0);
2313
2314        for value in iter {
2315            self.push(value);
2316        }
2317    }
2318}
2319
2320#[cfg(feature = "panic-on-alloc")]
2321impl<'t, T> Extend<&'t T> for FixedBumpVec<'_, T>
2322where
2323    T: Clone + 't,
2324{
2325    #[inline]
2326    fn extend<I: IntoIterator<Item = &'t T>>(&mut self, iter: I) {
2327        let iter = iter.into_iter();
2328
2329        self.reserve(iter.size_hint().0);
2330
2331        for value in iter {
2332            self.push(value.clone());
2333        }
2334    }
2335}
2336
2337impl<'a, T> IntoIterator for FixedBumpVec<'a, T> {
2338    type Item = T;
2339    type IntoIter = owned_slice::IntoIter<'a, T>;
2340
2341    #[inline(always)]
2342    fn into_iter(self) -> Self::IntoIter {
2343        self.initialized.into_iter()
2344    }
2345}
2346
2347impl<'c, T> IntoIterator for &'c FixedBumpVec<'_, T> {
2348    type Item = &'c T;
2349    type IntoIter = slice::Iter<'c, T>;
2350
2351    #[inline(always)]
2352    fn into_iter(self) -> Self::IntoIter {
2353        self.as_slice().iter()
2354    }
2355}
2356
2357impl<'c, T> IntoIterator for &'c mut FixedBumpVec<'_, T> {
2358    type Item = &'c mut T;
2359    type IntoIter = slice::IterMut<'c, T>;
2360
2361    #[inline(always)]
2362    fn into_iter(self) -> Self::IntoIter {
2363        self.as_mut_slice().iter_mut()
2364    }
2365}
2366
2367impl<T> AsRef<Self> for FixedBumpVec<'_, T> {
2368    #[inline(always)]
2369    fn as_ref(&self) -> &Self {
2370        self
2371    }
2372}
2373
2374impl<T> AsMut<Self> for FixedBumpVec<'_, T> {
2375    #[inline(always)]
2376    fn as_mut(&mut self) -> &mut Self {
2377        self
2378    }
2379}
2380
2381impl<T> AsRef<[T]> for FixedBumpVec<'_, T> {
2382    #[inline(always)]
2383    fn as_ref(&self) -> &[T] {
2384        self
2385    }
2386}
2387
2388impl<T> AsMut<[T]> for FixedBumpVec<'_, T> {
2389    #[inline(always)]
2390    fn as_mut(&mut self) -> &mut [T] {
2391        self
2392    }
2393}
2394
2395impl<T> Borrow<[T]> for FixedBumpVec<'_, T> {
2396    #[inline(always)]
2397    fn borrow(&self) -> &[T] {
2398        self
2399    }
2400}
2401
2402impl<T> BorrowMut<[T]> for FixedBumpVec<'_, T> {
2403    #[inline(always)]
2404    fn borrow_mut(&mut self) -> &mut [T] {
2405        self
2406    }
2407}
2408
2409impl<T: Hash> Hash for FixedBumpVec<'_, T> {
2410    #[inline(always)]
2411    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
2412        self.as_slice().hash(state);
2413    }
2414}
2415
2416/// Returns [`ErrorKind::OutOfMemory`](std::io::ErrorKind::OutOfMemory) when extending fails.
2417#[cfg(feature = "std")]
2418impl std::io::Write for FixedBumpVec<'_, u8> {
2419    #[inline(always)]
2420    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
2421        if self.try_extend_from_slice_copy(buf).is_err() {
2422            return Err(std::io::ErrorKind::OutOfMemory.into());
2423        }
2424
2425        Ok(buf.len())
2426    }
2427
2428    #[inline(always)]
2429    fn flush(&mut self) -> std::io::Result<()> {
2430        Ok(())
2431    }
2432
2433    #[inline]
2434    fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
2435        let len = bufs.iter().map(|b| b.len()).sum();
2436        self.try_reserve(len).map_err(|_| std::io::ErrorKind::OutOfMemory)?;
2437        for buf in bufs {
2438            self.try_extend_from_slice_copy(buf)
2439                .map_err(|_| std::io::ErrorKind::OutOfMemory)?;
2440        }
2441        Ok(len)
2442    }
2443
2444    #[inline(always)]
2445    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
2446        if self.try_extend_from_slice_copy(buf).is_err() {
2447            return Err(std::io::ErrorKind::OutOfMemory.into());
2448        }
2449
2450        Ok(())
2451    }
2452}
2453
2454impl<T: NoDrop> NoDrop for FixedBumpVec<'_, T> {}