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