diff --git a/Cargo.toml b/Cargo.toml index 672b4c2..179f2e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,11 @@ features = ["std"] [dependencies] +[build-dependencies] +rustc_version = "0.2" + [features] default = ["std"] std = [] i128 = [] +int_to_from_bytes = [] diff --git a/build.rs b/build.rs index fd60866..2188e95 100644 --- a/build.rs +++ b/build.rs @@ -1,3 +1,5 @@ +extern crate rustc_version; + use std::env; use std::io::Write; use std::process::{Command, Stdio}; @@ -8,6 +10,13 @@ fn main() { } else if env::var_os("CARGO_FEATURE_I128").is_some() { panic!("i128 support was not detected!"); } + + match rustc_version::version() { + Ok(ref version) if version.major >= 1 && version.minor >= 32 => { + println!("cargo:rustc-cfg=int_to_from_bytes"); + } + _ => {} + } } /// Test if a code snippet can be compiled diff --git a/src/int.rs b/src/int.rs index 225a3c9..c1d5694 100644 --- a/src/int.rs +++ b/src/int.rs @@ -1,4 +1,4 @@ -use core::mem::size_of; +use core::mem::transmute; use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr}; use bounds::Bounded; @@ -380,7 +380,7 @@ pub trait PrimInt: } macro_rules! prim_int_impl { - ($T:ty, $S:ty, $U:ty) => { + ($T:ty, $S:ty, $U:ty, $L:expr) => { impl PrimInt for $T { #[inline] fn count_ones(self) -> u32 { @@ -462,55 +462,97 @@ macro_rules! prim_int_impl { <$T>::pow(self, exp) } + #[cfg(feature = "int_to_from_bytes")] #[inline] fn to_be_bytes(self) -> Self::Bytes { <$T>::to_be_bytes(self) } + #[cfg(feature = "int_to_from_bytes")] #[inline] fn to_le_bytes(self) -> Self::Bytes { <$T>::to_le_bytes(self) } + #[cfg(feature = "int_to_from_bytes")] #[inline] fn to_ne_bytes(self) -> Self::Bytes { <$T>::to_ne_bytes(self) } + #[cfg(feature = "int_to_from_bytes")] #[inline] fn from_be_bytes(bytes: Self::Bytes) -> Self { <$T>::from_be_bytes(bytes) } + #[cfg(feature = "int_to_from_bytes")] #[inline] fn from_le_bytes(bytes: Self::Bytes) -> Self { <$T>::from_le_bytes(bytes) } + #[cfg(feature = "int_to_from_bytes")] #[inline] fn from_ne_bytes(bytes: Self::Bytes) -> Self { <$T>::from_ne_bytes(bytes) } + + #[cfg(not(feature = "int_to_from_bytes"))] + #[inline] + fn to_be_bytes(self) -> Self::Bytes { + <$T>::to_ne_bytes(<$T>::to_be(self)) + } + + #[cfg(not(feature = "int_to_from_bytes"))] + #[inline] + fn to_le_bytes(self) -> Self::Bytes { + <$T>::to_ne_bytes(<$T>::to_le(self)) + } + + #[cfg(not(feature = "int_to_from_bytes"))] + #[inline] + fn to_ne_bytes(self) -> Self::Bytes { + unsafe { transmute(self) } + } + + #[cfg(not(feature = "int_to_from_bytes"))] + #[inline] + fn from_be_bytes(bytes: Self::Bytes) -> Self { + Self::from_be(Self::from_ne_bytes(bytes)) + } + + #[cfg(not(feature = "int_to_from_bytes"))] + #[inline] + fn from_le_bytes(bytes: Self::Bytes) -> Self { + Self::from_le(Self::from_ne_bytes(bytes)) + } + + #[cfg(not(feature = "int_to_from_bytes"))] + #[inline] + fn from_ne_bytes(bytes: Self::Bytes) -> Self { + unsafe { transmute(bytes) } + } } impl Layout for $T { - type Bytes = [u8; size_of::<$T>()]; + type Bytes = [u8; $L]; } }; } // 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); +prim_int_impl!(u8, i8, u8, 1); +prim_int_impl!(u16, i16, u16, 2); +prim_int_impl!(u32, i32, u32, 4); +prim_int_impl!(u64, i64, u64, 8); #[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); +prim_int_impl!(u128, i128, u128, 16); +prim_int_impl!(usize, isize, usize, 8); +prim_int_impl!(i8, i8, u8, 1); +prim_int_impl!(i16, i16, u16, 2); +prim_int_impl!(i32, i32, u32, 4); +prim_int_impl!(i64, i64, u64, 8); #[cfg(has_i128)] -prim_int_impl!(i128, i128, u128); -prim_int_impl!(isize, isize, usize); +prim_int_impl!(i128, i128, u128, 16); +prim_int_impl!(isize, isize, usize, 8);