Merge 51a9e6114d
into 38655c91c1
This commit is contained in:
commit
78ffa9c5ae
13
build.rs
13
build.rs
|
@ -8,6 +8,19 @@ fn main() {
|
|||
} else if env::var_os("CARGO_FEATURE_I128").is_some() {
|
||||
panic!("i128 support was not detected!");
|
||||
}
|
||||
|
||||
if probe(r#"
|
||||
fn main() {
|
||||
let bytes = 0x1234567890123456u64.to_ne_bytes();
|
||||
|
||||
assert_eq!(bytes, if cfg!(target_endian = "big") {
|
||||
[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]
|
||||
} else {
|
||||
[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]
|
||||
});
|
||||
}"#) {
|
||||
println!("cargo:rustc-cfg=int_to_from_bytes");
|
||||
}
|
||||
}
|
||||
|
||||
/// Test if a code snippet can be compiled
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
|
||||
|
||||
use bounds::Bounded;
|
||||
use ops::bytes::IntToFromBytes;
|
||||
use ops::checked::*;
|
||||
use ops::saturating::Saturating;
|
||||
use {Num, NumCast};
|
||||
|
@ -51,6 +52,7 @@ pub trait PrimInt:
|
|||
+ CheckedMul<Output = Self>
|
||||
+ CheckedDiv<Output = Self>
|
||||
+ Saturating
|
||||
+ IntToFromBytes
|
||||
{
|
||||
/// Returns the number of ones in the binary representation of `self`.
|
||||
///
|
||||
|
|
|
@ -33,6 +33,7 @@ pub use float::FloatConst;
|
|||
pub use cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
|
||||
pub use identities::{one, zero, One, Zero};
|
||||
pub use int::PrimInt;
|
||||
pub use ops::bytes::IntToFromBytes;
|
||||
pub use ops::checked::{
|
||||
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
use core::borrow::{Borrow, BorrowMut};
|
||||
use core::cmp::{Eq, Ord, PartialEq, PartialOrd};
|
||||
use core::fmt::Debug;
|
||||
use core::hash::Hash;
|
||||
use core::mem::transmute;
|
||||
|
||||
pub trait IntToFromBytes {
|
||||
type Bytes: Debug
|
||||
+ AsRef<[u8]>
|
||||
+ AsMut<[u8]>
|
||||
+ PartialEq
|
||||
+ Eq
|
||||
+ PartialOrd
|
||||
+ Ord
|
||||
+ Hash
|
||||
+ Borrow<[u8]>
|
||||
+ BorrowMut<[u8]>
|
||||
+ Default;
|
||||
|
||||
/// Return the memory representation of this integer as a byte array in big-endian byte order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use num_traits::IntToFromBytes;
|
||||
///
|
||||
/// 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::IntToFromBytes;
|
||||
///
|
||||
/// 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::IntToFromBytes;
|
||||
///
|
||||
/// 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::IntToFromBytes;
|
||||
///
|
||||
/// 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::IntToFromBytes;
|
||||
///
|
||||
/// 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::IntToFromBytes;
|
||||
///
|
||||
/// 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! int_to_from_bytes_impl {
|
||||
($T:ty, $L:expr) => {
|
||||
#[cfg(feature = "int_to_from_bytes")]
|
||||
impl IntToFromBytes for $T {
|
||||
type Bytes = [u8; $L];
|
||||
|
||||
#[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)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "int_to_from_bytes"))]
|
||||
impl IntToFromBytes for $T {
|
||||
type Bytes = [u8; $L];
|
||||
|
||||
#[inline]
|
||||
fn to_be_bytes(self) -> Self::Bytes {
|
||||
<$T>::to_ne_bytes(<$T>::to_be(self))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_le_bytes(self) -> Self::Bytes {
|
||||
<$T>::to_ne_bytes(<$T>::to_le(self))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_ne_bytes(self) -> Self::Bytes {
|
||||
unsafe { transmute(self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_be_bytes(bytes: Self::Bytes) -> Self {
|
||||
Self::from_be(Self::from_ne_bytes(bytes))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_le_bytes(bytes: Self::Bytes) -> Self {
|
||||
Self::from_le(Self::from_ne_bytes(bytes))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_ne_bytes(bytes: Self::Bytes) -> Self {
|
||||
unsafe { transmute(bytes) }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// int_to_from_bytes_impl!(type, signed, unsigned);
|
||||
int_to_from_bytes_impl!(u8, 1);
|
||||
int_to_from_bytes_impl!(u16, 2);
|
||||
int_to_from_bytes_impl!(u32, 4);
|
||||
int_to_from_bytes_impl!(u64, 8);
|
||||
#[cfg(has_i128)]
|
||||
int_to_from_bytes_impl!(u128, 16);
|
||||
int_to_from_bytes_impl!(usize, 8);
|
||||
int_to_from_bytes_impl!(i8, 1);
|
||||
int_to_from_bytes_impl!(i16, 2);
|
||||
int_to_from_bytes_impl!(i32, 4);
|
||||
int_to_from_bytes_impl!(i64, 8);
|
||||
#[cfg(has_i128)]
|
||||
int_to_from_bytes_impl!(i128, 16);
|
||||
int_to_from_bytes_impl!(isize, 8);
|
|
@ -3,3 +3,4 @@ pub mod inv;
|
|||
pub mod mul_add;
|
||||
pub mod saturating;
|
||||
pub mod wrapping;
|
||||
pub mod bytes;
|
Loading…
Reference in New Issue