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