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 {Cmp, Equal, Greater, Less, NonZero, PowerOfTwo}; 15 16 pub use marker_traits::Bit; 17 18 /// The type-level bit 0. 19 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] 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 pub struct B1; 33 34 impl B1 { 35 /// Instantiates a singleton representing this bit. 36 #[inline] new() -> B137 pub fn new() -> B1 { 38 B1 39 } 40 } 41 42 impl Bit for B0 { 43 const U8: u8 = 0; 44 const BOOL: bool = false; 45 46 #[inline] to_u8() -> u847 fn to_u8() -> u8 { 48 0 49 } 50 #[inline] to_bool() -> bool51 fn to_bool() -> bool { 52 false 53 } 54 } 55 56 impl Bit for B1 { 57 const U8: u8 = 1; 58 const BOOL: bool = true; 59 60 #[inline] to_u8() -> u861 fn to_u8() -> u8 { 62 1 63 } 64 #[inline] to_bool() -> bool65 fn to_bool() -> bool { 66 true 67 } 68 } 69 70 impl NonZero for B1 {} 71 impl PowerOfTwo for B1 {} 72 73 /// Not of 0 (!0 = 1) 74 impl Not for B0 { 75 type Output = B1; not(self) -> Self::Output76 fn not(self) -> Self::Output { 77 B1 78 } 79 } 80 /// Not of 1 (!1 = 0) 81 impl Not for B1 { 82 type Output = B0; not(self) -> Self::Output83 fn not(self) -> Self::Output { 84 B0 85 } 86 } 87 88 /// And with 0 ( 0 & B = 0) 89 impl<Rhs: Bit> BitAnd<Rhs> for B0 { 90 type Output = B0; bitand(self, _: Rhs) -> Self::Output91 fn bitand(self, _: Rhs) -> Self::Output { 92 B0 93 } 94 } 95 96 /// And with 1 ( 1 & 0 = 0) 97 impl BitAnd<B0> for B1 { 98 type Output = B0; bitand(self, _: B0) -> Self::Output99 fn bitand(self, _: B0) -> Self::Output { 100 B0 101 } 102 } 103 104 /// And with 1 ( 1 & 1 = 1) 105 impl BitAnd<B1> for B1 { 106 type Output = B1; bitand(self, _: B1) -> Self::Output107 fn bitand(self, _: B1) -> Self::Output { 108 B1 109 } 110 } 111 112 /// Or with 0 ( 0 | 0 = 0) 113 impl BitOr<B0> for B0 { 114 type Output = B0; bitor(self, _: B0) -> Self::Output115 fn bitor(self, _: B0) -> Self::Output { 116 B0 117 } 118 } 119 120 /// Or with 0 ( 0 | 1 = 1) 121 impl BitOr<B1> for B0 { 122 type Output = B1; bitor(self, _: B1) -> Self::Output123 fn bitor(self, _: B1) -> Self::Output { 124 B1 125 } 126 } 127 128 /// Or with 1 ( 1 | B = 1) 129 impl<Rhs: Bit> BitOr<Rhs> for B1 { 130 type Output = B1; bitor(self, _: Rhs) -> Self::Output131 fn bitor(self, _: Rhs) -> Self::Output { 132 B1 133 } 134 } 135 136 /// Xor between 0 and 0 ( 0 ^ 0 = 0) 137 impl BitXor<B0> for B0 { 138 type Output = B0; bitxor(self, _: B0) -> Self::Output139 fn bitxor(self, _: B0) -> Self::Output { 140 B0 141 } 142 } 143 /// Xor between 1 and 0 ( 1 ^ 0 = 1) 144 impl BitXor<B0> for B1 { 145 type Output = B1; bitxor(self, _: B0) -> Self::Output146 fn bitxor(self, _: B0) -> Self::Output { 147 B1 148 } 149 } 150 /// Xor between 0 and 1 ( 0 ^ 1 = 1) 151 impl BitXor<B1> for B0 { 152 type Output = B1; bitxor(self, _: B1) -> Self::Output153 fn bitxor(self, _: B1) -> Self::Output { 154 B1 155 } 156 } 157 /// Xor between 1 and 1 ( 1 ^ 1 = 0) 158 impl BitXor<B1> for B1 { 159 type Output = B0; bitxor(self, _: B1) -> Self::Output160 fn bitxor(self, _: B1) -> Self::Output { 161 B0 162 } 163 } 164 165 #[cfg(tests)] 166 mod tests { 167 // macro for testing operation results. Uses `Same` to ensure the types are equal and 168 // not just the values they evaluate to. 169 macro_rules! test_bit_op { 170 ($op:ident $Lhs:ident = $Answer:ident) => {{ 171 type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output; 172 assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8()); 173 }}; 174 ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => {{ 175 type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output; 176 assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8()); 177 }}; 178 } 179 180 #[test] bit_operations()181 fn bit_operations() { 182 test_bit_op!(Not B0 = B1); 183 test_bit_op!(Not B1 = B0); 184 185 test_bit_op!(B0 BitAnd B0 = B0); 186 test_bit_op!(B0 BitAnd B1 = B0); 187 test_bit_op!(B1 BitAnd B0 = B0); 188 test_bit_op!(B1 BitAnd B1 = B1); 189 190 test_bit_op!(B0 BitOr B0 = B0); 191 test_bit_op!(B0 BitOr B1 = B1); 192 test_bit_op!(B1 BitOr B0 = B1); 193 test_bit_op!(B1 BitOr B1 = B1); 194 195 test_bit_op!(B0 BitXor B0 = B0); 196 test_bit_op!(B0 BitXor B1 = B1); 197 test_bit_op!(B1 BitXor B0 = B1); 198 test_bit_op!(B1 BitXor B1 = B0); 199 } 200 } 201 202 impl Cmp<B0> for B0 { 203 type Output = Equal; 204 } 205 206 impl Cmp<B1> for B0 { 207 type Output = Less; 208 } 209 210 impl Cmp<B0> for B1 { 211 type Output = Greater; 212 } 213 214 impl Cmp<B1> for B1 { 215 type Output = Equal; 216 } 217 218 use Min; 219 impl Min<B0> for B0 { 220 type Output = B0; min(self, _: B0) -> B0221 fn min(self, _: B0) -> B0 { 222 self 223 } 224 } 225 impl Min<B1> for B0 { 226 type Output = B0; min(self, _: B1) -> B0227 fn min(self, _: B1) -> B0 { 228 self 229 } 230 } 231 impl Min<B0> for B1 { 232 type Output = B0; min(self, rhs: B0) -> B0233 fn min(self, rhs: B0) -> B0 { 234 rhs 235 } 236 } 237 impl Min<B1> for B1 { 238 type Output = B1; min(self, _: B1) -> B1239 fn min(self, _: B1) -> B1 { 240 self 241 } 242 } 243 244 use Max; 245 impl Max<B0> for B0 { 246 type Output = B0; max(self, _: B0) -> B0247 fn max(self, _: B0) -> B0 { 248 self 249 } 250 } 251 impl Max<B1> for B0 { 252 type Output = B1; max(self, rhs: B1) -> B1253 fn max(self, rhs: B1) -> B1 { 254 rhs 255 } 256 } 257 impl Max<B0> for B1 { 258 type Output = B1; max(self, _: B0) -> B1259 fn max(self, _: B0) -> B1 { 260 self 261 } 262 } 263 impl Max<B1> for B1 { 264 type Output = B1; max(self, _: B1) -> B1265 fn max(self, _: B1) -> B1 { 266 self 267 } 268 } 269