1 //! Type-level bits.
2 //!
3 //! These are rather simple and are used as the building blocks of the
4 //! other number types in this crate.
5 //!
6 //!
7 //! **Type operators** implemented:
8 //!
9 //! - From `core::ops`: `BitAnd`, `BitOr`, `BitXor`, and `Not`.
10 //! - From `typenum`: `Same` and `Cmp`.
11 
12 use crate::{private::InternalMarker, Cmp, Equal, Greater, Less, NonZero, PowerOfTwo, Zero};
13 use core::ops::{BitAnd, BitOr, BitXor, Not};
14 
15 pub use crate::marker_traits::Bit;
16 
17 /// The type-level bit 0.
18 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
19 #[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
20 pub struct B0;
21 
22 impl B0 {
23     /// Instantiates a singleton representing this bit.
24     #[inline]
new() -> B025     pub fn new() -> B0 {
26         B0
27     }
28 }
29 
30 /// The type-level bit 1.
31 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
32 #[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
33 pub struct B1;
34 
35 impl B1 {
36     /// Instantiates a singleton representing this bit.
37     #[inline]
new() -> B138     pub fn new() -> B1 {
39         B1
40     }
41 }
42 
43 impl Bit for B0 {
44     const U8: u8 = 0;
45     const BOOL: bool = false;
46 
47     #[inline]
new() -> Self48     fn new() -> Self {
49         Self
50     }
51     #[inline]
to_u8() -> u852     fn to_u8() -> u8 {
53         0
54     }
55     #[inline]
to_bool() -> bool56     fn to_bool() -> bool {
57         false
58     }
59 }
60 
61 impl Bit for B1 {
62     const U8: u8 = 1;
63     const BOOL: bool = true;
64 
65     #[inline]
new() -> Self66     fn new() -> Self {
67         Self
68     }
69     #[inline]
to_u8() -> u870     fn to_u8() -> u8 {
71         1
72     }
73     #[inline]
to_bool() -> bool74     fn to_bool() -> bool {
75         true
76     }
77 }
78 
79 impl Zero for B0 {}
80 impl NonZero for B1 {}
81 impl PowerOfTwo for B1 {}
82 
83 /// Not of 0 (!0 = 1)
84 impl Not for B0 {
85     type Output = B1;
86     #[inline]
not(self) -> Self::Output87     fn not(self) -> Self::Output {
88         B1
89     }
90 }
91 /// Not of 1 (!1 = 0)
92 impl Not for B1 {
93     type Output = B0;
94     #[inline]
not(self) -> Self::Output95     fn not(self) -> Self::Output {
96         B0
97     }
98 }
99 
100 /// And with 0 ( 0 & B = 0)
101 impl<Rhs: Bit> BitAnd<Rhs> for B0 {
102     type Output = B0;
103     #[inline]
bitand(self, _: Rhs) -> Self::Output104     fn bitand(self, _: Rhs) -> Self::Output {
105         B0
106     }
107 }
108 
109 /// And with 1 ( 1 & 0 = 0)
110 impl BitAnd<B0> for B1 {
111     type Output = B0;
112     #[inline]
bitand(self, _: B0) -> Self::Output113     fn bitand(self, _: B0) -> Self::Output {
114         B0
115     }
116 }
117 
118 /// And with 1 ( 1 & 1 = 1)
119 impl BitAnd<B1> for B1 {
120     type Output = B1;
121     #[inline]
bitand(self, _: B1) -> Self::Output122     fn bitand(self, _: B1) -> Self::Output {
123         B1
124     }
125 }
126 
127 /// Or with 0 ( 0 | 0 = 0)
128 impl BitOr<B0> for B0 {
129     type Output = B0;
130     #[inline]
bitor(self, _: B0) -> Self::Output131     fn bitor(self, _: B0) -> Self::Output {
132         B0
133     }
134 }
135 
136 /// Or with 0 ( 0 | 1 = 1)
137 impl BitOr<B1> for B0 {
138     type Output = B1;
139     #[inline]
bitor(self, _: B1) -> Self::Output140     fn bitor(self, _: B1) -> Self::Output {
141         B1
142     }
143 }
144 
145 /// Or with 1 ( 1 | B = 1)
146 impl<Rhs: Bit> BitOr<Rhs> for B1 {
147     type Output = B1;
148     #[inline]
bitor(self, _: Rhs) -> Self::Output149     fn bitor(self, _: Rhs) -> Self::Output {
150         B1
151     }
152 }
153 
154 /// Xor between 0 and 0 ( 0 ^ 0 = 0)
155 impl BitXor<B0> for B0 {
156     type Output = B0;
157     #[inline]
bitxor(self, _: B0) -> Self::Output158     fn bitxor(self, _: B0) -> Self::Output {
159         B0
160     }
161 }
162 /// Xor between 1 and 0 ( 1 ^ 0 = 1)
163 impl BitXor<B0> for B1 {
164     type Output = B1;
165     #[inline]
bitxor(self, _: B0) -> Self::Output166     fn bitxor(self, _: B0) -> Self::Output {
167         B1
168     }
169 }
170 /// Xor between 0 and 1 ( 0 ^ 1 = 1)
171 impl BitXor<B1> for B0 {
172     type Output = B1;
173     #[inline]
bitxor(self, _: B1) -> Self::Output174     fn bitxor(self, _: B1) -> Self::Output {
175         B1
176     }
177 }
178 /// Xor between 1 and 1 ( 1 ^ 1 = 0)
179 impl BitXor<B1> for B1 {
180     type Output = B0;
181     #[inline]
bitxor(self, _: B1) -> Self::Output182     fn bitxor(self, _: B1) -> Self::Output {
183         B0
184     }
185 }
186 
187 #[cfg(tests)]
188 mod tests {
189     // macro for testing operation results. Uses `Same` to ensure the types are equal and
190     // not just the values they evaluate to.
191     macro_rules! test_bit_op {
192         ($op:ident $Lhs:ident = $Answer:ident) => {{
193             type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
194             assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
195         }};
196         ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => {{
197             type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
198             assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
199         }};
200     }
201 
202     #[test]
bit_operations()203     fn bit_operations() {
204         test_bit_op!(Not B0 = B1);
205         test_bit_op!(Not B1 = B0);
206 
207         test_bit_op!(B0 BitAnd B0 = B0);
208         test_bit_op!(B0 BitAnd B1 = B0);
209         test_bit_op!(B1 BitAnd B0 = B0);
210         test_bit_op!(B1 BitAnd B1 = B1);
211 
212         test_bit_op!(B0 BitOr B0 = B0);
213         test_bit_op!(B0 BitOr B1 = B1);
214         test_bit_op!(B1 BitOr B0 = B1);
215         test_bit_op!(B1 BitOr B1 = B1);
216 
217         test_bit_op!(B0 BitXor B0 = B0);
218         test_bit_op!(B0 BitXor B1 = B1);
219         test_bit_op!(B1 BitXor B0 = B1);
220         test_bit_op!(B1 BitXor B1 = B0);
221     }
222 }
223 
224 impl Cmp<B0> for B0 {
225     type Output = Equal;
226 
227     #[inline]
compare<P: InternalMarker>(&self, _: &B0) -> Self::Output228     fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
229         Equal
230     }
231 }
232 
233 impl Cmp<B1> for B0 {
234     type Output = Less;
235 
236     #[inline]
compare<P: InternalMarker>(&self, _: &B1) -> Self::Output237     fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
238         Less
239     }
240 }
241 
242 impl Cmp<B0> for B1 {
243     type Output = Greater;
244 
245     #[inline]
compare<P: InternalMarker>(&self, _: &B0) -> Self::Output246     fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
247         Greater
248     }
249 }
250 
251 impl Cmp<B1> for B1 {
252     type Output = Equal;
253 
254     #[inline]
compare<P: InternalMarker>(&self, _: &B1) -> Self::Output255     fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
256         Equal
257     }
258 }
259 
260 use crate::Min;
261 impl Min<B0> for B0 {
262     type Output = B0;
263     #[inline]
min(self, _: B0) -> B0264     fn min(self, _: B0) -> B0 {
265         self
266     }
267 }
268 impl Min<B1> for B0 {
269     type Output = B0;
270     #[inline]
min(self, _: B1) -> B0271     fn min(self, _: B1) -> B0 {
272         self
273     }
274 }
275 impl Min<B0> for B1 {
276     type Output = B0;
277     #[inline]
min(self, rhs: B0) -> B0278     fn min(self, rhs: B0) -> B0 {
279         rhs
280     }
281 }
282 impl Min<B1> for B1 {
283     type Output = B1;
284     #[inline]
min(self, _: B1) -> B1285     fn min(self, _: B1) -> B1 {
286         self
287     }
288 }
289 
290 use crate::Max;
291 impl Max<B0> for B0 {
292     type Output = B0;
293     #[inline]
max(self, _: B0) -> B0294     fn max(self, _: B0) -> B0 {
295         self
296     }
297 }
298 impl Max<B1> for B0 {
299     type Output = B1;
300     #[inline]
max(self, rhs: B1) -> B1301     fn max(self, rhs: B1) -> B1 {
302         rhs
303     }
304 }
305 impl Max<B0> for B1 {
306     type Output = B1;
307     #[inline]
max(self, _: B0) -> B1308     fn max(self, _: B0) -> B1 {
309         self
310     }
311 }
312 impl Max<B1> for B1 {
313     type Output = B1;
314     #[inline]
max(self, _: B1) -> B1315     fn max(self, _: B1) -> B1 {
316         self
317     }
318 }
319 
320 #[cfg(test)]
321 mod tests {
322     #[test]
bit_creation()323     fn bit_creation() {
324         {
325             use crate::{B0, B1};
326             let _: B0 = B0::new();
327             let _: B1 = B1::new();
328         }
329 
330         {
331             use crate::{Bit, B0, B1};
332 
333             let _: B0 = <B0 as Bit>::new();
334             let _: B1 = <B1 as Bit>::new();
335         }
336     }
337 }
338