Skip to main content

index_type/
vec.rs

1//! A growable vector with typed indexing.
2//!
3//! This module provides [`TypedVec`], a wrapper around [`alloc::vec::Vec`] that uses a custom
4//! [`IndexType`] for all indexing operations. This provides compile-time guarantees that
5//! indices from one `TypedVec` cannot be accidentally used with another.
6//!
7//! # Example
8//!
9//! ```
10//! use index_type::IndexType;
11//! use index_type::vec::TypedVec;
12//!
13//! #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
14//! struct NodeId(u32);
15//!
16//! let mut nodes: TypedVec<NodeId, String> = TypedVec::new();
17//! let id0 = nodes.push("Alice".to_string());
18//! let id1 = nodes.push("Bob".to_string());
19//!
20//! assert_eq!(nodes[id0], "Alice");
21//! assert_eq!(nodes[id1], "Bob");
22//! ```
23//!
24//! # Capacity and Growth
25//!
26//! `TypedVec` has the same growth behavior as [`Vec`]. Operations that would cause the length
27//! to exceed `I::MAX_RAW_INDEX` return an error or panic, depending on whether you use
28//! the fallible or infallible variant.
29
30use core::{
31    borrow::{Borrow, BorrowMut},
32    iter::FusedIterator,
33    marker::PhantomData,
34    ops::{Deref, DerefMut},
35};
36
37use alloc::{boxed::Box, collections::TryReserveError, vec::Vec};
38
39use crate::{
40    IndexScalarType, IndexTooBigError, IndexType,
41    enumerate::UncheckedTypedEnumerate,
42    range::{TypedRange, TypedRangeIterExt},
43    slice::TypedSlice,
44    utils::{range_bounds_to_raw, resolve_range_bounds},
45};
46
47#[cold]
48fn panic_index_too_big<I: IndexType>(error: I::IndexTooBigError) -> ! {
49    panic!("{}", error)
50}
51
52/// A growable vector with typed indexing.
53///
54/// `TypedVec<I, T>` is a wrapper around `Vec<T>` that uses the custom index type `I`
55/// for all indexing operations. This provides compile-time guarantees that indices
56/// cannot be accidentally used with the wrong collection.
57///
58/// # Type Parameters
59///
60/// - `I`: The index type that implements [`IndexType`]
61/// - `T`: The element type stored in the vector
62///
63/// # Example
64///
65/// ```
66/// use index_type::IndexType;
67/// use index_type::vec::TypedVec;
68///
69/// #[derive(IndexType, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
70/// struct RowId(u32);
71///
72/// let mut rows: TypedVec<RowId, String> = TypedVec::new();
73/// let id0 = rows.push("Row 0".to_string());
74/// let id1 = rows.push("Row 1".to_string());
75///
76/// assert_eq!(rows[id0], "Row 0");
77/// ```
78#[repr(transparent)]
79pub struct TypedVec<I: IndexType, T> {
80    raw: Vec<T>,
81    phantom: PhantomData<fn(&I)>,
82}
83
84impl<I: IndexType, T> TypedVec<I, T> {
85    /// Creates a new, empty `TypedVec`.
86    ///
87    /// The vector will not allocate until elements are pushed.
88    ///
89    /// # Example
90    ///
91    /// ```
92    /// use index_type::IndexType;
93    /// use index_type::vec::TypedVec;
94    ///
95    /// #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
96    /// struct Idx(u32);
97    ///
98    /// let vec: TypedVec<Idx, i32> = TypedVec::new();
99    /// assert!(vec.is_empty());
100    /// ```
101    #[inline]
102    pub const fn new() -> Self {
103        Self {
104            raw: Vec::new(),
105            phantom: PhantomData,
106        }
107    }
108
109    /// Creates a new `TypedVec` with the specified capacity.
110    ///
111    /// The vector will be able to hold at least `capacity` elements without reallocating.
112    ///
113    /// # Example
114    ///
115    /// ```
116    /// use index_type::IndexType;
117    /// use index_type::vec::TypedVec;
118    ///
119    /// #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
120    /// struct Idx(u32);
121    ///
122    /// let vec: TypedVec<Idx, i32> = TypedVec::with_capacity(10);
123    /// assert!(vec.capacity() >= 10);
124    /// ```
125    #[inline]
126    pub fn with_capacity(capacity: usize) -> Self {
127        Self {
128            raw: Vec::with_capacity(capacity),
129            phantom: PhantomData,
130        }
131    }
132
133    /// Attempts to create a `TypedVec` from a `Vec`.
134    ///
135    /// Returns an error if the `Vec`'s length exceeds `I::MAX_RAW_INDEX`.
136    ///
137    /// # Example
138    ///
139    /// ```
140    /// use index_type::IndexType;
141    /// use index_type::vec::TypedVec;
142    ///
143    /// #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
144    /// struct Idx(u8);
145    ///
146    /// let std_vec: Vec<i32> = vec![1, 2, 3];
147    /// let typed: Result<TypedVec<Idx, i32>, _> = TypedVec::try_from_vec(std_vec);
148    /// assert!(typed.is_ok());
149    /// ```
150    #[inline]
151    pub fn try_from_vec(vec: Vec<T>) -> Result<Self, I::IndexTooBigError> {
152        let _ = I::try_from_raw_index(vec.len())?;
153        let res = Self {
154            raw: vec,
155            phantom: PhantomData,
156        };
157        Ok(res)
158    }
159
160    /// Creates a `TypedVec` from a `Vec`.
161    ///
162    /// # Panics
163    ///
164    /// Panics if the `Vec`'s length exceeds `I::MAX_RAW_INDEX`.
165    ///
166    /// # Example
167    ///
168    /// ```
169    /// use index_type::IndexType;
170    /// use index_type::vec::TypedVec;
171    ///
172    /// #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
173    /// struct Idx(u32);
174    ///
175    /// let std_vec = vec![1, 2, 3];
176    /// let typed: TypedVec<Idx, i32> = TypedVec::from_vec(std_vec);
177    /// assert_eq!(typed.len().to_raw_index(), 3);
178    /// ```
179    #[inline]
180    pub fn from_vec(vec: Vec<T>) -> Self {
181        Self::try_from_vec(vec).unwrap_or_else(|error| panic_index_too_big::<I>(error))
182    }
183
184    /// Creates a `TypedVec` from a `Vec` without checking bounds.
185    ///
186    /// # Safety
187    ///
188    /// The `Vec`'s length must not exceed `I::MAX_RAW_INDEX`.
189    #[inline]
190    pub unsafe fn from_vec_unchecked(vec: Vec<T>) -> Self {
191        Self {
192            raw: vec,
193            phantom: PhantomData,
194        }
195    }
196
197    /// Attempts to create a `TypedVec` from raw parts.
198    ///
199    /// # Safety
200    ///
201    /// Same as [`Vec::from_raw_parts`], plus the length must not exceed `I::MAX_RAW_INDEX`.
202    #[inline]
203    pub unsafe fn try_from_raw_parts(
204        ptr: *mut T,
205        length: usize,
206        capacity: usize,
207    ) -> Result<Self, I::IndexTooBigError> {
208        let _ = I::try_from_raw_index(length)?;
209        Ok(unsafe { Self::from_raw_parts_unchecked(ptr, length, capacity) })
210    }
211
212    /// Creates a `TypedVec` from raw parts without checking bounds.
213    ///
214    /// # Safety
215    ///
216    /// Same as [`Vec::from_raw_parts`], plus the length must not exceed `I::MAX_RAW_INDEX`.
217    #[inline]
218    pub unsafe fn from_raw_parts_unchecked(ptr: *mut T, length: usize, capacity: usize) -> Self {
219        Self {
220            raw: unsafe { Vec::from_raw_parts(ptr, length, capacity) },
221            phantom: PhantomData,
222        }
223    }
224
225    /// Creates a `TypedVec` from raw parts.
226    ///
227    /// # Safety
228    ///
229    /// Same as [`Vec::from_raw_parts`].
230    #[inline]
231    pub unsafe fn from_raw_parts(ptr: *mut T, length: I, capacity: usize) -> Self {
232        unsafe { Self::from_raw_parts_unchecked(ptr, length.to_raw_index(), capacity) }
233    }
234
235    /// Decomposes the `TypedVec` into its raw parts.
236    ///
237    /// Returns the pointer, length, and capacity of the underlying `Vec`.
238    #[inline]
239    pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
240        self.raw.into_raw_parts()
241    }
242
243    /// Converts the `TypedVec` into a `Vec`.
244    #[inline]
245    pub fn into_vec(self) -> Vec<T> {
246        self.raw
247    }
248
249    /// Returns the length of the vector as an index.
250    #[inline]
251    pub fn len(&self) -> I {
252        unsafe { I::from_raw_index_unchecked(self.raw.len()) }
253    }
254
255    /// Returns the length of the vector as a `usize`.
256    #[inline]
257    pub const fn len_usize(&self) -> usize {
258        self.raw.len()
259    }
260
261    /// Returns the total capacity of the vector (in elements).
262    ///
263    /// Note: This returns the raw `usize` capacity, not the typed capacity.
264    ///
265    /// # Design Decision
266    ///
267    /// Unlike [`len()`](Self::len) which returns a typed index `I`, this method returns a raw
268    /// `usize`. This is an intentional design choice: `TypedVec` may have a capacity that exceeds
269    /// what the index type `I` can represent.
270    ///
271    /// If we limited capacity to `I::MAX_RAW_INDEX`, strange behaviors would occur. For example,
272    /// with a `u8` index type (max 255), consider this scenario:
273    /// - Vector starts with capacity 100
274    /// - After some pushes, it reallocates and doubles to capacity 200
275    /// - The next push (201st element) would require reallocation to capacity 400, which exceeds
276    ///   `u8::MAX_RAW_INDEX` (255), so this push would fail
277    ///
278    /// This would be surprising: a vector with a `u8` index could suddenly fail to push even though
279    /// it should be able to hold up to 255 elements. By allowing capacity to exceed the index
280    /// type's range, we ensure that the vector can always grow to accommodate up to 255 elements,
281    /// even if it temporarily has excess capacity.
282    ///
283    /// Use [`len()`](Self::len) when you need the typed length, and [`remaining_capacity`](Self::remaining_capacity)
284    /// when you need to know how many more elements can be added before reaching the index limit.
285    #[inline]
286    pub fn capacity(&self) -> usize {
287        self.raw.capacity()
288    }
289
290    /// Returns the remaining capacity until the vector would exceed the index type's limit.
291    ///
292    /// This is the maximum number of additional elements that can be pushed before the
293    /// index type's maximum would be exceeded, regardless of the underlying allocation.
294    ///
295    /// # Example
296    ///
297    /// ```
298    /// use index_type::IndexType;
299    /// use index_type::vec::TypedVec;
300    ///
301    /// #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
302    /// struct Idx(u8);
303    ///
304    /// let vec: TypedVec<Idx, i32> = TypedVec::with_capacity(10);
305    /// // remaining_capacity is based on index type, not allocation
306    /// assert_eq!(vec.remaining_capacity().to_raw_index(), 255);
307    /// ```
308    #[inline]
309    pub fn remaining_capacity(&self) -> I {
310        // This is safe because remaining capacity is always within I's range
311        unsafe {
312            I::from_raw_index_unchecked(I::MAX_RAW_INDEX.saturating_sub(self.len().to_raw_index()))
313        }
314    }
315
316    /// Returns an iterator over the valid indices of this vector.
317    ///
318    /// # Example
319    ///
320    /// ```
321    /// use index_type::IndexType;
322    /// use index_type::vec::TypedVec;
323    ///
324    /// #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
325    /// struct Idx(u32);
326    ///
327    /// let vec: TypedVec<Idx, i32> = TypedVec::from_vec(vec![10, 20, 30]);
328    /// for idx in vec.indices() {
329    ///     println!("{}: {}", idx.to_raw_index(), vec[idx]);
330    /// }
331    /// ```
332    #[inline]
333    pub fn indices(&self) -> TypedRange<I> {
334        (I::ZERO..self.len()).iter()
335    }
336
337    /// Returns an iterator over the elements with their indices.
338    #[inline]
339    pub fn iter_enumerated(&self) -> UncheckedTypedEnumerate<I, core::slice::Iter<'_, T>> {
340        // SAFETY: `self.raw.iter()` yields exactly `self.len()` items, which already fit in `I`.
341        unsafe { UncheckedTypedEnumerate::new(self.raw.iter()) }
342    }
343
344    /// Returns an iterator over the elements with their mutable references and indices.
345    #[inline]
346    pub fn iter_mut_enumerated(
347        &mut self,
348    ) -> UncheckedTypedEnumerate<I, core::slice::IterMut<'_, T>> {
349        // SAFETY: `self.raw.iter_mut()` yields exactly `self.len()` items, which already fit in `I`.
350        unsafe { UncheckedTypedEnumerate::new(self.raw.iter_mut()) }
351    }
352
353    /// Consumes the vector and returns an iterator over the elements with their indices.
354    #[inline]
355    pub fn into_iter_enumerated(self) -> UncheckedTypedEnumerate<I, alloc::vec::IntoIter<T>> {
356        // SAFETY: `self.raw.into_iter()` yields exactly the vector length, which already fits in `I`.
357        unsafe { UncheckedTypedEnumerate::new(self.raw.into_iter()) }
358    }
359
360    /// Attempts to append an element to the back of the vector.
361    ///
362    /// Returns the index of the appended element, or an error if the length
363    /// would exceed `I::MAX_RAW_INDEX`.
364    ///
365    /// # Example
366    ///
367    /// ```
368    /// use index_type::IndexType;
369    /// use index_type::vec::TypedVec;
370    ///
371    /// #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
372    /// struct Idx(u32);
373    ///
374    /// let mut vec: TypedVec<Idx, i32> = TypedVec::new();
375    /// let idx = vec.try_push(42).unwrap();
376    /// assert_eq!(vec[idx], 42);
377    /// ```
378    #[inline]
379    pub fn try_push(&mut self, value: T) -> Result<I, I::IndexTooBigError> {
380        let res = self.len();
381        let _new_len = res.checked_add_scalar(I::Scalar::ONE)?;
382        self.raw.push(value);
383        Ok(res)
384    }
385
386    /// Attempts to append an element to the back of the vector.
387    ///
388    /// Returns a mutable reference to the appended element, or an error if the length
389    /// would exceed `I::MAX_RAW_INDEX`.
390    ///
391    /// # Example
392    ///
393    /// ```
394    /// use index_type::IndexType;
395    /// use index_type::vec::TypedVec;
396    ///
397    /// #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
398    /// struct Idx(u32);
399    ///
400    /// let mut vec: TypedVec<Idx, i32> = TypedVec::new();
401    /// let item = vec.try_push_mut(42).unwrap();
402    /// assert_eq!(*item, 42);
403    /// ```
404    #[inline]
405    pub fn try_push_mut(&mut self, value: T) -> Result<&mut T, I::IndexTooBigError> {
406        let _new_len = self.len().checked_add_scalar(I::Scalar::ONE)?;
407        Ok(self.raw.push_mut(value))
408    }
409
410    /// Appends an element to the back of the vector.
411    ///
412    /// Returns a mutable reference to the appended element.
413    ///
414    /// # Panics
415    ///
416    /// Panics if the length would exceed `I::MAX_RAW_INDEX`.
417    #[inline]
418    pub fn push_mut(&mut self, value: T) -> &mut T {
419        self.try_push_mut(value)
420            .unwrap_or_else(|error| panic_index_too_big::<I>(error))
421    }
422
423    /// Appends an element to the back of the vector.
424    ///
425    /// Returns the index of the appended element.
426    ///
427    /// # Panics
428    ///
429    /// Panics if the length would exceed `I::MAX_RAW_INDEX`.
430    #[inline]
431    pub fn push(&mut self, value: T) -> I {
432        self.try_push(value)
433            .unwrap_or_else(|error| panic_index_too_big::<I>(error))
434    }
435
436    /// Attempts to append all elements from another `TypedVec` to this one.
437    ///
438    /// Returns an error if the combined length would exceed `I::MAX_RAW_INDEX`.
439    /// The source vector is emptied after the operation.
440    #[inline]
441    pub fn try_append(&mut self, other: &mut TypedVec<I, T>) -> Result<(), I::IndexTooBigError> {
442        let _new_len = self.len().checked_add_scalar(other.len().to_scalar())?;
443        self.raw.append(&mut other.raw);
444        Ok(())
445    }
446
447    /// Appends all elements from another `TypedVec` to this one.
448    ///
449    /// The source vector is emptied after the operation.
450    ///
451    /// # Panics
452    ///
453    /// Panics if the combined length would exceed `I::MAX_RAW_INDEX`.
454    #[inline]
455    pub fn append(&mut self, other: &mut TypedVec<I, T>) {
456        self.try_append(other)
457            .unwrap_or_else(|error| panic_index_too_big::<I>(error))
458    }
459
460    /// Returns a raw pointer to the vector's buffer.
461    #[inline]
462    pub const fn as_mut_ptr(&mut self) -> *mut T {
463        self.raw.as_mut_ptr()
464    }
465
466    /// Reserves capacity for at least `additional` more elements.
467    ///
468    /// See [`Vec::reserve`] for details.
469    #[inline]
470    pub fn reserve(&mut self, additional: usize) {
471        self.raw.reserve(additional);
472    }
473
474    /// Reserves the exact capacity for `additional` more elements.
475    ///
476    /// See [`Vec::reserve_exact`] for details.
477    #[inline]
478    pub fn reserve_exact(&mut self, additional: usize) {
479        self.raw.reserve_exact(additional)
480    }
481
482    /// Attempts to reserve capacity for at least `additional` more elements.
483    ///
484    /// See [`Vec::try_reserve`] for details.
485    #[inline]
486    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
487        self.raw.try_reserve(additional)
488    }
489
490    /// Attempts to reserve the exact capacity for `additional` more elements.
491    ///
492    /// See [`Vec::try_reserve_exact`] for details.
493    #[inline]
494    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
495        self.raw.try_reserve_exact(additional)
496    }
497
498    /// Reduces the capacity to fit the current length.
499    ///
500    /// See [`Vec::shrink_to_fit`] for details.
501    #[inline]
502    pub fn shrink_to_fit(&mut self) {
503        self.raw.shrink_to_fit();
504    }
505
506    /// Shrinks the capacity to at least the specified minimum.
507    ///
508    /// See [`Vec::shrink_to`] for details.
509    #[inline]
510    pub fn shrink_to(&mut self, min_capacity: usize) {
511        self.raw.shrink_to(min_capacity);
512    }
513
514    /// Converts the vector into a boxed slice.
515    ///
516    /// The resulting slice has the same lifetime as the original vector.
517    #[inline]
518    pub fn into_boxed_slice(self) -> Box<TypedSlice<I, T>> {
519        // SAFETY: TypedSlice is repr(transparent) over [T].
520        unsafe { core::mem::transmute(self.raw.into_boxed_slice()) }
521    }
522
523    /// Shortens the vector to the specified length.
524    ///
525    /// If `len` is greater than the current length, this has no effect.
526    #[inline]
527    pub fn truncate(&mut self, len: I) {
528        self.raw.truncate(len.to_raw_index());
529    }
530
531    /// Returns the vector as a typed slice reference.
532    #[inline]
533    pub fn as_slice(&self) -> &TypedSlice<I, T> {
534        unsafe { TypedSlice::from_slice_unchecked(self.raw.as_slice()) }
535    }
536
537    /// Returns a mutable typed slice reference.
538    #[inline]
539    pub fn as_mut_slice(&mut self) -> &mut TypedSlice<I, T> {
540        unsafe { TypedSlice::from_slice_unchecked_mut(self.raw.as_mut_slice()) }
541    }
542
543    /// Casts the index type of the `TypedVec`.
544    #[inline]
545    pub fn cast_index_type<I2: IndexType>(self) -> Result<TypedVec<I2, T>, I2::IndexTooBigError> {
546        if I::MAX_RAW_INDEX <= I2::MAX_RAW_INDEX {
547            Ok(unsafe { TypedVec::from_vec_unchecked(self.raw) })
548        } else {
549            TypedVec::try_from_vec(self.raw)
550        }
551    }
552
553    /// Returns a raw pointer to the vector's buffer.
554    #[inline]
555    pub const fn as_ptr(&self) -> *const T {
556        self.raw.as_ptr()
557    }
558
559    /// Sets the length of the vector.
560    ///
561    /// # Safety
562    ///
563    /// Same as [`Vec::set_len`], plus the new length must not exceed `I::MAX_RAW_INDEX`.
564    #[inline]
565    pub unsafe fn set_len(&mut self, new_len: I) {
566        unsafe { self.raw.set_len(new_len.to_scalar().to_usize()) };
567    }
568
569    /// Removes and returns the element at `index`, swapping the last element into that position.
570    ///
571    /// This operation is O(1).
572    ///
573    /// # Panics
574    ///
575    /// Panics if `index` is out of bounds.
576    #[inline]
577    pub fn swap_remove(&mut self, index: I) -> T {
578        self.raw.swap_remove(index.to_raw_index())
579    }
580
581    /// Attempts to insert an element at `index`, shifting all elements after it to the right.
582    ///
583    /// Returns an error if the new length would exceed `I::MAX_RAW_INDEX`.
584    ///
585    /// # Panics
586    ///
587    /// Panics if `index > len`.
588    #[inline]
589    pub fn try_insert(&mut self, index: I, element: T) -> Result<(), I::IndexTooBigError> {
590        let _new_potential_len = self.len().checked_add_scalar(I::Scalar::ONE)?;
591        self.raw.insert(index.to_raw_index(), element);
592        Ok(())
593    }
594
595    /// Attempts to insert an element at `index`, shifting all elements after it to the right.
596    ///
597    /// Returns a mutable reference to the inserted element, or an error if the new length
598    /// would exceed `I::MAX_RAW_INDEX`.
599    ///
600    /// # Panics
601    ///
602    /// Panics if `index > len`.
603    #[inline]
604    pub fn try_insert_mut(&mut self, index: I, element: T) -> Result<&mut T, I::IndexTooBigError> {
605        let _new_potential_len = self.len().checked_add_scalar(I::Scalar::ONE)?;
606        Ok(self.raw.insert_mut(index.to_raw_index(), element))
607    }
608
609    /// Inserts an element at `index`, shifting all elements after it to the right.
610    ///
611    /// Returns a mutable reference to the inserted element.
612    ///
613    /// # Panics
614    ///
615    /// Panics if `index > len` or if the new length would exceed `I::MAX_RAW_INDEX`.
616    #[inline]
617    pub fn insert_mut(&mut self, index: I, element: T) -> &mut T {
618        self.try_insert_mut(index, element)
619            .unwrap_or_else(|error| panic_index_too_big::<I>(error))
620    }
621
622    /// Inserts an element at `index`, shifting all elements after it to the right.
623    ///
624    /// # Panics
625    ///
626    /// Panics if `index > len` or if the new length would exceed `I::MAX_RAW_INDEX`.
627    #[inline]
628    pub fn insert(&mut self, index: I, element: T) {
629        self.try_insert(index, element)
630            .unwrap_or_else(|error| panic_index_too_big::<I>(error))
631    }
632
633    /// Removes and returns the element at `index`, shifting all elements after it to the left.
634    ///
635    /// This operation is O(n).
636    ///
637    /// # Panics
638    ///
639    /// Panics if `index` is out of bounds.
640    #[inline]
641    pub fn remove(&mut self, index: I) -> T {
642        self.raw.remove(index.to_raw_index())
643    }
644
645    /// Retains only elements that satisfy the predicate.
646    ///
647    /// See [`Vec::retain`] for details.
648    #[inline]
649    pub fn retain<F>(&mut self, f: F)
650    where
651        F: FnMut(&T) -> bool,
652    {
653        self.raw.retain(f)
654    }
655
656    /// Retains only elements that satisfy the predicate, passing a mutable reference.
657    ///
658    /// See [`Vec::retain_mut`] for details.
659    #[inline]
660    pub fn retain_mut<F>(&mut self, f: F)
661    where
662        F: FnMut(&mut T) -> bool,
663    {
664        self.raw.retain_mut(f)
665    }
666
667    /// Removes consecutive duplicate elements, using `key` to determine equality.
668    ///
669    /// See [`Vec::dedup_by_key`] for details.
670    #[inline]
671    pub fn dedup_by_key<F, K>(&mut self, key: F)
672    where
673        F: FnMut(&mut T) -> K,
674        K: PartialEq,
675    {
676        self.raw.dedup_by_key(key);
677    }
678
679    /// Removes consecutive duplicate elements, using `same_bucket` to determine equality.
680    ///
681    /// See [`Vec::dedup_by`] for details.
682    #[inline]
683    pub fn dedup_by<F>(&mut self, same_bucket: F)
684    where
685        F: FnMut(&mut T, &mut T) -> bool,
686    {
687        self.raw.dedup_by(same_bucket);
688    }
689
690    /// Removes and returns the last element, or `None` if the vector is empty.
691    #[inline]
692    pub fn pop(&mut self) -> Option<T> {
693        self.raw.pop()
694    }
695
696    /// Removes and returns the last element if `predicate` returns `true`.
697    ///
698    /// See [`Vec::pop_if`] for details.
699    #[inline]
700    pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
701        self.raw.pop_if(predicate)
702    }
703
704    /// Removes all elements from the vector.
705    #[inline]
706    pub fn clear(&mut self) {
707        self.raw.clear();
708    }
709
710    /// Returns `true` if the vector contains no elements.
711    #[inline]
712    pub fn is_empty(&self) -> bool {
713        self.raw.is_empty()
714    }
715
716    /// Splits the vector into two at the given index.
717    ///
718    /// Returns everything after the split point.
719    #[inline]
720    pub fn split_off(&mut self, at: I) -> Self {
721        let new_vec = self.raw.split_off(at.to_raw_index());
722        unsafe { Self::from_vec_unchecked(new_vec) }
723    }
724
725    /// Grows the vector in place, filling new positions with the result of `f`.
726    ///
727    /// See [`Vec::resize_with`] for details.
728    #[inline]
729    pub fn resize_with<F>(&mut self, new_len: I, f: F)
730    where
731        F: FnMut() -> T,
732    {
733        self.raw.resize_with(new_len.to_scalar().to_usize(), f);
734    }
735
736    /// Leaks the vector and returns a mutable reference to its contents.
737    ///
738    /// See [`Vec::leak`] for details.
739    #[inline]
740    pub fn leak<'a>(self) -> &'a mut TypedSlice<I, T> {
741        let raw = self.raw.leak();
742        // SAFETY: The leaked slice has the same length as the vector, which was valid for `I`.
743        unsafe { TypedSlice::from_slice_unchecked_mut(raw) }
744    }
745
746    /// Creates a draining iterator that removes the specified range.
747    ///
748    /// See [`Vec::drain`] for details.
749    #[inline]
750    pub fn drain<R>(&mut self, range: R) -> alloc::vec::Drain<'_, T>
751    where
752        R: core::ops::RangeBounds<I>,
753    {
754        self.raw.drain(range_bounds_to_raw(&range))
755    }
756
757    /// Creates a splicing iterator that removes the specified range and replaces it.
758    ///
759    /// See [`Vec::splice`] for details.
760    #[inline]
761    pub fn splice<R, X>(
762        &mut self,
763        range: R,
764        replace_with: X,
765    ) -> alloc::vec::Splice<'_, BoundedSpliceIter<I, X::IntoIter>>
766    where
767        R: core::ops::RangeBounds<I>,
768        X: IntoIterator<Item = T>,
769    {
770        let resolved_range = resolve_range_bounds(&range, self.len());
771        let range_len = resolved_range
772            .end
773            .checked_sub_index(resolved_range.start)
774            .expect("invalid range");
775        let remaining_len = self
776            .len()
777            .checked_sub_scalar(range_len)
778            .expect("range out of bounds");
779        let replace_with_max_allowed_len =
780            unsafe { I::MAX_INDEX.unchecked_sub_index(remaining_len) };
781        self.raw.splice(
782            range_bounds_to_raw(&range),
783            BoundedSpliceIter::new(replace_with.into_iter(), replace_with_max_allowed_len),
784        )
785    }
786
787    /// Attempts to extend the vector with the contents of an iterator.
788    ///
789    /// Returns an error if the new length would exceed `I::MAX_RAW_INDEX`.
790    /// On error, the vector is unchanged.
791    #[inline]
792    pub fn try_extend<X: IntoIterator<Item = T>>(
793        &mut self,
794        iter: X,
795    ) -> Result<(), I::IndexTooBigError> {
796        let iter = iter.into_iter();
797
798        if let Some(upper_bound) = iter.size_hint().1 {
799            let _ = self.len().checked_add_scalar(
800                I::Scalar::try_from_usize(upper_bound).ok_or(I::IndexTooBigError::new())?,
801            )?;
802        }
803
804        let orig_len = self.raw.len();
805        for item in iter {
806            self.try_push(item).inspect_err(|_err| {
807                self.raw.truncate(orig_len);
808            })?;
809        }
810        Ok(())
811    }
812}
813
814/// An iterator adapter used by [`TypedVec::splice`] to cap replacement growth.
815///
816/// This wrapper forwards items from an underlying iterator while tracking how many
817/// replacement elements may still be yielded without making the final vector length
818/// exceed the index type's maximum.
819///
820/// Once the allowed replacement count is exhausted, further iteration panics.
821#[derive(Debug)]
822pub struct BoundedSpliceIter<I: IndexType, Iter> {
823    inner: Iter,
824    remaining: I::Scalar,
825}
826
827impl<I: IndexType, Iter> BoundedSpliceIter<I, Iter> {
828    #[inline]
829    fn new(inner: Iter, remaining: I::Scalar) -> Self {
830        Self { inner, remaining }
831    }
832
833    #[inline]
834    fn take_one(&mut self) {
835        self.remaining = self
836            .remaining
837            .checked_sub_scalar(I::Scalar::ONE)
838            .expect("splice would exceed the index type's maximum length");
839    }
840}
841
842impl<I: IndexType, T, Iter: Iterator<Item = T>> Iterator for BoundedSpliceIter<I, Iter> {
843    type Item = T;
844
845    #[inline]
846    fn next(&mut self) -> Option<Self::Item> {
847        let item = self.inner.next()?;
848        self.take_one();
849        Some(item)
850    }
851
852    #[inline]
853    fn size_hint(&self) -> (usize, Option<usize>) {
854        let (lower, upper) = self.inner.size_hint();
855        let remaining = self.remaining.to_usize();
856        (
857            lower.min(remaining),
858            upper.map(|upper| upper.min(remaining)),
859        )
860    }
861}
862
863impl<I: IndexType, T, Iter: DoubleEndedIterator<Item = T>> DoubleEndedIterator
864    for BoundedSpliceIter<I, Iter>
865{
866    #[inline]
867    fn next_back(&mut self) -> Option<Self::Item> {
868        let item = self.inner.next_back()?;
869        self.take_one();
870        Some(item)
871    }
872}
873
874impl<I: IndexType, T, Iter: ExactSizeIterator<Item = T>> ExactSizeIterator
875    for BoundedSpliceIter<I, Iter>
876{
877    #[inline]
878    fn len(&self) -> usize {
879        self.inner.len().min(self.remaining.to_usize())
880    }
881}
882
883impl<I: IndexType, T, Iter: FusedIterator<Item = T>> FusedIterator for BoundedSpliceIter<I, Iter> {}
884
885impl<I: IndexType, T: PartialEq> TypedVec<I, T> {
886    /// Removes consecutive duplicate elements.
887    ///
888    /// See [`Vec::dedup`] for details.
889    #[inline]
890    pub fn dedup(&mut self) {
891        self.raw.dedup();
892    }
893}
894
895impl<I: IndexType, T: Clone> TypedVec<I, T> {
896    /// Extends the vector by cloning elements from a typed slice.
897    ///
898    /// See [`Vec::extend_from_slice`] for details.
899    #[inline]
900    pub fn extend_from_slice(&mut self, other: &TypedSlice<I, T>) {
901        self.try_extend_from_slice(other)
902            .unwrap_or_else(|error| panic_index_too_big::<I>(error))
903    }
904
905    /// Attempts to extend the vector by cloning elements from a typed slice.
906    ///
907    /// Returns an error if the resulting length would exceed `I::MAX_RAW_INDEX`.
908    #[inline]
909    pub fn try_extend_from_slice(
910        &mut self,
911        other: &TypedSlice<I, T>,
912    ) -> Result<(), I::IndexTooBigError> {
913        let _new_len = self.len().checked_add_scalar(other.len().to_scalar())?;
914        self.raw.extend_from_slice(other.as_slice());
915        Ok(())
916    }
917
918    /// Attempts to copy elements from the specified range to the end of the vector.
919    ///
920    /// Returns an error if the resulting length would exceed `I::MAX_RAW_INDEX`.
921    ///
922    /// See [`Vec::extend_from_within`] for details.
923    #[inline]
924    pub fn try_extend_from_within<R>(&mut self, src: R) -> Result<(), I::IndexTooBigError>
925    where
926        R: core::ops::RangeBounds<I>,
927    {
928        let src_range = resolve_range_bounds(&src, self.len());
929        let src_range_len = src_range
930            .end
931            .checked_sub_index(src_range.start)
932            .expect("invalid range");
933        let _ = self.len().checked_add_scalar(src_range_len)?;
934        self.raw.extend_from_within(range_bounds_to_raw(&src));
935        Ok(())
936    }
937
938    /// Copies elements from the specified range to the end of the vector.
939    ///
940    /// See [`Vec::extend_from_within`] for details.
941    #[inline]
942    pub fn extend_from_within<R>(&mut self, src: R)
943    where
944        R: core::ops::RangeBounds<I>,
945    {
946        self.try_extend_from_within(src)
947            .unwrap_or_else(|error| panic_index_too_big::<I>(error))
948    }
949
950    /// Creates an iterator that filters and transforms elements, removing them in place.
951    ///
952    /// See [`Vec::extract_if`] for details.
953    #[inline]
954    pub fn extract_if<F, R>(&mut self, range: R, filter: F) -> alloc::vec::ExtractIf<'_, T, F>
955    where
956        F: FnMut(&mut T) -> bool,
957        R: core::ops::RangeBounds<I>,
958    {
959        self.raw.extract_if(range_bounds_to_raw(&range), filter)
960    }
961
962    /// Resizes the vector to the specified length, filling new positions with `value`.
963    ///
964    /// See [`Vec::resize`] for details.
965    #[inline]
966    pub fn resize(&mut self, new_len: I, value: T) {
967        self.raw.resize(new_len.to_raw_index(), value);
968    }
969}
970
971impl<I: IndexType, T, const N: usize> TypedVec<I, [T; N]> {
972    /// Attempts to flatten the vector of arrays into a vector of elements.
973    ///
974    /// Returns an error if the flattened length would exceed `I::MAX_RAW_INDEX`.
975    ///
976    /// # Example
977    ///
978    /// ```
979    /// use index_type::IndexType;
980    /// use index_type::vec::TypedVec;
981    ///
982    /// #[derive(IndexType, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
983    /// struct Idx(u16);
984    ///
985    /// let vec: TypedVec<Idx, [u8; 2]> = TypedVec::from_vec(vec![[1, 2], [3, 4]]);
986    /// let flat: TypedVec<Idx, u8> = vec.try_into_flattened().unwrap();
987    /// assert_eq!(flat.len_usize(), 4);
988    /// ```
989    pub fn try_into_flattened(self) -> Result<TypedVec<I, T>, I::IndexTooBigError> {
990        let _new_len = self
991            .len()
992            .checked_mul_scalar(I::Scalar::try_from_usize(N).ok_or(I::IndexTooBigError::new())?)?;
993        Ok(unsafe { TypedVec::from_vec_unchecked(self.raw.into_flattened()) })
994    }
995
996    /// Flattens the vector of arrays into a vector of elements.
997    ///
998    /// # Panics
999    ///
1000    /// Panics if the flattened length would exceed `I::MAX_RAW_INDEX`.
1001    pub fn into_flattened(self) -> TypedVec<I, T> {
1002        self.try_into_flattened()
1003            .unwrap_or_else(|error| panic_index_too_big::<I>(error))
1004    }
1005}
1006impl<I: IndexType, T: core::fmt::Debug> core::fmt::Debug for TypedVec<I, T> {
1007    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1008        core::fmt::Debug::fmt(&self.raw, f)
1009    }
1010}
1011impl<I: IndexType, T: PartialEq> PartialEq for TypedVec<I, T> {
1012    fn eq(&self, other: &Self) -> bool {
1013        PartialEq::eq(&self.raw, &other.raw)
1014    }
1015}
1016impl<I: IndexType, T: Eq> Eq for TypedVec<I, T> {}
1017impl<I: IndexType, T: Clone> Clone for TypedVec<I, T> {
1018    fn clone(&self) -> Self {
1019        Self {
1020            raw: Clone::clone(&self.raw),
1021            phantom: PhantomData,
1022        }
1023    }
1024
1025    fn clone_from(&mut self, source: &Self) {
1026        Clone::clone_from(&mut self.raw, &source.raw);
1027    }
1028}
1029impl<I: IndexType, T: core::hash::Hash> core::hash::Hash for TypedVec<I, T> {
1030    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1031        core::hash::Hash::hash(&self.raw, state);
1032    }
1033}
1034impl<I: IndexType, T> Default for TypedVec<I, T> {
1035    fn default() -> Self {
1036        Self {
1037            raw: Default::default(),
1038            phantom: PhantomData,
1039        }
1040    }
1041}
1042impl<I: IndexType, T> Deref for TypedVec<I, T> {
1043    type Target = TypedSlice<I, T>;
1044
1045    fn deref(&self) -> &Self::Target {
1046        self.as_slice()
1047    }
1048}
1049impl<I: IndexType, T> DerefMut for TypedVec<I, T> {
1050    fn deref_mut(&mut self) -> &mut Self::Target {
1051        self.as_mut_slice()
1052    }
1053}
1054impl<I: IndexType, T> AsRef<TypedSlice<I, T>> for TypedVec<I, T> {
1055    fn as_ref(&self) -> &TypedSlice<I, T> {
1056        self.as_slice()
1057    }
1058}
1059impl<I: IndexType, T> AsMut<TypedSlice<I, T>> for TypedVec<I, T> {
1060    fn as_mut(&mut self) -> &mut TypedSlice<I, T> {
1061        self.as_mut_slice()
1062    }
1063}
1064impl<I: IndexType, T> AsRef<TypedVec<I, T>> for TypedVec<I, T> {
1065    fn as_ref(&self) -> &TypedVec<I, T> {
1066        self
1067    }
1068}
1069impl<I: IndexType, T> AsMut<TypedVec<I, T>> for TypedVec<I, T> {
1070    fn as_mut(&mut self) -> &mut TypedVec<I, T> {
1071        self
1072    }
1073}
1074impl<I: IndexType, T> Borrow<TypedSlice<I, T>> for TypedVec<I, T> {
1075    fn borrow(&self) -> &TypedSlice<I, T> {
1076        self.as_slice()
1077    }
1078}
1079impl<I: IndexType, T> BorrowMut<TypedSlice<I, T>> for TypedVec<I, T> {
1080    fn borrow_mut(&mut self) -> &mut TypedSlice<I, T> {
1081        self.as_mut_slice()
1082    }
1083}
1084impl<'a, I: IndexType, T: Clone> From<&'a TypedSlice<I, T>> for TypedVec<I, T> {
1085    fn from(value: &'a TypedSlice<I, T>) -> Self {
1086        // SAFETY: The length of the slice is already guaranteed to be in bounds for I.
1087        unsafe { Self::from_vec_unchecked(Vec::from(value.as_slice())) }
1088    }
1089}
1090impl<I: IndexType, T> IntoIterator for TypedVec<I, T> {
1091    type Item = T;
1092
1093    type IntoIter = alloc::vec::IntoIter<T>;
1094
1095    fn into_iter(self) -> Self::IntoIter {
1096        self.raw.into_iter()
1097    }
1098}
1099impl<'a, I: IndexType, T> IntoIterator for &'a TypedVec<I, T> {
1100    type Item = &'a T;
1101
1102    type IntoIter = core::slice::Iter<'a, T>;
1103
1104    fn into_iter(self) -> Self::IntoIter {
1105        self.raw.iter()
1106    }
1107}
1108impl<'a, I: IndexType, T> IntoIterator for &'a mut TypedVec<I, T> {
1109    type Item = &'a mut T;
1110
1111    type IntoIter = core::slice::IterMut<'a, T>;
1112
1113    fn into_iter(self) -> Self::IntoIter {
1114        self.raw.iter_mut()
1115    }
1116}
1117impl<I: IndexType, T> Extend<T> for TypedVec<I, T> {
1118    fn extend<X: IntoIterator<Item = T>>(&mut self, iter: X) {
1119        self.try_extend(iter)
1120            .unwrap_or_else(|error| panic_index_too_big::<I>(error))
1121    }
1122}
1123
1124impl<I: IndexType, T> FromIterator<T> for TypedVec<I, T> {
1125    fn from_iter<X: IntoIterator<Item = T>>(iter: X) -> Self {
1126        Self::from_vec(Vec::from_iter(iter))
1127    }
1128}
1129impl<I: IndexType, T: PartialEq> PartialEq<TypedSlice<I, T>> for TypedVec<I, T> {
1130    fn eq(&self, other: &TypedSlice<I, T>) -> bool {
1131        PartialEq::eq(&self.raw, other.as_slice())
1132    }
1133}
1134impl<'a, I: IndexType, T: PartialEq> PartialEq<&'a TypedSlice<I, T>> for TypedVec<I, T> {
1135    fn eq(&self, other: &&'a TypedSlice<I, T>) -> bool {
1136        PartialEq::eq(&self.raw, other.as_slice())
1137    }
1138}
1139impl<'a, I: IndexType, T: PartialEq> PartialEq<&'a mut TypedSlice<I, T>> for TypedVec<I, T> {
1140    fn eq(&self, other: &&'a mut TypedSlice<I, T>) -> bool {
1141        PartialEq::eq(&self.raw, other.as_slice())
1142    }
1143}
1144impl<I: IndexType, T: PartialOrd> PartialOrd for TypedVec<I, T> {
1145    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1146        PartialOrd::partial_cmp(&self.raw, &other.raw)
1147    }
1148}
1149impl<I: IndexType, T: Ord> Ord for TypedVec<I, T> {
1150    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1151        Ord::cmp(&self.raw, &other.raw)
1152    }
1153}