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