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 {Cmp, Equal, Greater, Less, NonZero, PowerOfTwo};
15 
16 pub use marker_traits::Bit;
17 
18 /// The type-level bit 0.
19 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
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 pub struct B1;
33 
34 impl B1 {
35     /// Instantiates a singleton representing this bit.
36     #[inline]
new() -> B137     pub fn new() -> B1 {
38         B1
39     }
40 }
41 
42 impl Bit for B0 {
43     const U8: u8 = 0;
44     const BOOL: bool = false;
45 
46     #[inline]
to_u8() -> u847     fn to_u8() -> u8 {
48         0
49     }
50     #[inline]
to_bool() -> bool51     fn to_bool() -> bool {
52         false
53     }
54 }
55 
56 impl Bit for B1 {
57     const U8: u8 = 1;
58     const BOOL: bool = true;
59 
60     #[inline]
to_u8() -> u861     fn to_u8() -> u8 {
62         1
63     }
64     #[inline]
to_bool() -> bool65     fn to_bool() -> bool {
66         true
67     }
68 }
69 
70 impl NonZero for B1 {}
71 impl PowerOfTwo for B1 {}
72 
73 /// Not of 0 (!0 = 1)
74 impl Not for B0 {
75     type Output = B1;
not(self) -> Self::Output76     fn not(self) -> Self::Output {
77         B1
78     }
79 }
80 /// Not of 1 (!1 = 0)
81 impl Not for B1 {
82     type Output = B0;
not(self) -> Self::Output83     fn not(self) -> Self::Output {
84         B0
85     }
86 }
87 
88 /// And with 0 ( 0 & B = 0)
89 impl<Rhs: Bit> BitAnd<Rhs> for B0 {
90     type Output = B0;
bitand(self, _: Rhs) -> Self::Output91     fn bitand(self, _: Rhs) -> Self::Output {
92         B0
93     }
94 }
95 
96 /// And with 1 ( 1 & 0 = 0)
97 impl BitAnd<B0> for B1 {
98     type Output = B0;
bitand(self, _: B0) -> Self::Output99     fn bitand(self, _: B0) -> Self::Output {
100         B0
101     }
102 }
103 
104 /// And with 1 ( 1 & 1 = 1)
105 impl BitAnd<B1> for B1 {
106     type Output = B1;
bitand(self, _: B1) -> Self::Output107     fn bitand(self, _: B1) -> Self::Output {
108         B1
109     }
110 }
111 
112 /// Or with 0 ( 0 | 0 = 0)
113 impl BitOr<B0> for B0 {
114     type Output = B0;
bitor(self, _: B0) -> Self::Output115     fn bitor(self, _: B0) -> Self::Output {
116         B0
117     }
118 }
119 
120 /// Or with 0 ( 0 | 1 = 1)
121 impl BitOr<B1> for B0 {
122     type Output = B1;
bitor(self, _: B1) -> Self::Output123     fn bitor(self, _: B1) -> Self::Output {
124         B1
125     }
126 }
127 
128 /// Or with 1 ( 1 | B = 1)
129 impl<Rhs: Bit> BitOr<Rhs> for B1 {
130     type Output = B1;
bitor(self, _: Rhs) -> Self::Output131     fn bitor(self, _: Rhs) -> Self::Output {
132         B1
133     }
134 }
135 
136 /// Xor between 0 and 0 ( 0 ^ 0 = 0)
137 impl BitXor<B0> for B0 {
138     type Output = B0;
bitxor(self, _: B0) -> Self::Output139     fn bitxor(self, _: B0) -> Self::Output {
140         B0
141     }
142 }
143 /// Xor between 1 and 0 ( 1 ^ 0 = 1)
144 impl BitXor<B0> for B1 {
145     type Output = B1;
bitxor(self, _: B0) -> Self::Output146     fn bitxor(self, _: B0) -> Self::Output {
147         B1
148     }
149 }
150 /// Xor between 0 and 1 ( 0 ^ 1 = 1)
151 impl BitXor<B1> for B0 {
152     type Output = B1;
bitxor(self, _: B1) -> Self::Output153     fn bitxor(self, _: B1) -> Self::Output {
154         B1
155     }
156 }
157 /// Xor between 1 and 1 ( 1 ^ 1 = 0)
158 impl BitXor<B1> for B1 {
159     type Output = B0;
bitxor(self, _: B1) -> Self::Output160     fn bitxor(self, _: B1) -> Self::Output {
161         B0
162     }
163 }
164 
165 #[cfg(tests)]
166 mod tests {
167     // macro for testing operation results. Uses `Same` to ensure the types are equal and
168     // not just the values they evaluate to.
169     macro_rules! test_bit_op {
170         ($op:ident $Lhs:ident = $Answer:ident) => {{
171             type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
172             assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
173         }};
174         ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => {{
175             type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
176             assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
177         }};
178     }
179 
180     #[test]
bit_operations()181     fn bit_operations() {
182         test_bit_op!(Not B0 = B1);
183         test_bit_op!(Not B1 = B0);
184 
185         test_bit_op!(B0 BitAnd B0 = B0);
186         test_bit_op!(B0 BitAnd B1 = B0);
187         test_bit_op!(B1 BitAnd B0 = B0);
188         test_bit_op!(B1 BitAnd B1 = B1);
189 
190         test_bit_op!(B0 BitOr B0 = B0);
191         test_bit_op!(B0 BitOr B1 = B1);
192         test_bit_op!(B1 BitOr B0 = B1);
193         test_bit_op!(B1 BitOr B1 = B1);
194 
195         test_bit_op!(B0 BitXor B0 = B0);
196         test_bit_op!(B0 BitXor B1 = B1);
197         test_bit_op!(B1 BitXor B0 = B1);
198         test_bit_op!(B1 BitXor B1 = B0);
199     }
200 }
201 
202 impl Cmp<B0> for B0 {
203     type Output = Equal;
204 }
205 
206 impl Cmp<B1> for B0 {
207     type Output = Less;
208 }
209 
210 impl Cmp<B0> for B1 {
211     type Output = Greater;
212 }
213 
214 impl Cmp<B1> for B1 {
215     type Output = Equal;
216 }
217 
218 use Min;
219 impl Min<B0> for B0 {
220     type Output = B0;
min(self, _: B0) -> B0221     fn min(self, _: B0) -> B0 {
222         self
223     }
224 }
225 impl Min<B1> for B0 {
226     type Output = B0;
min(self, _: B1) -> B0227     fn min(self, _: B1) -> B0 {
228         self
229     }
230 }
231 impl Min<B0> for B1 {
232     type Output = B0;
min(self, rhs: B0) -> B0233     fn min(self, rhs: B0) -> B0 {
234         rhs
235     }
236 }
237 impl Min<B1> for B1 {
238     type Output = B1;
min(self, _: B1) -> B1239     fn min(self, _: B1) -> B1 {
240         self
241     }
242 }
243 
244 use Max;
245 impl Max<B0> for B0 {
246     type Output = B0;
max(self, _: B0) -> B0247     fn max(self, _: B0) -> B0 {
248         self
249     }
250 }
251 impl Max<B1> for B0 {
252     type Output = B1;
max(self, rhs: B1) -> B1253     fn max(self, rhs: B1) -> B1 {
254         rhs
255     }
256 }
257 impl Max<B0> for B1 {
258     type Output = B1;
max(self, _: B0) -> B1259     fn max(self, _: B0) -> B1 {
260         self
261     }
262 }
263 impl Max<B1> for B1 {
264     type Output = B1;
max(self, _: B1) -> B1265     fn max(self, _: B1) -> B1 {
266         self
267     }
268 }
269