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}