summaryrefslogtreecommitdiffstats
path: root/vendor/num-traits/src/int.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/num-traits/src/int.rs')
-rw-r--r--vendor/num-traits/src/int.rs409
1 files changed, 409 insertions, 0 deletions
diff --git a/vendor/num-traits/src/int.rs b/vendor/num-traits/src/int.rs
new file mode 100644
index 000000000..10e751a9d
--- /dev/null
+++ b/vendor/num-traits/src/int.rs
@@ -0,0 +1,409 @@
+use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
+
+use bounds::Bounded;
+use ops::checked::*;
+use ops::saturating::Saturating;
+use {Num, NumCast};
+
+/// 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.
+pub trait 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 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 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;
+
+ /// 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;
+}
+
+macro_rules! prim_int_impl {
+ ($T:ty, $S:ty, $U:ty) => {
+ impl PrimInt for $T {
+ #[inline]
+ fn count_ones(self) -> u32 {
+ <$T>::count_ones(self)
+ }
+
+ #[inline]
+ fn count_zeros(self) -> u32 {
+ <$T>::count_zeros(self)
+ }
+
+ #[inline]
+ fn leading_zeros(self) -> u32 {
+ <$T>::leading_zeros(self)
+ }
+
+ #[inline]
+ fn trailing_zeros(self) -> u32 {
+ <$T>::trailing_zeros(self)
+ }
+
+ #[inline]
+ fn rotate_left(self, n: u32) -> Self {
+ <$T>::rotate_left(self, n)
+ }
+
+ #[inline]
+ fn rotate_right(self, n: u32) -> Self {
+ <$T>::rotate_right(self, n)
+ }
+
+ #[inline]
+ fn signed_shl(self, n: u32) -> Self {
+ ((self as $S) << n) as $T
+ }
+
+ #[inline]
+ fn signed_shr(self, n: u32) -> Self {
+ ((self as $S) >> n) as $T
+ }
+
+ #[inline]
+ fn unsigned_shl(self, n: u32) -> Self {
+ ((self as $U) << n) as $T
+ }
+
+ #[inline]
+ fn unsigned_shr(self, n: u32) -> Self {
+ ((self as $U) >> n) as $T
+ }
+
+ #[inline]
+ fn swap_bytes(self) -> Self {
+ <$T>::swap_bytes(self)
+ }
+
+ #[inline]
+ fn from_be(x: Self) -> Self {
+ <$T>::from_be(x)
+ }
+
+ #[inline]
+ fn from_le(x: Self) -> Self {
+ <$T>::from_le(x)
+ }
+
+ #[inline]
+ fn to_be(self) -> Self {
+ <$T>::to_be(self)
+ }
+
+ #[inline]
+ fn to_le(self) -> Self {
+ <$T>::to_le(self)
+ }
+
+ #[inline]
+ fn pow(self, exp: u32) -> Self {
+ <$T>::pow(self, exp)
+ }
+ }
+ };
+}
+
+// prim_int_impl!(type, signed, unsigned);
+prim_int_impl!(u8, i8, u8);
+prim_int_impl!(u16, i16, u16);
+prim_int_impl!(u32, i32, u32);
+prim_int_impl!(u64, i64, u64);
+#[cfg(has_i128)]
+prim_int_impl!(u128, i128, u128);
+prim_int_impl!(usize, isize, usize);
+prim_int_impl!(i8, i8, u8);
+prim_int_impl!(i16, i16, u16);
+prim_int_impl!(i32, i32, u32);
+prim_int_impl!(i64, i64, u64);
+#[cfg(has_i128)]
+prim_int_impl!(i128, i128, u128);
+prim_int_impl!(isize, isize, usize);