Use FieldIdx
in FieldsShape
Finally got to the main motivating example from the MCP :)
This commit is contained in:
parent
bf41e753ec
commit
21bb8ef24e
7 changed files with 133 additions and 101 deletions
|
@ -24,6 +24,7 @@ pub trait Idx: Copy + 'static + Eq + PartialEq + Debug + Hash {
|
|||
}
|
||||
|
||||
#[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)
|
||||
}
|
||||
|
@ -283,6 +284,11 @@ impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> {
|
|||
}
|
||||
|
||||
impl<I: Idx, T> IndexSlice<I, T> {
|
||||
#[inline]
|
||||
pub fn empty() -> &'static Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_raw(raw: &[T]) -> &Self {
|
||||
let ptr: *const [T] = raw;
|
||||
|
@ -398,6 +404,36 @@ impl<I: Idx, T> IndexSlice<I, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<I: Idx, J: Idx> IndexSlice<I, J> {
|
||||
/// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`,
|
||||
/// assuming the values in `self` are a permutation of `0..self.len()`.
|
||||
///
|
||||
/// This is used to go between `memory_index` (source field order to memory order)
|
||||
/// and `inverse_memory_index` (memory order to source field order).
|
||||
/// See also `FieldsShape::Arbitrary::memory_index` for more details.
|
||||
// FIXME(eddyb) build a better abstraction for permutations, if possible.
|
||||
pub fn invert_bijective_mapping(&self) -> IndexVec<J, I> {
|
||||
debug_assert_eq!(
|
||||
self.iter().map(|x| x.index() as u128).sum::<u128>(),
|
||||
(0..self.len() as u128).sum::<u128>(),
|
||||
"The values aren't 0..N in input {self:?}",
|
||||
);
|
||||
|
||||
let mut inverse = IndexVec::from_elem_n(Idx::new(0), self.len());
|
||||
for (i1, &i2) in self.iter_enumerated() {
|
||||
inverse[i2] = i1;
|
||||
}
|
||||
|
||||
debug_assert_eq!(
|
||||
inverse.iter().map(|x| x.index() as u128).sum::<u128>(),
|
||||
(0..inverse.len() as u128).sum::<u128>(),
|
||||
"The values aren't 0..N in result {self:?}",
|
||||
);
|
||||
|
||||
inverse
|
||||
}
|
||||
}
|
||||
|
||||
/// `IndexVec` is often used as a map, so it provides some map-like APIs.
|
||||
impl<I: Idx, T> IndexVec<I, Option<T>> {
|
||||
#[inline]
|
||||
|
@ -502,6 +538,13 @@ impl<I: Idx, T> FromIterator<T> for IndexVec<I, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<I: Idx, T, const N: usize> From<[T; N]> for IndexVec<I, T> {
|
||||
#[inline]
|
||||
fn from(array: [T; N]) -> Self {
|
||||
IndexVec::from_raw(array.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Idx, T> IntoIterator for IndexVec<I, T> {
|
||||
type Item = T;
|
||||
type IntoIter = vec::IntoIter<T>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue