/// Generic trait for primitive integers. /// /// The `PrimInt` trait is an abstraction over the builtin primitive integer types (e.g., `u8`, /// `u32`, `isize`, `i128`, ...). It inherits the basic numeric traits and extends them with /// bitwise operators and non-wrapping arithmetic. /// /// The trait explicitly inherits `Copy`, `Eq`, `Ord`, and `Sized`. The intention is that all /// types implementing this trait behave like primitive types that are passed by value by default /// and behave like builtin integers. Furthermore, the types are expected to expose the integer /// value in binary representation and support bitwise operators. The standard bitwise operations /// (e.g., bitwise-and, bitwise-or, right-shift, left-shift) are inherited and the trait extends /// these with introspective queries (e.g., `PrimInt::count_ones()`, `PrimInt::leading_zeros()`), /// bitwise combinators (e.g., `PrimInt::rotate_left()`), and endianness converters (e.g., /// `PrimInt::to_be()`). /// /// All `PrimInt` types are expected to be fixed-width binary integers. The width can be queried /// via `T::zero().count_zeros()`. The trait currently lacks a way to query the width at /// compile-time. /// /// While a default implementation for all builtin primitive integers is provided, the trait is in /// no way restricted to these. Other integer types that fulfil the requirements are free to /// implement the trait was well. /// /// This trait and many of the method names originate in the unstable `core::num::Int` trait from /// the rust standard library. The original trait was never stabilized and thus removed from the /// standard library. pubtrait PrimInt:
Sized
+ Copy
+ Num
+ NumCast
+ Bounded
+ PartialOrd
+ Ord
+ Eq
+ Not<Output = Self>
+ BitAnd<Output = Self>
+ BitOr<Output = Self>
+ BitXor<Output = Self>
+ Shl<usize, Output = Self>
+ Shr<usize, Output = Self>
+ CheckedAdd<Output = Self>
+ CheckedSub<Output = Self>
+ CheckedMul<Output = Self>
+ CheckedDiv<Output = Self>
+ Saturating
{ /// Returns the number of ones in the binary representation of `self`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0b01001100u8; /// /// assert_eq!(n.count_ones(), 3); /// ``` fn count_ones(self) -> u32;
/// Returns the number of zeros in the binary representation of `self`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0b01001100u8; /// /// assert_eq!(n.count_zeros(), 5); /// ``` fn count_zeros(self) -> u32;
/// Returns the number of leading ones in the binary representation /// of `self`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0xF00Du16; /// /// assert_eq!(n.leading_ones(), 4); /// ``` fn leading_ones(self) -> u32 {
(!self).leading_zeros()
}
/// Returns the number of leading zeros in the binary representation /// of `self`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0b0101000u16; /// /// assert_eq!(n.leading_zeros(), 10); /// ``` fn leading_zeros(self) -> u32;
/// Returns the number of trailing ones in the binary representation /// of `self`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0xBEEFu16; /// /// assert_eq!(n.trailing_ones(), 4); /// ``` fn trailing_ones(self) -> u32 {
(!self).trailing_zeros()
}
/// Returns the number of trailing zeros in the binary representation /// of `self`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0b0101000u16; /// /// assert_eq!(n.trailing_zeros(), 3); /// ``` fn trailing_zeros(self) -> u32;
/// Shifts the bits to the left by a specified amount, `n`, wrapping /// the truncated bits to the end of the resulting integer. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x0123456789ABCDEFu64; /// let m = 0x3456789ABCDEF012u64; /// /// assert_eq!(n.rotate_left(12), m); /// ``` fn rotate_left(self, n: u32) -> Self;
/// Shifts the bits to the right by a specified amount, `n`, wrapping /// the truncated bits to the beginning of the resulting integer. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x0123456789ABCDEFu64; /// let m = 0xDEF0123456789ABCu64; /// /// assert_eq!(n.rotate_right(12), m); /// ``` fn rotate_right(self, n: u32) -> Self;
/// Shifts the bits to the left by a specified amount, `n`, filling /// zeros in the least significant bits. /// /// This is bitwise equivalent to signed `Shl`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x0123456789ABCDEFu64; /// let m = 0x3456789ABCDEF000u64; /// /// assert_eq!(n.signed_shl(12), m); /// ``` fn signed_shl(self, n: u32) -> Self;
/// Shifts the bits to the right by a specified amount, `n`, copying /// the "sign bit" in the most significant bits even for unsigned types. /// /// This is bitwise equivalent to signed `Shr`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0xFEDCBA9876543210u64; /// let m = 0xFFFFEDCBA9876543u64; /// /// assert_eq!(n.signed_shr(12), m); /// ``` fn signed_shr(self, n: u32) -> Self;
/// Shifts the bits to the left by a specified amount, `n`, filling /// zeros in the least significant bits. /// /// This is bitwise equivalent to unsigned `Shl`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x0123456789ABCDEFi64; /// let m = 0x3456789ABCDEF000i64; /// /// assert_eq!(n.unsigned_shl(12), m); /// ``` fn unsigned_shl(self, n: u32) -> Self;
/// Shifts the bits to the right by a specified amount, `n`, filling /// zeros in the most significant bits. /// /// This is bitwise equivalent to unsigned `Shr`. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = -8i8; // 0b11111000 /// let m = 62i8; // 0b00111110 /// /// assert_eq!(n.unsigned_shr(2), m); /// ``` fn unsigned_shr(self, n: u32) -> Self;
/// Reverses the byte order of the integer. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x0123456789ABCDEFu64; /// let m = 0xEFCDAB8967452301u64; /// /// assert_eq!(n.swap_bytes(), m); /// ``` fn swap_bytes(self) -> Self;
/// Reverses the order of bits in the integer. /// /// The least significant bit becomes the most significant bit, second least-significant bit /// becomes second most-significant bit, etc. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x12345678u32; /// let m = 0x1e6a2c48u32; /// /// assert_eq!(n.reverse_bits(), m); /// assert_eq!(0u32.reverse_bits(), 0); /// ``` fn reverse_bits(self) -> Self {
reverse_bits_fallback(self)
}
/// Convert an integer from big endian to the target's endianness. /// /// On big endian this is a no-op. On little endian the bytes are swapped. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "big") { /// assert_eq!(u64::from_be(n), n) /// } else { /// assert_eq!(u64::from_be(n), n.swap_bytes()) /// } /// ``` fn from_be(x: Self) -> Self;
/// Convert an integer from little endian to the target's endianness. /// /// On little endian this is a no-op. On big endian the bytes are swapped. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "little") { /// assert_eq!(u64::from_le(n), n) /// } else { /// assert_eq!(u64::from_le(n), n.swap_bytes()) /// } /// ``` fn from_le(x: Self) -> Self;
/// Convert `self` to big endian from the target's endianness. /// /// On big endian this is a no-op. On little endian the bytes are swapped. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "big") { /// assert_eq!(n.to_be(), n) /// } else { /// assert_eq!(n.to_be(), n.swap_bytes()) /// } /// ``` fn to_be(self) -> Self;
/// Convert `self` to little endian from the target's endianness. /// /// On little endian this is a no-op. On big endian the bytes are swapped. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "little") { /// assert_eq!(n.to_le(), n) /// } else { /// assert_eq!(n.to_le(), n.swap_bytes()) /// } /// ``` fn to_le(self) -> Self;
/// Raises self to the power of `exp`, using exponentiation by squaring. /// /// # Examples /// /// ``` /// use num_traits::PrimInt; /// /// assert_eq!(2i32.pow(4), 16); /// ``` fn pow(self, exp: u32) -> Self;
}
fn one_per_byte<P: PrimInt>() -> P { // i8, u8: return 0x01 // i16, u16: return 0x0101 = (0x01 << 8) | 0x01 // i32, u32: return 0x01010101 = (0x0101 << 16) | 0x0101 // ... letmut ret = P::one(); letmut shift = 8; letmut b = ret.count_zeros() >> 3; while b != 0 {
ret = (ret << shift) | ret;
shift <<= 1;
b >>= 1;
}
ret
}
fn reverse_bits_fallback<P: PrimInt>(i: P) -> P { let rep_01: P = one_per_byte(); let rep_03 = (rep_01 << 1) | rep_01; let rep_05 = (rep_01 << 2) | rep_01; let rep_0f = (rep_03 << 2) | rep_03; let rep_33 = (rep_03 << 4) | rep_03; let rep_55 = (rep_05 << 4) | rep_05;
// code above only used to determine rep_0f, rep_33, rep_55; // optimizer should be able to do it in compile time letmut ret = i.swap_bytes();
ret = ((ret & rep_0f) << 4) | ((ret >> 4) & rep_0f);
ret = ((ret & rep_33) << 2) | ((ret >> 2) & rep_33);
ret = ((ret & rep_55) << 1) | ((ret >> 1) & rep_55);
ret
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.