use std::fmt;
use std::hash::Hash;
use std::marker::PhantomData;
use std::mem::MaybeUninit;
pub trait Discrim: fmt::Debug + Copy + PartialEq + Eq + Hash + Send + Sync + 'static {
type FullMap<S>: FullMap<Discrim = Self, Key = Self, Value = S>;
fn from_usize(usize: usize) -> Self;
fn into_usize(self) -> usize;
}
pub trait Set<D: Discrim>: Send + Sync + 'static {
type Iter<'t>: Iterator<Item = D>
where
Self: 't;
fn iter_discrims(&self) -> Self::Iter<'_>;
type Key: fmt::Debug + Copy + 'static;
type Mapped<U>: Mapped<Discrim = D, Key = Self::Key, Value = U>;
fn map<U, F: FnMut(D) -> U>(&self, func: F) -> Self::Mapped<U>;
}
impl<D: Discrim, const N: usize> Set<D> for [D; N] {
type Iter<'t> = impl Iterator<Item = D> where Self: 't;
fn iter_discrims(&self) -> Self::Iter<'_> { (*self).into_iter() }
type Key = usize;
type Mapped<U> = [(D, U); N];
fn map<U, F: FnMut(D) -> U>(&self, mut func: F) -> Self::Mapped<U> {
<[D; N]>::map(*self, |discrim| (discrim, func(discrim)))
}
}
impl<D: Discrim> Set<D> for Vec<D> {
type Iter<'t> = impl Iterator<Item = D> + 't where Self: 't;
fn iter_discrims(&self) -> Self::Iter<'_> { self[..].iter().copied() }
type Key = usize;
type Mapped<U> = Vec<(D, U)>;
fn map<U, F: FnMut(D) -> U>(&self, mut func: F) -> Self::Mapped<U> {
self[..].iter().map(|&discrim| (discrim, func(discrim))).collect()
}
}
pub trait Mapped {
type Discrim: Discrim;
type Key: fmt::Debug + Copy + 'static;
type Value;
fn get_discrim(&self, key: Self::Key) -> Option<Self::Discrim>;
fn get_by(&self, key: Self::Key) -> Option<&Self::Value>;
fn get_mut_by(&mut self, key: Self::Key) -> Option<&mut Self::Value>;
fn get_mut_array_by<'t, U, TransformFn, OnMissing, const N: usize>(
&'t mut self,
keys: [Self::Key; N],
transform: TransformFn,
on_missing: OnMissing,
) -> [U; N]
where
U: RefToPtr,
TransformFn: FnMut(&'t mut Self::Value) -> U,
OnMissing: FnMut(Self::Key) -> !;
type Iter<'t>: Iterator<Item = (Self::Key, Self::Discrim, &'t Self::Value)> + 't
where
Self: 't;
fn iter_mapped(&self) -> Self::Iter<'_>;
type IterMut<'t>: Iterator<Item = (Self::Discrim, &'t mut Self::Value)> + 't
where
Self: 't;
fn iter_mapped_mut(&mut self) -> Self::IterMut<'_>;
type IntoIter: Iterator<Item = (Self::Discrim, Self::Value)>;
fn into_iter_mapped(self) -> Self::IntoIter;
}
pub trait FullMap
where
Self: Mapped<Key = <Self as Mapped>::Discrim> + FromIterator<(Self::Discrim, Self::Value)>,
{
type MapRef<U>: Mapped<Discrim = Self::Discrim, Key = Self::Key, Value = U>;
fn map_ref<U, F>(&self, f: F) -> Self::MapRef<U>
where
F: FnMut(&Self::Value) -> U;
fn get_by_or_insert<F: FnOnce() -> Self::Value>(
&mut self,
discrim: Self::Discrim,
inserter: F,
) -> &mut Self::Value;
fn get_by_or_insert_array<'t, T, Inserter, Transform, const N: usize>(
&'t mut self,
discrims: [Self::Discrim; N],
inserter: Inserter,
transform: Transform,
) -> [T; N]
where
T: RefToPtr,
Inserter: FnMut(Self::Discrim) -> Self::Value,
Transform: FnMut(Self::Discrim, &'t mut Self::Value) -> T;
}
unsafe fn split_mut_array<'t, C, Getter, T: 't, U, TransformFn, OnMissingFn, const N: usize>(
getter_context: &'t mut C,
mut getter: Getter,
keys: [usize; N],
mut transform: TransformFn,
mut on_missing: OnMissingFn,
) -> [U; N]
where
Getter: FnMut(&mut C, usize) -> Option<&mut T>,
TransformFn: FnMut(usize, &'t mut T) -> U,
OnMissingFn: FnMut(usize) -> !,
U: RefToPtr,
{
let mut array: [MaybeUninit<U>; N] = MaybeUninit::uninit_array();
for (i, key) in keys.into_iter().enumerate() {
assert!(
keys[..i].iter().all(|&item| item != key),
"Cannot split isotopes with duplicate key {key:?}"
);
let value = match getter(&mut *(getter_context as *mut C), key) {
Some(value) => transform(i, value),
None => on_missing(i),
};
assert!(
array[..i].iter().all(|prev| {
let prev_ptr_ptr: &U = unsafe { prev.assume_init_ref() };
let prev_ptr = prev_ptr_ptr.as_ptr();
!std::ptr::eq(prev_ptr, value.as_ptr())
}),
"Cannot split isotopes with duplicate key {key:?}"
);
array[i] = MaybeUninit::new(value);
}
MaybeUninit::array_assume_init(array)
}
mod sealed {
pub trait Sealed {}
}
pub trait RefToPtr: sealed::Sealed {
type Target: ?Sized;
fn as_ptr(&self) -> *const Self::Target;
}
impl<'t, T: ?Sized> sealed::Sealed for &'t T {}
impl<'t, T: ?Sized> RefToPtr for &'t T {
type Target = T;
fn as_ptr(&self) -> *const T { *self as *const T }
}
impl<'t, T: ?Sized> sealed::Sealed for &'t mut T {}
impl<'t, T: ?Sized> RefToPtr for &'t mut T {
type Target = T;
fn as_ptr(&self) -> *const T { *self as *const T }
}
impl<D: Discrim, V, const N: usize> Mapped for [(D, V); N] {
type Discrim = D;
type Key = usize;
type Value = V;
fn get_discrim(&self, key: usize) -> Option<Self::Discrim> { self.get(key).map(|&(d, _)| d) }
fn get_by(&self, key: usize) -> Option<&V> {
let (_, value) = self.get(key)?;
Some(value)
}
fn get_mut_by(&mut self, key: usize) -> Option<&mut V> {
let (_, value) = self.get_mut(key)?;
Some(value)
}
fn get_mut_array_by<'t, U, TransformFn, OnMissing, const M: usize>(
&'t mut self,
keys: [usize; M],
mut transform: TransformFn,
mut on_missing: OnMissing,
) -> [U; M]
where
U: RefToPtr,
TransformFn: FnMut(&'t mut Self::Value) -> U,
OnMissing: FnMut(Self::Key) -> !,
{
unsafe {
split_mut_array(
self,
|slice, index| slice.get_mut(index),
keys,
|_i, (_d, v)| transform(v),
|i| on_missing(keys[i]),
)
}
}
type Iter<'t> = impl Iterator<Item = (usize, D, &'t V)> + 't where Self: 't;
fn iter_mapped(&self) -> Self::Iter<'_> {
self[..].iter().enumerate().map(|(key, (discrim, value))| (key, *discrim, value))
}
type IterMut<'t> = impl Iterator<Item = (D, &'t mut V)> + 't where Self: 't;
fn iter_mapped_mut(&mut self) -> Self::IterMut<'_> {
self[..].iter_mut().map(|(discrim, value)| (*discrim, value))
}
type IntoIter = impl Iterator<Item = (D, V)>;
fn into_iter_mapped(self) -> Self::IntoIter { self.into_iter() }
}
impl<D: Discrim, V> Mapped for Vec<(D, V)> {
type Discrim = D;
type Key = usize;
type Value = V;
fn get_discrim(&self, key: usize) -> Option<Self::Discrim> { self.get(key).map(|&(d, _)| d) }
fn get_by(&self, key: usize) -> Option<&V> {
let (_, value) = self.get(key)?;
Some(value)
}
fn get_mut_by(&mut self, key: usize) -> Option<&mut V> {
let (_, value) = self.get_mut(key)?;
Some(value)
}
fn get_mut_array_by<'t, U, TransformFn, OnMissing, const M: usize>(
&'t mut self,
keys: [usize; M],
mut transform: TransformFn,
mut on_missing: OnMissing,
) -> [U; M]
where
U: RefToPtr,
TransformFn: FnMut(&'t mut Self::Value) -> U,
OnMissing: FnMut(Self::Key) -> !,
{
unsafe {
split_mut_array(
self,
|slice, index| slice.get_mut(index),
keys,
|_i, (_d, v)| transform(v),
|i| on_missing(keys[i]),
)
}
}
type Iter<'t> = impl Iterator<Item = (usize, D, &'t V)> + 't where Self: 't;
fn iter_mapped(&self) -> Self::Iter<'_> {
self[..].iter().enumerate().map(|(key, (discrim, value))| (key, *discrim, value))
}
type IterMut<'t> = impl Iterator<Item = (D, &'t mut V)> + 't where Self: 't;
fn iter_mapped_mut(&mut self) -> Self::IterMut<'_> {
self[..].iter_mut().map(|(discrim, value)| (*discrim, value))
}
type IntoIter = impl Iterator<Item = (D, V)>;
fn into_iter_mapped(self) -> Self::IntoIter { self.into_iter() }
}
pub struct LinearVecMap<D: Discrim, T> {
vec: Vec<(D, T)>,
}
impl<D: Discrim, T> FromIterator<(D, T)> for LinearVecMap<D, T> {
fn from_iter<I: IntoIterator<Item = (D, T)>>(iter: I) -> Self {
Self { vec: iter.into_iter().collect() }
}
}
impl<D: Discrim, T> Mapped for LinearVecMap<D, T> {
type Discrim = D;
type Key = D;
type Value = T;
fn get_discrim(&self, key: D) -> Option<Self::Discrim> { Some(key) }
fn get_by(&self, key: D) -> Option<&T> {
self.vec[..].iter().find(|&&(d, _)| d == key).map(|(_, s)| s)
}
fn get_mut_by(&mut self, key: D) -> Option<&mut T> {
self.vec[..].iter_mut().find(|&&mut (d, _)| d == key).map(|(_, s)| s)
}
fn get_mut_array_by<'t, U, TransformFn, OnMissing, const M: usize>(
&'t mut self,
keys: [D; M],
mut transform: TransformFn,
mut on_missing: OnMissing,
) -> [U; M]
where
U: RefToPtr,
TransformFn: FnMut(&'t mut Self::Value) -> U,
OnMissing: FnMut(Self::Key) -> !,
{
let indices = keys.map(|key| match self.vec[..].iter_mut().position(|(d, _)| *d == key) {
Some(position) => position,
None => on_missing(key),
});
unsafe {
split_mut_array(
&mut self.vec,
|slice, index| slice.get_mut(index),
indices,
|_i, (_d, t)| transform(t),
|_| unreachable!("result from iter_mut().position()"),
)
}
}
type Iter<'t> = impl Iterator<Item = (D, D, &'t T)> + 't where Self: 't;
fn iter_mapped(&self) -> Self::Iter<'_> {
self.vec[..].iter().map(|&(discrim, ref value)| (discrim, discrim, value))
}
type IterMut<'t> = impl Iterator<Item = (D, &'t mut T)> + 't where Self: 't;
fn iter_mapped_mut(&mut self) -> Self::IterMut<'_> {
self.vec[..].iter_mut().map(|(discrim, value)| (*discrim, value))
}
type IntoIter = impl Iterator<Item = (D, T)>;
fn into_iter_mapped(self) -> Self::IntoIter { self.vec.into_iter() }
}
impl<D: Discrim, T> FullMap for LinearVecMap<D, T> {
type MapRef<U> = LinearVecMap<D, U>;
fn map_ref<U, F>(&self, mut f: F) -> Self::MapRef<U>
where
F: FnMut(&Self::Value) -> U,
{
LinearVecMap { vec: self.vec.iter().map(|&(d, ref t)| (d, f(t))).collect() }
}
fn get_by_or_insert<F: FnOnce() -> T>(
&mut self,
discrim: Self::Discrim,
inserter: F,
) -> &mut T {
for (i, &(d, _)) in self.vec.iter().enumerate() {
if d == discrim {
return &mut self.vec.get_mut(i).expect("i comes from iterator").1;
}
}
self.vec.push((discrim, inserter()));
&mut self.vec.last_mut().expect("vec should be nonempty after push").1
}
fn get_by_or_insert_array<'t, U, Inserter, Transform, const N: usize>(
&'t mut self,
discrims: [Self::Discrim; N],
mut inserter: Inserter,
mut transform: Transform,
) -> [U; N]
where
U: RefToPtr,
Inserter: FnMut(Self::Discrim) -> Self::Value,
Transform: FnMut(Self::Discrim, &'t mut Self::Value) -> U,
{
let indices =
discrims.map(|discrim| match self.vec.iter().position(|&(d, _)| d == discrim) {
Some(index) => index,
None => {
self.vec.push((discrim, inserter(discrim)));
self.vec.len() - 1
}
});
unsafe {
split_mut_array(
&mut self.vec,
|slice, index| slice.get_mut(index),
indices,
|_i, (d, t)| transform(*d, t),
|_| unreachable!("returned by position() or below len()"),
)
}
}
}
#[derive(Clone)]
pub struct SortedVecMap<D: Discrim, T> {
vec: Vec<(D, T)>,
}
impl<D: Discrim, T> FromIterator<(D, T)> for SortedVecMap<D, T> {
fn from_iter<I: IntoIterator<Item = (D, T)>>(iter: I) -> Self {
let mut vec: Vec<_> = iter.into_iter().collect();
vec.sort_by_key(|(d, _)| d.into_usize());
Self { vec }
}
}
impl<D: Discrim, T> Mapped for SortedVecMap<D, T> {
type Discrim = D;
type Key = D;
type Value = T;
fn get_discrim(&self, key: D) -> Option<Self::Discrim> { Some(key) }
fn get_by(&self, key: D) -> Option<&T> {
match self.vec[..].binary_search_by_key(&key.into_usize(), |(di, _)| di.into_usize()) {
Ok(index) => Some(&self.vec.get(index).expect("result of binary_search_by_key").1),
Err(_) => None,
}
}
fn get_mut_by(&mut self, key: D) -> Option<&mut T> {
match self.vec[..].binary_search_by_key(&key.into_usize(), |(di, _)| di.into_usize()) {
Ok(index) => {
Some(&mut self.vec.get_mut(index).expect("result of binary_search_by_key").1)
}
Err(_) => None,
}
}
fn get_mut_array_by<'t, U, TransformFn, OnMissing, const M: usize>(
&'t mut self,
keys: [D; M],
mut transform: TransformFn,
mut on_missing: OnMissing,
) -> [U; M]
where
U: RefToPtr,
TransformFn: FnMut(&'t mut Self::Value) -> U,
OnMissing: FnMut(Self::Key) -> !,
{
let indices = keys.map(|key| {
match self.vec[..].binary_search_by_key(&key.into_usize(), |(d, _)| d.into_usize()) {
Ok(position) => position,
Err(_) => on_missing(key),
}
});
unsafe {
split_mut_array(
&mut self.vec,
|slice, index| slice.get_mut(index),
indices,
|_i, (_d, t)| transform(t),
|_| unreachable!("result from binary_search_by_key"),
)
}
}
type Iter<'t> = impl Iterator<Item = (D, D, &'t T)> + 't where Self: 't;
fn iter_mapped(&self) -> Self::Iter<'_> {
self.vec[..].iter().map(|&(discrim, ref value)| (discrim, discrim, value))
}
type IterMut<'t> = impl Iterator<Item = (D, &'t mut T)> + 't where Self: 't;
fn iter_mapped_mut(&mut self) -> Self::IterMut<'_> {
self.vec[..].iter_mut().map(|(discrim, value)| (*discrim, value))
}
type IntoIter = impl Iterator<Item = (D, T)>;
fn into_iter_mapped(self) -> Self::IntoIter { self.vec.into_iter() }
}
impl<D: Discrim, T> FullMap for SortedVecMap<D, T> {
type MapRef<U> = SortedVecMap<D, U>;
fn map_ref<U, F>(&self, mut f: F) -> Self::MapRef<U>
where
F: FnMut(&Self::Value) -> U,
{
SortedVecMap { vec: self.vec.iter().map(|&(d, ref t)| (d, f(t))).collect() }
}
fn get_by_or_insert<F: FnOnce() -> T>(
&mut self,
discrim: Self::Discrim,
inserter: F,
) -> &mut T {
match self.vec[..].binary_search_by_key(&discrim.into_usize(), |(d, _)| d.into_usize()) {
Ok(index) => &mut self.vec.get_mut(index).expect("result of binary_search_by_key").1,
Err(index) => {
self.vec.insert(index, (discrim, inserter()));
&mut self.vec.get_mut(index).expect("vec.insert(index) called above").1
}
}
}
fn get_by_or_insert_array<'t, U, Inserter, Transform, const N: usize>(
&'t mut self,
discrims: [Self::Discrim; N],
mut inserter: Inserter,
mut transform: Transform,
) -> [U; N]
where
U: RefToPtr,
Inserter: FnMut(Self::Discrim) -> Self::Value,
Transform: FnMut(Self::Discrim, &'t mut Self::Value) -> U,
{
let indices = discrims.map(|discrim| {
match self.vec[..].binary_search_by_key(&discrim.into_usize(), |(d, _)| d.into_usize())
{
Ok(index) => index,
Err(index) => {
self.vec.insert(index, (discrim, inserter(discrim)));
index
}
}
});
unsafe {
split_mut_array(
&mut self.vec,
|slice, index| slice.get_mut(index),
indices,
|_i, (d, t)| transform(*d, t),
|_| unreachable!("returned by binary_search_by_key() or below len()"),
)
}
}
}
#[derive(Clone)]
pub struct BoundedVecMap<D: Discrim, T> {
vec: Vec<Option<T>>,
_ph: PhantomData<D>,
}
impl<D: Discrim, T> FromIterator<(D, T)> for BoundedVecMap<D, T> {
fn from_iter<I: IntoIterator<Item = (D, T)>>(iter: I) -> Self {
let iter = iter.into_iter();
let vec: Vec<Option<T>> = (0..iter.size_hint().0).map(|_| None).collect();
let mut this = Self { vec, _ph: PhantomData };
this.extend(iter);
this
}
}
impl<D: Discrim, T> Extend<(D, T)> for BoundedVecMap<D, T> {
fn extend<I: IntoIterator<Item = (D, T)>>(&mut self, iter: I) {
for (d, s) in iter {
let index = d.into_usize();
let required_len = index + 1;
if self.vec.len() < required_len {
self.vec.resize_with(required_len, || None);
}
let entry = self.vec.get_mut(index).expect("just resized");
*entry = Some(s);
}
}
}
impl<D: Discrim, T> Mapped for BoundedVecMap<D, T> {
type Discrim = D;
type Key = D;
type Value = T;
fn get_discrim(&self, key: D) -> Option<Self::Discrim> { Some(key) }
fn get_by(&self, key: D) -> Option<&T> {
self.vec.get(key.into_usize()).and_then(Option::as_ref)
}
fn get_mut_by(&mut self, key: D) -> Option<&mut T> {
self.vec.get_mut(key.into_usize()).and_then(Option::as_mut)
}
fn get_mut_array_by<'t, U, TransformFn, OnMissing, const M: usize>(
&'t mut self,
keys: [D; M],
mut transform: TransformFn,
mut on_missing: OnMissing,
) -> [U; M]
where
U: RefToPtr,
TransformFn: FnMut(&'t mut Self::Value) -> U,
OnMissing: FnMut(Self::Key) -> !,
{
let indices = keys.map(D::into_usize);
unsafe {
split_mut_array(
&mut self.vec,
|slice, index| match slice.get_mut(index) {
Some(Some(value)) => Some(value),
_ => None,
},
indices,
|_, t| transform(t),
|i| on_missing(keys[i]),
)
}
}
type Iter<'t> = impl Iterator<Item = (D, D, &'t T)> + 't where Self: 't;
fn iter_mapped(&self) -> Self::Iter<'_> {
self.vec[..].iter().enumerate().filter_map(|(discrim, value)| {
Some((D::from_usize(discrim), D::from_usize(discrim), value.as_ref()?))
})
}
type IterMut<'t> = impl Iterator<Item = (D, &'t mut T)> + 't where Self: 't;
fn iter_mapped_mut(&mut self) -> Self::IterMut<'_> {
self.vec[..]
.iter_mut()
.enumerate()
.filter_map(|(discrim, value)| Some((D::from_usize(discrim), value.as_mut()?)))
}
type IntoIter = impl Iterator<Item = (D, T)>;
fn into_iter_mapped(self) -> Self::IntoIter {
self.vec
.into_iter()
.enumerate()
.filter_map(|(discrim, value)| Some((D::from_usize(discrim), value?)))
}
}
impl<D: Discrim, T> FullMap for BoundedVecMap<D, T> {
type MapRef<U> = BoundedVecMap<D, U>;
fn map_ref<U, F>(&self, mut f: F) -> Self::MapRef<U>
where
F: FnMut(&Self::Value) -> U,
{
BoundedVecMap {
vec: self.vec.iter().map(|option| option.as_ref().map(&mut f)).collect(),
_ph: PhantomData,
}
}
fn get_by_or_insert<F: FnOnce() -> T>(
&mut self,
discrim: Self::Discrim,
inserter: F,
) -> &mut Self::Value {
let index = discrim.into_usize();
if self.vec.len() <= index {
self.vec.resize_with(index + 1, || None);
}
let entry = self.vec.get_mut(index).expect("just resized");
entry.get_or_insert_with(inserter)
}
fn get_by_or_insert_array<'t, U, Inserter, Transform, const N: usize>(
&'t mut self,
discrims: [Self::Discrim; N],
mut inserter: Inserter,
mut transform: Transform,
) -> [U; N]
where
U: RefToPtr,
Inserter: FnMut(Self::Discrim) -> Self::Value,
Transform: FnMut(Self::Discrim, &'t mut Self::Value) -> U,
{
let indices = discrims.map(|discrim| {
let index = discrim.into_usize();
if self.vec.len() <= index {
self.vec.resize_with(index + 1, || None);
}
let entry = self.vec.get_mut(index).expect("just resized");
_ = entry.get_or_insert_with(|| inserter(discrim));
index
});
unsafe {
split_mut_array(
&mut self.vec,
|slice, index| slice.get_mut(index).expect("resize_with was called above").as_mut(),
indices,
|i, t| transform(D::from_usize(i), t),
|_| unreachable!("get_or_insert_with was called above"),
)
}
}
}
#[derive(Clone)]
pub struct ArrayMap<D: Discrim, T, const N: usize> {
array: [Option<T>; N],
_ph: PhantomData<D>,
}
impl<D: Discrim, T, const N: usize> FromIterator<(D, T)> for ArrayMap<D, T, N> {
fn from_iter<I: IntoIterator<Item = (D, T)>>(iter: I) -> Self {
let array: [Option<T>; N] = [(); N].map(|()| None);
let mut this = Self { array, _ph: PhantomData };
for (d, s) in iter {
match this.array.get_mut(d.into_usize()) {
Some(Some(_)) => panic!("Duplicate value with discriminant {d:?}"),
Some(option) => *option = Some(s),
None => panic!(
"Discriminants using ArrayMap<N = {N}> must return integers less than {N} in \
into_usize()",
),
}
}
this
}
}
impl<D: Discrim, T, const N: usize> Mapped for ArrayMap<D, T, N> {
type Discrim = D;
type Key = D;
type Value = T;
fn get_discrim(&self, key: D) -> Option<Self::Discrim> { Some(key) }
fn get_by(&self, key: D) -> Option<&T> {
self.array.get(key.into_usize()).and_then(Option::as_ref)
}
fn get_mut_by(&mut self, key: D) -> Option<&mut T> {
self.array.get_mut(key.into_usize()).and_then(Option::as_mut)
}
fn get_mut_array_by<'t, U, TransformFn, OnMissing, const M: usize>(
&'t mut self,
keys: [D; M],
mut transform: TransformFn,
mut on_missing: OnMissing,
) -> [U; M]
where
U: RefToPtr,
TransformFn: FnMut(&'t mut Self::Value) -> U,
OnMissing: FnMut(Self::Key) -> !,
{
let indices = keys.map(D::into_usize);
unsafe {
split_mut_array(
&mut self.array,
|slice, index| match slice.get_mut(index) {
Some(Some(value)) => Some(value),
_ => None,
},
indices,
|_, t| transform(t),
|i| on_missing(keys[i]),
)
}
}
type Iter<'t> = impl Iterator<Item = (D, D, &'t T)> + 't where Self: 't;
fn iter_mapped(&self) -> Self::Iter<'_> {
self.array[..].iter().enumerate().filter_map(|(discrim, value)| {
Some((D::from_usize(discrim), D::from_usize(discrim), value.as_ref()?))
})
}
type IterMut<'t> = impl Iterator<Item = (D, &'t mut T)> + 't where Self: 't;
fn iter_mapped_mut(&mut self) -> Self::IterMut<'_> {
self.array[..]
.iter_mut()
.enumerate()
.filter_map(|(discrim, value)| Some((D::from_usize(discrim), value.as_mut()?)))
}
type IntoIter = impl Iterator<Item = (D, T)>;
fn into_iter_mapped(self) -> Self::IntoIter {
self.array
.into_iter()
.enumerate()
.filter_map(|(discrim, value)| Some((D::from_usize(discrim), value?)))
}
}
impl<D: Discrim, T, const N: usize> FullMap for ArrayMap<D, T, N> {
type MapRef<U> = ArrayMap<D, U, N>;
fn map_ref<U, F>(&self, mut f: F) -> Self::MapRef<U>
where
F: FnMut(&Self::Value) -> U,
{
let mut next_index = 0;
let array = [(); N].map(|()| {
let index = next_index;
next_index += 1;
self.array[index].as_ref().map(&mut f)
});
ArrayMap { array, _ph: PhantomData }
}
fn get_by_or_insert<F: FnOnce() -> T>(
&mut self,
discrim: Self::Discrim,
inserter: F,
) -> &mut T {
match self.array.get_mut(discrim.into_usize()) {
Some(Some(entry)) => entry,
Some(option) => option.insert(inserter()),
None => {
panic!(
"Discriminants using ArrayMap<N = {N}> must return integers less than {N} in \
into_usize()",
)
}
}
}
fn get_by_or_insert_array<'t, U, Inserter, Transform, const M: usize>(
&'t mut self,
discrims: [Self::Discrim; M],
mut inserter: Inserter,
mut transform: Transform,
) -> [U; M]
where
U: RefToPtr,
Inserter: FnMut(Self::Discrim) -> Self::Value,
Transform: FnMut(Self::Discrim, &'t mut Self::Value) -> U,
{
let indices = discrims.map(|discrim| {
let index = discrim.into_usize();
let entry = match self.array.get_mut(index) {
Some(entry) => entry,
None => {
panic!(
"Discriminants using ArrayMap<N = {N}> must return integers less than {N} \
in into_usize()",
)
}
};
_ = entry.get_or_insert_with(|| inserter(discrim));
index
});
unsafe {
split_mut_array(
&mut self.array,
|slice, index| slice.get_mut(index).expect("checked above").as_mut(),
indices,
|i, t| transform(D::from_usize(i), t),
|_| unreachable!("get_or_insert_with was called above"),
)
}
}
}