1use 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#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
19pub struct B0;
20
21impl B0 {
22 #[inline]
24 pub fn new() -> B0 {
25 B0
26 }
27}
28
29#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
31pub struct B1;
32
33impl B1 {
34 #[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
81impl Not for B0 {
83 type Output = B1;
84 #[inline]
85 fn not(self) -> Self::Output {
86 B1
87 }
88}
89impl Not for B1 {
91 type Output = B0;
92 #[inline]
93 fn not(self) -> Self::Output {
94 B0
95 }
96}
97
98impl<Rhs: Bit> BitAnd<Rhs> for B0 {
100 type Output = B0;
101 #[inline]
102 fn bitand(self, _: Rhs) -> Self::Output {
103 B0
104 }
105}
106
107impl BitAnd<B0> for B1 {
109 type Output = B0;
110 #[inline]
111 fn bitand(self, _: B0) -> Self::Output {
112 B0
113 }
114}
115
116impl BitAnd<B1> for B1 {
118 type Output = B1;
119 #[inline]
120 fn bitand(self, _: B1) -> Self::Output {
121 B1
122 }
123}
124
125impl BitOr<B0> for B0 {
127 type Output = B0;
128 #[inline]
129 fn bitor(self, _: B0) -> Self::Output {
130 B0
131 }
132}
133
134impl BitOr<B1> for B0 {
136 type Output = B1;
137 #[inline]
138 fn bitor(self, _: B1) -> Self::Output {
139 B1
140 }
141}
142
143impl<Rhs: Bit> BitOr<Rhs> for B1 {
145 type Output = B1;
146 #[inline]
147 fn bitor(self, _: Rhs) -> Self::Output {
148 B1
149 }
150}
151
152impl BitXor<B0> for B0 {
154 type Output = B0;
155 #[inline]
156 fn bitxor(self, _: B0) -> Self::Output {
157 B0
158 }
159}
160impl BitXor<B0> for B1 {
162 type Output = B1;
163 #[inline]
164 fn bitxor(self, _: B0) -> Self::Output {
165 B1
166 }
167}
168impl BitXor<B1> for B0 {
170 type Output = B1;
171 #[inline]
172 fn bitxor(self, _: B1) -> Self::Output {
173 B1
174 }
175}
176impl 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_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}