use crate::Halting;
pub trait RawState {
private! {}
}
pub trait HaltingState
where
Self: RawState + Halting,
{
private! {}
}
pub trait StateExt: HaltingState
where
Self: Clone + Default + PartialEq + PartialOrd + core::fmt::Debug + core::fmt::Display,
{
}
pub trait HashState: RawState
where
Self: Eq + core::hash::Hash,
{
private! {}
}
pub trait NumState: StateExt
where
Self: Copy
+ Default
+ Eq
+ core::ops::Add<Output = Self>
+ core::ops::Div<Output = Self>
+ core::ops::Mul<Output = Self>
+ core::ops::Not<Output = Self>
+ core::ops::Rem<Output = Self>
+ core::ops::Sub<Output = Self>
+ core::ops::AddAssign
+ core::ops::DivAssign
+ core::ops::MulAssign
+ core::ops::RemAssign
+ core::ops::SubAssign
+ num_traits::One
+ num_traits::Zero
+ num_traits::ToPrimitive
+ num_traits::FromPrimitive,
{
private! {}
}
impl RawState for () {
seal! {}
}
impl<T> RawState for &T
where
T: RawState,
{
seal! {}
}
impl<T> RawState for &mut T
where
T: RawState,
{
seal! {}
}
impl<T> HaltingState for T
where
T: RawState + Halting,
{
seal! {}
}
impl<T> HashState for T
where
T: RawState + Eq + core::hash::Hash,
{
seal! {}
}
impl<T> StateExt for T where
T: HaltingState
+ Clone
+ Default
+ PartialEq
+ PartialOrd
+ core::fmt::Debug
+ core::fmt::Display
{
}
impl<T> NumState for T
where
T: StateExt
+ Copy
+ Eq
+ PartialOrd
+ core::ops::Add<Output = Self>
+ core::ops::Sub<Output = Self>
+ core::ops::Mul<Output = Self>
+ core::ops::Div<Output = Self>
+ core::ops::Rem<Output = Self>
+ core::ops::Not<Output = Self>
+ core::ops::AddAssign
+ core::ops::DivAssign
+ core::ops::MulAssign
+ core::ops::RemAssign
+ core::ops::SubAssign
+ num_traits::One
+ num_traits::Zero
+ num_traits::ToPrimitive
+ num_traits::FromPrimitive,
{
seal! {}
}
impl RawState for &str {
seal! {}
}
impl<Q> RawState for [Q]
where
Q: RawState,
{
seal! {}
}
impl<Q> RawState for &[Q]
where
Q: RawState,
{
seal! {}
}
impl<Q> RawState for &mut [Q]
where
Q: RawState,
{
seal! {}
}
impl<const N: usize, Q> RawState for [Q; N]
where
Q: RawState,
{
seal! {}
}
macro_rules! impl_raw_state {
(impl $trait:ident for {$($($cont:ident)::*<$($T:ident),*> $({where $($rest:tt)*})?),* $(,)?}) => {
$(impl_raw_state! { @impl $trait for $($cont)::*<$($T),*> $(where $($rest)*)?})*
};
(impl $trait:ident for {$($T:ty),* $(,)?}) => {
$(impl_raw_state!{ @impl $trait for $T })*
};
(@impl $trait:ident for $($cont:ident)::*<$($T:ident),*> $(where $($rest:tt)*)?) => {
impl<$($T),*> $trait for $($cont)::*<$($T),*> $(where $($rest)*)? {
seal! {}
}
};
(@impl $trait:ident for $t:ty) => {
impl $trait for $t {
seal! {}
}
};
}
impl_raw_state! {
impl RawState for {
usize, u8, u16, u32, u64, u128,
isize, i8, i16, i32, i64, i128,
f32, f64,
bool, char, str
}
}
impl_raw_state! {
impl RawState for {
Option<Q> { where Q: RawState },
Result<Q, E> { where Q: RawState },
core::cell::Cell<Q> { where Q: RawState },
core::cell::RefCell<Q> { where Q: RawState },
core::mem::MaybeUninit<Q> { where Q: RawState },
core::ops::ControlFlow<Q, H> { where Q: RawState, H: RawState },
core::ops::Range<Q> { where Q: RawState },
}
}
#[cfg(feature = "alloc")]
impl_raw_state! {
impl RawState for {
alloc::string::String,
}
}
#[cfg(feature = "alloc")]
impl_raw_state! {
impl RawState for {
alloc::boxed::Box<Q> { where Q: RawState },
alloc::collections::VecDeque<Q> { where Q: RawState },
alloc::vec::Vec<Q> { where Q: RawState },
}
}