1#![allow(clippy::inline_always)]
143#![allow(clippy::partialeq_ne_impl)]
144#![no_std]
145extern crate alloc;
146
147use alloc::{
148 borrow::{Cow, ToOwned},
149 boxed::Box,
150 vec,
151 vec::Vec,
152};
153use core::{
154 borrow::{Borrow, BorrowMut},
155 fmt,
156 fmt::Debug,
157 hash::Hash,
158 iter::{self, FromIterator},
159 marker::PhantomData,
160 ops::Range,
161 slice,
162};
163mod idxslice;
164mod indexing;
165pub use idxslice::{IndexBox, IndexSlice};
166pub use indexing::{IdxRangeBounds, IdxSliceIndex};
167#[cfg(feature = "nonmax")]
168pub use nonmax;
169#[cfg(feature = "rayon")]
170pub use rayon_impl::*;
171#[cfg(feature = "serde")]
172pub use serde;
173#[cfg(feature = "rayon")]
174mod rayon_impl;
175
176#[macro_use]
177mod macros;
178
179pub trait Idx: Copy + 'static + Ord + Debug + Hash {
199 const MAX: usize;
201
202 unsafe fn from_usize_unchecked(idx: usize) -> Self;
207
208 fn index(self) -> usize;
210
211 fn from_usize(idx: usize) -> Self {
217 assert!(idx <= Self::MAX);
218 unsafe { Self::from_usize_unchecked(idx) }
220 }
221}
222
223#[macro_export]
225macro_rules! index_vec {
226 ($($tokens:tt)*) => {
227 $crate::IndexVec::from_vec(vec![$($tokens)*])
228 }
229}
230
231#[macro_export]
234macro_rules! index_box {
235 ($($tokens:tt)*) => {
236 $crate::IndexVec::from_vec(vec![$($tokens)*]).into_boxed_slice()
237 }
238}
239
240#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
258pub struct IndexVec<I: Idx, T> {
259 pub raw: Vec<T>,
261 _marker: PhantomData<fn(&I)>,
262}
263
264unsafe impl<I: Idx, T> Send for IndexVec<I, T> where T: Send {}
267
268impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {
269 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
270 fmt::Debug::fmt(&self.raw, fmt)
271 }
272}
273type Enumerated<Iter, I, T> = iter::Map<iter::Enumerate<Iter>, fn((usize, T)) -> (I, T)>;
274
275impl<I: Idx, T> IndexVec<I, T> {
276 #[inline]
278 pub const fn new() -> Self {
279 IndexVec { raw: Vec::new(), _marker: PhantomData }
280 }
281
282 #[inline]
286 pub fn from_vec(vec: Vec<T>) -> Self {
287 let _ = I::from_usize(vec.len());
289 IndexVec { raw: vec, _marker: PhantomData }
290 }
291
292 #[inline]
295 pub fn with_capacity(capacity: usize) -> Self {
296 IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData }
297 }
298
299 #[inline(always)]
302 pub fn into_iter_enumerated(self) -> Enumerated<vec::IntoIter<T>, I, T> {
303 self.raw.into_iter().enumerate().map(|(i, t)| (I::from_usize(i), t))
304 }
305
306 #[inline]
310 pub fn splice<R, It>(
311 &mut self,
312 range: R,
313 replace_with: It,
314 ) -> vec::Splice<'_, <It as IntoIterator>::IntoIter>
315 where
316 It: IntoIterator<Item = T>,
317 R: IdxRangeBounds<I>,
318 {
319 self.raw.splice(range.into_range(), replace_with)
320 }
321
322 #[inline]
325 pub fn drain_enumerated<R: IdxRangeBounds<I>>(
326 &mut self,
327 range: R,
328 ) -> Enumerated<vec::Drain<'_, T>, I, T> {
329 self.raw.drain(range.into_range()).enumerate().map(|(i, t)| (I::from_usize(i), t))
330 }
331
332 #[inline]
335 pub fn next_idx(&self) -> I {
336 I::from_usize(self.len())
337 }
338
339 #[inline(always)]
341 pub fn as_raw_slice(&self) -> &[T] {
342 &self.raw
343 }
344
345 #[inline(always)]
347 pub fn as_raw_slice_mut(&mut self) -> &mut [T] {
348 &mut self.raw
349 }
350
351 #[inline(always)]
353 pub const fn as_vec(&self) -> &Vec<T> {
354 &self.raw
355 }
356
357 #[inline(always)]
360 pub const fn as_mut_vec(&mut self) -> &mut Vec<T> {
361 &mut self.raw
362 }
363
364 #[inline]
366 pub fn push(&mut self, d: T) -> I {
367 let len = self.len();
368 let idx = unsafe { I::from_usize_unchecked(len) };
372 self.raw.push(d);
373 idx
374 }
375
376 #[inline]
378 pub fn pop(&mut self) -> Option<T> {
379 self.raw.pop()
380 }
381
382 #[inline]
384 pub fn into_boxed_slice(self) -> Box<IndexSlice<I, [T]>> {
385 let b = self.raw.into_boxed_slice();
386 unsafe { Box::from_raw(Box::into_raw(b) as *mut IndexSlice<I, [T]>) }
388 }
389
390 #[inline]
396 pub fn drain<R: IdxRangeBounds<I>>(&mut self, range: R) -> vec::Drain<'_, T> {
397 self.raw.drain(range.into_range())
398 }
399
400 #[inline]
402 pub fn shrink_to_fit(&mut self) {
403 self.raw.shrink_to_fit();
404 }
405
406 #[inline]
408 pub fn shrink_to(&mut self, min_capacity: usize) {
409 self.raw.shrink_to(min_capacity);
410 }
411
412 #[inline]
415 pub fn truncate(&mut self, a: usize) {
416 self.raw.truncate(a);
417 }
418
419 #[inline]
421 pub fn clear(&mut self) {
422 self.raw.clear();
423 }
424
425 #[inline]
427 pub fn reserve(&mut self, c: usize) {
428 self.raw.reserve(c);
429 }
430
431 #[inline]
433 pub fn get<J: IdxSliceIndex<I, T>>(&self, index: J) -> Option<&J::Output> {
434 index.get(self.as_slice())
435 }
436
437 #[inline]
440 pub fn get_mut<J: IdxSliceIndex<I, T>>(&mut self, index: J) -> Option<&mut J::Output> {
441 index.get_mut(self.as_mut_slice())
442 }
443
444 #[inline]
446 pub fn resize(&mut self, new_len: usize, value: T)
447 where
448 T: Clone,
449 {
450 self.raw.resize(new_len, value);
451 }
452
453 #[inline]
455 pub fn resize_with<F: FnMut() -> T>(&mut self, new_len: usize, f: F) {
456 self.raw.resize_with(new_len, f);
457 }
458
459 #[inline]
462 pub fn append(&mut self, other: &mut Self) {
463 self.raw.append(&mut other.raw);
464 }
465
466 #[inline]
469 #[must_use]
470 pub fn split_off(&mut self, idx: I) -> Self {
471 Self::from_vec(self.raw.split_off(idx.index()))
472 }
473
474 #[inline]
476 pub fn remove(&mut self, index: I) -> T {
477 self.raw.remove(index.index())
478 }
479
480 #[inline]
483 pub fn swap_remove(&mut self, index: I) -> T {
484 self.raw.swap_remove(index.index())
485 }
486
487 #[inline]
489 pub fn insert(&mut self, index: I, element: T) {
490 self.raw.insert(index.index(), element);
491 }
492
493 #[inline]
497 pub fn extend_from_slice(&mut self, other: &IndexSlice<I, [T]>)
498 where
499 T: Clone,
500 {
501 self.raw.extend_from_slice(&other.raw);
502 }
503
504 #[inline]
506 pub fn retain<F: FnMut(&T) -> bool>(&mut self, f: F) {
507 self.raw.retain(f);
508 }
509
510 #[inline]
512 pub fn dedup_by_key<F: FnMut(&mut T) -> K, K: PartialEq>(&mut self, key: F) {
513 self.raw.dedup_by_key(key);
514 }
515
516 #[inline]
518 pub fn dedup(&mut self)
519 where
520 T: PartialEq,
521 {
522 self.raw.dedup();
523 }
524
525 #[inline]
527 pub fn dedup_by<F: FnMut(&mut T, &mut T) -> bool>(&mut self, same_bucket: F) {
528 self.raw.dedup_by(same_bucket);
529 }
530
531 #[inline(always)]
534 pub fn as_slice(&self) -> &IndexSlice<I, [T]> {
535 IndexSlice::new(&self.raw)
536 }
537
538 #[inline(always)]
541 pub fn as_mut_slice(&mut self) -> &mut IndexSlice<I, [T]> {
542 IndexSlice::new_mut(&mut self.raw)
543 }
544}
545
546impl<I: Idx, T> Default for IndexVec<I, T> {
547 #[inline]
548 fn default() -> Self {
549 Self::new()
550 }
551}
552
553impl<I: Idx, T> Extend<T> for IndexVec<I, T> {
554 #[inline]
555 fn extend<J: IntoIterator<Item = T>>(&mut self, iter: J) {
556 self.raw.extend(iter);
557 }
558}
559
560impl<'a, I: Idx, T: 'a + Copy> Extend<&'a T> for IndexVec<I, T> {
561 #[inline]
562 fn extend<J: IntoIterator<Item = &'a T>>(&mut self, iter: J) {
563 self.raw.extend(iter);
564 }
565}
566
567impl<I: Idx, T> FromIterator<T> for IndexVec<I, T> {
568 #[inline]
569 fn from_iter<J>(iter: J) -> Self
570 where
571 J: IntoIterator<Item = T>,
572 {
573 IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData }
574 }
575}
576
577impl<I: Idx, T> IntoIterator for IndexVec<I, T> {
578 type IntoIter = vec::IntoIter<T>;
579 type Item = T;
580
581 #[inline]
582 fn into_iter(self) -> vec::IntoIter<T> {
583 self.raw.into_iter()
584 }
585}
586
587impl<'a, I: Idx, T> IntoIterator for &'a IndexVec<I, T> {
588 type IntoIter = slice::Iter<'a, T>;
589 type Item = &'a T;
590
591 #[inline]
592 fn into_iter(self) -> slice::Iter<'a, T> {
593 self.raw.iter()
594 }
595}
596
597impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> {
598 type IntoIter = slice::IterMut<'a, T>;
599 type Item = &'a mut T;
600
601 #[inline]
602 fn into_iter(self) -> slice::IterMut<'a, T> {
603 self.raw.iter_mut()
604 }
605}
606
607impl<I: Idx, T> From<IndexVec<I, T>> for Box<IndexSlice<I, [T]>> {
608 #[inline]
609 fn from(src: IndexVec<I, T>) -> Self {
610 src.into_boxed_slice()
611 }
612}
613
614impl<I: Idx, T> From<Box<IndexSlice<I, [T]>>> for IndexVec<I, T> {
615 #[inline]
616 fn from(src: Box<IndexSlice<I, [T]>>) -> Self {
617 src.into_vec()
618 }
619}
620
621impl<'a, I: Idx, T> From<Cow<'a, IndexSlice<I, [T]>>> for IndexVec<I, T>
622where
623 IndexSlice<I, [T]>: ToOwned<Owned = IndexVec<I, T>>,
624{
625 #[inline]
626 fn from(s: Cow<'a, IndexSlice<I, [T]>>) -> IndexVec<I, T> {
627 s.into_owned()
628 }
629}
630
631impl<'a, I: Idx, T: Clone> From<&'a IndexSlice<I, [T]>> for IndexVec<I, T> {
632 #[inline]
633 fn from(src: &'a IndexSlice<I, [T]>) -> Self {
634 src.to_owned()
635 }
636}
637impl<'a, I: Idx, T: Clone> From<&'a mut IndexSlice<I, [T]>> for IndexVec<I, T> {
638 #[inline]
639 fn from(src: &'a mut IndexSlice<I, [T]>) -> Self {
640 src.to_owned()
641 }
642}
643
644impl<I: Idx, T> From<Vec<T>> for IndexVec<I, T> {
645 #[inline]
646 fn from(v: Vec<T>) -> Self {
647 Self { raw: v, _marker: PhantomData }
648 }
649}
650
651impl<I: Idx, T: Clone> Clone for IndexVec<I, T> {
652 #[inline]
653 fn clone(&self) -> Self {
654 Self { raw: self.raw.clone(), _marker: PhantomData }
655 }
656
657 #[inline]
658 fn clone_from(&mut self, o: &Self) {
659 self.raw.clone_from(&o.raw);
660 }
661}
662
663impl<I: Idx, A> AsRef<[A]> for IndexVec<I, A> {
664 #[inline]
665 fn as_ref(&self) -> &[A] {
666 &self.raw
667 }
668}
669
670impl<I: Idx, A> AsMut<[A]> for IndexVec<I, A> {
671 #[inline]
672 fn as_mut(&mut self) -> &mut [A] {
673 &mut self.raw
674 }
675}
676
677impl<I: Idx, A> AsRef<IndexSlice<I, [A]>> for IndexVec<I, A> {
678 #[inline]
679 fn as_ref(&self) -> &IndexSlice<I, [A]> {
680 IndexSlice::new(&self.raw)
681 }
682}
683
684impl<I: Idx, A> AsMut<IndexSlice<I, [A]>> for IndexVec<I, A> {
685 #[inline]
686 fn as_mut(&mut self) -> &mut IndexSlice<I, [A]> {
687 IndexSlice::new_mut(&mut self.raw)
688 }
689}
690
691impl<I: Idx, A> core::ops::Deref for IndexVec<I, A> {
692 type Target = IndexSlice<I, [A]>;
693
694 #[inline]
695 fn deref(&self) -> &IndexSlice<I, [A]> {
696 IndexSlice::new(&self.raw)
697 }
698}
699
700impl<I: Idx, A> core::ops::DerefMut for IndexVec<I, A> {
701 #[inline]
702 fn deref_mut(&mut self) -> &mut IndexSlice<I, [A]> {
703 IndexSlice::new_mut(&mut self.raw)
704 }
705}
706
707impl<I: Idx, T> Borrow<IndexSlice<I, [T]>> for IndexVec<I, T> {
708 #[inline]
709 fn borrow(&self) -> &IndexSlice<I, [T]> {
710 self.as_slice()
711 }
712}
713
714impl<I: Idx, T> BorrowMut<IndexSlice<I, [T]>> for IndexVec<I, T> {
715 #[inline]
716 fn borrow_mut(&mut self) -> &mut IndexSlice<I, [T]> {
717 self.as_mut_slice()
718 }
719}
720
721macro_rules! impl_partialeq {
722 ($Lhs: ty, $Rhs: ty) => {
723 impl<'a, 'b, A, B, I: Idx> PartialEq<$Rhs> for $Lhs
724 where
725 A: PartialEq<B>,
726 {
727 #[inline]
728 fn eq(&self, other: &$Rhs) -> bool {
729 self[..] == other[..]
730 }
731
732 #[inline]
733 fn ne(&self, other: &$Rhs) -> bool {
734 self[..] != other[..]
735 }
736 }
737 };
738}
739
740macro_rules! impl_partialeq2 {
741 ($Lhs: ty, $Rhs: ty) => {
742 impl<'a, 'b, A, B, I: Idx, J: Idx> PartialEq<$Rhs> for $Lhs
743 where
744 A: PartialEq<B>,
745 {
746 #[inline]
747 fn eq(&self, other: &$Rhs) -> bool {
748 self.raw[..] == other.raw[..]
749 }
750
751 #[inline]
752 fn ne(&self, other: &$Rhs) -> bool {
753 self.raw[..] != other.raw[..]
754 }
755 }
756 };
757}
758
759impl_partialeq! { IndexVec<I, A>, Vec<B> }
760impl_partialeq! { IndexVec<I, A>, &'b [B] }
761impl_partialeq! { IndexVec<I, A>, &'b mut [B] }
762
763impl_partialeq2! { IndexVec<I, A>, &'b IndexSlice<J, [B]> }
764impl_partialeq2! { IndexVec<I, A>, &'b mut IndexSlice<J, [B]> }
765
766impl_partialeq! { &'a IndexSlice<I, [A]>, Vec<B> }
767impl_partialeq! { &'a mut IndexSlice<I, [A]>, Vec<B> }
768
769impl_partialeq! { IndexSlice<I, [A]>, &'b [B] }
770impl_partialeq! { IndexSlice<I, [A]>, &'b mut [B] }
771
772impl_partialeq2! { &'a IndexSlice<I, [A]>, IndexVec<J, B> }
773impl_partialeq2! { &'a mut IndexSlice<I, [A]>, IndexVec<J, B> }
774
775impl_partialeq2! { IndexSlice<I, [A]>, &'a IndexSlice<J, [B]> }
776impl_partialeq2! { IndexSlice<I, [A]>, &'a mut IndexSlice<J, [B]> }
777
778macro_rules! array_impls {
779 ($($N: expr_2021)+) => {$(
780 impl_partialeq! { IndexVec<I, A>, [B; $N] }
781 impl_partialeq! { IndexVec<I, A>, &'b [B; $N] }
782 impl_partialeq! { IndexSlice<I, [A]>, [B; $N] }
783 impl_partialeq! { IndexSlice<I, [A]>, &'b [B; $N] }
784 )+};
787}
788
789array_impls! {
790 0 1 2 3 4 5 6 7 8 9
791 10 11 12 13 14 15 16 17 18 19
792 20 21 22 23 24 25 26 27 28 29
793 30 31 32
794}
795
796#[inline(never)]
797#[cold]
798#[doc(hidden)]
799pub fn __max_check_fail(u: usize, max: usize) -> ! {
800 panic!("index_vec index overflow: {} is outside the range [0, {})", u, max,)
801}
802
803#[cfg(feature = "serde")]
804impl<I: Idx, T: crate::serde::ser::Serialize> crate::serde::ser::Serialize for IndexVec<I, T> {
805 fn serialize<S: crate::serde::ser::Serializer>(
806 &self,
807 serializer: S,
808 ) -> Result<S::Ok, S::Error> {
809 self.raw.serialize(serializer)
810 }
811}
812
813#[cfg(feature = "serde")]
814impl<'de, I: Idx, T: crate::serde::de::Deserialize<'de>> crate::serde::de::Deserialize<'de>
815 for IndexVec<I, T>
816{
817 fn deserialize<D: crate::serde::de::Deserializer<'de>>(
818 deserializer: D,
819 ) -> Result<Self, D::Error> {
820 Vec::deserialize(deserializer).map(Self::from_vec)
821 }
822}
823
824#[cfg(feature = "serde")]
825impl<I: Idx, T: crate::serde::ser::Serialize> crate::serde::ser::Serialize for IndexBox<I, T> {
826 fn serialize<S: crate::serde::ser::Serializer>(
827 &self,
828 serializer: S,
829 ) -> Result<S::Ok, S::Error> {
830 self.raw.serialize(serializer)
831 }
832}
833
834#[cfg(feature = "serde")]
835impl<'de, I: Idx, T: crate::serde::de::Deserialize<'de>> crate::serde::de::Deserialize<'de>
836 for IndexBox<I, [T]>
837{
838 fn deserialize<D: crate::serde::de::Deserializer<'de>>(
839 deserializer: D,
840 ) -> Result<Self, D::Error> {
841 Box::<[T]>::deserialize(deserializer).map(Into::into)
842 }
843}
844
845#[cfg(test)]
846#[expect(clippy::legacy_numeric_constants)]
847mod test {
848 use super::*;
849
850 define_index_type! {
851 pub struct TestIdx = u32;
852 }
853
854 #[test]
855 fn test_resize() {
856 let mut v = IndexVec::<TestIdx, u32>::with_capacity(10);
857 assert_eq!(v.len(), 0);
858 assert!(v.is_empty());
859
860 v.push(1);
861 assert_eq!(v.len(), 1);
862
863 v.resize(5, 1);
864 assert_eq!(v.len(), 5);
865 assert_eq!(v.as_slice(), &[1, 1, 1, 1, 1]);
866
867 v.shrink_to_fit();
868 assert_eq!(v.len(), 5);
869 }
870
871 #[test]
872 fn test_push_pop() {
873 let mut v = IndexVec::<TestIdx, u32>::new();
874 v.push(1);
875 assert_eq!(v.pop(), Some(1));
876 }
877
878 #[test]
879 fn test_clear() {
880 let mut v: IndexVec<TestIdx, u32> = [1, 2, 3].into_iter().collect();
881 assert_eq!(v.len(), 3);
882
883 v.clear();
884 assert_eq!(v.len(), 0);
885 assert_eq!(v.as_slice(), &[]);
886 assert_eq!(v, IndexVec::<TestIdx, u32>::new());
887 }
888}