pub use exhaustive_map_macros::Finite;
use generic_array::{ArrayLength, typenum::Unsigned};
pub trait Finite: Sized {
type INHABITANTS: ArrayLength + FitsInUsize;
#[must_use]
fn to_usize(&self) -> usize;
#[must_use]
fn from_usize(i: usize) -> Option<Self>;
}
pub trait FitsInUsize: sealed::Sealed {}
impl<T: sealed::Sealed> FitsInUsize for T {}
mod sealed {
use crate::typenum::{B1, IsLessOrEqual, Pow, Sub1, U, U256, Unsigned};
type UsizeMax = Sub1<<U256 as Pow<U<{ size_of::<usize>() }>>>::Output>;
pub trait Sealed {}
impl<U: Unsigned> Sealed for U where U: IsLessOrEqual<UsizeMax, Output = B1> {}
}
pub trait FiniteExt: Finite {
fn iter_all() -> IterAll<Self> {
IterAll((0..Self::INHABITANTS::USIZE).map(|i| {
Self::from_usize(i).expect("unexpected None returned from Finite::from_usize in range")
}))
}
}
impl<T: Finite> FiniteExt for T {}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct IterAll<T>(core::iter::Map<core::ops::Range<usize>, fn(usize) -> T>);
impl<T> Iterator for IterAll<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.0.len(), Some(self.0.len()))
}
}
impl<T> ExactSizeIterator for IterAll<T> {
fn len(&self) -> usize {
self.0.len()
}
}
impl<T> DoubleEndedIterator for IterAll<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back()
}
}