typenum/
bit.rs

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
12use crate::{private::InternalMarker, Cmp, Equal, Greater, Less, NonZero, PowerOfTwo, Zero};
13use core::ops::{BitAnd, BitOr, BitXor, Not};
14
15pub use crate::marker_traits::Bit;
16
17/// The type-level bit 0.
18#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
19pub struct B0;
20
21impl B0 {
22    /// Instantiates a singleton representing this bit.
23    #[inline]
24    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)]
31pub struct B1;
32
33impl B1 {
34    /// Instantiates a singleton representing this bit.
35    #[inline]
36    pub fn new() -> B1 {
37        B1
38    }
39}
40
41impl Bit for B0 {
42    const U8: u8 = 0;
43    const BOOL: bool = false;
44
45    #[inline]
46    fn new() -> Self {
47        Self
48    }
49    #[inline]
50    fn to_u8() -> u8 {
51        0
52    }
53    #[inline]
54    fn to_bool() -> bool {
55        false
56    }
57}
58
59impl Bit for B1 {
60    const U8: u8 = 1;
61    const BOOL: bool = true;
62
63    #[inline]
64    fn new() -> Self {
65        Self
66    }
67    #[inline]
68    fn to_u8() -> u8 {
69        1
70    }
71    #[inline]
72    fn to_bool() -> bool {
73        true
74    }
75}
76
77impl Zero for B0 {}
78impl NonZero for B1 {}
79impl PowerOfTwo for B1 {}
80
81/// Not of 0 (!0 = 1)
82impl Not for B0 {
83    type Output = B1;
84    #[inline]
85    fn not(self) -> Self::Output {
86        B1
87    }
88}
89/// Not of 1 (!1 = 0)
90impl Not for B1 {
91    type Output = B0;
92    #[inline]
93    fn not(self) -> Self::Output {
94        B0
95    }
96}
97
98/// And with 0 ( 0 & B = 0)
99impl<Rhs: Bit> BitAnd<Rhs> for B0 {
100    type Output = B0;
101    #[inline]
102    fn bitand(self, _: Rhs) -> Self::Output {
103        B0
104    }
105}
106
107/// And with 1 ( 1 & 0 = 0)
108impl BitAnd<B0> for B1 {
109    type Output = B0;
110    #[inline]
111    fn bitand(self, _: B0) -> Self::Output {
112        B0
113    }
114}
115
116/// And with 1 ( 1 & 1 = 1)
117impl BitAnd<B1> for B1 {
118    type Output = B1;
119    #[inline]
120    fn bitand(self, _: B1) -> Self::Output {
121        B1
122    }
123}
124
125/// Or with 0 ( 0 | 0 = 0)
126impl BitOr<B0> for B0 {
127    type Output = B0;
128    #[inline]
129    fn bitor(self, _: B0) -> Self::Output {
130        B0
131    }
132}
133
134/// Or with 0 ( 0 | 1 = 1)
135impl BitOr<B1> for B0 {
136    type Output = B1;
137    #[inline]
138    fn bitor(self, _: B1) -> Self::Output {
139        B1
140    }
141}
142
143/// Or with 1 ( 1 | B = 1)
144impl<Rhs: Bit> BitOr<Rhs> for B1 {
145    type Output = B1;
146    #[inline]
147    fn bitor(self, _: Rhs) -> Self::Output {
148        B1
149    }
150}
151
152/// Xor between 0 and 0 ( 0 ^ 0 = 0)
153impl BitXor<B0> for B0 {
154    type Output = B0;
155    #[inline]
156    fn bitxor(self, _: B0) -> Self::Output {
157        B0
158    }
159}
160/// Xor between 1 and 0 ( 1 ^ 0 = 1)
161impl BitXor<B0> for B1 {
162    type Output = B1;
163    #[inline]
164    fn bitxor(self, _: B0) -> Self::Output {
165        B1
166    }
167}
168/// Xor between 0 and 1 ( 0 ^ 1 = 1)
169impl BitXor<B1> for B0 {
170    type Output = B1;
171    #[inline]
172    fn bitxor(self, _: B1) -> Self::Output {
173        B1
174    }
175}
176/// Xor between 1 and 1 ( 1 ^ 1 = 0)
177impl BitXor<B1> for B1 {
178    type Output = B0;
179    #[inline]
180    fn bitxor(self, _: B1) -> Self::Output {
181        B0
182    }
183}
184
185#[cfg(tests)]
186mod 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]
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
222impl Cmp<B0> for B0 {
223    type Output = Equal;
224
225    #[inline]
226    fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
227        Equal
228    }
229}
230
231impl Cmp<B1> for B0 {
232    type Output = Less;
233
234    #[inline]
235    fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
236        Less
237    }
238}
239
240impl Cmp<B0> for B1 {
241    type Output = Greater;
242
243    #[inline]
244    fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
245        Greater
246    }
247}
248
249impl Cmp<B1> for B1 {
250    type Output = Equal;
251
252    #[inline]
253    fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
254        Equal
255    }
256}
257
258use crate::Min;
259impl Min<B0> for B0 {
260    type Output = B0;
261    #[inline]
262    fn min(self, _: B0) -> B0 {
263        self
264    }
265}
266impl Min<B1> for B0 {
267    type Output = B0;
268    #[inline]
269    fn min(self, _: B1) -> B0 {
270        self
271    }
272}
273impl Min<B0> for B1 {
274    type Output = B0;
275    #[inline]
276    fn min(self, rhs: B0) -> B0 {
277        rhs
278    }
279}
280impl Min<B1> for B1 {
281    type Output = B1;
282    #[inline]
283    fn min(self, _: B1) -> B1 {
284        self
285    }
286}
287
288use crate::Max;
289impl Max<B0> for B0 {
290    type Output = B0;
291    #[inline]
292    fn max(self, _: B0) -> B0 {
293        self
294    }
295}
296impl Max<B1> for B0 {
297    type Output = B1;
298    #[inline]
299    fn max(self, rhs: B1) -> B1 {
300        rhs
301    }
302}
303impl Max<B0> for B1 {
304    type Output = B1;
305    #[inline]
306    fn max(self, _: B0) -> B1 {
307        self
308    }
309}
310impl Max<B1> for B1 {
311    type Output = B1;
312    #[inline]
313    fn max(self, _: B1) -> B1 {
314        self
315    }
316}
317
318#[cfg(test)]
319mod tests {
320    #[test]
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}