devela/num/logic/
bool.rs
1use crate::sf;
28
29#[rustfmt::skip]
33#[diagnostic::on_unimplemented(
34 message = "Only expressions that evaluate to a constant 0 or 1 are valid for `ConstBool`.",
35 label = "This expression does not evaluate to a constant 0 or 1 (as usize)."
36)]
37pub trait ConstBool {
38 type Value: Sized;
40 const VALUE: Self::Value;
42
43 }
47sf! {
48 impl ConstBool for False { type Value = False; const VALUE: Self::Value = False; }
49 impl ConstBool for [(); 0] { type Value = False; const VALUE: Self::Value = False; }
50 impl ConstBool for True { type Value = True; const VALUE: Self::Value = True; }
51 impl ConstBool for [(); 1] { type Value = True; const VALUE: Self::Value = True; }
52}
53
54#[rustfmt::skip]
58#[diagnostic::on_unimplemented(
59 message = "Only expressions that evaluate to a constant 0 or 1 are valid for `ConstBool`.",
60 label = "This expression does not evaluate to a constant 0 or 1 (as usize)."
61)]
62pub trait ConstTrool {
63 type Value: Sized;
65 const VALUE: Self::Value;
67
68 }
72sf! {
73 impl ConstTrool for False { type Value = False; const VALUE: False = False; }
74 impl ConstTrool for [(); 0] { type Value = False; const VALUE: False = False; }
75 impl ConstTrool for True { type Value = True; const VALUE: True = True; }
76 impl ConstTrool for [(); 1] { type Value = True; const VALUE: True = True; }
77 impl ConstTrool for Maybe { type Value = Maybe; const VALUE: Maybe = Maybe; }
78 impl ConstTrool for [(); 2] { type Value = Maybe; const VALUE: Maybe = Maybe; }
79}
80
81pub trait ConstLogic<const N: usize> {
84 type Value: Sized;
86 const VALUE: Self::Value;
88}
89sf! {
90 impl ConstLogic<2> for False { type Value = False; const VALUE: False = False; }
91 impl ConstLogic<3> for False { type Value = False; const VALUE: False = False; }
92 impl ConstLogic<2> for True { type Value = True; const VALUE: True = True; }
93 impl ConstLogic<3> for True { type Value = True; const VALUE: True = True; }
94 impl ConstLogic<3> for Maybe { type Value = Maybe; const VALUE: Maybe = Maybe; }
95}
96#[macro_export]
98#[cfg_attr(cargo_primary_package, doc(hidden))]
99macro_rules! const_logic {
100 (bool: $bool:expr) => {{
101 <[(); { $bool as usize }] as $crate::ConstBool>::VALUE
102 }};
103 }
106#[doc(inline)]
107pub use const_logic;
108
109
110#[macro_export]
126#[cfg_attr(cargo_primary_package, doc(hidden))]
127macro_rules! const_bool {
128 ($bool:expr) => {{
129 <[(); { $bool as usize }] as $crate::ConstBool>::VALUE
130 }};
131}
132#[doc(inline)]
133pub use const_bool;
134
135#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
141pub struct True;
142
143#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
149pub struct False;
150
151#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
158pub struct Maybe;
159
160
161#[rustfmt::skip]
163impl False {
164 pub const fn not(self) -> True { True }
166 pub const fn not_ref(&self) -> &'static True { &True }
168
169 pub fn and<T>(self, _other: T) -> False { False }
171 pub const fn and_ref<T>(&self, _other: &T) -> &'static False { &False }
173
174 pub fn or<T>(self, other: T) -> T { other }
176 pub const fn or_ref<'a, T>(&self, other: &'a T) -> &'a T { other }
178
179 pub const fn value(self) -> bool { false }
181 pub const fn value_ref(&self) -> bool { false }
183}
184#[rustfmt::skip]
186impl True {
187 pub const fn not(self) -> False { False }
189 pub const fn not_ref(&self) -> &'static False { &False }
191
192 pub const fn and<T>(self, other: T) -> T { other }
194 pub const fn and_ref<'a, T>(&self, other: &'a T) -> &'a T { other }
196
197 pub fn or<T>(self, _other: T) -> True { True }
199 pub const fn or_ref<T>(&self, _other: &T) -> &'static True { &True }
201
202 pub const fn value(self) -> bool { true }
204 pub const fn value_ref(&self) -> bool { true }
206}
207
208impl False {
214}
215impl True {
217}