| 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<I, T: ?Sized> { | |
| type Output: SliceIndex<T>; | |
| fn into_slice_idx(self) -> Self::Output; | |
| } | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for I { | |
| type Output = usize; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| self.index() | |
| } | |
| } | |
| impl<I, T> IntoSliceIdx<I, [T]> for ops::RangeFull { | |
| type Output = ops::RangeFull; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| self | |
| } | |
| } | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::Range<I> { | |
| type Output = ops::Range<usize>; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| ops::Range { start: self.start.index(), end: self.end.index() } | |
| } | |
| } | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::RangeFrom<I> { | |
| type Output = ops::RangeFrom<usize>; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| ops::RangeFrom { start: self.start.index() } | |
| } | |
| } | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::RangeTo<I> { | |
| type Output = ops::RangeTo<usize>; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| ..self.end.index() | |
| } | |
| } | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::RangeInclusive<I> { | |
| type Output = ops::RangeInclusive<usize>; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| ops::RangeInclusive::new(self.start().index(), self.end().index()) | |
| } | |
| } | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::RangeToInclusive<I> { | |
| type Output = ops::RangeToInclusive<usize>; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| ..=self.end.index() | |
| } | |
| } | |
| #[cfg(feature = "nightly")] | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::Range<I> { | |
| type Output = core::range::Range<usize>; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| core::range::Range { start: self.start.index(), end: self.end.index() } | |
| } | |
| } | |
| #[cfg(feature = "nightly")] | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::RangeFrom<I> { | |
| type Output = core::range::RangeFrom<usize>; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| core::range::RangeFrom { start: self.start.index() } | |
| } | |
| } | |
| #[cfg(feature = "nightly")] | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::RangeInclusive<I> { | |
| type Output = core::range::RangeInclusive<usize>; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| core::range::RangeInclusive { start: self.start.index(), last: self.last.index() } | |
| } | |
| } | |
| #[cfg(feature = "nightly")] | |
| impl<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::RangeToInclusive<I> { | |
| type Output = core::range::RangeToInclusive<usize>; | |
| #[inline] | |
| fn into_slice_idx(self) -> Self::Output { | |
| core::range::RangeToInclusive { last: self.last.index() } | |
| } | |
| } |