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.append([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_append([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(always)]
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 /// Appends an element to the back of a collection, returning a reference to it.
991 ///
992 /// # Panics
993 /// Panics if the vector does not have enough capacity.
994 ///
995 /// # Examples
996 /// ```
997 /// # use bump_scope::{Bump, FixedBumpVec};
998 /// # let bump: Bump = Bump::new();
999 /// let mut vec = FixedBumpVec::with_capacity_in(4, &bump);
1000 /// vec.extend_from_slice_copy(&[1, 2]);
1001 ///
1002 /// let last = vec.push_mut(3);
1003 /// assert_eq!(*last, 3);
1004 /// assert_eq!(vec, [1, 2, 3]);
1005 ///
1006 /// let last = vec.push_mut(3);
1007 /// *last += 1;
1008 /// assert_eq!(vec, [1, 2, 3, 4]);
1009 /// ```
1010 #[inline(always)]
1011 #[cfg(feature = "panic-on-alloc")]
1012 #[must_use = "if you don't need a reference to the value, use `push` instead"]
1013 pub fn push_mut(&mut self, value: T) -> &mut T {
1014 panic_on_error(self.generic_push_mut(value))
1015 }
1016
1017 /// Appends an element to the back of a collection, returning a reference to it.
1018 ///
1019 /// # Errors
1020 /// Errors if the vector does not have enough capacity.
1021 ///
1022 /// # Examples
1023 /// ```
1024 /// # use bump_scope::{Bump, FixedBumpVec};
1025 /// # let bump: Bump = Bump::new();
1026 /// let mut vec = FixedBumpVec::with_capacity_in(4, &bump);
1027 /// vec.extend_from_slice_copy(&[1, 2]);
1028 ///
1029 /// let last = vec.try_push_mut(3)?;
1030 /// assert_eq!(*last, 3);
1031 /// assert_eq!(vec, [1, 2, 3]);
1032 ///
1033 /// let last = vec.try_push_mut(3)?;
1034 /// *last += 1;
1035 /// assert_eq!(vec, [1, 2, 3, 4]);
1036 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1037 /// ```
1038 #[inline(always)]
1039 #[must_use = "if you don't need a reference to the value, use `try_push` instead"]
1040 pub fn try_push_mut(&mut self, value: T) -> Result<&mut T, AllocError> {
1041 self.generic_push_mut(value)
1042 }
1043
1044 #[inline(always)]
1045 pub(crate) fn generic_push_mut<E: ErrorBehavior>(&mut self, value: T) -> Result<&mut T, E> {
1046 self.generic_push_mut_with(|| value)
1047 }
1048
1049 /// Reserves space for one more element, then calls `f`
1050 /// to produce the value that is appended.
1051 ///
1052 /// In some cases this could be more performant than `push_mut(f())` because it
1053 /// permits the compiler to directly place `T` in the vector instead of
1054 /// constructing it on the stack and copying it over.
1055 ///
1056 /// # Panics
1057 /// Panics if the vector does not have enough capacity.
1058 ///
1059 /// # Examples
1060 /// ```
1061 /// # use bump_scope::{Bump, FixedBumpVec};
1062 /// # let bump: Bump = Bump::new();
1063 /// let mut vec = FixedBumpVec::with_capacity_in(1, &bump);
1064 /// let item = vec.push_mut_with(i32::default);
1065 /// *item += 1;
1066 /// assert_eq!(*item, 1);
1067 /// ```
1068 #[inline(always)]
1069 #[cfg(feature = "panic-on-alloc")]
1070 #[must_use = "if you don't need a reference to the value, use `push` instead"]
1071 pub fn push_mut_with(&mut self, f: impl FnOnce() -> T) -> &mut T {
1072 panic_on_error(self.generic_push_mut_with(f))
1073 }
1074
1075 /// Reserves space for one more element, then calls `f`
1076 /// to produce the value that is appended.
1077 ///
1078 /// In some cases this could be more performant than `push(f())` because it
1079 /// permits the compiler to directly place `T` in the vector instead of
1080 /// constructing it on the stack and copying it over.
1081 ///
1082 /// # Errors
1083 /// Errors if the vector does not have enough capacity.
1084 ///
1085 /// # Examples
1086 /// ```
1087 /// # use bump_scope::{Bump, FixedBumpVec};
1088 /// # let bump: Bump = Bump::new();
1089 /// let mut vec = FixedBumpVec::with_capacity_in(1, &bump);
1090 /// let item = vec.try_push_mut_with(i32::default)?;
1091 /// *item += 1;
1092 /// assert_eq!(*item, 1);
1093 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1094 /// ```
1095 #[inline(always)]
1096 #[must_use = "if you don't need a reference to the value, use `push` instead"]
1097 pub fn try_push_mut_with(&mut self, f: impl FnOnce() -> T) -> Result<&mut T, AllocError> {
1098 self.generic_push_mut_with(f)
1099 }
1100
1101 #[inline(always)]
1102 pub(crate) fn generic_push_with<E: ErrorBehavior>(&mut self, f: impl FnOnce() -> T) -> Result<(), E> {
1103 self.generic_push_mut_with(f).map(drop)
1104 }
1105
1106 #[inline(always)]
1107 pub(crate) fn generic_push_mut_with<E: ErrorBehavior>(&mut self, f: impl FnOnce() -> T) -> Result<&mut T, E> {
1108 self.generic_reserve_one()?;
1109 Ok(unsafe { self.push_mut_unchecked(f()) })
1110 }
1111
1112 /// Inserts an element at position `index` within the vector, shifting all elements after it to the right.
1113 ///
1114 /// # Panics
1115 /// Panics if the vector does not have enough capacity.
1116 ///
1117 /// Panics if `index > len`.
1118 ///
1119 /// # Examples
1120 /// ```
1121 /// # use bump_scope::{Bump, FixedBumpVec};
1122 /// # let bump: Bump = Bump::new();
1123 /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
1124 /// vec.append(['b', 'd']);
1125 /// vec.insert(1, 'c');
1126 /// assert_eq!(vec, ['b', 'c', 'd']);
1127 /// vec.insert(0, 'a');
1128 /// assert_eq!(vec, ['a', 'b', 'c', 'd']);
1129 /// vec.insert(4, 'e');
1130 /// assert_eq!(vec, ['a', 'b', 'c', 'd', 'e']);
1131 /// ```
1132 #[inline(always)]
1133 #[cfg(feature = "panic-on-alloc")]
1134 pub fn insert(&mut self, index: usize, element: T) {
1135 panic_on_error(self.generic_insert_mut(index, element));
1136 }
1137
1138 /// Inserts an element at position `index` within the vector, shifting all elements after it to the right.
1139 ///
1140 /// # Panics
1141 /// Panics if `index > len`.
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(5, &bump)?;
1151 /// vec.try_append(['b', 'd'])?;
1152 /// vec.try_insert(1, 'c')?;
1153 /// assert_eq!(vec, ['b', 'c', 'd']);
1154 /// vec.try_insert(0, 'a')?;
1155 /// assert_eq!(vec, ['a', 'b', 'c', 'd']);
1156 /// vec.try_insert(4, 'e')?;
1157 /// assert_eq!(vec, ['a', 'b', 'c', 'd', 'e']);
1158 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1159 /// ```
1160 #[inline(always)]
1161 pub fn try_insert(&mut self, index: usize, element: T) -> Result<(), AllocError> {
1162 self.generic_insert_mut(index, element).map(drop)
1163 }
1164
1165 /// Inserts an element at position `index` within the vector, shifting all elements after it to the right.
1166 ///
1167 /// # Panics
1168 /// Panics if the vector does not have enough capacity.
1169 ///
1170 /// Panics if `index > len`.
1171 ///
1172 /// # Examples
1173 /// ```
1174 /// # use bump_scope::{Bump, FixedBumpVec};
1175 /// # let bump: Bump = Bump::new();
1176 /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
1177 /// vec.append([1, 3, 5, 9]);
1178 /// let x = vec.insert_mut(3, 6);
1179 /// *x += 1;
1180 /// assert_eq!(vec, [1, 3, 5, 7, 9]);
1181 /// ```
1182 #[inline(always)]
1183 #[cfg(feature = "panic-on-alloc")]
1184 #[must_use = "if you don't need a reference to the value, use `insert` instead"]
1185 pub fn insert_mut(&mut self, index: usize, element: T) -> &mut T {
1186 panic_on_error(self.generic_insert_mut(index, element))
1187 }
1188
1189 /// Inserts an element at position `index` within the vector, shifting all elements after it to the right.
1190 ///
1191 /// # Panics
1192 /// Panics if `index > len`.
1193 ///
1194 /// # Errors
1195 /// Errors if the vector does not have enough capacity.
1196 ///
1197 /// # Examples
1198 /// ```
1199 /// # use bump_scope::{Bump, FixedBumpVec};
1200 /// # let bump: Bump = Bump::new();
1201 /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
1202 /// vec.try_append([1, 3, 5, 9]);
1203 /// let x = vec.try_insert_mut(3, 6)?;
1204 /// *x += 1;
1205 /// assert_eq!(vec, [1, 3, 5, 7, 9]);
1206 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1207 /// ```
1208 #[inline(always)]
1209 #[must_use = "if you don't need a reference to the value, use `try_insert` instead"]
1210 pub fn try_insert_mut(&mut self, index: usize, element: T) -> Result<&mut T, AllocError> {
1211 self.generic_insert_mut(index, element)
1212 }
1213
1214 #[inline]
1215 pub(crate) fn generic_insert_mut<E: ErrorBehavior>(&mut self, index: usize, element: T) -> Result<&mut T, E> {
1216 #[cold]
1217 #[track_caller]
1218 #[inline(never)]
1219 fn assert_failed(index: usize, len: usize) -> ! {
1220 panic!("insertion index (is {index}) should be <= len (is {len})");
1221 }
1222
1223 if index > self.len() {
1224 assert_failed(index, self.len());
1225 }
1226
1227 self.generic_reserve_one()?;
1228
1229 unsafe {
1230 let pos = self.as_mut_ptr().add(index);
1231
1232 if index != self.len() {
1233 let len = self.len() - index;
1234 ptr::copy(pos, pos.add(1), len);
1235 }
1236
1237 pos.write(element);
1238 self.inc_len(1);
1239 Ok(&mut *pos)
1240 }
1241 }
1242
1243 /// Copies and appends all elements in a slice to the `FixedBumpVec`.
1244 ///
1245 /// Iterates over the `slice`, copies each element, and then appends
1246 /// it to this `FixedBumpVec`. The `slice` is traversed in-order.
1247 ///
1248 /// Note that this function is same as [`extend`] except that it is
1249 /// specialized to work with copyable slices instead.
1250 ///
1251 /// [`extend`]: Self::extend
1252 ///
1253 /// # Panics
1254 /// Panics if the vector does not have enough capacity.
1255 ///
1256 /// # Examples
1257 /// ```
1258 /// # use bump_scope::{ Bump, FixedBumpVec };
1259 /// # let bump: Bump = Bump::new();
1260 /// let mut vec = FixedBumpVec::with_capacity_in(4, &bump);
1261 /// vec.push(1);
1262 /// vec.extend_from_slice_copy(&[2, 3, 4]);
1263 /// assert_eq!(vec, [1, 2, 3, 4]);
1264 /// ```
1265 #[inline(always)]
1266 #[cfg(feature = "panic-on-alloc")]
1267 pub fn extend_from_slice_copy(&mut self, slice: &[T])
1268 where
1269 T: Copy,
1270 {
1271 panic_on_error(self.generic_extend_from_slice_copy(slice));
1272 }
1273
1274 /// Copies and appends all elements in a slice to the `FixedBumpVec`.
1275 ///
1276 /// Iterates over the `slice`, copies each element, and then appends
1277 /// it to this `FixedBumpVec`. The `slice` is traversed in-order.
1278 ///
1279 /// Note that this function is same as [`extend`] except that it is
1280 /// specialized to work with copyable slices instead.
1281 ///
1282 /// [`extend`]: Self::extend
1283 ///
1284 /// # Errors
1285 /// Errors if the vector does not have enough capacity.
1286 ///
1287 /// # Examples
1288 /// ```
1289 /// # use bump_scope::{ Bump, FixedBumpVec };
1290 /// # let bump: Bump = Bump::new();
1291 /// let mut vec = FixedBumpVec::try_with_capacity_in(4, &bump)?;
1292 /// vec.try_push(1)?;
1293 /// vec.try_extend_from_slice_copy(&[2, 3, 4])?;
1294 /// assert_eq!(vec, [1, 2, 3, 4]);
1295 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1296 /// ```
1297 #[inline(always)]
1298 pub fn try_extend_from_slice_copy(&mut self, slice: &[T]) -> Result<(), AllocError>
1299 where
1300 T: Copy,
1301 {
1302 self.generic_extend_from_slice_copy(slice)
1303 }
1304
1305 #[inline]
1306 pub(crate) fn generic_extend_from_slice_copy<E: ErrorBehavior>(&mut self, slice: &[T]) -> Result<(), E>
1307 where
1308 T: Copy,
1309 {
1310 unsafe { self.extend_by_copy_nonoverlapping(slice) }
1311 }
1312
1313 /// Clones and appends all elements in a slice to the `FixedBumpVec`.
1314 ///
1315 /// Iterates over the `slice`, clones each element, and then appends
1316 /// it to this `FixedBumpVec`. The `slice` is traversed in-order.
1317 ///
1318 /// Note that this function is same as [`extend`] except that it is
1319 /// specialized to work with slices instead.
1320 ///
1321 /// [`extend`]: Self::extend
1322 ///
1323 /// # Panics
1324 /// Panics if the vector does not have enough capacity.
1325 ///
1326 /// # Examples
1327 /// ```
1328 /// # use std::string::String;
1329 /// # use bump_scope::{ Bump, FixedBumpVec };
1330 /// # let bump: Bump = Bump::new();
1331 /// let mut vec = FixedBumpVec::with_capacity_in(3, &bump);
1332 /// vec.push(String::from("a"));
1333 /// vec.extend_from_slice_clone(&[String::from("b"), String::from("c")]);
1334 /// assert_eq!(vec, ["a", "b", "c"]);
1335 /// ```
1336 #[inline(always)]
1337 #[cfg(feature = "panic-on-alloc")]
1338 pub fn extend_from_slice_clone(&mut self, slice: &[T])
1339 where
1340 T: Clone,
1341 {
1342 panic_on_error(self.generic_extend_from_slice_clone(slice));
1343 }
1344
1345 /// Clones and appends all elements in a slice to the `FixedBumpVec`.
1346 ///
1347 /// Iterates over the `slice`, clones each element, and then appends
1348 /// it to this `FixedBumpVec`. The `slice` is traversed in-order.
1349 ///
1350 /// Note that this function is same as [`extend`] except that it is
1351 /// specialized to work with slices instead.
1352 ///
1353 /// [`extend`]: Self::extend
1354 ///
1355 /// # Errors
1356 /// Errors if the vector does not have enough capacity.
1357 ///
1358 /// # Examples
1359 /// ```
1360 /// # use std::string::String;
1361 /// # use bump_scope::{ Bump, FixedBumpVec };
1362 /// # let bump: Bump = Bump::new();
1363 /// let mut vec = FixedBumpVec::try_with_capacity_in(3, &bump)?;
1364 /// vec.try_push(String::from("a"))?;
1365 /// vec.try_extend_from_slice_clone(&[String::from("b"), String::from("c")])?;
1366 /// assert_eq!(vec, ["a", "b", "c"]);
1367 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1368 /// ```
1369 #[inline(always)]
1370 pub fn try_extend_from_slice_clone(&mut self, slice: &[T]) -> Result<(), AllocError>
1371 where
1372 T: Clone,
1373 {
1374 self.generic_extend_from_slice_clone(slice)
1375 }
1376
1377 #[inline]
1378 pub(crate) fn generic_extend_from_slice_clone<E: ErrorBehavior>(&mut self, slice: &[T]) -> Result<(), E>
1379 where
1380 T: Clone,
1381 {
1382 self.generic_reserve(slice.len())?;
1383
1384 unsafe {
1385 let mut pos = 0usize;
1386
1387 while likely(pos != slice.len()) {
1388 let elem = slice.get_unchecked(pos);
1389 self.push_unchecked(elem.clone());
1390 pos += 1;
1391 }
1392 }
1393
1394 Ok(())
1395 }
1396
1397 /// Copies elements from `src` range to the end of the vector.
1398 ///
1399 /// # Panics
1400 /// Panics if the vector does not have enough capacity.
1401 ///
1402 /// Panics if the starting point is greater than the end point or if
1403 /// the end point is greater than the length of the vector.
1404 ///
1405 /// # Examples
1406 /// ```
1407 /// # use bump_scope::{Bump, FixedBumpVec};
1408 /// # let bump: Bump = Bump::new();
1409 /// let mut vec = FixedBumpVec::with_capacity_in(100, &bump);
1410 /// vec.extend_from_slice_copy(&[0, 1, 2, 3, 4]);
1411 ///
1412 /// vec.extend_from_within_copy(2..);
1413 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1414 ///
1415 /// vec.extend_from_within_copy(..2);
1416 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1417 ///
1418 /// vec.extend_from_within_copy(4..8);
1419 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1420 /// ```
1421 #[inline(always)]
1422 #[cfg(feature = "panic-on-alloc")]
1423 pub fn extend_from_within_copy<R>(&mut self, src: R)
1424 where
1425 T: Copy,
1426 R: RangeBounds<usize>,
1427 {
1428 panic_on_error(self.generic_extend_from_within_copy(src));
1429 }
1430
1431 /// Copies elements from `src` range to the end of the vector.
1432 ///
1433 /// # Panics
1434 /// Panics if the starting point is greater than the end point or if
1435 /// the end point is greater than the length of the vector.
1436 ///
1437 /// # Errors
1438 /// Errors if the vector does not have enough capacity.
1439 ///
1440 /// # Examples
1441 /// ```
1442 /// # use bump_scope::{Bump, FixedBumpVec};
1443 /// # let bump: Bump = Bump::new();
1444 /// let mut vec = FixedBumpVec::try_with_capacity_in(100, &bump)?;
1445 /// vec.try_extend_from_slice_copy(&[0, 1, 2, 3, 4])?;
1446 ///
1447 /// vec.try_extend_from_within_copy(2..)?;
1448 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1449 ///
1450 /// vec.try_extend_from_within_copy(..2)?;
1451 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1452 ///
1453 /// vec.try_extend_from_within_copy(4..8)?;
1454 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1455 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1456 /// ```
1457 #[inline(always)]
1458 pub fn try_extend_from_within_copy<R>(&mut self, src: R) -> Result<(), AllocError>
1459 where
1460 T: Copy,
1461 R: RangeBounds<usize>,
1462 {
1463 self.generic_extend_from_within_copy(src)
1464 }
1465
1466 #[inline]
1467 pub(crate) fn generic_extend_from_within_copy<E: ErrorBehavior, R>(&mut self, src: R) -> Result<(), E>
1468 where
1469 T: Copy,
1470 R: RangeBounds<usize>,
1471 {
1472 let range = slice::range(src, ..self.len());
1473 let count = range.len();
1474
1475 self.generic_reserve(count)?;
1476
1477 // SAFETY:
1478 // - `slice::range` guarantees that the given range is valid for indexing self
1479 unsafe {
1480 let ptr = self.as_mut_ptr();
1481
1482 let src = ptr.add(range.start);
1483 let dst = ptr.add(self.len());
1484 ptr::copy_nonoverlapping(src, dst, count);
1485
1486 self.inc_len(count);
1487 Ok(())
1488 }
1489 }
1490
1491 /// Clones elements from `src` range to the end of the vector.
1492 ///
1493 /// # Panics
1494 /// Panics if the vector does not have enough capacity.
1495 ///
1496 /// Panics if the starting point is greater than the end point or if
1497 /// the end point is greater than the length of the vector.
1498 ///
1499 /// # Examples
1500 /// ```
1501 /// # use bump_scope::{Bump, FixedBumpVec};
1502 /// # let bump: Bump = Bump::new();
1503 /// let mut vec = FixedBumpVec::with_capacity_in(14, &bump);
1504 /// vec.extend_from_slice_copy(&[0, 1, 2, 3, 4]);
1505 ///
1506 /// vec.extend_from_within_clone(2..);
1507 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1508 ///
1509 /// vec.extend_from_within_clone(..2);
1510 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1511 ///
1512 /// vec.extend_from_within_clone(4..8);
1513 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1514 /// ```
1515 #[inline(always)]
1516 #[cfg(feature = "panic-on-alloc")]
1517 pub fn extend_from_within_clone<R>(&mut self, src: R)
1518 where
1519 T: Clone,
1520 R: RangeBounds<usize>,
1521 {
1522 panic_on_error(self.generic_extend_from_within_clone(src));
1523 }
1524
1525 /// Clones elements from `src` range to the end of the vector.
1526 ///
1527 /// # Panics
1528 /// Panics if the starting point is greater than the end point or if
1529 /// the end point is greater than the length of the vector.
1530 ///
1531 /// # Errors
1532 /// Errors if the vector does not have enough capacity.
1533 ///
1534 /// # Examples
1535 /// ```
1536 /// # use bump_scope::{Bump, FixedBumpVec};
1537 /// # let bump: Bump = Bump::new();
1538 /// let mut vec = FixedBumpVec::try_with_capacity_in(14, &bump)?;
1539 /// vec.try_extend_from_slice_copy(&[0, 1, 2, 3, 4])?;
1540 ///
1541 /// vec.try_extend_from_within_clone(2..)?;
1542 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
1543 ///
1544 /// vec.try_extend_from_within_clone(..2)?;
1545 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
1546 ///
1547 /// vec.try_extend_from_within_clone(4..8)?;
1548 /// assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
1549 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1550 /// ```
1551 #[inline(always)]
1552 pub fn try_extend_from_within_clone<R>(&mut self, src: R) -> Result<(), AllocError>
1553 where
1554 T: Clone,
1555 R: RangeBounds<usize>,
1556 {
1557 self.generic_extend_from_within_clone(src)
1558 }
1559
1560 #[inline]
1561 pub(crate) fn generic_extend_from_within_clone<E: ErrorBehavior, R>(&mut self, src: R) -> Result<(), E>
1562 where
1563 T: Clone,
1564 R: RangeBounds<usize>,
1565 {
1566 let range = slice::range(src, ..self.len());
1567 let count = range.len();
1568
1569 self.generic_reserve(count)?;
1570
1571 if T::IS_ZST {
1572 unsafe {
1573 // We can materialize ZST's from nothing.
1574 #[expect(clippy::uninit_assumed_init)]
1575 let fake = ManuallyDrop::new(MaybeUninit::<T>::uninit().assume_init());
1576
1577 for _ in 0..count {
1578 self.push_unchecked((*fake).clone());
1579 }
1580
1581 return Ok(());
1582 }
1583 }
1584
1585 // SAFETY:
1586 // - `slice::range` guarantees that the given range is valid for indexing self
1587 unsafe {
1588 let ptr = self.as_mut_ptr();
1589
1590 let mut src = ptr.add(range.start);
1591 let mut dst = ptr.add(self.len());
1592
1593 let src_end = src.add(count);
1594
1595 while src != src_end {
1596 dst.write((*src).clone());
1597
1598 src = src.add(1);
1599 dst = dst.add(1);
1600 self.inc_len(1);
1601 }
1602 }
1603
1604 Ok(())
1605 }
1606
1607 /// Checks if at least `additional` more elements can be inserted
1608 /// in the given `FixedBumpVec<T>` due to capacity.
1609 ///
1610 /// # Panics
1611 /// Panics if the vector does not have enough capacity.
1612 #[inline(always)]
1613 #[cfg(feature = "panic-on-alloc")]
1614 pub fn reserve(&mut self, additional: usize) {
1615 panic_on_error(self.generic_reserve(additional));
1616 }
1617
1618 /// Checks if at least `additional` more elements can be inserted
1619 /// in the given `FixedBumpVec<T>` due to capacity.
1620 ///
1621 /// # Errors
1622 /// Errors if the vector does not have enough capacity.
1623 #[inline(always)]
1624 pub fn try_reserve(&mut self, additional: usize) -> Result<(), AllocError> {
1625 self.generic_reserve(additional)
1626 }
1627
1628 #[inline]
1629 pub(crate) fn generic_reserve<E: ErrorBehavior>(&mut self, additional: usize) -> Result<(), E> {
1630 if additional > (self.capacity() - self.len()) {
1631 Err(E::fixed_size_vector_no_space(additional))
1632 } else {
1633 Ok(())
1634 }
1635 }
1636
1637 /// Resizes the `FixedBumpVec` in-place so that `len` is equal to `new_len`.
1638 ///
1639 /// If `new_len` is greater than `len`, the `FixedBumpVec` is extended by the
1640 /// difference, with each additional slot filled with `value`.
1641 /// If `new_len` is less than `len`, the `FixedBumpVec` is simply truncated.
1642 ///
1643 /// This method requires `T` to implement [`Clone`],
1644 /// in order to be able to clone the passed value.
1645 /// If you need more flexibility (or want to rely on [`Default`] instead of
1646 /// [`Clone`]), use [`resize_with`].
1647 /// If you only need to resize to a smaller size, use [`truncate`].
1648 ///
1649 /// [`resize_with`]: Self::resize_with
1650 /// [`truncate`]: Self::truncate
1651 ///
1652 /// # Panics
1653 /// Panics if the vector does not have enough capacity.
1654 ///
1655 /// # Examples
1656 /// ```
1657 /// # use bump_scope::{Bump, FixedBumpVec};
1658 /// # let bump: Bump = Bump::new();
1659 /// let mut vec = FixedBumpVec::with_capacity_in(10, &bump);
1660 /// vec.extend_from_slice_copy(&["hello"]);
1661 /// vec.resize(3, "world");
1662 /// assert_eq!(vec, ["hello", "world", "world"]);
1663 /// drop(vec);
1664 ///
1665 /// let mut vec = FixedBumpVec::with_capacity_in(10, &bump);
1666 /// vec.extend_from_slice_copy(&[1, 2, 3, 4]);
1667 /// vec.resize(2, 0);
1668 /// assert_eq!(vec, [1, 2]);
1669 /// ```
1670 #[inline(always)]
1671 #[cfg(feature = "panic-on-alloc")]
1672 pub fn resize(&mut self, new_len: usize, value: T)
1673 where
1674 T: Clone,
1675 {
1676 panic_on_error(self.generic_resize(new_len, value));
1677 }
1678
1679 /// Resizes the `FixedBumpVec` in-place so that `len` is equal to `new_len`.
1680 ///
1681 /// If `new_len` is greater than `len`, the `FixedBumpVec` is extended by the
1682 /// difference, with each additional slot filled with `value`.
1683 /// If `new_len` is less than `len`, the `FixedBumpVec` is simply truncated.
1684 ///
1685 /// This method requires `T` to implement [`Clone`],
1686 /// in order to be able to clone the passed value.
1687 /// If you need more flexibility (or want to rely on [`Default`] instead of
1688 /// [`Clone`]), use [`resize_with`].
1689 /// If you only need to resize to a smaller size, use [`truncate`].
1690 ///
1691 /// [`resize_with`]: Self::resize_with
1692 /// [`truncate`]: Self::truncate
1693 ///
1694 /// # Errors
1695 /// Errors if the vector does not have enough capacity.
1696 ///
1697 /// # Examples
1698 /// ```
1699 /// # use bump_scope::{Bump, FixedBumpVec};
1700 /// # let bump: Bump = Bump::new();
1701 /// let mut vec = FixedBumpVec::try_with_capacity_in(10, &bump)?;
1702 /// vec.try_extend_from_slice_copy(&["hello"])?;
1703 /// vec.try_resize(3, "world")?;
1704 /// assert_eq!(vec, ["hello", "world", "world"]);
1705 /// drop(vec);
1706 ///
1707 /// let mut vec = FixedBumpVec::try_with_capacity_in(10, &bump)?;
1708 /// vec.try_extend_from_slice_copy(&[1, 2, 3, 4])?;
1709 /// vec.try_resize(2, 0)?;
1710 /// assert_eq!(vec, [1, 2]);
1711 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1712 /// ```
1713 #[inline(always)]
1714 pub fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), AllocError>
1715 where
1716 T: Clone,
1717 {
1718 self.generic_resize(new_len, value)
1719 }
1720
1721 #[inline]
1722 pub(crate) fn generic_resize<E: ErrorBehavior>(&mut self, new_len: usize, value: T) -> Result<(), E>
1723 where
1724 T: Clone,
1725 {
1726 let len = self.len();
1727
1728 if new_len > len {
1729 self.extend_with(new_len - len, value)
1730 } else {
1731 self.truncate(new_len);
1732 Ok(())
1733 }
1734 }
1735
1736 /// Resizes the `FixedBumpVec` in-place so that `len` is equal to `new_len`.
1737 ///
1738 /// If `new_len` is greater than `len`, the `FixedBumpVec` is extended by the
1739 /// difference, with each additional slot filled with the result of
1740 /// calling the closure `f`. The return values from `f` will end up
1741 /// in the `FixedBumpVec` in the order they have been generated.
1742 ///
1743 /// If `new_len` is less than `len`, the `FixedBumpVec` is simply truncated.
1744 ///
1745 /// This method uses a closure to create new values on every push. If
1746 /// you'd rather [`Clone`] a given value, use [`FixedBumpVec::resize`]. If you
1747 /// want to use the [`Default`] trait to generate values, you can
1748 /// pass [`Default::default`] as the second argument.
1749 ///
1750 /// # Panics
1751 /// Panics if the vector does not have enough capacity.
1752 ///
1753 /// # Examples
1754 /// ```
1755 /// # use bump_scope::{Bump, FixedBumpVec};
1756 /// # let bump: Bump = Bump::new();
1757 /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
1758 /// vec.extend_from_slice_copy(&[1, 2, 3]);
1759 /// vec.resize_with(5, Default::default);
1760 /// assert_eq!(vec, [1, 2, 3, 0, 0]);
1761 /// drop(vec);
1762 ///
1763 /// let mut vec = FixedBumpVec::with_capacity_in(4, &bump);
1764 /// let mut p = 1;
1765 /// vec.resize_with(4, || { p *= 2; p });
1766 /// assert_eq!(vec, [2, 4, 8, 16]);
1767 /// ```
1768 #[inline(always)]
1769 #[cfg(feature = "panic-on-alloc")]
1770 pub fn resize_with<F>(&mut self, new_len: usize, f: F)
1771 where
1772 F: FnMut() -> T,
1773 {
1774 panic_on_error(self.generic_resize_with(new_len, f));
1775 }
1776
1777 /// Resizes the `FixedBumpVec` in-place so that `len` is equal to `new_len`.
1778 ///
1779 /// If `new_len` is greater than `len`, the `FixedBumpVec` is extended by the
1780 /// difference, with each additional slot filled with the result of
1781 /// calling the closure `f`. The return values from `f` will end up
1782 /// in the `FixedBumpVec` in the order they have been generated.
1783 ///
1784 /// If `new_len` is less than `len`, the `FixedBumpVec` is simply truncated.
1785 ///
1786 /// This method uses a closure to create new values on every push. If
1787 /// you'd rather [`Clone`] a given value, use [`FixedBumpVec::resize`]. If you
1788 /// want to use the [`Default`] trait to generate values, you can
1789 /// pass [`Default::default`] as the second argument.
1790 ///
1791 /// # Errors
1792 /// Errors if the vector does not have enough capacity.
1793 ///
1794 /// # Examples
1795 /// ```
1796 /// # use bump_scope::{Bump, FixedBumpVec};
1797 /// # let bump: Bump = Bump::new();
1798 /// let mut vec = FixedBumpVec::try_with_capacity_in(5, &bump)?;
1799 /// vec.try_extend_from_slice_copy(&[1, 2, 3])?;
1800 /// vec.try_resize_with(5, Default::default)?;
1801 /// assert_eq!(vec, [1, 2, 3, 0, 0]);
1802 /// drop(vec);
1803 ///
1804 /// let mut vec = FixedBumpVec::try_with_capacity_in(4, &bump)?;
1805 /// let mut p = 1;
1806 /// vec.try_resize_with(4, || { p *= 2; p })?;
1807 /// assert_eq!(vec, [2, 4, 8, 16]);
1808 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1809 /// ```
1810 #[inline(always)]
1811 pub fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), AllocError>
1812 where
1813 F: FnMut() -> T,
1814 {
1815 self.generic_resize_with(new_len, f)
1816 }
1817
1818 #[inline]
1819 pub(crate) fn generic_resize_with<E: ErrorBehavior, F>(&mut self, new_len: usize, f: F) -> Result<(), E>
1820 where
1821 F: FnMut() -> T,
1822 {
1823 let len = self.len();
1824 if new_len > len {
1825 unsafe { self.extend_trusted(iter::repeat_with(f).take(new_len - len)) }
1826 } else {
1827 self.truncate(new_len);
1828 Ok(())
1829 }
1830 }
1831
1832 /// Moves all the elements of `other` into `self`, leaving `other` empty.
1833 ///
1834 /// # Panics
1835 /// Panics if the vector does not have enough capacity.
1836 ///
1837 /// # Examples
1838 /// ```
1839 /// # use bump_scope::{Bump, FixedBumpVec};
1840 /// # let bump: Bump = Bump::new();
1841 /// let mut vec = FixedBumpVec::with_capacity_in(8, &bump);
1842 ///
1843 /// // append by value
1844 /// vec.append([1, 2]);
1845 /// vec.append(vec![3, 4]);
1846 /// vec.append(bump.alloc_iter(5..=6));
1847 ///
1848 /// // append by mutable reference
1849 /// let mut other = vec![7, 8];
1850 /// vec.append(&mut other);
1851 ///
1852 /// assert_eq!(other, []);
1853 /// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]);
1854 /// ```
1855 #[inline(always)]
1856 #[cfg(feature = "panic-on-alloc")]
1857 pub fn append(&mut self, other: impl OwnedSlice<Item = T>) {
1858 panic_on_error(self.generic_append(other));
1859 }
1860
1861 /// Moves all the elements of `other` into `self`, leaving `other` empty.
1862 ///
1863 /// # Errors
1864 /// Errors if the vector does not have enough capacity.
1865 ///
1866 /// # Examples
1867 /// ```
1868 /// # use bump_scope::{Bump, FixedBumpVec};
1869 /// # let bump: Bump = Bump::new();
1870 /// let mut vec = FixedBumpVec::try_with_capacity_in(8, &bump)?;
1871 ///
1872 /// // append by value
1873 /// vec.try_append([1, 2])?;
1874 /// vec.try_append(vec![3, 4])?;
1875 /// vec.try_append(bump.alloc_iter(5..=6))?;
1876 ///
1877 /// // append by mutable reference
1878 /// let mut other = vec![7, 8];
1879 /// vec.try_append(&mut other)?;
1880 ///
1881 /// assert_eq!(other, []);
1882 /// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]);
1883 /// # Ok::<(), bump_scope::alloc::AllocError>(())
1884 /// ```
1885 #[inline(always)]
1886 pub fn try_append(&mut self, other: impl OwnedSlice<Item = T>) -> Result<(), AllocError> {
1887 self.generic_append(other)
1888 }
1889
1890 #[inline]
1891 pub(crate) fn generic_append<E: ErrorBehavior>(&mut self, other: impl OwnedSlice<Item = T>) -> Result<(), E> {
1892 unsafe {
1893 let mut owned_slice = other.into_take_owned_slice();
1894
1895 let slice = NonNull::from(owned_slice.owned_slice_ref());
1896 self.generic_reserve(slice.len())?;
1897
1898 let src = slice.cast::<T>().as_ptr();
1899 let dst = self.as_mut_ptr().add(self.len());
1900 ptr::copy_nonoverlapping(src, dst, slice.len());
1901
1902 owned_slice.take_owned_slice();
1903 self.inc_len(slice.len());
1904 Ok(())
1905 }
1906 }
1907
1908 /// Returns a fixed vector of the same size as `self`, with function `f` applied to each element in order.
1909 ///
1910 /// 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.
1911 ///
1912 /// # Examples
1913 /// Mapping to a type with an equal alignment and size:
1914 /// ```
1915 /// # use bump_scope::{Bump, FixedBumpVec};
1916 /// # use core::num::NonZero;
1917 /// # let bump: Bump = Bump::new();
1918 /// let a = FixedBumpVec::from_iter_exact_in([0, 1, 2], &bump);
1919 /// let b = a.map_in_place(NonZero::new);
1920 /// assert_eq!(format!("{b:?}"), "[None, Some(1), Some(2)]");
1921 /// ```
1922 ///
1923 /// Mapping to a type with a smaller alignment and size:
1924 /// ```
1925 /// # use bump_scope::{Bump, FixedBumpVec};
1926 /// # let bump: Bump = Bump::new();
1927 /// let a: FixedBumpVec<u32> = FixedBumpVec::from_iter_exact_in([0, 1, 2], &bump);
1928 /// assert_eq!(a.capacity(), 3);
1929 ///
1930 /// let b: FixedBumpVec<u16> = a.map_in_place(|i| i as u16);
1931 /// assert_eq!(b.capacity(), 6);
1932 ///
1933 /// assert_eq!(b, [0, 1, 2]);
1934 /// ```
1935 ///
1936 /// Mapping to a type with a greater alignment won't compile:
1937 /// ```compile_fail,E0080
1938 /// # use bump_scope::{Bump, FixedBumpVec};
1939 /// # let bump: Bump = Bump::new();
1940 /// let a: FixedBumpVec<[u8; 4]> = FixedBumpVec::from_iter_exact_in([[0, 1, 2, 3]], &bump);
1941 /// let b: FixedBumpVec<u32> = a.map_in_place(u32::from_le_bytes);
1942 /// # _ = b;
1943 /// ```
1944 ///
1945 /// Mapping to a type with a greater size won't compile:
1946 /// ```compile_fail,E0080
1947 /// # use bump_scope::{Bump, FixedBumpVec};
1948 /// # let bump: Bump = Bump::new();
1949 /// let a: FixedBumpVec<u32> = FixedBumpVec::from_iter_exact_in([42], &bump);
1950 /// let b: FixedBumpVec<[u32; 2]> = a.map_in_place(|i| [i; 2]);
1951 /// # _ = b;
1952 /// ```
1953 pub fn map_in_place<U>(self, f: impl FnMut(T) -> U) -> FixedBumpVec<'a, U> {
1954 let Self { initialized, capacity } = self;
1955
1956 FixedBumpVec {
1957 initialized: initialized.map_in_place(f),
1958 capacity: if U::IS_ZST {
1959 usize::MAX
1960 } else {
1961 (capacity * T::SIZE) / U::SIZE
1962 },
1963 }
1964 }
1965
1966 /// Appends an element to the back of the collection.
1967 ///
1968 /// # Safety
1969 /// Vector must not be full.
1970 ///
1971 /// # Examples
1972 /// ```
1973 /// # use bump_scope::{Bump, FixedBumpVec};
1974 /// # let bump: Bump = Bump::new();
1975 /// let mut vec = FixedBumpVec::with_capacity_in(3, &bump);
1976 /// vec.append([1, 2]);
1977 /// unsafe { vec.push_unchecked(3) };
1978 /// assert_eq!(vec, [1, 2, 3]);
1979 /// ```
1980 #[inline(always)]
1981 pub unsafe fn push_unchecked(&mut self, value: T) {
1982 _ = unsafe { self.push_mut_unchecked(value) };
1983 }
1984
1985 /// Appends an element to the back of the collection, returning a reference to it.
1986 ///
1987 /// # Safety
1988 /// Vector must not be full.
1989 ///
1990 /// # Examples
1991 /// ```
1992 /// # use bump_scope::{Bump, FixedBumpVec};
1993 /// # let bump: Bump = Bump::new();
1994 /// let mut vec = FixedBumpVec::with_capacity_in(4, &bump);
1995 /// vec.append([1, 2]);
1996 ///
1997 /// let last = unsafe { vec.push_mut_unchecked(3) };
1998 /// assert_eq!(*last, 3);
1999 /// assert_eq!(vec, [1, 2, 3]);
2000 ///
2001 /// let last = unsafe { vec.push_mut_unchecked(3) };
2002 /// *last += 1;
2003 /// assert_eq!(vec, [1, 2, 3, 4]);
2004 /// ```
2005 #[inline(always)]
2006 #[must_use = "if you don't need a reference to the value, use `push_unchecked` instead"]
2007 pub unsafe fn push_mut_unchecked(&mut self, value: T) -> &mut T {
2008 debug_assert!(!self.is_full());
2009
2010 unsafe {
2011 let ptr = self.as_mut_ptr().add(self.len());
2012 ptr.write(value);
2013 self.inc_len(1);
2014 &mut *ptr
2015 }
2016 }
2017
2018 /// Appends an element to the back of the collection.
2019 ///
2020 /// # Safety
2021 /// Vector must not be full.
2022 #[inline(always)]
2023 #[deprecated = "use `push_unchecked(f())` instead"]
2024 pub unsafe fn push_with_unchecked(&mut self, f: impl FnOnce() -> T) {
2025 unsafe { self.push_unchecked(f()) };
2026 }
2027
2028 /// Extend the vector by `n` clones of value.
2029 fn extend_with<B: ErrorBehavior>(&mut self, n: usize, value: T) -> Result<(), B>
2030 where
2031 T: Clone,
2032 {
2033 self.generic_reserve(n)?;
2034 unsafe {
2035 self.extend_with_unchecked(n, value);
2036 }
2037 Ok(())
2038 }
2039
2040 /// Extend the vector by `n` clones of value.
2041 ///
2042 /// # Safety
2043 /// Capacity must be sufficient.
2044 pub(crate) unsafe fn extend_with_unchecked(&mut self, n: usize, value: T)
2045 where
2046 T: Clone,
2047 {
2048 unsafe {
2049 let mut ptr = self.as_mut_ptr().add(self.len());
2050
2051 // Use SetLenOnDrop to work around bug where compiler
2052 // might not realize the store through `ptr` through self.set_len()
2053 // don't alias.
2054 let mut local_len = self.initialized.set_len_on_drop();
2055
2056 // Write all elements except the last one
2057 for _ in 1..n {
2058 pointer::write_with(ptr, || value.clone());
2059 ptr = ptr.add(1);
2060
2061 // Increment the length in every step in case clone() panics
2062 local_len.increment_len(1);
2063 }
2064
2065 if n > 0 {
2066 // We can write the last element directly without cloning needlessly
2067 ptr.write(value);
2068 local_len.increment_len(1);
2069 }
2070
2071 // len set by scope guard
2072 }
2073 }
2074
2075 /// Retains only the elements specified by the predicate, passing a mutable reference to it.
2076 ///
2077 /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
2078 /// This method operates in place, visiting each element exactly once in the
2079 /// original order, and preserves the order of the retained elements.
2080 ///
2081 /// # Examples
2082 ///
2083 /// ```
2084 /// # use bump_scope::{Bump, FixedBumpVec};
2085 /// # let bump: Bump = Bump::new();
2086 /// #
2087 /// let mut vec = FixedBumpVec::with_capacity_in(4, &bump);
2088 /// vec.extend_from_slice_copy(&[1, 2, 3, 4]);
2089 ///
2090 /// vec.retain(|x| if *x <= 3 {
2091 /// *x += 1;
2092 /// true
2093 /// } else {
2094 /// false
2095 /// });
2096 ///
2097 /// assert_eq!(vec, [2, 3, 4]);
2098 /// ```
2099 #[expect(clippy::pedantic)]
2100 pub fn retain<F>(&mut self, f: F)
2101 where
2102 F: FnMut(&mut T) -> bool,
2103 {
2104 self.initialized.retain(f)
2105 }
2106
2107 /// Removes the specified range from the vector in bulk, returning all
2108 /// removed elements as an iterator. If the iterator is dropped before
2109 /// being fully consumed, it drops the remaining removed elements.
2110 ///
2111 /// The returned iterator keeps a mutable borrow on the vector to optimize
2112 /// its implementation.
2113 ///
2114 /// # Panics
2115 ///
2116 /// Panics if the starting point is greater than the end point or if
2117 /// the end point is greater than the length of the vector.
2118 ///
2119 /// # Leaking
2120 ///
2121 /// If the returned iterator goes out of scope without being dropped (due to
2122 /// [`mem::forget`](core::mem::forget), for example), the vector may have lost and leaked
2123 /// elements arbitrarily, including elements outside the range.
2124 ///
2125 /// # Examples
2126 ///
2127 /// ```
2128 /// # use bump_scope::{Bump, FixedBumpVec};
2129 /// # let bump: Bump = Bump::new();
2130 /// #
2131 /// let mut v = FixedBumpVec::with_capacity_in(3, &bump);
2132 /// v.extend_from_slice_copy(&[1, 2, 3]);
2133 /// let u = bump.alloc_iter(v.drain(1..));
2134 /// assert_eq!(v, [1]);
2135 /// assert_eq!(u, [2, 3]);
2136 ///
2137 /// // A full range clears the vector, like `clear()` does
2138 /// v.drain(..);
2139 /// assert_eq!(v, []);
2140 /// ```
2141 pub fn drain<R>(&mut self, range: R) -> owned_slice::Drain<'_, T>
2142 where
2143 R: RangeBounds<usize>,
2144 {
2145 self.initialized.drain(range)
2146 }
2147
2148 /// Creates an iterator which uses a closure to determine if an element should be removed.
2149 ///
2150 /// If the closure returns true, then the element is removed and yielded.
2151 /// If the closure returns false, the element will remain in the vector and will not be yielded
2152 /// by the iterator.
2153 ///
2154 /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
2155 /// or the iteration short-circuits, then the remaining elements will be retained.
2156 /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
2157 ///
2158 /// Using this method is equivalent to the following code:
2159 ///
2160 /// ```
2161 /// # let some_predicate = |x: &mut i32| { *x == 2 || *x == 3 || *x == 6 };
2162 /// # use bump_scope::{Bump, FixedBumpVec};
2163 /// # let bump: Bump = Bump::new();
2164 /// # let mut vec = FixedBumpVec::with_capacity_in(6, &bump);
2165 /// # vec.extend_from_slice_copy(&[1, 2, 3, 4, 5, 6]);
2166 /// let mut i = 0;
2167 /// while i < vec.len() {
2168 /// if some_predicate(&mut vec[i]) {
2169 /// let val = vec.remove(i);
2170 /// // your code here
2171 /// # _ = val;
2172 /// } else {
2173 /// i += 1;
2174 /// }
2175 /// }
2176 ///
2177 /// # assert_eq!(vec, [1, 4, 5]);
2178 /// ```
2179 ///
2180 /// But `extract_if` is easier to use. `extract_if` is also more efficient,
2181 /// because it can backshift the elements of the array in bulk.
2182 ///
2183 /// Note that `extract_if` also lets you mutate every element in the filter closure,
2184 /// regardless of whether you choose to keep or remove it.
2185 ///
2186 /// # Examples
2187 ///
2188 /// Splitting an array into evens and odds, reusing the original allocation:
2189 ///
2190 /// ```
2191 /// # use bump_scope::{Bump, FixedBumpVec};
2192 /// # let bump: Bump = Bump::new();
2193 /// let mut numbers = FixedBumpVec::with_capacity_in(16, &bump);
2194 /// numbers.extend_from_slice_copy(&[1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]);
2195 ///
2196 /// let evens = bump.alloc_iter(numbers.extract_if(|x| *x % 2 == 0));
2197 /// let odds = numbers;
2198 ///
2199 /// assert_eq!(evens, [2, 4, 6, 8, 14]);
2200 /// assert_eq!(odds, [1, 3, 5, 9, 11, 13, 15]);
2201 /// ```
2202 ///
2203 /// [`retain`]: Self::retain
2204 pub fn extract_if<F>(&mut self, filter: F) -> owned_slice::ExtractIf<'_, T, F>
2205 where
2206 F: FnMut(&mut T) -> bool,
2207 {
2208 self.initialized.extract_if(filter)
2209 }
2210
2211 /// Removes consecutive repeated elements in the vector according to the
2212 /// [`PartialEq`] trait implementation.
2213 ///
2214 /// If the vector is sorted, this removes all duplicates.
2215 ///
2216 /// # Examples
2217 ///
2218 /// ```
2219 /// # use bump_scope::{Bump, FixedBumpVec};
2220 /// # let bump: Bump = Bump::new();
2221 /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
2222 /// vec.extend_from_slice_copy(&[1, 2, 2, 3, 2]);
2223 ///
2224 /// vec.dedup();
2225 ///
2226 /// assert_eq!(vec, [1, 2, 3, 2]);
2227 /// ```
2228 #[inline]
2229 pub fn dedup(&mut self)
2230 where
2231 T: PartialEq,
2232 {
2233 self.initialized.dedup();
2234 }
2235
2236 /// Removes all but the first of consecutive elements in the vector that resolve to the same
2237 /// key.
2238 ///
2239 /// If the vector is sorted, this removes all duplicates.
2240 ///
2241 /// # Examples
2242 ///
2243 /// ```
2244 /// # use bump_scope::{Bump, FixedBumpVec};
2245 /// # let bump: Bump = Bump::new();
2246 /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
2247 /// vec.extend_from_slice_copy(&[10, 20, 21, 30, 20]);
2248 ///
2249 /// vec.dedup_by_key(|i| *i / 10);
2250 ///
2251 /// assert_eq!(vec, [10, 20, 30, 20]);
2252 /// ```
2253 #[inline]
2254 pub fn dedup_by_key<F, K>(&mut self, key: F)
2255 where
2256 F: FnMut(&mut T) -> K,
2257 K: PartialEq,
2258 {
2259 self.initialized.dedup_by_key(key);
2260 }
2261
2262 /// Removes all but the first of consecutive elements in the vector satisfying a given equality
2263 /// relation.
2264 ///
2265 /// The `same_bucket` function is passed references to two elements from the vector and
2266 /// must determine if the elements compare equal. The elements are passed in opposite order
2267 /// from their order in the vector, so if `same_bucket(a, b)` returns `true`, `a` is removed.
2268 ///
2269 /// If the vector is sorted, this removes all duplicates.
2270 ///
2271 /// # Examples
2272 ///
2273 /// ```
2274 /// # use bump_scope::{Bump, FixedBumpVec};
2275 /// # let bump: Bump = Bump::new();
2276 /// let mut vec = FixedBumpVec::with_capacity_in(5, &bump);
2277 /// vec.extend_from_slice_copy(&["foo", "bar", "Bar", "baz", "bar"]);
2278 ///
2279 /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
2280 ///
2281 /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
2282 /// ```
2283 pub fn dedup_by<F>(&mut self, same_bucket: F)
2284 where
2285 F: FnMut(&mut T, &mut T) -> bool,
2286 {
2287 self.initialized.dedup_by(same_bucket);
2288 }
2289
2290 /// Returns the vector content as a boxed slice of `T`, along with the remaining spare
2291 /// capacity of the vector as a boxed slice of `MaybeUninit<T>`.
2292 #[inline]
2293 #[must_use]
2294 pub fn split_at_spare(self) -> (BumpBox<'a, [T]>, BumpBox<'a, [MaybeUninit<T>]>) {
2295 unsafe {
2296 let uninitialized_ptr = self
2297 .initialized
2298 .as_non_null()
2299 .add(self.initialized.len())
2300 .cast::<MaybeUninit<T>>();
2301 let uninitialized_len = self.capacity - self.len();
2302 let uninitialized = BumpBox::from_raw(NonNull::slice_from_raw_parts(uninitialized_ptr, uninitialized_len));
2303 (self.initialized, uninitialized)
2304 }
2305 }
2306
2307 #[inline(always)]
2308 pub(crate) fn into_raw_parts(self) -> (BumpBox<'a, [T]>, usize) {
2309 (self.initialized, self.capacity)
2310 }
2311
2312 #[inline(always)]
2313 pub(crate) unsafe fn from_raw_parts(initialized: BumpBox<'a, [T]>, capacity: usize) -> Self {
2314 Self { initialized, capacity }
2315 }
2316
2317 #[inline(always)]
2318 unsafe fn extend_by_copy_nonoverlapping<B: ErrorBehavior>(&mut self, other: *const [T]) -> Result<(), B> {
2319 unsafe {
2320 let len = other.len();
2321 self.generic_reserve(len)?;
2322
2323 let src = other.cast::<T>();
2324 let dst = self.as_mut_ptr().add(self.len());
2325 ptr::copy_nonoverlapping(src, dst, len);
2326
2327 self.inc_len(len);
2328 Ok(())
2329 }
2330 }
2331
2332 /// # Safety
2333 ///
2334 /// `iterator` must satisfy the invariants of nightly's `TrustedLen`.
2335 unsafe fn extend_trusted<B: ErrorBehavior>(&mut self, iterator: impl Iterator<Item = T>) -> Result<(), B> {
2336 unsafe {
2337 let (low, high) = iterator.size_hint();
2338 if let Some(additional) = high {
2339 debug_assert_eq!(
2340 low,
2341 additional,
2342 "TrustedLen iterator's size hint is not exact: {:?}",
2343 (low, high)
2344 );
2345
2346 self.generic_reserve(additional)?;
2347
2348 let ptr = self.as_mut_ptr();
2349 let mut local_len = self.initialized.set_len_on_drop();
2350
2351 iterator.for_each(move |element| {
2352 let dst = ptr.add(local_len.current_len());
2353
2354 ptr::write(dst, element);
2355 // Since the loop executes user code which can panic we have to update
2356 // the length every step to correctly drop what we've written.
2357 // NB can't overflow since we would have had to alloc the address space
2358 local_len.increment_len(1);
2359 });
2360
2361 Ok(())
2362 } else {
2363 // Per TrustedLen contract a `None` upper bound means that the iterator length
2364 // truly exceeds usize::MAX, which would eventually lead to a capacity overflow anyway.
2365 // Since the other branch already panics eagerly (via `reserve()`) we do the same here.
2366 // This avoids additional codegen for a fallback code path which would eventually
2367 // panic anyway.
2368 Err(B::fixed_size_vector_is_full())
2369 }
2370 }
2371 }
2372
2373 #[inline(always)]
2374 fn generic_reserve_one<B: ErrorBehavior>(&self) -> Result<(), B> {
2375 if self.is_full() {
2376 Err(B::fixed_size_vector_is_full())
2377 } else {
2378 Ok(())
2379 }
2380 }
2381}
2382
2383impl<'a, T, const N: usize> FixedBumpVec<'a, [T; N]> {
2384 /// Takes a `FixedBumpVec<[T; N]>` and flattens it into a `FixedBumpVec<T>`.
2385 ///
2386 /// # Panics
2387 ///
2388 /// Panics if the length of the resulting vector would overflow a `usize`.
2389 ///
2390 /// This is only possible when flattening a vector of arrays of zero-sized
2391 /// types, and thus tends to be irrelevant in practice. If
2392 /// `size_of::<T>() > 0`, this will never panic.
2393 ///
2394 /// # Examples
2395 ///
2396 /// ```
2397 /// # use bump_scope::{Bump, FixedBumpVec};
2398 /// # let bump: Bump = Bump::new();
2399 /// #
2400 /// let mut vec = FixedBumpVec::with_capacity_in(3, &bump);
2401 /// vec.append([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
2402 /// assert_eq!(vec.pop(), Some([7, 8, 9]));
2403 ///
2404 /// let mut flattened = vec.into_flattened();
2405 /// assert_eq!(flattened.pop(), Some(6));
2406 /// ```
2407 #[must_use]
2408 pub fn into_flattened(self) -> FixedBumpVec<'a, T> {
2409 let (initialized, cap) = self.into_raw_parts();
2410 let ptr = initialized.into_raw();
2411 let len = ptr.len();
2412
2413 let (new_len, new_cap) = if T::IS_ZST {
2414 (len.checked_mul(N).expect("vec len overflow"), usize::MAX)
2415 } else {
2416 // SAFETY:
2417 // - `cap * N` cannot overflow because the allocation is already in
2418 // the address space.
2419 // - Each `[T; N]` has `N` valid elements, so there are `len * N`
2420 // valid elements in the allocation.
2421 unsafe { (len.unchecked_mul(N), cap.unchecked_mul(N)) }
2422 };
2423
2424 // SAFETY:
2425 // - `ptr` was allocated by `self`
2426 // - `ptr` is well-aligned because `[T; N]` has the same alignment as `T`.
2427 // - `new_cap` refers to the same sized allocation as `cap` because
2428 // `new_cap * size_of::<T>()` == `cap * size_of::<[T; N]>()`
2429 // - `len` <= `cap`, so `len * N` <= `cap * N`.
2430 unsafe {
2431 let slice = NonNull::slice_from_raw_parts(ptr.cast(), new_len);
2432 let initialized = BumpBox::from_raw(slice);
2433 FixedBumpVec::from_raw_parts(initialized, new_cap)
2434 }
2435 }
2436}
2437
2438impl<T> Debug for FixedBumpVec<'_, T>
2439where
2440 T: Debug,
2441{
2442 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2443 self.initialized.fmt(f)
2444 }
2445}
2446
2447impl<T> Default for FixedBumpVec<'_, T> {
2448 fn default() -> Self {
2449 Self::new()
2450 }
2451}
2452
2453impl<T> Deref for FixedBumpVec<'_, T> {
2454 type Target = [T];
2455
2456 fn deref(&self) -> &Self::Target {
2457 &self.initialized
2458 }
2459}
2460
2461impl<T> DerefMut for FixedBumpVec<'_, T> {
2462 fn deref_mut(&mut self) -> &mut Self::Target {
2463 &mut self.initialized
2464 }
2465}
2466
2467impl<T, I: SliceIndex<[T]>> Index<I> for FixedBumpVec<'_, T> {
2468 type Output = I::Output;
2469
2470 #[inline(always)]
2471 fn index(&self, index: I) -> &Self::Output {
2472 Index::index(self.as_slice(), index)
2473 }
2474}
2475
2476impl<T, I: SliceIndex<[T]>> IndexMut<I> for FixedBumpVec<'_, T> {
2477 #[inline(always)]
2478 fn index_mut(&mut self, index: I) -> &mut Self::Output {
2479 IndexMut::index_mut(self.as_mut_slice(), index)
2480 }
2481}
2482
2483#[cfg(feature = "panic-on-alloc")]
2484impl<T> Extend<T> for FixedBumpVec<'_, T> {
2485 #[inline]
2486 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
2487 let iter = iter.into_iter();
2488
2489 self.reserve(iter.size_hint().0);
2490
2491 for value in iter {
2492 self.push(value);
2493 }
2494 }
2495}
2496
2497#[cfg(feature = "panic-on-alloc")]
2498impl<'t, T> Extend<&'t T> for FixedBumpVec<'_, T>
2499where
2500 T: Clone + 't,
2501{
2502 #[inline]
2503 fn extend<I: IntoIterator<Item = &'t T>>(&mut self, iter: I) {
2504 let iter = iter.into_iter();
2505
2506 self.reserve(iter.size_hint().0);
2507
2508 for value in iter {
2509 self.push(value.clone());
2510 }
2511 }
2512}
2513
2514impl<'a, T> IntoIterator for FixedBumpVec<'a, T> {
2515 type Item = T;
2516 type IntoIter = owned_slice::IntoIter<'a, T>;
2517
2518 #[inline(always)]
2519 fn into_iter(self) -> Self::IntoIter {
2520 self.initialized.into_iter()
2521 }
2522}
2523
2524impl<'c, T> IntoIterator for &'c FixedBumpVec<'_, T> {
2525 type Item = &'c T;
2526 type IntoIter = slice::Iter<'c, T>;
2527
2528 #[inline(always)]
2529 fn into_iter(self) -> Self::IntoIter {
2530 self.as_slice().iter()
2531 }
2532}
2533
2534impl<'c, T> IntoIterator for &'c mut FixedBumpVec<'_, T> {
2535 type Item = &'c mut T;
2536 type IntoIter = slice::IterMut<'c, T>;
2537
2538 #[inline(always)]
2539 fn into_iter(self) -> Self::IntoIter {
2540 self.as_mut_slice().iter_mut()
2541 }
2542}
2543
2544impl<T> AsRef<Self> for FixedBumpVec<'_, T> {
2545 #[inline(always)]
2546 fn as_ref(&self) -> &Self {
2547 self
2548 }
2549}
2550
2551impl<T> AsMut<Self> for FixedBumpVec<'_, T> {
2552 #[inline(always)]
2553 fn as_mut(&mut self) -> &mut Self {
2554 self
2555 }
2556}
2557
2558impl<T> AsRef<[T]> for FixedBumpVec<'_, T> {
2559 #[inline(always)]
2560 fn as_ref(&self) -> &[T] {
2561 self
2562 }
2563}
2564
2565impl<T> AsMut<[T]> for FixedBumpVec<'_, T> {
2566 #[inline(always)]
2567 fn as_mut(&mut self) -> &mut [T] {
2568 self
2569 }
2570}
2571
2572impl<T> Borrow<[T]> for FixedBumpVec<'_, T> {
2573 #[inline(always)]
2574 fn borrow(&self) -> &[T] {
2575 self
2576 }
2577}
2578
2579impl<T> BorrowMut<[T]> for FixedBumpVec<'_, T> {
2580 #[inline(always)]
2581 fn borrow_mut(&mut self) -> &mut [T] {
2582 self
2583 }
2584}
2585
2586impl<T: Hash> Hash for FixedBumpVec<'_, T> {
2587 #[inline(always)]
2588 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
2589 self.as_slice().hash(state);
2590 }
2591}
2592
2593/// Returns [`ErrorKind::OutOfMemory`](std::io::ErrorKind::OutOfMemory) when extending fails.
2594#[cfg(feature = "std")]
2595impl std::io::Write for FixedBumpVec<'_, u8> {
2596 #[inline(always)]
2597 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
2598 if self.try_extend_from_slice_copy(buf).is_err() {
2599 return Err(std::io::ErrorKind::OutOfMemory.into());
2600 }
2601
2602 Ok(buf.len())
2603 }
2604
2605 #[inline(always)]
2606 fn flush(&mut self) -> std::io::Result<()> {
2607 Ok(())
2608 }
2609
2610 #[inline]
2611 fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
2612 let len = bufs.iter().map(|b| b.len()).sum();
2613 self.try_reserve(len).map_err(|_| std::io::ErrorKind::OutOfMemory)?;
2614 for buf in bufs {
2615 self.try_extend_from_slice_copy(buf)
2616 .map_err(|_| std::io::ErrorKind::OutOfMemory)?;
2617 }
2618 Ok(len)
2619 }
2620
2621 #[inline(always)]
2622 fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
2623 if self.try_extend_from_slice_copy(buf).is_err() {
2624 return Err(std::io::ErrorKind::OutOfMemory.into());
2625 }
2626
2627 Ok(())
2628 }
2629}
2630
2631impl<T: NoDrop> NoDrop for FixedBumpVec<'_, T> {}