diff options
Diffstat (limited to 'vendor/typenum/src/bit.rs')
-rw-r--r-- | vendor/typenum/src/bit.rs | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/vendor/typenum/src/bit.rs b/vendor/typenum/src/bit.rs new file mode 100644 index 000000000..4a098fe84 --- /dev/null +++ b/vendor/typenum/src/bit.rs @@ -0,0 +1,337 @@ +//! Type-level bits. +//! +//! These are rather simple and are used as the building blocks of the +//! other number types in this crate. +//! +//! +//! **Type operators** implemented: +//! +//! - From `core::ops`: `BitAnd`, `BitOr`, `BitXor`, and `Not`. +//! - From `typenum`: `Same` and `Cmp`. + +use crate::{private::InternalMarker, Cmp, Equal, Greater, Less, NonZero, PowerOfTwo, Zero}; +use core::ops::{BitAnd, BitOr, BitXor, Not}; + +pub use crate::marker_traits::Bit; + +/// The type-level bit 0. +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] +#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))] +pub struct B0; + +impl B0 { + /// Instantiates a singleton representing this bit. + #[inline] + pub fn new() -> B0 { + B0 + } +} + +/// The type-level bit 1. +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] +#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))] +pub struct B1; + +impl B1 { + /// Instantiates a singleton representing this bit. + #[inline] + pub fn new() -> B1 { + B1 + } +} + +impl Bit for B0 { + const U8: u8 = 0; + const BOOL: bool = false; + + #[inline] + fn new() -> Self { + Self + } + #[inline] + fn to_u8() -> u8 { + 0 + } + #[inline] + fn to_bool() -> bool { + false + } +} + +impl Bit for B1 { + const U8: u8 = 1; + const BOOL: bool = true; + + #[inline] + fn new() -> Self { + Self + } + #[inline] + fn to_u8() -> u8 { + 1 + } + #[inline] + fn to_bool() -> bool { + true + } +} + +impl Zero for B0 {} +impl NonZero for B1 {} +impl PowerOfTwo for B1 {} + +/// Not of 0 (!0 = 1) +impl Not for B0 { + type Output = B1; + #[inline] + fn not(self) -> Self::Output { + B1 + } +} +/// Not of 1 (!1 = 0) +impl Not for B1 { + type Output = B0; + #[inline] + fn not(self) -> Self::Output { + B0 + } +} + +/// And with 0 ( 0 & B = 0) +impl<Rhs: Bit> BitAnd<Rhs> for B0 { + type Output = B0; + #[inline] + fn bitand(self, _: Rhs) -> Self::Output { + B0 + } +} + +/// And with 1 ( 1 & 0 = 0) +impl BitAnd<B0> for B1 { + type Output = B0; + #[inline] + fn bitand(self, _: B0) -> Self::Output { + B0 + } +} + +/// And with 1 ( 1 & 1 = 1) +impl BitAnd<B1> for B1 { + type Output = B1; + #[inline] + fn bitand(self, _: B1) -> Self::Output { + B1 + } +} + +/// Or with 0 ( 0 | 0 = 0) +impl BitOr<B0> for B0 { + type Output = B0; + #[inline] + fn bitor(self, _: B0) -> Self::Output { + B0 + } +} + +/// Or with 0 ( 0 | 1 = 1) +impl BitOr<B1> for B0 { + type Output = B1; + #[inline] + fn bitor(self, _: B1) -> Self::Output { + B1 + } +} + +/// Or with 1 ( 1 | B = 1) +impl<Rhs: Bit> BitOr<Rhs> for B1 { + type Output = B1; + #[inline] + fn bitor(self, _: Rhs) -> Self::Output { + B1 + } +} + +/// Xor between 0 and 0 ( 0 ^ 0 = 0) +impl BitXor<B0> for B0 { + type Output = B0; + #[inline] + fn bitxor(self, _: B0) -> Self::Output { + B0 + } +} +/// Xor between 1 and 0 ( 1 ^ 0 = 1) +impl BitXor<B0> for B1 { + type Output = B1; + #[inline] + fn bitxor(self, _: B0) -> Self::Output { + B1 + } +} +/// Xor between 0 and 1 ( 0 ^ 1 = 1) +impl BitXor<B1> for B0 { + type Output = B1; + #[inline] + fn bitxor(self, _: B1) -> Self::Output { + B1 + } +} +/// Xor between 1 and 1 ( 1 ^ 1 = 0) +impl BitXor<B1> for B1 { + type Output = B0; + #[inline] + fn bitxor(self, _: B1) -> Self::Output { + B0 + } +} + +#[cfg(tests)] +mod tests { + // macro for testing operation results. Uses `Same` to ensure the types are equal and + // not just the values they evaluate to. + macro_rules! test_bit_op { + ($op:ident $Lhs:ident = $Answer:ident) => {{ + type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output; + assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8()); + }}; + ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => {{ + type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output; + assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8()); + }}; + } + + #[test] + fn bit_operations() { + test_bit_op!(Not B0 = B1); + test_bit_op!(Not B1 = B0); + + test_bit_op!(B0 BitAnd B0 = B0); + test_bit_op!(B0 BitAnd B1 = B0); + test_bit_op!(B1 BitAnd B0 = B0); + test_bit_op!(B1 BitAnd B1 = B1); + + test_bit_op!(B0 BitOr B0 = B0); + test_bit_op!(B0 BitOr B1 = B1); + test_bit_op!(B1 BitOr B0 = B1); + test_bit_op!(B1 BitOr B1 = B1); + + test_bit_op!(B0 BitXor B0 = B0); + test_bit_op!(B0 BitXor B1 = B1); + test_bit_op!(B1 BitXor B0 = B1); + test_bit_op!(B1 BitXor B1 = B0); + } +} + +impl Cmp<B0> for B0 { + type Output = Equal; + + #[inline] + fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output { + Equal + } +} + +impl Cmp<B1> for B0 { + type Output = Less; + + #[inline] + fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output { + Less + } +} + +impl Cmp<B0> for B1 { + type Output = Greater; + + #[inline] + fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output { + Greater + } +} + +impl Cmp<B1> for B1 { + type Output = Equal; + + #[inline] + fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output { + Equal + } +} + +use crate::Min; +impl Min<B0> for B0 { + type Output = B0; + #[inline] + fn min(self, _: B0) -> B0 { + self + } +} +impl Min<B1> for B0 { + type Output = B0; + #[inline] + fn min(self, _: B1) -> B0 { + self + } +} +impl Min<B0> for B1 { + type Output = B0; + #[inline] + fn min(self, rhs: B0) -> B0 { + rhs + } +} +impl Min<B1> for B1 { + type Output = B1; + #[inline] + fn min(self, _: B1) -> B1 { + self + } +} + +use crate::Max; +impl Max<B0> for B0 { + type Output = B0; + #[inline] + fn max(self, _: B0) -> B0 { + self + } +} +impl Max<B1> for B0 { + type Output = B1; + #[inline] + fn max(self, rhs: B1) -> B1 { + rhs + } +} +impl Max<B0> for B1 { + type Output = B1; + #[inline] + fn max(self, _: B0) -> B1 { + self + } +} +impl Max<B1> for B1 { + type Output = B1; + #[inline] + fn max(self, _: B1) -> B1 { + self + } +} + +#[cfg(test)] +mod tests { + #[test] + fn bit_creation() { + { + use crate::{B0, B1}; + let _: B0 = B0::new(); + let _: B1 = B1::new(); + } + + { + use crate::{Bit, B0, B1}; + + let _: B0 = <B0 as Bit>::new(); + let _: B1 = <B1 as Bit>::new(); + } + } +} |