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 ≎ 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> {}