use std::fmt::Debug; use std::hash::Hash; use std::ops; use std::slice::SliceIndex; /// Represents some newtyped `usize` wrapper. /// /// Purpose: avoid mixing indexes for different bitvector domains. pub trait Idx: Copy + 'static + Eq + PartialEq + Debug + Hash { fn new(idx: usize) -> Self; fn index(self) -> usize; #[inline] fn increment_by(&mut self, amount: usize) { *self = self.plus(amount); } #[inline] #[must_use = "Use `increment_by` if you wanted to update the index in-place"] fn plus(self, amount: usize) -> Self { Self::new(self.index() + amount) } } impl Idx for usize { #[inline] fn new(idx: usize) -> Self { idx } #[inline] fn index(self) -> usize { self } } impl Idx for u32 { #[inline] fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 } #[inline] fn index(self) -> usize { self as usize } } /// Helper trait for indexing operations with a custom index type. pub trait IntoSliceIdx { type Output: SliceIndex; fn into_slice_idx(self) -> Self::Output; } impl IntoSliceIdx for I { type Output = usize; #[inline] fn into_slice_idx(self) -> Self::Output { self.index() } } impl IntoSliceIdx for ops::RangeFull { type Output = ops::RangeFull; #[inline] fn into_slice_idx(self) -> Self::Output { self } } impl IntoSliceIdx for ops::Range { type Output = ops::Range; #[inline] fn into_slice_idx(self) -> Self::Output { ops::Range { start: self.start.index(), end: self.end.index() } } } impl IntoSliceIdx for ops::RangeFrom { type Output = ops::RangeFrom; #[inline] fn into_slice_idx(self) -> Self::Output { ops::RangeFrom { start: self.start.index() } } } impl IntoSliceIdx for ops::RangeTo { type Output = ops::RangeTo; #[inline] fn into_slice_idx(self) -> Self::Output { ..self.end.index() } } impl IntoSliceIdx for ops::RangeInclusive { type Output = ops::RangeInclusive; #[inline] fn into_slice_idx(self) -> Self::Output { ops::RangeInclusive::new(self.start().index(), self.end().index()) } } impl IntoSliceIdx for ops::RangeToInclusive { type Output = ops::RangeToInclusive; #[inline] fn into_slice_idx(self) -> Self::Output { ..=self.end.index() } } #[cfg(feature = "nightly")] impl IntoSliceIdx for core::range::Range { type Output = core::range::Range; #[inline] fn into_slice_idx(self) -> Self::Output { core::range::Range { start: self.start.index(), end: self.end.index() } } } #[cfg(feature = "nightly")] impl IntoSliceIdx for core::range::RangeFrom { type Output = core::range::RangeFrom; #[inline] fn into_slice_idx(self) -> Self::Output { core::range::RangeFrom { start: self.start.index() } } } #[cfg(feature = "nightly")] impl IntoSliceIdx for core::range::RangeInclusive { type Output = core::range::RangeInclusive; #[inline] fn into_slice_idx(self) -> Self::Output { core::range::RangeInclusive { start: self.start.index(), end: self.end.index() } } }