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}