convert between integer and byte array
This commit is contained in:
parent
d668985fae
commit
51df9728ab
133
src/int.rs
133
src/int.rs
|
@ -1,3 +1,4 @@
|
||||||
|
use core::mem::size_of;
|
||||||
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
|
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
|
||||||
|
|
||||||
use bounds::Bounded;
|
use bounds::Bounded;
|
||||||
|
@ -5,6 +6,11 @@ use ops::checked::*;
|
||||||
use ops::saturating::Saturating;
|
use ops::saturating::Saturating;
|
||||||
use {Num, NumCast};
|
use {Num, NumCast};
|
||||||
|
|
||||||
|
pub trait Layout {
|
||||||
|
/// The type representation as a byte array.
|
||||||
|
type Bytes;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait PrimInt:
|
pub trait PrimInt:
|
||||||
Sized
|
Sized
|
||||||
+ Copy
|
+ Copy
|
||||||
|
@ -25,6 +31,7 @@ pub trait PrimInt:
|
||||||
+ CheckedMul<Output = Self>
|
+ CheckedMul<Output = Self>
|
||||||
+ CheckedDiv<Output = Self>
|
+ CheckedDiv<Output = Self>
|
||||||
+ Saturating
|
+ Saturating
|
||||||
|
+ Layout
|
||||||
{
|
{
|
||||||
/// Returns the number of ones in the binary representation of `self`.
|
/// Returns the number of ones in the binary representation of `self`.
|
||||||
///
|
///
|
||||||
|
@ -278,6 +285,98 @@ pub trait PrimInt:
|
||||||
/// assert_eq!(2i32.pow(4), 16);
|
/// assert_eq!(2i32.pow(4), 16);
|
||||||
/// ```
|
/// ```
|
||||||
fn pow(self, exp: u32) -> Self;
|
fn pow(self, exp: u32) -> Self;
|
||||||
|
|
||||||
|
/// Return the memory representation of this integer as a byte array in big-endian byte order.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use num_traits::PrimInt;
|
||||||
|
///
|
||||||
|
/// let bytes = 0x12345678u32.to_be_bytes();
|
||||||
|
/// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
|
||||||
|
/// ```
|
||||||
|
fn to_be_bytes(self) -> Self::Bytes;
|
||||||
|
|
||||||
|
/// Return the memory representation of this integer as a byte array in little-endian byte order.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use num_traits::PrimInt;
|
||||||
|
///
|
||||||
|
/// let bytes = 0x12345678u32.to_le_bytes();
|
||||||
|
/// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]);
|
||||||
|
/// ```
|
||||||
|
fn to_le_bytes(self) -> Self::Bytes;
|
||||||
|
|
||||||
|
/// Return the memory representation of this integer as a byte array in native byte order.
|
||||||
|
///
|
||||||
|
/// As the target platform's native endianness is used,
|
||||||
|
/// portable code should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
|
||||||
|
///
|
||||||
|
/// [`to_be_bytes`]: #method.to_be_bytes
|
||||||
|
/// [`to_le_bytes`]: #method.to_le_bytes
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use num_traits::PrimInt;
|
||||||
|
///
|
||||||
|
/// let bytes = 0x12345678u32.to_ne_bytes();
|
||||||
|
/// assert_eq!(bytes, if cfg!(target_endian = "big") {
|
||||||
|
/// [0x12, 0x34, 0x56, 0x78]
|
||||||
|
/// } else {
|
||||||
|
/// [0x78, 0x56, 0x34, 0x12]
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
|
fn to_ne_bytes(self) -> Self::Bytes;
|
||||||
|
|
||||||
|
/// Create an integer value from its representation as a byte array in big endian.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use num_traits::PrimInt;
|
||||||
|
///
|
||||||
|
/// let value = u32::from_be_bytes([0x12, 0x34, 0x56, 0x78]);
|
||||||
|
/// assert_eq!(value, 0x12345678);
|
||||||
|
/// ```
|
||||||
|
fn from_be_bytes(bytes: Self::Bytes) -> Self;
|
||||||
|
|
||||||
|
/// Create an integer value from its representation as a byte array in little endian.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use num_traits::PrimInt;
|
||||||
|
///
|
||||||
|
/// let value = u32::from_le_bytes([0x78, 0x56, 0x34, 0x12]);
|
||||||
|
/// assert_eq!(value, 0x12345678);
|
||||||
|
/// ```
|
||||||
|
fn from_le_bytes(bytes: Self::Bytes) -> Self;
|
||||||
|
|
||||||
|
/// Create an integer value from its memory representation as a byte array in native endianness.
|
||||||
|
///
|
||||||
|
/// As the target platform's native endianness is used,
|
||||||
|
/// portable code likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as appropriate instead.
|
||||||
|
///
|
||||||
|
/// [`from_be_bytes`]: #method.from_be_bytes
|
||||||
|
/// [`from_le_bytes`]: #method.from_le_bytes
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use num_traits::PrimInt;
|
||||||
|
///
|
||||||
|
/// let value = u32::from_ne_bytes(if cfg!(target_endian = "big") {
|
||||||
|
/// [0x12, 0x34, 0x56, 0x78]
|
||||||
|
/// } else {
|
||||||
|
/// [0x78, 0x56, 0x34, 0x12]
|
||||||
|
/// });
|
||||||
|
/// assert_eq!(value, 0x12345678);
|
||||||
|
/// ```
|
||||||
|
fn from_ne_bytes(bytes: Self::Bytes) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! prim_int_impl {
|
macro_rules! prim_int_impl {
|
||||||
|
@ -362,6 +461,40 @@ macro_rules! prim_int_impl {
|
||||||
fn pow(self, exp: u32) -> Self {
|
fn pow(self, exp: u32) -> Self {
|
||||||
<$T>::pow(self, exp)
|
<$T>::pow(self, exp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_be_bytes(self) -> Self::Bytes {
|
||||||
|
<$T>::to_be_bytes(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_le_bytes(self) -> Self::Bytes {
|
||||||
|
<$T>::to_le_bytes(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_ne_bytes(self) -> Self::Bytes {
|
||||||
|
<$T>::to_ne_bytes(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_be_bytes(bytes: Self::Bytes) -> Self {
|
||||||
|
<$T>::from_be_bytes(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_le_bytes(bytes: Self::Bytes) -> Self {
|
||||||
|
<$T>::from_le_bytes(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_ne_bytes(bytes: Self::Bytes) -> Self {
|
||||||
|
<$T>::from_ne_bytes(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Layout for $T {
|
||||||
|
type Bytes = [u8; size_of::<$T>()];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
36
src/lib.rs
36
src/lib.rs
|
@ -32,7 +32,7 @@ pub use float::FloatConst;
|
||||||
// pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
|
// pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
|
||||||
pub use cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
|
pub use cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
|
||||||
pub use identities::{one, zero, One, Zero};
|
pub use identities::{one, zero, One, Zero};
|
||||||
pub use int::PrimInt;
|
pub use int::{Layout, PrimInt};
|
||||||
pub use ops::checked::{
|
pub use ops::checked::{
|
||||||
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
|
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
|
||||||
};
|
};
|
||||||
|
@ -90,13 +90,12 @@ pub trait NumOps<Rhs = Self, Output = Self>:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Rhs, Output> NumOps<Rhs, Output> for T
|
impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
|
||||||
where
|
|
||||||
T: Add<Rhs, Output = Output>
|
T: Add<Rhs, Output = Output>
|
||||||
+ Sub<Rhs, Output = Output>
|
+ Sub<Rhs, Output = Output>
|
||||||
+ Mul<Rhs, Output = Output>
|
+ Mul<Rhs, Output = Output>
|
||||||
+ Div<Rhs, Output = Output>
|
+ Div<Rhs, Output = Output>
|
||||||
+ Rem<Rhs, Output = Output>,
|
+ Rem<Rhs, Output = Output>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,22 +104,14 @@ where
|
||||||
///
|
///
|
||||||
/// This is automatically implemented for types which implement the operators.
|
/// This is automatically implemented for types which implement the operators.
|
||||||
pub trait NumRef: Num + for<'r> NumOps<&'r Self> {}
|
pub trait NumRef: Num + for<'r> NumOps<&'r Self> {}
|
||||||
impl<T> NumRef for T
|
impl<T> NumRef for T where T: Num + for<'r> NumOps<&'r T> {}
|
||||||
where
|
|
||||||
T: Num + for<'r> NumOps<&'r T>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The trait for references which implement numeric operations, taking the
|
/// The trait for references which implement numeric operations, taking the
|
||||||
/// second operand either by value or by reference.
|
/// second operand either by value or by reference.
|
||||||
///
|
///
|
||||||
/// This is automatically implemented for types which implement the operators.
|
/// This is automatically implemented for types which implement the operators.
|
||||||
pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
|
pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
|
||||||
impl<T, Base> RefNum<Base> for T
|
impl<T, Base> RefNum<Base> for T where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
|
||||||
where
|
|
||||||
T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The trait for types implementing numeric assignment operators (like `+=`).
|
/// The trait for types implementing numeric assignment operators (like `+=`).
|
||||||
///
|
///
|
||||||
|
@ -130,9 +121,8 @@ pub trait NumAssignOps<Rhs = Self>:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Rhs> NumAssignOps<Rhs> for T
|
impl<T, Rhs> NumAssignOps<Rhs> for T where
|
||||||
where
|
T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
|
||||||
T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,22 +130,14 @@ where
|
||||||
///
|
///
|
||||||
/// This is automatically implemented for types which implement the operators.
|
/// This is automatically implemented for types which implement the operators.
|
||||||
pub trait NumAssign: Num + NumAssignOps {}
|
pub trait NumAssign: Num + NumAssignOps {}
|
||||||
impl<T> NumAssign for T
|
impl<T> NumAssign for T where T: Num + NumAssignOps {}
|
||||||
where
|
|
||||||
T: Num + NumAssignOps,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The trait for `NumAssign` types which also implement assignment operations
|
/// The trait for `NumAssign` types which also implement assignment operations
|
||||||
/// taking the second operand by reference.
|
/// taking the second operand by reference.
|
||||||
///
|
///
|
||||||
/// This is automatically implemented for types which implement the operators.
|
/// This is automatically implemented for types which implement the operators.
|
||||||
pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {}
|
pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {}
|
||||||
impl<T> NumAssignRef for T
|
impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {}
|
||||||
where
|
|
||||||
T: NumAssign + for<'r> NumAssignOps<&'r T>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! int_trait_impl {
|
macro_rules! int_trait_impl {
|
||||||
($name:ident for $($t:ty)*) => ($(
|
($name:ident for $($t:ty)*) => ($(
|
||||||
|
|
Loading…
Reference in New Issue