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