use crate::sf;
#[doc = crate::_tags!(code logic)]
#[doc = crate::_doc_location!("num/fin/logic")]
#[rustfmt::skip]
#[diagnostic::on_unimplemented(
message = "Only expressions that evaluate to a constant 0 or 1 are valid for `ConstBool`.",
label = "This expression does not evaluate to a constant 0 or 1 (as usize)."
)]
pub trait ConstBool {
type Value: Sized;
const VALUE: Self::Value;
}
sf! {
impl ConstBool for False { type Value = False; const VALUE: Self::Value = False; }
impl ConstBool for [(); 0] { type Value = False; const VALUE: Self::Value = False; }
impl ConstBool for True { type Value = True; const VALUE: Self::Value = True; }
impl ConstBool for [(); 1] { type Value = True; const VALUE: Self::Value = True; }
}
#[doc = crate::_tags!(code logic)]
#[doc = crate::_doc_location!("num/fin/logic")]
#[macro_export]
#[cfg_attr(cargo_primary_package, doc(hidden))]
macro_rules! const_bool {
($bool:expr) => {{ <[(); { $bool as usize }] as $crate::ConstBool>::VALUE }};
}
#[doc(inline)]
pub use const_bool;
#[doc = crate::_tags!(code logic)]
#[doc = crate::_doc_location!("num/fin/logic")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct True;
#[doc = crate::_tags!(code logic)]
#[doc = crate::_doc_location!("num/fin/logic")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct False;
#[rustfmt::skip]
impl True {
pub const fn not(self) -> False { False }
pub const fn not_ref(&self) -> &'static False { &False }
pub const fn and<T>(self, other: T) -> T { other }
pub const fn and_ref<'a, T>(&self, other: &'a T) -> &'a T { other }
pub fn or<T>(self, _other: T) -> True { True }
pub const fn or_ref<T>(&self, _other: &T) -> &'static True { &True }
pub const fn value(self) -> bool { true }
pub const fn value_ref(&self) -> bool { true }
}
#[rustfmt::skip]
impl False {
pub const fn not(self) -> True { True }
pub const fn not_ref(&self) -> &'static True { &True }
pub fn and<T>(self, _other: T) -> False { False }
pub const fn and_ref<T>(&self, _other: &T) -> &'static False { &False }
pub fn or<T>(self, other: T) -> T { other }
pub const fn or_ref<'a, T>(&self, other: &'a T) -> &'a T { other }
pub const fn value(self) -> bool { false }
pub const fn value_ref(&self) -> bool { false }
}