use crate::RawState;
use crate::state::{Halt, State};
impl<Q> State<Q> {
pub const fn new(state: Q) -> Self {
Self(state)
}
#[inline]
pub fn init<F>(f: F) -> Self
where
F: FnOnce() -> Q,
{
State(f())
}
pub fn one() -> Self
where
Q: num_traits::One,
{
State::init(Q::one)
}
pub fn zero() -> Self
where
Q: num_traits::Zero,
{
State::init(Q::zero)
}
pub const fn as_ptr(&self) -> *const Q {
core::ptr::addr_of!(self.0)
}
pub const fn as_mut_ptr(&mut self) -> *mut Q {
core::ptr::addr_of_mut!(self.0)
}
pub const fn get(&self) -> &Q {
&self.0
}
pub const fn get_mut(&mut self) -> &mut Q {
&mut self.0
}
#[inline]
pub fn value(self) -> Q {
self.0
}
#[inline]
pub unsafe fn cast<R>(self) -> State<R> {
unsafe { State(core::ptr::read(&self.0 as *const Q as *const R)) }
}
pub fn map<R, F>(self, f: F) -> State<R>
where
F: FnOnce(Q) -> R,
{
State(f(self.value()))
}
pub fn reset(&mut self) -> State<Q>
where
Q: Default,
{
let prev = self.take();
State(prev)
}
#[inline]
pub fn set(&mut self, state: Q) {
self.0 = state;
}
pub const fn replace(&mut self, state: Q) -> Q {
core::mem::replace(self.get_mut(), state)
}
pub const fn swap(&mut self, other: &mut State<Q>) {
core::mem::swap(self.get_mut(), other.get_mut());
}
pub fn take(&mut self) -> Q
where
Q: Default,
{
core::mem::take(self.get_mut())
}
pub fn as_halt(&self) -> State<Halt<&Q>>
where
Q: RawState,
{
State::new(Halt::Halt(self.get()))
}
pub fn into_halt(self) -> State<Halt<Q>>
where
Q: RawState,
{
State::new(Halt::Step(self.value()))
}
pub fn halt(self) -> State<Halt<Q>>
where
Q: RawState,
{
State::new(Halt::Halt(self.value()))
}
pub const fn view(&self) -> State<&Q> {
State(self.get())
}
pub const fn view_mut(&mut self) -> State<&mut Q> {
State(self.get_mut())
}
pub fn get_inner_type_name(&self) -> &'static str {
core::any::type_name::<Q>()
}
pub const fn get_inner_type_id(&self) -> core::any::TypeId
where
Q: 'static,
{
core::any::TypeId::of::<Q>()
}
}
#[cfg(feature = "alloc")]
impl<Q> State<Q> {
pub fn boxed(self) -> State<alloc::boxed::Box<Q>> {
self.map(alloc::boxed::Box::new)
}
pub fn as_any(&self) -> State<alloc::boxed::Box<dyn core::any::Any>>
where
Q: Clone + 'static,
{
State(alloc::boxed::Box::new(self.get().clone()))
}
pub fn into_any(self) -> State<alloc::boxed::Box<dyn core::any::Any>>
where
Q: 'static,
{
State(alloc::boxed::Box::new(self.value()))
}
pub fn shared(self) -> State<alloc::sync::Arc<Q>> {
self.map(alloc::sync::Arc::new)
}
pub fn to_shared(&self) -> State<alloc::sync::Arc<Q>>
where
Q: Clone,
{
self.clone().shared()
}
}
impl<Q> AsRef<Q> for State<Q> {
fn as_ref(&self) -> &Q {
self.get()
}
}
impl<Q> AsMut<Q> for State<Q> {
fn as_mut(&mut self) -> &mut Q {
self.get_mut()
}
}
impl<Q> core::borrow::Borrow<Q> for State<Q> {
fn borrow(&self) -> &Q {
self.get()
}
}
impl<Q> core::borrow::BorrowMut<Q> for State<Q> {
fn borrow_mut(&mut self) -> &mut Q {
self.get_mut()
}
}
impl<Q> core::ops::Deref for State<Q> {
type Target = Q;
fn deref(&self) -> &Self::Target {
self.get()
}
}
impl<Q> core::ops::DerefMut for State<Q> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.get_mut()
}
}
impl<Q> From<Q> for State<Q> {
fn from(state: Q) -> Self {
State(state)
}
}
impl<Q: PartialEq> PartialEq<Q> for State<Q> {
fn eq(&self, other: &Q) -> bool {
self.0.eq(other)
}
}
impl<'a, Q: PartialEq> PartialEq<&'a Q> for State<Q> {
fn eq(&self, other: &&'a Q) -> bool {
self.0.eq(*other)
}
}
impl<'a, Q: PartialEq> PartialEq<&'a mut Q> for State<Q> {
fn eq(&self, other: &&'a mut Q) -> bool {
self.0.eq(*other)
}
}
impl<Q: PartialOrd> PartialOrd<Q> for State<Q> {
fn partial_cmp(&self, other: &Q) -> Option<core::cmp::Ordering> {
self.0.partial_cmp(other)
}
}
impl<'a, Q: PartialOrd> PartialOrd<&'a Q> for State<Q> {
fn partial_cmp(&self, other: &&'a Q) -> Option<core::cmp::Ordering> {
self.0.partial_cmp(*other)
}
}
impl<'a, Q: PartialOrd> PartialOrd<&'a mut Q> for State<Q> {
fn partial_cmp(&self, other: &&'a mut Q) -> Option<core::cmp::Ordering> {
self.0.partial_cmp(*other)
}
}
unsafe impl<Q: Send> Send for State<Q> {}
unsafe impl<Q: Sync> Sync for State<Q> {}