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 pub struct B0;
20 
21 impl B0 {
22     /// Instantiates a singleton representing this bit.
23     #[inline]
new() -> B024     pub fn new() -> B0 {
25         B0
26     }
27 }
28 
29 /// The type-level bit 1.
30 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
31 pub struct B1;
32 
33 impl B1 {
34     /// Instantiates a singleton representing this bit.
35     #[inline]
new() -> B136     pub fn new() -> B1 {
37         B1
38     }
39 }
40 
41 impl Bit for B0 {
42     const U8: u8 = 0;
43     const BOOL: bool = false;
44 
45     #[inline]
new() -> Self46     fn new() -> Self {
47         Self
48     }
49     #[inline]
to_u8() -> u850     fn to_u8() -> u8 {
51         0
52     }
53     #[inline]
to_bool() -> bool54     fn to_bool() -> bool {
55         false
56     }
57 }
58 
59 impl Bit for B1 {
60     const U8: u8 = 1;
61     const BOOL: bool = true;
62 
63     #[inline]
new() -> Self64     fn new() -> Self {
65         Self
66     }
67     #[inline]
to_u8() -> u868     fn to_u8() -> u8 {
69         1
70     }
71     #[inline]
to_bool() -> bool72     fn to_bool() -> bool {
73         true
74     }
75 }
76 
77 impl Zero for B0 {}
78 impl NonZero for B1 {}
79 impl PowerOfTwo for B1 {}
80 
81 /// Not of 0 (!0 = 1)
82 impl Not for B0 {
83     type Output = B1;
84     #[inline]
not(self) -> Self::Output85     fn not(self) -> Self::Output {
86         B1
87     }
88 }
89 /// Not of 1 (!1 = 0)
90 impl Not for B1 {
91     type Output = B0;
92     #[inline]
not(self) -> Self::Output93     fn not(self) -> Self::Output {
94         B0
95     }
96 }
97 
98 /// And with 0 ( 0 & B = 0)
99 impl<Rhs: Bit> BitAnd<Rhs> for B0 {
100     type Output = B0;
101     #[inline]
bitand(self, _: Rhs) -> Self::Output102     fn bitand(self, _: Rhs) -> Self::Output {
103         B0
104     }
105 }
106 
107 /// And with 1 ( 1 & 0 = 0)
108 impl BitAnd<B0> for B1 {
109     type Output = B0;
110     #[inline]
bitand(self, _: B0) -> Self::Output111     fn bitand(self, _: B0) -> Self::Output {
112         B0
113     }
114 }
115 
116 /// And with 1 ( 1 & 1 = 1)
117 impl BitAnd<B1> for B1 {
118     type Output = B1;
119     #[inline]
bitand(self, _: B1) -> Self::Output120     fn bitand(self, _: B1) -> Self::Output {
121         B1
122     }
123 }
124 
125 /// Or with 0 ( 0 | 0 = 0)
126 impl BitOr<B0> for B0 {
127     type Output = B0;
128     #[inline]
bitor(self, _: B0) -> Self::Output129     fn bitor(self, _: B0) -> Self::Output {
130         B0
131     }
132 }
133 
134 /// Or with 0 ( 0 | 1 = 1)
135 impl BitOr<B1> for B0 {
136     type Output = B1;
137     #[inline]
bitor(self, _: B1) -> Self::Output138     fn bitor(self, _: B1) -> Self::Output {
139         B1
140     }
141 }
142 
143 /// Or with 1 ( 1 | B = 1)
144 impl<Rhs: Bit> BitOr<Rhs> for B1 {
145     type Output = B1;
146     #[inline]
bitor(self, _: Rhs) -> Self::Output147     fn bitor(self, _: Rhs) -> Self::Output {
148         B1
149     }
150 }
151 
152 /// Xor between 0 and 0 ( 0 ^ 0 = 0)
153 impl BitXor<B0> for B0 {
154     type Output = B0;
155     #[inline]
bitxor(self, _: B0) -> Self::Output156     fn bitxor(self, _: B0) -> Self::Output {
157         B0
158     }
159 }
160 /// Xor between 1 and 0 ( 1 ^ 0 = 1)
161 impl BitXor<B0> for B1 {
162     type Output = B1;
163     #[inline]
bitxor(self, _: B0) -> Self::Output164     fn bitxor(self, _: B0) -> Self::Output {
165         B1
166     }
167 }
168 /// Xor between 0 and 1 ( 0 ^ 1 = 1)
169 impl BitXor<B1> for B0 {
170     type Output = B1;
171     #[inline]
bitxor(self, _: B1) -> Self::Output172     fn bitxor(self, _: B1) -> Self::Output {
173         B1
174     }
175 }
176 /// Xor between 1 and 1 ( 1 ^ 1 = 0)
177 impl BitXor<B1> for B1 {
178     type Output = B0;
179     #[inline]
bitxor(self, _: B1) -> Self::Output180     fn bitxor(self, _: B1) -> Self::Output {
181         B0
182     }
183 }
184 
185 #[cfg(tests)]
186 mod tests {
187     // macro for testing operation results. Uses `Same` to ensure the types are equal and
188     // not just the values they evaluate to.
189     macro_rules! test_bit_op {
190         ($op:ident $Lhs:ident = $Answer:ident) => {{
191             type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
192             assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
193         }};
194         ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => {{
195             type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
196             assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
197         }};
198     }
199 
200     #[test]
bit_operations()201     fn bit_operations() {
202         test_bit_op!(Not B0 = B1);
203         test_bit_op!(Not B1 = B0);
204 
205         test_bit_op!(B0 BitAnd B0 = B0);
206         test_bit_op!(B0 BitAnd B1 = B0);
207         test_bit_op!(B1 BitAnd B0 = B0);
208         test_bit_op!(B1 BitAnd B1 = B1);
209 
210         test_bit_op!(B0 BitOr B0 = B0);
211         test_bit_op!(B0 BitOr B1 = B1);
212         test_bit_op!(B1 BitOr B0 = B1);
213         test_bit_op!(B1 BitOr B1 = B1);
214 
215         test_bit_op!(B0 BitXor B0 = B0);
216         test_bit_op!(B0 BitXor B1 = B1);
217         test_bit_op!(B1 BitXor B0 = B1);
218         test_bit_op!(B1 BitXor B1 = B0);
219     }
220 }
221 
222 impl Cmp<B0> for B0 {
223     type Output = Equal;
224 
225     #[inline]
compare<P: InternalMarker>(&self, _: &B0) -> Self::Output226     fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
227         Equal
228     }
229 }
230 
231 impl Cmp<B1> for B0 {
232     type Output = Less;
233 
234     #[inline]
compare<P: InternalMarker>(&self, _: &B1) -> Self::Output235     fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
236         Less
237     }
238 }
239 
240 impl Cmp<B0> for B1 {
241     type Output = Greater;
242 
243     #[inline]
compare<P: InternalMarker>(&self, _: &B0) -> Self::Output244     fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
245         Greater
246     }
247 }
248 
249 impl Cmp<B1> for B1 {
250     type Output = Equal;
251 
252     #[inline]
compare<P: InternalMarker>(&self, _: &B1) -> Self::Output253     fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
254         Equal
255     }
256 }
257 
258 use crate::Min;
259 impl Min<B0> for B0 {
260     type Output = B0;
261     #[inline]
min(self, _: B0) -> B0262     fn min(self, _: B0) -> B0 {
263         self
264     }
265 }
266 impl Min<B1> for B0 {
267     type Output = B0;
268     #[inline]
min(self, _: B1) -> B0269     fn min(self, _: B1) -> B0 {
270         self
271     }
272 }
273 impl Min<B0> for B1 {
274     type Output = B0;
275     #[inline]
min(self, rhs: B0) -> B0276     fn min(self, rhs: B0) -> B0 {
277         rhs
278     }
279 }
280 impl Min<B1> for B1 {
281     type Output = B1;
282     #[inline]
min(self, _: B1) -> B1283     fn min(self, _: B1) -> B1 {
284         self
285     }
286 }
287 
288 use crate::Max;
289 impl Max<B0> for B0 {
290     type Output = B0;
291     #[inline]
max(self, _: B0) -> B0292     fn max(self, _: B0) -> B0 {
293         self
294     }
295 }
296 impl Max<B1> for B0 {
297     type Output = B1;
298     #[inline]
max(self, rhs: B1) -> B1299     fn max(self, rhs: B1) -> B1 {
300         rhs
301     }
302 }
303 impl Max<B0> for B1 {
304     type Output = B1;
305     #[inline]
max(self, _: B0) -> B1306     fn max(self, _: B0) -> B1 {
307         self
308     }
309 }
310 impl Max<B1> for B1 {
311     type Output = B1;
312     #[inline]
max(self, _: B1) -> B1313     fn max(self, _: B1) -> B1 {
314         self
315     }
316 }
317 
318 #[cfg(test)]
319 mod tests {
320     #[test]
bit_creation()321     fn bit_creation() {
322         {
323             use crate::{B0, B1};
324             let _: B0 = B0::new();
325             let _: B1 = B1::new();
326         }
327 
328         {
329             use crate::{Bit, B0, B1};
330 
331             let _: B0 = <B0 as Bit>::new();
332             let _: B1 = <B1 as Bit>::new();
333         }
334     }
335 }
336