cl_generic_vec/lib.rs
1#![cfg_attr(not(any(doc, feature = "std")), no_std)]
2#![cfg_attr(
3 any(doc, feature = "nightly"),
4 feature(
5 trusted_len,
6 min_specialization,
7 exact_size_is_empty,
8 allocator_api,
9 alloc_layout_extra,
10 const_fn_trait_bound,
11 const_mut_refs,
12 doc_cfg,
13 ptr_metadata,
14 )
15)]
16#![cfg_attr(all(feature = "nightly", feature = "alloc"), feature(new_uninit))]
17#![cfg_attr(feature = "nightly", forbid(unsafe_op_in_unsafe_fn))]
18#![allow(unused_unsafe)]
19#![forbid(missing_docs, clippy::missing_safety_doc)]
20#![warn(clippy::pedantic)]
21#![allow(clippy::must_use_candidate, clippy::module_name_repetitions)]
22
23//! A vector that can store items anywhere: in slices, arrays, or the heap!
24//!
25//! [`GenericVec`] has complete parity with [`Vec`], and even provides some features
26//! that are only in `nightly` on `std` (like [`GenericVec::drain_filter`]), or a more permissive
27//! interface like [`GenericVec::retain`]. In fact, you can trivially convert a [`Vec`] to a
28//! [`HeapVec`] and back!
29//!
30//! This crate is `no_std` compatible, just turn off all default features.
31//!
32//! # Features
33//!
34//! * `std` (default) - enables you to use an allocator, and
35//! * `alloc` - enables you to use an allocator, for heap allocated storages
36//! (like [`Vec`])
37//! * `nightly` - enables you to use the Allocator trait
38//!
39//! # Basic Usage
40//!
41//! ### [`SliceVec`]
42//!
43//! [`SliceVec`] stores an uninit slice buffer, and they store all of thier values in that buffer.
44//!
45//! ```rust
46//! use cl_generic_vec::{SliceVec, uninit_array};
47//!
48//! let mut uninit_buffer = uninit_array::<_, 16>();
49//! let mut slice_vec = unsafe { SliceVec::new(&mut uninit_buffer) };
50//!
51//! assert!(slice_vec.is_empty());
52//! slice_vec.push(10);
53//! assert_eq!(slice_vec, [10]);
54//! ```
55//!
56//! Of course if you try to push past a `*SliceVec`'s capacity
57//! (the length of the slice you passed in), then it will panic.
58//!
59//! ### [`ArrayVec`](type@ArrayVec)
60//!
61//! [`ArrayVec`](type@ArrayVec) is like the slice version, but since they own their data,
62//! they can be freely moved around, unconstrained. You can also create
63//! a new [`ArrayVec`](type@ArrayVec) without passing in an existing buffer,
64//! unlike the slice versions.
65//!
66//! ```rust
67//! use cl_generic_vec::ArrayVec;
68//!
69//! let mut array_vec = ArrayVec::<i32, 16>::new();
70//!
71//! array_vec.push(10);
72//! array_vec.push(20);
73//! array_vec.push(30);
74//!
75//! assert_eq!(array_vec, [10, 20, 30]);
76//! ```
77//!
78//! ## `alloc`
79//!
80//! A [`HeapVec`] is just [`Vec`], but built atop [`GenericVec`],
81//! meaning you get all the features of [`GenericVec`] for free! But this
82//! requries either the `alloc` or `std` feature to be enabled.
83//!
84//! ```rust
85//! use cl_generic_vec::{HeapVec, gvec};
86//! let mut vec: HeapVec<u32> = gvec![1, 2, 3, 4];
87//! assert_eq!(vec.capacity(), 4);
88//! vec.extend([5, 6, 7, 8]);
89//!
90//! assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]);
91//!
92//! vec.try_push(5).expect_err("Tried to push past capacity!");
93//! ```
94//!
95//! ## `nightly`
96//!
97//! On `nightly`
98//! * a number of optimizations are enabled
99//! * some diagnostics become better
100//!
101//! Note on the documentation: if the feature exists on [`Vec`], then the documentation
102//! is either exactly the same as [`Vec`] or slightly adapted to better fit [`GenericVec`]
103//!
104//! Note on implementation: large parts of the implementation came straight from [`Vec`]
105//! so thanks for the amazing reference `std`!
106
107#[cfg(all(feature = "alloc", not(feature = "std")))]
108extern crate alloc as std;
109
110use core::{
111 mem::{ManuallyDrop, MaybeUninit},
112 ops::{Deref, DerefMut, RangeBounds},
113 ptr,
114};
115
116mod extension;
117mod impls;
118mod slice;
119
120pub mod iter;
121pub mod raw;
122
123use raw::{AllocError, AllocResult, Storage};
124
125#[doc(hidden)]
126pub use core;
127
128/// A type provided purely for simplicity.
129///
130/// [`GenericVec`] includes it's `T` type as a type parameter,
131/// even though it can be trivially inferred from the [`Storage::Item`] field.
132/// This is because it helps in generic contexts, the T type just gives the compiler
133/// a little nudge to be able to tell apart a `GenericVec<Item = u8>` from `GenericVec<Item = u16>`.
134pub type SimpleVec<S> = GenericVec<<S as Storage>::Item, S>;
135
136/// A heap backed vector with a growable capacity
137#[cfg(any(doc, all(feature = "alloc", feature = "nightly")))]
138#[cfg_attr(doc, doc(cfg(all(feature = "alloc", feature = "nightly"))))]
139pub type HeapVec<T, A = std::alloc::Global> = GenericVec<T, Box<[MaybeUninit<T>], A>>;
140
141/// A heap backed vector with a growable capacity
142#[cfg(all(not(doc), feature = "alloc", not(feature = "nightly")))]
143#[cfg_attr(doc, doc(cfg(feature = "alloc")))]
144pub type HeapVec<T> = GenericVec<T, Box<[MaybeUninit<T>]>>;
145
146/// An array backed vector backed by potentially uninitialized memory
147pub type ArrayVec<T, const N: usize> = GenericVec<T, [MaybeUninit<T>; N]>;
148/// An slice backed vector backed by potentially uninitialized memory
149pub type SliceVec<'a, T> = GenericVec<T, &'a mut [MaybeUninit<T>]>;
150
151/// Creates a new uninit array, See [`MaybeUninit::uninit_array`]
152pub fn uninit_array<T, const N: usize>() -> [MaybeUninit<T>; N] {
153 unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() }
154}
155
156/// Create a new generic vector
157///
158/// Because this can create any generic vector, you will likely
159/// need to add some type annotations when you use it,
160///
161/// ```rust
162/// # use cl_generic_vec::{gvec, ArrayVec};
163/// let x: ArrayVec<i32, 2> = gvec![0, 1];
164/// assert_eq!(x, [0, 1]);
165/// ```
166#[macro_export]
167#[cfg(feature = "nightly")]
168macro_rules! gvec {
169 ($expr:expr; $n:expr) => {{
170 let len = $n;
171 let mut vec = $crate::GenericVec::with_capacity(len);
172 vec.grow(len, $expr);
173 vec
174 }};
175 ($($expr:expr),*) => {{
176 let expr = [$($expr),*];
177 let mut vec = $crate::GenericVec::with_capacity(expr.len());
178 unsafe { vec.push_array_unchecked(expr); }
179 vec
180 }};
181}
182
183#[doc(hidden)]
184#[macro_export]
185macro_rules! count {
186 () => { 0 };
187 ($($a:tt $b:tt)*) => { $crate::count!($($a)*) << 1 };
188 ($c:tt $($a:tt $b:tt)*) => { ($crate::count!($($a)*) << 1) | 1 };
189}
190
191/// Create a new generic vector
192///
193/// Because this can create any generic vector, you will likely
194/// need to add some type annotations when you use it,
195///
196/// ```rust
197/// # use cl_generic_vec::{gvec, ArrayVec};
198/// let x: ArrayVec<i32, 4> = gvec![1, 2, 3, 4];
199/// assert_eq!(x, [1, 2, 3, 4]);
200/// ```
201#[macro_export]
202#[cfg(not(feature = "nightly"))]
203macro_rules! gvec {
204 ($expr:expr; $n:expr) => {{
205 let len = $n;
206 let mut vec = $crate::GenericVec::with_capacity(len);
207 vec.grow(len, $expr);
208 vec
209 }};
210 ($($expr:expr),*) => {{
211 let mut vec = $crate::GenericVec::with_capacity($crate::count!($(($expr))*));
212 unsafe {
213 $(vec.push_unchecked($expr);)*
214 }
215 vec
216 }};
217}
218
219/// Save the changes to [`GenericVec::spare_capacity_mut`]
220///
221/// $orig - a mutable reference to a [`GenericVec`]
222/// $spare - the [`SliceVec`] that was obtained from [`$orig.spare_capacity_mut()`]
223///
224/// # Safety
225///
226/// `$spare` should be the [`SliceVec`] returned by `$orig.spare_capacity_mut()`
227#[macro_export]
228macro_rules! save_spare {
229 ($spare:expr, $orig:expr) => {{
230 let spare: $crate::SliceVec<_> = $spare;
231 let spare = $crate::core::mem::ManuallyDrop::new(spare);
232 let len = spare.len();
233 let ptr = spare.as_ptr();
234 let orig: &mut $crate::GenericVec<_, _> = $orig;
235 $crate::validate_spare(ptr, orig);
236 let len = len + orig.len();
237 $orig.set_len_unchecked(len);
238 }};
239}
240
241#[doc(hidden)]
242pub fn validate_spare<T>(spare_ptr: *const T, orig: &[T]) {
243 debug_assert!(
244 unsafe { orig.as_ptr().add(orig.len()) == spare_ptr },
245 "Tried to use `save_spare!` with a `SliceVec` that was not obtained from `GenricVec::spare_capacity_mut`. \
246 This is undefined behavior on release mode!"
247 );
248}
249
250/// A vector type that can be backed up by a variety of different backends
251/// including slices, arrays, and the heap.
252#[repr(C)]
253pub struct GenericVec<T, S: ?Sized + Storage<Item = T>> {
254 len: usize,
255 storage: S,
256}
257
258unsafe fn slice_assume_init_ref<T>(slice: &[MaybeUninit<T>]) -> &[T] {
259 // SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that
260 // `slice` is initialized, and `MaybeUninit` is guaranteed to have the same layout as `T`.
261 // The pointer obtained is valid since it refers to memory owned by `slice` which is a
262 // reference and thus guaranteed to be valid for reads.
263 unsafe { &*(slice as *const [MaybeUninit<T>] as *const [T]) }
264}
265
266unsafe fn slice_assume_init_mut<T>(slice: &mut [MaybeUninit<T>]) -> &mut [T] {
267 // SAFETY: similar to safety notes for `slice_get_ref`, but we have a
268 // mutable reference which is also guaranteed to be valid for writes.
269 unsafe { &mut *(slice as *mut [MaybeUninit<T>] as *mut [T]) }
270}
271
272impl<S: ?Sized + Storage> Deref for SimpleVec<S> {
273 type Target = [S::Item];
274
275 fn deref(&self) -> &Self::Target {
276 let len = self.len;
277 // The first `len` elements are guaranteed to be initialized
278 // as part of the guarantee on `self.set_len_unchecked`
279 unsafe { slice_assume_init_ref(&self.storage.as_ref()[..len]) }
280 }
281}
282
283impl<S: ?Sized + Storage> DerefMut for SimpleVec<S> {
284 fn deref_mut(&mut self) -> &mut Self::Target {
285 let len = self.len;
286 // The first `len` elements are guaranteed to be initialized
287 // as part of the guarantee on `self.set_len_unchecked`
288 unsafe { slice_assume_init_mut(&mut self.storage.as_mut()[..len]) }
289 }
290}
291
292impl<T, S: ?Sized + Storage<Item = T>> Drop for GenericVec<T, S> {
293 fn drop(&mut self) {
294 // The first `len` elements are guaranteed to be initialized
295 // as part of the guarantee on `self.set_len_unchecked`
296 // These elements should be dropped when the `GenericVec` gets dropped/
297 // The storage will clean it's self up on drop
298 unsafe { ptr::drop_in_place(self.as_mut_slice()) }
299 }
300}
301
302impl<S: Storage> SimpleVec<S> {
303 /// Create a new empty `GenericVec` with the given backend
304 ///
305 /// ```rust
306 /// use cl_generic_vec::{ArrayVec, uninit_array};
307 /// let vec = ArrayVec::<i32, 4>::with_storage(uninit_array());
308 /// ```
309 pub fn with_storage(storage: S) -> Self {
310 Self::with_storage_len(storage, 0)
311 }
312
313 fn with_storage_len(storage: S, len: usize) -> Self {
314 Self { len, storage }
315 }
316}
317
318impl<S: raw::StorageWithCapacity> SimpleVec<S> {
319 /// Create a new empty `GenericVec` with the backend with at least the given capacity
320 pub fn with_capacity(capacity: usize) -> Self {
321 Self::with_storage(S::with_capacity(capacity))
322 }
323
324 #[inline]
325 #[allow(non_snake_case)]
326 fn __with_capacity__const_capacity_checked(capacity: usize, old_capacity: Option<usize>) -> Self {
327 Self::with_storage(S::__with_capacity__const_capacity_checked(capacity, old_capacity))
328 }
329}
330
331unsafe fn tm_array<T, U, const N: usize>(array: [T; N]) -> [U; N] {
332 let array = ManuallyDrop::new(array);
333 unsafe { array.as_ptr().cast::<[U; N]>().read() }
334}
335
336impl<T, const N: usize> ArrayVec<T, N> {
337 /// Create a new empty `ArrayVec`
338 pub fn new() -> Self {
339 let uninit = MaybeUninit::<[T; N]>::uninit();
340 let uninit = unsafe { tm_array::<T, MaybeUninit<T>, N>(MaybeUninit::assume_init(uninit)) };
341 Self::with_storage(uninit)
342 }
343
344 /// Create a new full `ArrayVec`
345 pub fn from_array(array: [T; N]) -> Self {
346 // Safety:
347 // The two arrays have exactly the same representation
348 // and the code is taking ownership of the maybeuninit structure,
349 // specifying an initialised count of N, so it's still known to be
350 // initialised.
351 let storage = unsafe { tm_array(array) };
352 Self { len: N, storage }
353 }
354
355 /// Convert this `ArrayVec` into an array
356 ///
357 /// # Panics
358 ///
359 /// Panics if the the collection is not full
360 pub fn into_array(self) -> [T; N] {
361 match self.try_into_array() {
362 Ok(a) => a,
363 _ => panic!("ArrayVec is not full"),
364 }
365 }
366
367 /// Convert this `ArrayVec` into an array
368 ///
369 /// # Errors
370 ///
371 /// errors if the the collection is not full
372 pub fn try_into_array(self) -> Result<[T; N], Self> {
373 if self.is_full() {
374 let this = ManuallyDrop::new(self);
375
376 // Safety: we have just asserted that the full array is initialised
377 // unsafe { MaybeUninit::array_assume_init(self.storage) }
378 Ok(unsafe { this.storage.as_ptr().cast::<[T; N]>().read() })
379 } else {
380 Err(self)
381 }
382 }
383}
384
385#[cfg(feature = "alloc")]
386#[cfg_attr(doc, doc(cfg(feature = "alloc")))]
387impl<T> HeapVec<T> {
388 /// Create a new empty `HeapVec`
389 pub fn new() -> Self {
390 Self {
391 len: 0,
392 storage: Box::<[MaybeUninit<T>]>::default(),
393 }
394 }
395}
396
397#[cfg(any(doc, all(feature = "nightly", feature = "alloc")))]
398#[cfg_attr(doc, doc(cfg(all(feature = "nightly", feature = "alloc"))))]
399impl<T, A: std::alloc::Allocator> HeapVec<T, A> {
400 /// Create a new empty `HeapVec` with the given allocator
401 pub fn with_alloc(alloc: A) -> Self {
402 Self::with_storage(Box::new_uninit_slice_in(0, alloc))
403 }
404}
405
406impl<'a, T> SliceVec<'a, T> {
407 /// Create a new empty `SliceVec`.
408 ///
409 /// # Safety
410 /// The contents of the slice should be completely uninitialised
411 pub unsafe fn new(slice: &'a mut [MaybeUninit<T>]) -> Self {
412 Self::with_storage(slice)
413 }
414
415 /// Create a new full `SliceVec`
416 pub fn full(slice: &'a mut [T]) -> Self {
417 let len = slice.len();
418 let storage = unsafe { &mut *(slice as *mut [T] as *mut [MaybeUninit<T>]) };
419 Self::with_storage_len(storage, len)
420 }
421}
422
423impl<S: Storage> SimpleVec<S> {
424 /// Convert a `GenericVec` into a length-storage pair
425 pub fn into_raw_parts(self) -> (usize, S) {
426 let this = core::mem::ManuallyDrop::new(self);
427 unsafe { (this.len, core::ptr::read(&this.storage)) }
428 }
429
430 /// Create a `GenericVec` from a length-storage pair
431 ///
432 /// # Safety
433 ///
434 /// the length must be less than `raw.capacity()` and
435 /// all elements in the range `0..length`, must be initialized
436 ///
437 /// # Panic
438 ///
439 /// If the given storage cannot hold type `T`, then this method will panic
440 #[cfg(not(feature = "nightly"))]
441 pub unsafe fn from_raw_parts(len: usize, storage: S) -> Self {
442 Self { len, storage }
443 }
444}
445
446#[cfg(feature = "nightly")]
447impl<S: Storage> SimpleVec<S> {
448 /// Create a `GenericVec` from a length-storage pair
449 ///
450 /// Note: this is only const with the `nightly` feature enabled
451 ///
452 /// # Safety
453 ///
454 /// the length must be less than `raw.capacity()` and
455 /// all elements in the range `0..length`, must be initialized
456 ///
457 /// # Panic
458 ///
459 /// If the given storage cannot hold type `T`, then this method will panic
460 pub const unsafe fn from_raw_parts(len: usize, storage: S) -> Self {
461 Self { len, storage }
462 }
463}
464
465impl<S: ?Sized + Storage> SimpleVec<S> {
466 /// Returns the number of elements the vector can hold without reallocating or panicing.
467 pub fn capacity(&self) -> usize {
468 if core::mem::size_of::<S::Item>() == 0 {
469 isize::MAX as usize
470 } else {
471 self.storage.as_ref().len()
472 }
473 }
474
475 /// Returns true if and only if the vector contains no elements.
476 pub fn is_empty(&self) -> bool {
477 self.len() == 0
478 }
479
480 /// Returns true if and only if the vector's length is equal to it's capacity.
481 pub fn is_full(&self) -> bool {
482 self.len() == self.capacity()
483 }
484
485 /// Returns the length of the spare capacity of the `GenericVec`
486 pub fn remaining_capacity(&self) -> usize {
487 self.capacity().wrapping_sub(self.len())
488 }
489
490 /// Set the length of a vector
491 ///
492 /// # Safety
493 ///
494 /// * `new_len` must be less than or equal to `capacity()`.
495 /// * The elements at `old_len..new_len` must be initialized.
496 pub unsafe fn set_len_unchecked(&mut self, len: usize) {
497 self.len = len;
498 }
499
500 /// Set the length of a vector
501 ///
502 /// # Panics
503 /// If the length is set to be larger than the capacity
504 ///
505 /// # Safety
506 ///
507 /// * The elements at `old_len..new_len` must be initialized.
508 pub unsafe fn set_len(&mut self, len: usize) {
509 // Safety
510 //
511 // The storage only contains initialized data, and we check that
512 // the given length is smaller than the capacity
513 unsafe {
514 assert!(
515 len <= self.capacity(),
516 "Tried to set the length to larger than the capacity"
517 );
518 self.set_len_unchecked(len);
519 }
520 }
521
522 /// Extracts a slice containing the entire vector.
523 ///
524 /// Equivalent to &s[..].
525 pub fn as_slice(&self) -> &[S::Item] {
526 self
527 }
528
529 /// Extracts a mutable slice containing the entire vector.
530 ///
531 /// Equivalent to &mut s[..].
532 pub fn as_mut_slice(&mut self) -> &mut [S::Item] {
533 self
534 }
535
536 /// Returns the underlying storage
537 pub fn storage(&self) -> &S {
538 &self.storage
539 }
540
541 /// Returns the underlying storage
542 ///
543 /// # Safety
544 ///
545 /// You must not replace the storage
546 pub unsafe fn storage_mut(&mut self) -> &mut S {
547 &mut self.storage
548 }
549
550 /// Returns the remaining spare capacity of the vector as
551 /// a [`SliceVec<'_, T>`](SliceVec).
552 ///
553 /// Keep in mind that the [`SliceVec<'_, T>`](SliceVec) will drop all elements
554 /// that you push into it when it goes out of scope! If you want
555 /// these modifications to persist then you should use [`save_spare`]
556 /// to persist these writes.
557 ///
558 /// ```
559 /// let mut vec = cl_generic_vec::ArrayVec::<i32, 16>::new();
560 ///
561 /// let mut spare = vec.spare_capacity_mut();
562 /// spare.push(0);
563 /// spare.push(2);
564 /// drop(spare);
565 /// assert_eq!(vec, []);
566 ///
567 /// let mut spare = vec.spare_capacity_mut();
568 /// spare.push(0);
569 /// spare.push(2);
570 /// unsafe { cl_generic_vec::save_spare!(spare, &mut vec) }
571 /// assert_eq!(vec, [0, 2]);
572 /// ```
573 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<S::Item>] {
574 let len = self.len();
575 &mut self.storage.as_mut()[len..]
576 }
577
578 /// Reserve enough space for at least `additional` elements
579 ///
580 /// # Panics
581 ///
582 /// May panic or abort if it isn't possible to allocate enough space for
583 /// `additional` more elements
584 #[inline]
585 pub fn reserve(&mut self, additional: usize) {
586 #[cold]
587 #[inline(never)]
588 fn allocation_failure(additional: usize) -> ! {
589 panic!("Tried to allocate: {} more space and failed", additional)
590 }
591
592 if self.remaining_capacity() < additional {
593 self.storage.reserve(match self.len().checked_add(additional) {
594 Some(new_capacity) => new_capacity,
595 None => allocation_failure(additional),
596 });
597 }
598 }
599
600 /// Try to reserve enough space for at least `additional` elements
601 ///
602 /// # Errors
603 /// Returns `Err(_)` if it's not possible to reserve enough space
604 #[inline]
605 pub fn try_reserve(&mut self, additional: usize) -> AllocResult {
606 if self.remaining_capacity() < additional {
607 match self.len().checked_add(additional) {
608 Some(new_capacity) => self.storage.try_reserve(new_capacity),
609 None => Err(AllocError),
610 }
611 } else {
612 Ok(())
613 }
614 }
615
616 /// Shortens the vector, keeping the first len elements and dropping the rest.
617 ///
618 /// If len is greater than the vector's current length, this has no effect.
619 ///
620 /// Note that this method has no effect on the allocated capacity of the vector.
621 pub fn truncate(&mut self, len: usize) {
622 if let Some(diff) = self.len().checked_sub(len) {
623 // # Safety
624 //
625 // * the given length is smaller than the current length, so
626 // all the elements must be initialized
627 // * the elements from `len..self.len()` are valid,
628 // and should be dropped
629 unsafe {
630 self.set_len_unchecked(len);
631 let ptr = self.as_mut_ptr().add(len);
632 let len = diff;
633 core::ptr::drop_in_place(core::slice::from_raw_parts_mut(ptr, len));
634 }
635 }
636 }
637
638 /// Grows the `GenericVec` in-place by additional elements.
639 ///
640 /// This method requires `T` to implement `Clone`, in order to be able to clone
641 /// the passed value. If you need more flexibility (or want to rely on Default instead of `Clone`),
642 /// use [`GenericVec::grow_with`].
643 ///
644 /// # Panic
645 ///
646 /// May panic or reallocate if the collection is full
647 ///
648 /// # Panic behavor
649 ///
650 /// If `T::clone` panics, then all added items will be dropped. This is different
651 /// from `std`, where on panic, items will stay in the `Vec`. This behavior
652 /// is unstable, and may change in the future.
653 pub fn grow(&mut self, additional: usize, value: S::Item)
654 where
655 S::Item: Clone,
656 {
657 self.reserve(additional);
658 // # Safety
659 //
660 // * we reserved enough space
661 unsafe { extension::Extension::grow(self, additional, value) }
662 }
663
664 /// Grows the `GenericVec` in-place by additional elements.
665 ///
666 /// This method uses a closure to create new values on every push.
667 /// If you'd rather `Clone` a given value, use `GenericVec::resize`.
668 /// If you want to use the `Default` trait to generate values, you
669 /// can pass `Default::default` as the second argument.
670 ///
671 /// # Panic
672 ///
673 /// May panic or reallocate if the collection is full
674 ///
675 /// # Panic behavor
676 ///
677 /// If `F` panics, then all added items will be dropped. This is different
678 /// from `std`, where on panic, items will stay in the `Vec`. This behavior
679 /// is unstable, and may change in the future.
680 pub fn grow_with<F>(&mut self, additional: usize, mut value: F)
681 where
682 F: FnMut() -> S::Item,
683 {
684 // Safety
685 //
686 // * we reserve enough space for `additional` elements
687 // * we use `spare_capacity_mut` to ensure that the items are dropped,
688 // even on panic
689 // * the `ptr` always stays in bounds
690
691 self.reserve(additional);
692 let spare = self.spare_capacity_mut();
693 let mut writer = unsafe { SliceVec::new(spare) };
694
695 for _ in 0..additional {
696 unsafe {
697 writer.push_unchecked(value());
698 }
699 }
700
701 unsafe {
702 // don't drop the new data!
703 let writer = core::mem::ManuallyDrop::new(writer);
704 let len = writer.len() + self.len();
705 self.set_len_unchecked(len);
706 }
707 }
708
709 /// Resizes the [`GenericVec`] in-place so that `len` is equal to `new_len`.
710 ///
711 /// If `new_len` is greater than `len`, the [`GenericVec`] is extended by the difference,
712 /// with each additional slot filled with value. If `new_len` is less than `len`,
713 /// the [`GenericVec`] is simply truncated.
714 ///
715 /// If you know that `new_len` is larger than `len`, then use [`GenericVec::grow`]
716 ///
717 /// If you know that `new_len` is less than `len`, then use [`GenericVec::truncate`]
718 ///
719 /// This method requires `T` to implement `Clone`, in order to be able to clone
720 /// the passed value. If you need more flexibility (or want to rely on Default
721 /// instead of `Clone`), use [`GenericVec::resize_with`].
722 ///
723 /// # Panic
724 ///
725 /// May panic or reallocate if the collection is full
726 ///
727 /// # Panic behavor
728 ///
729 /// If `F` panics, then all added items will be dropped. This is different
730 /// from `std`, where on panic, items will stay in the `Vec`. This behavior
731 /// is unstable, and may change in the future.
732 pub fn resize(&mut self, new_len: usize, value: S::Item)
733 where
734 S::Item: Clone,
735 {
736 match new_len.checked_sub(self.len()) {
737 Some(0) => (),
738 Some(additional) => self.grow(additional, value),
739 None => self.truncate(new_len),
740 }
741 }
742
743 /// Resizes the [`GenericVec`] in-place so that len is equal to `new_len`.
744 ///
745 /// If `new_len` is greater than `len`, the [`GenericVec`] is extended by the
746 /// difference, with each additional slot filled with the result of calling
747 /// the closure `f`. The return values from `f` will end up in the [`GenericVec`]
748 /// in the order they have been generated.
749 ///
750 /// If `new_len` is less than `len`, the [`GenericVec`] is simply truncated.
751 ///
752 /// If you know that `new_len` is larger than `len`, then use [`GenericVec::grow_with`]
753 ///
754 /// If you know that `new_len` is less than `len`, then use [`GenericVec::truncate`]
755 ///
756 /// This method uses a closure to create new values on every push. If you'd
757 /// rather [`Clone`] a given value, use [`GenericVec::resize`]. If you want to
758 /// use the [`Default`] trait to generate values, you can pass [`Default::default`]
759 /// as the second argument.
760 ///
761 /// # Panic
762 ///
763 /// May panic or reallocate if the collection is full
764 ///
765 /// # Panic behavor
766 ///
767 /// If `F` panics, then all added items will be dropped. This is different
768 /// from `std`, where on panic, items will stay in the `Vec`. This behavior
769 /// is unstable, and may change in the future.
770 pub fn resize_with<F: FnMut() -> S::Item>(&mut self, new_len: usize, value: F) {
771 match new_len.checked_sub(self.len()) {
772 Some(0) => (),
773 Some(additional) => self.grow_with(additional, value),
774 None => self.truncate(new_len),
775 }
776 }
777
778 /// Clears the vector, removing all values.
779 ///
780 /// Note that this method has no effect on the allocated capacity of the vector.
781 pub fn clear(&mut self) {
782 self.truncate(0);
783 }
784
785 /// Appends an element to the back of a collection.
786 ///
787 /// # Panic
788 ///
789 /// May panic or reallocate if the collection is full
790 pub fn push(&mut self, value: S::Item) -> &mut S::Item {
791 if self.len() == self.capacity() {
792 self.reserve(1);
793 }
794
795 // Safety
796 //
797 // * we reserve enough space for 1 more element
798 unsafe { self.push_unchecked(value) }
799 }
800
801 /// Appends the array to the back of a collection.
802 ///
803 /// # Panic
804 ///
805 /// May panic or reallocate if the collection has less than N elements remaining
806 #[cfg(any(doc, feature = "nightly"))]
807 pub fn push_array<const N: usize>(&mut self, value: [S::Item; N]) -> &mut [S::Item; N] {
808 self.reserve(N);
809
810 // Safety
811 //
812 // * we reserve enough space for N more elements
813 unsafe { self.push_array_unchecked(value) }
814 }
815
816 /// Inserts an element at position index within the vector,
817 /// shifting all elements after it to the right.
818 ///
819 /// # Panics
820 ///
821 /// * May panic or reallocate if the collection is full
822 /// * Panics if index > len.
823 pub fn insert(&mut self, index: usize, value: S::Item) -> &mut S::Item {
824 #[cold]
825 #[inline(never)]
826 fn insert_fail(index: usize, len: usize) -> ! {
827 panic!("Tried to insert at {}, but length is {}", index, len);
828 }
829
830 if index > self.len() {
831 insert_fail(index, self.len())
832 }
833
834 if self.is_full() {
835 self.reserve(1);
836 }
837
838 // Safety
839 //
840 // * we reserve enough space for 1 more element
841 // * we verify that index is in bounds
842 unsafe { self.insert_unchecked(index, value) }
843 }
844
845 /// Inserts the array at position index within the vector,
846 /// shifting all elements after it to the right.
847 ///
848 /// # Panics
849 ///
850 /// * May panic or reallocate if the collection has less than N elements remaining
851 /// * Panics if index > len.
852 #[cfg(any(doc, feature = "nightly"))]
853 pub fn insert_array<const N: usize>(&mut self, index: usize, value: [S::Item; N]) -> &mut [S::Item; N] {
854 #[cold]
855 #[inline(never)]
856 fn insert_array_fail(index: usize, size: usize, len: usize) -> ! {
857 panic!(
858 "Tried to insert array of length {} at {}, but length is {}",
859 size, index, len
860 );
861 }
862
863 if index > self.len() {
864 insert_array_fail(index, N, self.len())
865 }
866
867 self.reserve(N);
868
869 // Safety
870 //
871 // * we reserve enough space for N more elements
872 // * we verify that index is in bounds
873 unsafe { self.insert_array_unchecked(index, value) }
874 }
875
876 /// Removes the last element from a vector and returns it
877 ///
878 /// # Panics
879 ///
880 /// Panics if the collection is empty
881 pub fn pop(&mut self) -> S::Item {
882 #[cold]
883 #[inline(never)]
884 fn pop_fail() -> ! {
885 panic!("Tried to pop an element from an empty vector",);
886 }
887
888 if self.is_empty() {
889 pop_fail()
890 }
891
892 // Safety
893 //
894 // * we verify we are not empty
895 unsafe { self.pop_unchecked() }
896 }
897
898 /// Removes the last `N` elements from a vector and returns it
899 ///
900 /// # Panics
901 ///
902 /// Panics if the collection contains less than `N` elements in it
903 #[cfg(any(doc, feature = "nightly"))]
904 pub fn pop_array<const N: usize>(&mut self) -> [S::Item; N] {
905 #[cold]
906 #[inline(never)]
907 fn pop_array_fail(size: usize, len: usize) -> ! {
908 panic!("Tried to pop an array of size {}, a vector of length {}", size, len);
909 }
910
911 if self.len() < N {
912 pop_array_fail(N, self.len())
913 }
914
915 // Safety
916 //
917 // * we verify we have at least N elements
918 unsafe { self.pop_array_unchecked() }
919 }
920
921 /// Removes and returns the element at position index within the vector,
922 /// shifting all elements after it to the left.
923 ///
924 /// # Panics
925 ///
926 /// Panics if `index` is out of bounds.
927 pub fn remove(&mut self, index: usize) -> S::Item {
928 #[cold]
929 #[inline(never)]
930 fn remove_fail(index: usize, len: usize) -> ! {
931 panic!("Tried to remove an element at {}, but length is {}", index, len);
932 }
933
934 if index > self.len() {
935 remove_fail(index, self.len())
936 }
937
938 // Safety
939 //
940 // * we verify that the index is in bounds
941 unsafe { self.remove_unchecked(index) }
942 }
943
944 /// Removes and returns `N` elements at position index within the vector,
945 /// shifting all elements after it to the left.
946 ///
947 /// # Panics
948 ///
949 /// Panics if `index` is out of bounds or if `index + N > len()`
950 #[cfg(any(doc, feature = "nightly"))]
951 pub fn remove_array<const N: usize>(&mut self, index: usize) -> [S::Item; N] {
952 #[cold]
953 #[inline(never)]
954 fn remove_array_fail(index: usize, size: usize, len: usize) -> ! {
955 panic!(
956 "Tried to remove an array length {} at {}, but length is {}",
957 size, index, len
958 );
959 }
960
961 if self.len() < index || self.len().wrapping_sub(index) < N {
962 remove_array_fail(index, N, self.len())
963 }
964
965 // Safety
966 //
967 // * we verify that the index is in bounds
968 // * we verify that there are at least `N` elements
969 // after the index
970 unsafe { self.remove_array_unchecked(index) }
971 }
972
973 /// Removes an element from the vector and returns it.
974 ///
975 /// The removed element is replaced by the last element of the vector.
976 ///
977 /// This does not preserve ordering, but is O(1).
978 ///
979 /// # Panics
980 ///
981 /// Panics if `index` is out of bounds.
982 pub fn swap_remove(&mut self, index: usize) -> S::Item {
983 #[cold]
984 #[inline(never)]
985 fn swap_remove_fail(index: usize, len: usize) -> ! {
986 panic!("Tried to remove an element at {}, but length is {}", index, len);
987 }
988
989 if index > self.len() {
990 swap_remove_fail(index, self.len())
991 }
992
993 // Safety
994 //
995 // * we verify that the index is in bounds
996 unsafe { self.swap_remove_unchecked(index) }
997 }
998
999 /// Tries to append an element to the back of a collection.
1000 ///
1001 /// # Errors
1002 /// Returns the `Err(value)` if the collection is full
1003 ///
1004 /// Guaranteed to not panic/abort/allocate
1005 pub fn try_push(&mut self, value: S::Item) -> Result<&mut S::Item, S::Item> {
1006 if self.is_full() {
1007 Err(value)
1008 } else {
1009 // Safety
1010 //
1011 // * we reserve enough space for 1 more element
1012 unsafe { Ok(self.push_unchecked(value)) }
1013 }
1014 }
1015
1016 /// Tries to append an array to the back of a collection.
1017 /// Returns the `Err(value)` if the collection doesn't have enough remaining capacity
1018 /// to hold `N` elements.
1019 ///
1020 /// Guaranteed to not panic/abort/allocate
1021 #[cfg(any(doc, feature = "nightly"))]
1022 pub fn try_push_array<const N: usize>(&mut self, value: [S::Item; N]) -> Result<&mut [S::Item; N], [S::Item; N]> {
1023 if self.remaining_capacity() < N {
1024 Err(value)
1025 } else {
1026 // Safety
1027 //
1028 // * we reserve enough space for N more elements
1029 unsafe { Ok(self.push_array_unchecked(value)) }
1030 }
1031 }
1032
1033 /// Inserts an element at position index within the vector,
1034 /// shifting all elements after it to the right.
1035 ///
1036 /// # Errors
1037 /// Returns the `Err(value)` if the collection is full or index is out of bounds
1038 ///
1039 /// Guaranteed to not panic/abort/allocate
1040 pub fn try_insert(&mut self, index: usize, value: S::Item) -> Result<&mut S::Item, S::Item> {
1041 if self.is_full() || index > self.len() {
1042 Err(value)
1043 } else {
1044 // Safety
1045 //
1046 // * we reserve enough space for 1 more element
1047 // * we verify that index is in bounds
1048 unsafe { Ok(self.insert_unchecked(index, value)) }
1049 }
1050 }
1051
1052 /// Inserts an array at position index within the vector,
1053 /// shifting all elements after it to the right.
1054 /// Returns the `Err(value)` if the collection doesn't have enough remaining capacity
1055 /// to hold `N` elements or index is out of bounds
1056 ///
1057 /// Guaranteed to not panic/abort/allocate
1058 #[cfg(any(doc, feature = "nightly"))]
1059 pub fn try_insert_array<const N: usize>(
1060 &mut self,
1061 index: usize,
1062 value: [S::Item; N],
1063 ) -> Result<&mut [S::Item; N], [S::Item; N]> {
1064 if self.capacity().wrapping_sub(self.len()) < N || index > self.len() {
1065 Err(value)
1066 } else {
1067 // Safety
1068 //
1069 // * we reserve enough space for N more elements
1070 // * we verify that index is in bounds
1071 unsafe { Ok(self.insert_array_unchecked(index, value)) }
1072 }
1073 }
1074
1075 /// Removes the last element from a vector and returns it,
1076 /// Returns `None` if the collection is empty
1077 ///
1078 /// Guaranteed to not panic/abort/allocate
1079 pub fn try_pop(&mut self) -> Option<S::Item> {
1080 if self.is_empty() {
1081 None
1082 } else {
1083 // Safety
1084 //
1085 // * we verify we are not empty
1086 unsafe { Some(self.pop_unchecked()) }
1087 }
1088 }
1089
1090 /// Removes the last `N` elements from a vector and returns it,
1091 /// Returns `None` if the collection is has less than N elements
1092 ///
1093 /// Guaranteed to not panic/abort/allocate
1094 #[cfg(any(doc, feature = "nightly"))]
1095 pub fn try_pop_array<const N: usize>(&mut self) -> Option<[S::Item; N]> {
1096 if self.is_empty() {
1097 None
1098 } else {
1099 // Safety
1100 //
1101 // * we verify we have at least N elements
1102 unsafe { Some(self.pop_array_unchecked()) }
1103 }
1104 }
1105
1106 /// Removes and returns the element at position index within the vector,
1107 /// shifting all elements after it to the left.
1108 /// Returns `None` if collection is empty or `index` is out of bounds.
1109 ///
1110 /// Guaranteed to not panic/abort/allocate
1111 pub fn try_remove(&mut self, index: usize) -> Option<S::Item> {
1112 if self.len() < index {
1113 None
1114 } else {
1115 // Safety
1116 //
1117 // * we verify that the index is in bounds
1118 unsafe { Some(self.remove_unchecked(index)) }
1119 }
1120 }
1121
1122 /// Removes and returns the element at position index within the vector,
1123 /// shifting all elements after it to the left.
1124 /// Returns `None` if the collection is has less than N elements
1125 /// or `index` is out of bounds.
1126 ///
1127 /// Guaranteed to not panic/abort/allocate
1128 #[cfg(any(doc, feature = "nightly"))]
1129 pub fn try_remove_array<const N: usize>(&mut self, index: usize) -> Option<[S::Item; N]> {
1130 if self.len() < index || self.len().wrapping_sub(index) < N {
1131 None
1132 } else {
1133 // Safety
1134 //
1135 // * we verify that the index is in bounds
1136 // * we verify that there are at least `N` elements
1137 // after the index
1138 unsafe { Some(self.remove_array_unchecked(index)) }
1139 }
1140 }
1141
1142 /// Removes an element from the vector and returns it.
1143 /// Returns `None` if collection is empty or `index` is out of bounds.
1144 ///
1145 /// The removed element is replaced by the last element of the vector.
1146 ///
1147 /// This does not preserve ordering, but is O(1).
1148 ///
1149 /// Guaranteed to not panic/abort/allocate
1150 pub fn try_swap_remove(&mut self, index: usize) -> Option<S::Item> {
1151 if index < self.len() {
1152 // Safety
1153 //
1154 // * we verify that the index is in bounds
1155 unsafe { Some(self.swap_remove_unchecked(index)) }
1156 } else {
1157 None
1158 }
1159 }
1160
1161 /// Appends an element to the back of a collection.
1162 ///
1163 /// # Safety
1164 ///
1165 /// the collection must not be full
1166 pub unsafe fn push_unchecked(&mut self, value: S::Item) -> &mut S::Item {
1167 debug_assert_ne!(
1168 self.len(),
1169 self.capacity(),
1170 "Tried to `push_unchecked` past capacity! This is UB in release mode"
1171 );
1172
1173 // Safety
1174 //
1175 // the collection isn't full, so `ptr.add(len)` is valid to write
1176 unsafe {
1177 let len = self.len();
1178 self.set_len_unchecked(len.wrapping_add(1));
1179 let ptr = self.as_mut_ptr().add(len);
1180 ptr.write(value);
1181 &mut *ptr
1182 }
1183 }
1184
1185 /// Appends the array to the back of a collection.
1186 ///
1187 /// # Safety
1188 ///
1189 /// the collection's remaining capacity must be at least N
1190 #[cfg(any(doc, feature = "nightly"))]
1191 pub unsafe fn push_array_unchecked<const N: usize>(&mut self, value: [S::Item; N]) -> &mut [S::Item; N] {
1192 match S::CONST_CAPACITY {
1193 Some(n) if n < N => {
1194 panic!("Tried to push an array larger than the maximum capacity of the vector!")
1195 }
1196 _ => (),
1197 }
1198
1199 // Safety
1200 //
1201 // the collection has at least N remaining elements of capacity left,
1202 // so `ptr.add(len)` is valid to write `N` elements
1203 unsafe {
1204 let len = self.len();
1205 self.set_len_unchecked(len.wrapping_add(N));
1206 let ptr = self.as_mut_ptr();
1207 let out = ptr.add(len) as *mut [S::Item; N];
1208 out.write(value);
1209 &mut *out
1210 }
1211 }
1212
1213 /// Inserts an element at position index within the vector,
1214 /// shifting all elements after it to the right.
1215 ///
1216 /// # Safety
1217 ///
1218 /// * the collection is must not be full
1219 /// * the index must be in bounds
1220 pub unsafe fn insert_unchecked(&mut self, index: usize, value: S::Item) -> &mut S::Item {
1221 unsafe {
1222 debug_assert_ne!(
1223 self.len(),
1224 self.capacity(),
1225 "Tried to `insert_unchecked` past capacity! This is UB in release mode"
1226 );
1227
1228 // Safety
1229 //
1230 // * the index is in bounds
1231 // * the collection is't full so `ptr.add(len)` is valid to write 1 element
1232 let len = self.len();
1233 self.set_len_unchecked(len.wrapping_add(1));
1234 let ptr = self.as_mut().as_mut_ptr().add(index);
1235 ptr.add(1).copy_from(ptr, len.wrapping_sub(index));
1236 ptr.write(value);
1237 &mut *ptr
1238 }
1239 }
1240
1241 /// Inserts an array at position index within the vector,
1242 /// shifting all elements after it to the right.
1243 ///
1244 /// # Safety
1245 ///
1246 /// * the collection's remaining capacity must be at least N
1247 /// * hte index must be in bounds
1248 #[cfg(any(doc, feature = "nightly"))]
1249 pub unsafe fn insert_array_unchecked<const N: usize>(
1250 &mut self,
1251 index: usize,
1252 value: [S::Item; N],
1253 ) -> &mut [S::Item; N] {
1254 match S::CONST_CAPACITY {
1255 Some(n) if n < N => {
1256 panic!("Tried to push an array larger than the maximum capacity of the vector!")
1257 }
1258 _ => (),
1259 }
1260
1261 // Safety
1262 //
1263 // * the index is in bounds
1264 // * the collection has at least N remaining elements of capacity left,
1265 // so `ptr.add(len)` is valid to write `N` elements
1266 unsafe {
1267 let len = self.len();
1268 self.set_len_unchecked(len.wrapping_add(N));
1269 let ptr = self.as_mut_ptr();
1270 let dist = len.wrapping_sub(index);
1271
1272 let out = ptr.add(index);
1273 out.add(N).copy_from(out, dist);
1274 let out = out as *mut [S::Item; N];
1275 out.write(value);
1276 &mut *out
1277 }
1278 }
1279
1280 /// Removes the last element from a vector and returns it
1281 ///
1282 /// # Safety
1283 ///
1284 /// the collection must not be empty
1285 pub unsafe fn pop_unchecked(&mut self) -> S::Item {
1286 let len = self.len();
1287 debug_assert_ne!(
1288 len, 0,
1289 "Tried to `pop_unchecked` an empty array vec! This is UB in release mode"
1290 );
1291
1292 // Safety
1293 //
1294 // * the collection isn't empty, so `ptr.add(len - 1)` is valid to read
1295 unsafe {
1296 let len = len.wrapping_sub(1);
1297 self.set_len_unchecked(len);
1298 self.as_mut_ptr().add(len).read()
1299 }
1300 }
1301
1302 /// Removes the last `N` elements from a vector and returns it
1303 ///
1304 /// # Safety
1305 ///
1306 /// The collection must contain at least `N` elements in it
1307 #[cfg(any(doc, feature = "nightly"))]
1308 pub unsafe fn pop_array_unchecked<const N: usize>(&mut self) -> [S::Item; N] {
1309 match S::CONST_CAPACITY {
1310 Some(n) if n < N => panic!("Tried to remove {} elements from a {} capacity vector!", N, n),
1311 _ => (),
1312 }
1313
1314 let len = self.len();
1315 debug_assert!(
1316 len > N,
1317 "Tried to remove {} elements from a {} length vector! This is UB in release mode",
1318 N,
1319 len,
1320 );
1321 // Safety
1322 //
1323 // * the collection has at least `N` elements, so `ptr.add(len - N)` is valid to read `N` elements
1324 unsafe {
1325 let len = len.wrapping_sub(N);
1326 self.set_len_unchecked(len);
1327 self.as_mut_ptr().add(len).cast::<[S::Item; N]>().read()
1328 }
1329 }
1330
1331 /// Removes and returns the element at position index within the vector,
1332 /// shifting all elements after it to the left.
1333 ///
1334 /// # Safety
1335 ///
1336 /// the collection must not be empty, and
1337 /// index must be in bounds
1338 pub unsafe fn remove_unchecked(&mut self, index: usize) -> S::Item {
1339 let len = self.len();
1340
1341 debug_assert!(
1342 index <= len,
1343 "Tried to remove an element at index {} from a {} length vector! This is UB in release mode",
1344 index,
1345 len,
1346 );
1347
1348 // Safety
1349 //
1350 // * the index is in bounds
1351 // * the collection isn't empty, so `ptr.add(len - index - 1)` is valid to read
1352 unsafe {
1353 self.set_len_unchecked(len.wrapping_sub(1));
1354 let ptr = self.as_mut().as_mut_ptr().add(index);
1355 let value = ptr.read();
1356 ptr.copy_from(ptr.add(1), len.wrapping_sub(index).wrapping_sub(1));
1357 value
1358 }
1359 }
1360
1361 /// Removes and returns the element at position index within the vector,
1362 /// shifting all elements after it to the left.
1363 ///
1364 /// # Safety
1365 ///
1366 /// the collection must contain at least N elements, and
1367 /// index must be in bounds
1368 #[cfg(any(doc, feature = "nightly"))]
1369 pub unsafe fn remove_array_unchecked<const N: usize>(&mut self, index: usize) -> [S::Item; N] {
1370 match S::CONST_CAPACITY {
1371 Some(n) if n < N => panic!("Tried to remove {} elements from a {} capacity vector!", N, n),
1372 _ => (),
1373 }
1374
1375 let len = self.len();
1376 debug_assert!(
1377 index <= len,
1378 "Tried to remove elements at index {} from a {} length vector! This is UB in release mode",
1379 index,
1380 len,
1381 );
1382 debug_assert!(
1383 len.wrapping_sub(index) > N,
1384 "Tried to remove {} elements from a {} length vector! This is UB in release mode",
1385 N,
1386 len,
1387 );
1388
1389 // Safety
1390 //
1391 // * the index is in bounds
1392 // * the collection isn't empty, so `ptr.add(len - index - N)` is valid to read `N` elements
1393 unsafe {
1394 self.set_len_unchecked(len.wrapping_sub(N));
1395 let ptr = self.as_mut_ptr().add(index);
1396 let value = ptr.cast::<[S::Item; N]>().read();
1397 if N != 0 {
1398 ptr.copy_from(ptr.add(N), len.wrapping_sub(index).wrapping_sub(N));
1399 }
1400 value
1401 }
1402 }
1403
1404 /// Removes an element from the vector and returns it.
1405 ///
1406 /// The removed element is replaced by the last element of the vector.
1407 ///
1408 /// This does not preserve ordering, but is O(1).
1409 ///
1410 /// # Safety
1411 ///
1412 /// the `index` must be in bounds
1413 pub unsafe fn swap_remove_unchecked(&mut self, index: usize) -> S::Item {
1414 // Safety
1415 //
1416 // * the index is in bounds
1417 // * the collection isn't empty
1418 unsafe {
1419 let len = self.len();
1420 self.set_len_unchecked(len.wrapping_sub(1));
1421 let ptr = self.as_mut().as_mut_ptr();
1422 let at = ptr.add(index);
1423 let end = ptr.add(len.wrapping_sub(1));
1424 let value = at.read();
1425 at.copy_from(end, 1);
1426 value
1427 }
1428 }
1429
1430 /// Splits the collection into two at the given index.
1431 ///
1432 /// Returns a newly allocated vector containing the elements in the range `[at, len)`.
1433 /// After the call, the original vector will be left containing the elements `[0, at)`
1434 /// with its previous capacity unchanged.
1435 ///
1436 /// ```rust
1437 /// # use cl_generic_vec::{gvec, SliceVec, uninit_array};
1438 /// # let mut vec_buf = uninit_array::<_, 3>();
1439 /// # let mut vec2_buf = uninit_array::<_, 5>();
1440 /// # let mut vec: SliceVec<_> = unsafe { SliceVec::new(&mut vec_buf) }; vec.extend([1, 2, 3].iter().copied());
1441 /// # let mut vec2: SliceVec<_> = unsafe { SliceVec::new(&mut vec2_buf) }; vec2.extend([4, 5, 6].iter().copied());
1442 /// assert_eq!(vec, [1, 2, 3]);
1443 /// assert_eq!(vec2, [4, 5, 6]);
1444 /// vec.split_off_into(1, &mut vec2);
1445 /// assert_eq!(vec, [1]);
1446 /// assert_eq!(vec2, [4, 5, 6, 2, 3]);
1447 /// ```
1448 ///
1449 /// # Panics
1450 /// If the index is out of bounds
1451 pub fn split_off<B>(&mut self, index: usize) -> GenericVec<S::Item, B>
1452 where
1453 B: raw::StorageWithCapacity<Item = S::Item>,
1454 {
1455 assert!(
1456 index <= self.len(),
1457 "Tried to split at index {}, but length is {}",
1458 index,
1459 self.len()
1460 );
1461
1462 let mut vec = GenericVec::<S::Item, B>::__with_capacity__const_capacity_checked(
1463 self.len().wrapping_sub(index),
1464 S::CONST_CAPACITY,
1465 );
1466
1467 self.split_off_into(index, &mut vec);
1468
1469 vec
1470 }
1471
1472 /// Splits the collection into two at the given index.
1473 ///
1474 /// Appends the elements from the range `[at, len)` to `other`.
1475 /// After the call, the original vector will be left containing the elements `[0, at)`
1476 /// with its previous capacity unchanged.
1477 ///
1478 /// ```rust
1479 /// # use cl_generic_vec::{gvec, SliceVec, uninit_array};
1480 /// # let mut vec_buf = uninit_array::<_, 3>();
1481 /// # let mut vec2_buf = uninit_array::<_, 5>();
1482 /// # let mut vec: SliceVec<_> = unsafe { SliceVec::new(&mut vec_buf) }; vec.extend([1, 2, 3].iter().copied());
1483 /// # let mut vec2: SliceVec<_> = unsafe { SliceVec::new(&mut vec2_buf) }; vec2.extend([4, 5, 6].iter().copied());
1484 /// assert_eq!(vec, [1, 2, 3]);
1485 /// assert_eq!(vec2, [4, 5, 6]);
1486 /// vec.split_off_into(1, &mut vec2);
1487 /// assert_eq!(vec, [1]);
1488 /// assert_eq!(vec2, [4, 5, 6, 2, 3]);
1489 /// ```
1490 ///
1491 /// # Panics
1492 /// If the index is out of bounds
1493 pub fn split_off_into<B>(&mut self, index: usize, other: &mut GenericVec<S::Item, B>)
1494 where
1495 B: raw::Storage<Item = S::Item> + ?Sized,
1496 {
1497 assert!(
1498 index <= self.len(),
1499 "Tried to split at index {}, but length is {}",
1500 index,
1501 self.len()
1502 );
1503
1504 unsafe {
1505 // Safety
1506 //
1507 // * the index is in bounds
1508 // * other has reserved enough space
1509 // * we ignore all elements after index
1510 let slice = self.get_unchecked(index..);
1511 other.reserve(slice.len());
1512 other.extend_from_slice_unchecked(slice);
1513 self.set_len_unchecked(index);
1514 }
1515 }
1516
1517 /// Moves all the elements of `other` into `Self`, leaving `other` empty.
1518 ///
1519 /// Does not change the capacity of either collection.
1520 ///
1521 /// ```rust
1522 /// # use cl_generic_vec::{gvec, SliceVec, uninit_array};
1523 /// # let mut vec_buf = uninit_array::<_, 6>();
1524 /// # let mut vec2_buf = uninit_array::<_, 3>();
1525 /// # let mut vec: SliceVec<_> = unsafe { SliceVec::new(&mut vec_buf) }; vec.extend([1, 2, 3].iter().copied());
1526 /// # let mut vec2: SliceVec<_> = unsafe { SliceVec::new(&mut vec2_buf) }; vec2.extend([4, 5, 6].iter().copied());
1527 /// assert_eq!(vec, [1, 2, 3]);
1528 /// assert_eq!(vec2, [4, 5, 6]);
1529 /// vec.append(&mut vec2);
1530 /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
1531 /// assert_eq!(vec2, []);
1532 /// ```
1533 ///
1534 /// # Panic
1535 ///
1536 /// May panic or reallocate if the collection is full
1537 pub fn append<B: Storage<Item = S::Item> + ?Sized>(&mut self, other: &mut GenericVec<S::Item, B>) {
1538 other.split_off_into(0, self);
1539 }
1540
1541 /// Convert the backing storage type, and moves all the elements in `self` to the new vector
1542 pub fn convert<B: raw::StorageWithCapacity<Item = S::Item>>(mut self) -> GenericVec<S::Item, B>
1543 where
1544 S: Sized,
1545 {
1546 self.split_off(0)
1547 }
1548
1549 /// Creates a raw cursor that can be used to remove elements in the specified range.
1550 /// Usage of [`RawCursor`](iter::RawCursor) is `unsafe` because it doesn't do any checks.
1551 /// [`RawCursor`](iter::RawCursor) is meant to be a low level tool to implement fancier
1552 /// iterators, like [`GenericVec::drain`], [`GenericVec::drain_filter`],
1553 /// or [`GenericVec::splice`].
1554 ///
1555 /// # Panic
1556 ///
1557 /// Panics if the starting point is greater than the end point or if the end point
1558 /// is greater than the length of the vector.
1559 #[inline]
1560 pub fn raw_cursor<R>(&mut self, range: R) -> iter::RawCursor<'_, S>
1561 where
1562 R: RangeBounds<usize>,
1563 {
1564 let range = slice::check_range(self.len(), range);
1565 iter::RawCursor::new(self, range)
1566 }
1567
1568 /// Creates a cursor that can be used to remove elements in the specified range.
1569 ///
1570 /// # Panic
1571 ///
1572 /// Panics if the starting point is greater than the end point or if the end point
1573 /// is greater than the length of the vector.
1574 #[inline]
1575 pub fn cursor<R>(&mut self, range: R) -> iter::Cursor<'_, S>
1576 where
1577 R: RangeBounds<usize>,
1578 {
1579 iter::Cursor::new(self.raw_cursor(range))
1580 }
1581
1582 /// Creates a draining iterator that removes the specified range in the
1583 /// vector and yields the removed items.
1584 ///
1585 /// When the iterator is dropped, all elements in the range are removed from
1586 /// the vector, even if the iterator was not fully consumed. If the iterator
1587 /// is not dropped (with `mem::forget` for example), it is unspecified how many
1588 /// elements are removed.
1589 ///
1590 /// # Panic
1591 ///
1592 /// Panics if the starting point is greater than the end point or if the end point
1593 /// is greater than the length of the vector.
1594 #[inline]
1595 pub fn drain<R>(&mut self, range: R) -> iter::Drain<'_, S>
1596 where
1597 R: RangeBounds<usize>,
1598 {
1599 iter::Drain::new(self.raw_cursor(range))
1600 }
1601
1602 /// Creates an iterator which uses a closure to determine if an element should be removed.
1603 ///
1604 /// If the closure returns true, then the element is removed and yielded.
1605 /// If the closure returns false, the element will remain in the vector
1606 /// and will not be yielded by the iterator.
1607 ///
1608 /// # Panic
1609 ///
1610 /// Panics if the starting point is greater than the end point or if the end point
1611 /// is greater than the length of the vector.
1612 #[inline]
1613 pub fn drain_filter<R, F>(&mut self, range: R, f: F) -> iter::DrainFilter<'_, S, F>
1614 where
1615 R: RangeBounds<usize>,
1616 F: FnMut(&mut S::Item) -> bool,
1617 {
1618 iter::DrainFilter::new(self.raw_cursor(range), f)
1619 }
1620
1621 /// Creates a splicing iterator that replaces the specified range in the vector with
1622 /// the given `replace_with` iterator and yields the removed items. `replace_with` does
1623 /// not need to be the same length as range.
1624 ///
1625 /// range is removed even if the iterator is not consumed until the end.
1626 ///
1627 /// It is unspecified how many elements are removed from the vector if the
1628 /// [`Splice`](iter::Splice) value is leaked.
1629 ///
1630 /// The input iterator `replace_with` is only consumed when the [`Splice`](iter::Splice)
1631 /// value is dropped
1632 ///
1633 /// # Panic
1634 ///
1635 /// Panics if the starting point is greater than the end point or if the end point
1636 /// is greater than the length of the vector.
1637 #[inline]
1638 pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> iter::Splice<'_, S, I::IntoIter>
1639 where
1640 R: RangeBounds<usize>,
1641 I: IntoIterator<Item = S::Item>,
1642 {
1643 iter::Splice::new(self.raw_cursor(range), replace_with.into_iter())
1644 }
1645
1646 /// Retains only the elements specified by the predicate.
1647 ///
1648 /// In other words, remove all elements `e` such that `f(e)` returns false.
1649 /// This method operates in place, visiting each element exactly once in
1650 /// the original order, and preserves the order of the retained elements.
1651 #[inline]
1652 pub fn retain<F>(&mut self, f: F)
1653 where
1654 F: FnMut(&mut S::Item) -> bool,
1655 {
1656 fn not<F: FnMut(&mut T) -> bool, T>(mut f: F) -> impl FnMut(&mut T) -> bool {
1657 move |value| !f(value)
1658 }
1659 self.drain_filter(.., not(f));
1660 }
1661
1662 /// Shallow copies and appends all elements in a slice to the `GenericVec`.
1663 ///
1664 /// # Safety
1665 ///
1666 /// * You must not drop any of the elements in `slice`
1667 /// * There must be at least `slice.len()` remaining capacity in the vector
1668 pub unsafe fn extend_from_slice_unchecked(&mut self, slice: &[S::Item]) {
1669 debug_assert!(
1670 self.remaining_capacity() >= slice.len(),
1671 "Not enough capacity to hold the slice"
1672 );
1673
1674 unsafe {
1675 let len = self.len();
1676 self.as_mut_ptr()
1677 .add(len)
1678 .copy_from_nonoverlapping(slice.as_ptr(), slice.len());
1679 self.set_len_unchecked(len.wrapping_add(slice.len()));
1680 }
1681 }
1682
1683 /// Clones and appends all elements in a slice to the `GenericVec`.
1684 ///
1685 /// Iterates over the slice other, clones each element, and then appends
1686 /// it to this `GenericVec`. The other vector is traversed in-order.
1687 ///
1688 /// Note that this function is same as extend except that it is specialized
1689 /// to work with slices instead. If and when Rust gets specialization this
1690 /// function will likely be deprecated (but still available).
1691 ///
1692 /// # Panic behavor
1693 ///
1694 /// If `T::clone` panics, then all newly added items will be dropped. This is different
1695 /// from `std`, where on panic, newly added items will stay in the `Vec`. This behavior
1696 /// is unstable, and may change in the future.
1697 pub fn extend_from_slice(&mut self, slice: &[S::Item])
1698 where
1699 S::Item: Clone,
1700 {
1701 self.reserve(slice.len());
1702
1703 // Safety
1704 //
1705 // We reserved enough space
1706 unsafe { extension::Extension::extend_from_slice(self, slice) }
1707 }
1708
1709 /// Replaces all of the current elements with the ones in the slice
1710 ///
1711 /// equivalent to the following
1712 ///
1713 /// ```rust
1714 /// # let slice = [];
1715 /// # let mut buffer = cl_generic_vec::uninit_array::<_, 0>();
1716 /// # let mut vec = unsafe { cl_generic_vec::SliceVec::<()>::new(&mut buffer) };
1717 /// vec.clear();
1718 /// vec.extend_from_slice(&slice);
1719 /// ```
1720 ///
1721 /// # Panic
1722 ///
1723 /// May try to panic/reallocate if there is not enough capacity for the slice
1724 pub fn clone_from(&mut self, source: &[S::Item])
1725 where
1726 S::Item: Clone,
1727 {
1728 // If the `self` is longer than `source`, remove excess
1729 self.truncate(source.len());
1730
1731 // `self` is now at most the same length as `source`
1732 //
1733 // * `init.len() == self.len()`
1734 // * tail is the rest of the `source`, in the case
1735 // that `self` is smaller than `source`
1736 let (init, tail) = source.split_at(self.len());
1737
1738 // Clone in the beginning, using `slice::clone_from_slice`
1739 self.clone_from_slice(init);
1740
1741 // Append the remaining elements
1742 self.extend_from_slice(tail);
1743 }
1744
1745 /// Removes all but the first of consecutive elements in the vector satisfying
1746 /// a given equality relation.
1747 ///
1748 /// The `same_bucket` function is passed references to two elements from the
1749 /// vector and must determine if the elements compare equal. The elements
1750 /// are passed in opposite order from their order in the slice, so if
1751 /// `same_bucket(a, b)` returns true, a is removed.
1752 ///
1753 /// If the vector is sorted, this removes all duplicates.
1754 pub fn dedup_by<F>(&mut self, same_bucket: F)
1755 where
1756 F: FnMut(&mut S::Item, &mut S::Item) -> bool,
1757 {
1758 let (a, _) = slice::partition_dedup_by(self.as_mut_slice(), same_bucket);
1759 let new_len = a.len();
1760 self.truncate(new_len);
1761 }
1762
1763 /// Removes all but the first of consecutive elements in the vector that resolve to the same key.
1764 ///
1765 /// If the vector is sorted, this removes all duplicates.
1766 pub fn dedup_by_key<F, K>(&mut self, key: F)
1767 where
1768 F: FnMut(&mut S::Item) -> K,
1769 K: PartialEq,
1770 {
1771 #[inline]
1772 fn key_to_same_bucket<T, F, K>(mut f: F) -> impl FnMut(&mut T, &mut T) -> bool
1773 where
1774 F: FnMut(&mut T) -> K,
1775 K: PartialEq,
1776 {
1777 #[inline]
1778 move |a, b| {
1779 let a = f(a);
1780 let b = f(b);
1781 a == b
1782 }
1783 }
1784
1785 self.dedup_by(key_to_same_bucket(key));
1786 }
1787
1788 /// Removes all but the first of consecutive elements in the vector that resolve to the same key.
1789 ///
1790 /// If the vector is sorted, this removes all duplicates.
1791 pub fn dedup<F, K>(&mut self)
1792 where
1793 S::Item: PartialEq,
1794 {
1795 #[inline]
1796 fn eq_to_same_buckets<T, F>(mut f: F) -> impl FnMut(&mut T, &mut T) -> bool
1797 where
1798 F: FnMut(&T, &T) -> bool,
1799 {
1800 #[inline]
1801 move |a, b| f(a, b)
1802 }
1803
1804 self.dedup_by(eq_to_same_buckets(PartialEq::eq));
1805 }
1806}