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 
13 use core::ops::{BitAnd, BitOr, BitXor, Not};
14 use private::InternalMarker;
15 use {Cmp, Equal, Greater, Less, NonZero, PowerOfTwo};
16 
17 pub use marker_traits::Bit;
18 
19 /// The type-level bit 0.
20 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
21 pub struct B0;
22 
23 impl B0 {
24     /// Instantiates a singleton representing this bit.
25     #[inline]
new() -> B026     pub fn new() -> B0 {
27         B0
28     }
29 }
30 
31 /// The type-level bit 1.
32 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
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]
to_u8() -> u848     fn to_u8() -> u8 {
49         0
50     }
51     #[inline]
to_bool() -> bool52     fn to_bool() -> bool {
53         false
54     }
55 }
56 
57 impl Bit for B1 {
58     const U8: u8 = 1;
59     const BOOL: bool = true;
60 
61     #[inline]
to_u8() -> u862     fn to_u8() -> u8 {
63         1
64     }
65     #[inline]
to_bool() -> bool66     fn to_bool() -> bool {
67         true
68     }
69 }
70 
71 impl NonZero for B1 {}
72 impl PowerOfTwo for B1 {}
73 
74 /// Not of 0 (!0 = 1)
75 impl Not for B0 {
76     type Output = B1;
77     #[inline]
not(self) -> Self::Output78     fn not(self) -> Self::Output {
79         B1
80     }
81 }
82 /// Not of 1 (!1 = 0)
83 impl Not for B1 {
84     type Output = B0;
85     #[inline]
not(self) -> Self::Output86     fn not(self) -> Self::Output {
87         B0
88     }
89 }
90 
91 /// And with 0 ( 0 & B = 0)
92 impl<Rhs: Bit> BitAnd<Rhs> for B0 {
93     type Output = B0;
94     #[inline]
bitand(self, _: Rhs) -> Self::Output95     fn bitand(self, _: Rhs) -> Self::Output {
96         B0
97     }
98 }
99 
100 /// And with 1 ( 1 & 0 = 0)
101 impl BitAnd<B0> for B1 {
102     type Output = B0;
103     #[inline]
bitand(self, _: B0) -> Self::Output104     fn bitand(self, _: B0) -> Self::Output {
105         B0
106     }
107 }
108 
109 /// And with 1 ( 1 & 1 = 1)
110 impl BitAnd<B1> for B1 {
111     type Output = B1;
112     #[inline]
bitand(self, _: B1) -> Self::Output113     fn bitand(self, _: B1) -> Self::Output {
114         B1
115     }
116 }
117 
118 /// Or with 0 ( 0 | 0 = 0)
119 impl BitOr<B0> for B0 {
120     type Output = B0;
121     #[inline]
bitor(self, _: B0) -> Self::Output122     fn bitor(self, _: B0) -> Self::Output {
123         B0
124     }
125 }
126 
127 /// Or with 0 ( 0 | 1 = 1)
128 impl BitOr<B1> for B0 {
129     type Output = B1;
130     #[inline]
bitor(self, _: B1) -> Self::Output131     fn bitor(self, _: B1) -> Self::Output {
132         B1
133     }
134 }
135 
136 /// Or with 1 ( 1 | B = 1)
137 impl<Rhs: Bit> BitOr<Rhs> for B1 {
138     type Output = B1;
139     #[inline]
bitor(self, _: Rhs) -> Self::Output140     fn bitor(self, _: Rhs) -> Self::Output {
141         B1
142     }
143 }
144 
145 /// Xor between 0 and 0 ( 0 ^ 0 = 0)
146 impl BitXor<B0> for B0 {
147     type Output = B0;
148     #[inline]
bitxor(self, _: B0) -> Self::Output149     fn bitxor(self, _: B0) -> Self::Output {
150         B0
151     }
152 }
153 /// Xor between 1 and 0 ( 1 ^ 0 = 1)
154 impl BitXor<B0> for B1 {
155     type Output = B1;
156     #[inline]
bitxor(self, _: B0) -> Self::Output157     fn bitxor(self, _: B0) -> Self::Output {
158         B1
159     }
160 }
161 /// Xor between 0 and 1 ( 0 ^ 1 = 1)
162 impl BitXor<B1> for B0 {
163     type Output = B1;
164     #[inline]
bitxor(self, _: B1) -> Self::Output165     fn bitxor(self, _: B1) -> Self::Output {
166         B1
167     }
168 }
169 /// Xor between 1 and 1 ( 1 ^ 1 = 0)
170 impl BitXor<B1> for B1 {
171     type Output = B0;
172     #[inline]
bitxor(self, _: B1) -> Self::Output173     fn bitxor(self, _: B1) -> Self::Output {
174         B0
175     }
176 }
177 
178 #[cfg(tests)]
179 mod tests {
180     // macro for testing operation results. Uses `Same` to ensure the types are equal and
181     // not just the values they evaluate to.
182     macro_rules! test_bit_op {
183         ($op:ident $Lhs:ident = $Answer:ident) => {{
184             type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
185             assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
186         }};
187         ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => {{
188             type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
189             assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
190         }};
191     }
192 
193     #[test]
bit_operations()194     fn bit_operations() {
195         test_bit_op!(Not B0 = B1);
196         test_bit_op!(Not B1 = B0);
197 
198         test_bit_op!(B0 BitAnd B0 = B0);
199         test_bit_op!(B0 BitAnd B1 = B0);
200         test_bit_op!(B1 BitAnd B0 = B0);
201         test_bit_op!(B1 BitAnd B1 = B1);
202 
203         test_bit_op!(B0 BitOr B0 = B0);
204         test_bit_op!(B0 BitOr B1 = B1);
205         test_bit_op!(B1 BitOr B0 = B1);
206         test_bit_op!(B1 BitOr B1 = B1);
207 
208         test_bit_op!(B0 BitXor B0 = B0);
209         test_bit_op!(B0 BitXor B1 = B1);
210         test_bit_op!(B1 BitXor B0 = B1);
211         test_bit_op!(B1 BitXor B1 = B0);
212     }
213 }
214 
215 impl Cmp<B0> for B0 {
216     type Output = Equal;
217 
218     #[inline]
compare<P: InternalMarker>(&self, _: &B0) -> Self::Output219     fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
220         Equal
221     }
222 }
223 
224 impl Cmp<B1> for B0 {
225     type Output = Less;
226 
227     #[inline]
compare<P: InternalMarker>(&self, _: &B1) -> Self::Output228     fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
229         Less
230     }
231 }
232 
233 impl Cmp<B0> for B1 {
234     type Output = Greater;
235 
236     #[inline]
compare<P: InternalMarker>(&self, _: &B0) -> Self::Output237     fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
238         Greater
239     }
240 }
241 
242 impl Cmp<B1> for B1 {
243     type Output = Equal;
244 
245     #[inline]
compare<P: InternalMarker>(&self, _: &B1) -> Self::Output246     fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
247         Equal
248     }
249 }
250 
251 use Min;
252 impl Min<B0> for B0 {
253     type Output = B0;
254     #[inline]
min(self, _: B0) -> B0255     fn min(self, _: B0) -> B0 {
256         self
257     }
258 }
259 impl Min<B1> for B0 {
260     type Output = B0;
261     #[inline]
min(self, _: B1) -> B0262     fn min(self, _: B1) -> B0 {
263         self
264     }
265 }
266 impl Min<B0> for B1 {
267     type Output = B0;
268     #[inline]
min(self, rhs: B0) -> B0269     fn min(self, rhs: B0) -> B0 {
270         rhs
271     }
272 }
273 impl Min<B1> for B1 {
274     type Output = B1;
275     #[inline]
min(self, _: B1) -> B1276     fn min(self, _: B1) -> B1 {
277         self
278     }
279 }
280 
281 use Max;
282 impl Max<B0> for B0 {
283     type Output = B0;
284     #[inline]
max(self, _: B0) -> B0285     fn max(self, _: B0) -> B0 {
286         self
287     }
288 }
289 impl Max<B1> for B0 {
290     type Output = B1;
291     #[inline]
max(self, rhs: B1) -> B1292     fn max(self, rhs: B1) -> B1 {
293         rhs
294     }
295 }
296 impl Max<B0> for B1 {
297     type Output = B1;
298     #[inline]
max(self, _: B0) -> B1299     fn max(self, _: B0) -> B1 {
300         self
301     }
302 }
303 impl Max<B1> for B1 {
304     type Output = B1;
305     #[inline]
max(self, _: B1) -> B1306     fn max(self, _: B1) -> B1 {
307         self
308     }
309 }
310