mod checked;
mod ext;
mod unchecked;
mod volume;
use std::borrow::Borrow;
use std::{
ops::{Deref, DerefMut},
fmt::Debug, hash::Hash,
};
use apple_quant_core::{AddUnchecked, SubUnchecked};
pub use checked::*;
pub use ext::*;
pub use unchecked::*;
pub use volume::*;
#[cfg(debug_assertions)]
pub type ZeroableType<T> = ZeroableChecked<T>;
#[cfg(not(debug_assertions))]
pub type ZeroableType<T> = ZeroableUnchecked<T>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Zeroable<T: ZeroableVolume>(ZeroableType<T>);
impl<T: ZeroableVolume> Zeroable<T> {
pub const ZERO: Self = Self(ZeroableType::ZERO);
pub fn from_optional(
t: Option<T>,
) -> Self {
#[cfg(not(debug_assertions))]
let t = t.unwrap_or(T::ZERO);
#[cfg(debug_assertions)]
let t = if let Some(
t,
) = t && t.is_zero() {
None
} else {
t
};
Self(ZeroableType::new(t))
}
pub fn from_zeroable(
t: T,
) -> Self {
#[cfg(debug_assertions)]
let t = if t.is_zero() {
None
} else {
Some(t)
};
Self(ZeroableType::new(t))
}
pub fn is_zero(
&self,
) -> bool {
self.0.as_optional_nonzero_ref().is_none()
}
}
impl<T: ZeroableVolume> ZeroableExt<T> for Zeroable<T> {
fn as_optional_nonzero_ref(
&self,
) -> Option<&T> {
self.0.as_optional_nonzero_ref()
}
fn as_optional_nonzero_mut(
&mut self,
) -> Option<&mut T> {
self.0.as_optional_nonzero_mut()
}
fn into_optional_nonzero(
self,
) -> Option<T> {
self.0.into_optional_nonzero()
}
fn as_zeroable(
&self,
) -> T {
self.0.as_zeroable()
}
fn into_zeroable(
self,
) -> T {
self.0.into_zeroable()
}
fn as_nonzero_unchecked_ref(
&self,
) -> &T {
self.0.as_nonzero_unchecked_ref()
}
fn as_nonzero_unchecked_mut(
&mut self,
) -> &mut T {
self.0.as_nonzero_unchecked_mut()
}
fn into_nonzero_unchecked(
self,
) -> T {
self.0.into_nonzero_unchecked()
}
}
impl<T: ZeroableVolume> Deref for Zeroable<T> {
type Target = ZeroableType<T>;
fn deref(
&self,
) -> &Self::Target {
&self.0
}
}
impl<T: ZeroableVolume> DerefMut for Zeroable<T> {
fn deref_mut(
&mut self,
) -> &mut Self::Target {
&mut self.0
}
}
impl<T: ZeroableVolume> From<Zeroable<T>> for Result<Zeroable<T>, ()> {
fn from(
value: Zeroable<T>,
) -> Self {
Ok(value)
}
}
impl<T: ZeroableVolume> AddUnchecked<Zeroable<T>, Zeroable<T>> for Zeroable<T> {
fn add_unchecked(
self,
rhs: impl Borrow<Zeroable<T>>,
) -> Zeroable<T> {
let lhs = self.as_zeroable();
let rhs = rhs.borrow().as_zeroable();
Zeroable::from_zeroable(lhs.add_unchecked(rhs))
}
}
impl<T: ZeroableVolume> AddUnchecked<Zeroable<T>, Zeroable<T>> for &Zeroable<T> {
fn add_unchecked(
self,
rhs: impl Borrow<Zeroable<T>>,
) -> Zeroable<T> {
(*self).add_unchecked(rhs)
}
}
impl<T: ZeroableVolume> SubUnchecked<Zeroable<T>, Zeroable<T>> for Zeroable<T> {
fn sub_unchecked(
self,
rhs: impl Borrow<Zeroable<T>>,
) -> Zeroable<T> {
let lhs = self.as_zeroable();
let rhs = rhs.borrow().as_zeroable();
Zeroable::from_zeroable(lhs.sub_unchecked(rhs))
}
}
impl<T: ZeroableVolume> SubUnchecked<Zeroable<T>, Zeroable<T>> for &Zeroable<T> {
fn sub_unchecked(
self,
rhs: impl Borrow<Zeroable<T>>,
) -> Zeroable<T> {
(*self).sub_unchecked(rhs)
}
}