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 #[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))] 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 #[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))] 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] new() -> Self48 fn new() -> Self { 49 Self 50 } 51 #[inline] to_u8() -> u852 fn to_u8() -> u8 { 53 0 54 } 55 #[inline] to_bool() -> bool56 fn to_bool() -> bool { 57 false 58 } 59 } 60 61 impl Bit for B1 { 62 const U8: u8 = 1; 63 const BOOL: bool = true; 64 65 #[inline] new() -> Self66 fn new() -> Self { 67 Self 68 } 69 #[inline] to_u8() -> u870 fn to_u8() -> u8 { 71 1 72 } 73 #[inline] to_bool() -> bool74 fn to_bool() -> bool { 75 true 76 } 77 } 78 79 impl Zero for B0 {} 80 impl NonZero for B1 {} 81 impl PowerOfTwo for B1 {} 82 83 /// Not of 0 (!0 = 1) 84 impl Not for B0 { 85 type Output = B1; 86 #[inline] not(self) -> Self::Output87 fn not(self) -> Self::Output { 88 B1 89 } 90 } 91 /// Not of 1 (!1 = 0) 92 impl Not for B1 { 93 type Output = B0; 94 #[inline] not(self) -> Self::Output95 fn not(self) -> Self::Output { 96 B0 97 } 98 } 99 100 /// And with 0 ( 0 & B = 0) 101 impl<Rhs: Bit> BitAnd<Rhs> for B0 { 102 type Output = B0; 103 #[inline] bitand(self, _: Rhs) -> Self::Output104 fn bitand(self, _: Rhs) -> Self::Output { 105 B0 106 } 107 } 108 109 /// And with 1 ( 1 & 0 = 0) 110 impl BitAnd<B0> for B1 { 111 type Output = B0; 112 #[inline] bitand(self, _: B0) -> Self::Output113 fn bitand(self, _: B0) -> Self::Output { 114 B0 115 } 116 } 117 118 /// And with 1 ( 1 & 1 = 1) 119 impl BitAnd<B1> for B1 { 120 type Output = B1; 121 #[inline] bitand(self, _: B1) -> Self::Output122 fn bitand(self, _: B1) -> Self::Output { 123 B1 124 } 125 } 126 127 /// Or with 0 ( 0 | 0 = 0) 128 impl BitOr<B0> for B0 { 129 type Output = B0; 130 #[inline] bitor(self, _: B0) -> Self::Output131 fn bitor(self, _: B0) -> Self::Output { 132 B0 133 } 134 } 135 136 /// Or with 0 ( 0 | 1 = 1) 137 impl BitOr<B1> for B0 { 138 type Output = B1; 139 #[inline] bitor(self, _: B1) -> Self::Output140 fn bitor(self, _: B1) -> Self::Output { 141 B1 142 } 143 } 144 145 /// Or with 1 ( 1 | B = 1) 146 impl<Rhs: Bit> BitOr<Rhs> for B1 { 147 type Output = B1; 148 #[inline] bitor(self, _: Rhs) -> Self::Output149 fn bitor(self, _: Rhs) -> Self::Output { 150 B1 151 } 152 } 153 154 /// Xor between 0 and 0 ( 0 ^ 0 = 0) 155 impl BitXor<B0> for B0 { 156 type Output = B0; 157 #[inline] bitxor(self, _: B0) -> Self::Output158 fn bitxor(self, _: B0) -> Self::Output { 159 B0 160 } 161 } 162 /// Xor between 1 and 0 ( 1 ^ 0 = 1) 163 impl BitXor<B0> for B1 { 164 type Output = B1; 165 #[inline] bitxor(self, _: B0) -> Self::Output166 fn bitxor(self, _: B0) -> Self::Output { 167 B1 168 } 169 } 170 /// Xor between 0 and 1 ( 0 ^ 1 = 1) 171 impl BitXor<B1> for B0 { 172 type Output = B1; 173 #[inline] bitxor(self, _: B1) -> Self::Output174 fn bitxor(self, _: B1) -> Self::Output { 175 B1 176 } 177 } 178 /// Xor between 1 and 1 ( 1 ^ 1 = 0) 179 impl BitXor<B1> for B1 { 180 type Output = B0; 181 #[inline] bitxor(self, _: B1) -> Self::Output182 fn bitxor(self, _: B1) -> Self::Output { 183 B0 184 } 185 } 186 187 #[cfg(tests)] 188 mod tests { 189 // macro for testing operation results. Uses `Same` to ensure the types are equal and 190 // not just the values they evaluate to. 191 macro_rules! test_bit_op { 192 ($op:ident $Lhs:ident = $Answer:ident) => {{ 193 type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output; 194 assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8()); 195 }}; 196 ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => {{ 197 type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output; 198 assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8()); 199 }}; 200 } 201 202 #[test] bit_operations()203 fn bit_operations() { 204 test_bit_op!(Not B0 = B1); 205 test_bit_op!(Not B1 = B0); 206 207 test_bit_op!(B0 BitAnd B0 = B0); 208 test_bit_op!(B0 BitAnd B1 = B0); 209 test_bit_op!(B1 BitAnd B0 = B0); 210 test_bit_op!(B1 BitAnd B1 = B1); 211 212 test_bit_op!(B0 BitOr B0 = B0); 213 test_bit_op!(B0 BitOr B1 = B1); 214 test_bit_op!(B1 BitOr B0 = B1); 215 test_bit_op!(B1 BitOr B1 = B1); 216 217 test_bit_op!(B0 BitXor B0 = B0); 218 test_bit_op!(B0 BitXor B1 = B1); 219 test_bit_op!(B1 BitXor B0 = B1); 220 test_bit_op!(B1 BitXor B1 = B0); 221 } 222 } 223 224 impl Cmp<B0> for B0 { 225 type Output = Equal; 226 227 #[inline] compare<P: InternalMarker>(&self, _: &B0) -> Self::Output228 fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output { 229 Equal 230 } 231 } 232 233 impl Cmp<B1> for B0 { 234 type Output = Less; 235 236 #[inline] compare<P: InternalMarker>(&self, _: &B1) -> Self::Output237 fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output { 238 Less 239 } 240 } 241 242 impl Cmp<B0> for B1 { 243 type Output = Greater; 244 245 #[inline] compare<P: InternalMarker>(&self, _: &B0) -> Self::Output246 fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output { 247 Greater 248 } 249 } 250 251 impl Cmp<B1> for B1 { 252 type Output = Equal; 253 254 #[inline] compare<P: InternalMarker>(&self, _: &B1) -> Self::Output255 fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output { 256 Equal 257 } 258 } 259 260 use crate::Min; 261 impl Min<B0> for B0 { 262 type Output = B0; 263 #[inline] min(self, _: B0) -> B0264 fn min(self, _: B0) -> B0 { 265 self 266 } 267 } 268 impl Min<B1> for B0 { 269 type Output = B0; 270 #[inline] min(self, _: B1) -> B0271 fn min(self, _: B1) -> B0 { 272 self 273 } 274 } 275 impl Min<B0> for B1 { 276 type Output = B0; 277 #[inline] min(self, rhs: B0) -> B0278 fn min(self, rhs: B0) -> B0 { 279 rhs 280 } 281 } 282 impl Min<B1> for B1 { 283 type Output = B1; 284 #[inline] min(self, _: B1) -> B1285 fn min(self, _: B1) -> B1 { 286 self 287 } 288 } 289 290 use crate::Max; 291 impl Max<B0> for B0 { 292 type Output = B0; 293 #[inline] max(self, _: B0) -> B0294 fn max(self, _: B0) -> B0 { 295 self 296 } 297 } 298 impl Max<B1> for B0 { 299 type Output = B1; 300 #[inline] max(self, rhs: B1) -> B1301 fn max(self, rhs: B1) -> B1 { 302 rhs 303 } 304 } 305 impl Max<B0> for B1 { 306 type Output = B1; 307 #[inline] max(self, _: B0) -> B1308 fn max(self, _: B0) -> B1 { 309 self 310 } 311 } 312 impl Max<B1> for B1 { 313 type Output = B1; 314 #[inline] max(self, _: B1) -> B1315 fn max(self, _: B1) -> B1 { 316 self 317 } 318 } 319 320 #[cfg(test)] 321 mod tests { 322 #[test] bit_creation()323 fn bit_creation() { 324 { 325 use crate::{B0, B1}; 326 let _: B0 = B0::new(); 327 let _: B1 = B1::new(); 328 } 329 330 { 331 use crate::{Bit, B0, B1}; 332 333 let _: B0 = <B0 as Bit>::new(); 334 let _: B1 = <B1 as Bit>::new(); 335 } 336 } 337 } 338