aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2018-04-01 10:58:57 -0400
committerAndrew Gallant <jamslam@gmail.com>2018-04-01 10:58:57 -0400
commitdeb58862ddc0d02142abb4ffed6a966ada0fdec6 (patch)
tree836374786b908e0a4276b65089f9a0ac4fd2c84d /src
parente00c2331f66b7b0909d4484fba8c76054ab843a5 (diff)
downloadbyteorder-deb58862ddc0d02142abb4ffed6a966ada0fdec6.tar.gz
style: remove all uses of transmute
We should have done this from the start. Everything can be accomplished via pointer casts. Benchmarks show negligible differences.
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs134
1 files changed, 96 insertions, 38 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 9f668c5..d49d344 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -47,8 +47,8 @@ extern crate core;
use core::fmt::Debug;
use core::hash::Hash;
-use core::mem::transmute;
use core::ptr::copy_nonoverlapping;
+use core::slice;
#[cfg(feature = "std")]
pub use io::{ReadBytesExt, WriteBytesExt};
@@ -629,7 +629,7 @@ pub trait ByteOrder
/// ```
#[inline]
fn read_f32(buf: &[u8]) -> f32 {
- unsafe { transmute(Self::read_u32(buf)) }
+ unsafe { *(&Self::read_u32(buf) as *const u32 as *const f32) }
}
/// Reads a IEEE754 double-precision (8 bytes) floating point number.
@@ -652,7 +652,7 @@ pub trait ByteOrder
/// ```
#[inline]
fn read_f64(buf: &[u8]) -> f64 {
- unsafe { transmute(Self::read_u64(buf)) }
+ unsafe { *(&Self::read_u64(buf) as *const u64 as *const f64) }
}
/// Writes a signed 16 bit integer `n` to `buf`.
@@ -833,7 +833,8 @@ pub trait ByteOrder
/// ```
#[inline]
fn write_f32(buf: &mut [u8], n: f32) {
- Self::write_u32(buf, unsafe { transmute(n) })
+ let n = unsafe { *(&n as *const f32 as *const u32) };
+ Self::write_u32(buf, n)
}
/// Writes a IEEE754 double-precision (8 bytes) floating point number.
@@ -856,7 +857,8 @@ pub trait ByteOrder
/// ```
#[inline]
fn write_f64(buf: &mut [u8], n: f64) {
- Self::write_u64(buf, unsafe { transmute(n) })
+ let n = unsafe { *(&n as *const f64 as *const u64) };
+ Self::write_u64(buf, n)
}
/// Reads unsigned 16 bit integers from `src` into `dst`.
@@ -975,7 +977,10 @@ pub trait ByteOrder
/// ```
#[inline]
fn read_i16_into(src: &[u8], dst: &mut [i16]) {
- Self::read_u16_into(src, unsafe { transmute(dst) });
+ let dst = unsafe {
+ slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u16, dst.len())
+ };
+ Self::read_u16_into(src, dst)
}
/// Reads signed 32 bit integers from `src` into `dst`.
@@ -1001,7 +1006,10 @@ pub trait ByteOrder
/// ```
#[inline]
fn read_i32_into(src: &[u8], dst: &mut [i32]) {
- Self::read_u32_into(src, unsafe { transmute(dst) });
+ let dst = unsafe {
+ slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len())
+ };
+ Self::read_u32_into(src, dst);
}
/// Reads signed 64 bit integers from `src` into `dst`.
@@ -1027,7 +1035,10 @@ pub trait ByteOrder
/// ```
#[inline]
fn read_i64_into(src: &[u8], dst: &mut [i64]) {
- Self::read_u64_into(src, unsafe { transmute(dst) });
+ let dst = unsafe {
+ slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len())
+ };
+ Self::read_u64_into(src, dst);
}
/// Reads signed 128 bit integers from `src` into `dst`.
@@ -1054,7 +1065,10 @@ pub trait ByteOrder
#[cfg(feature = "i128")]
#[inline]
fn read_i128_into(src: &[u8], dst: &mut [i128]) {
- Self::read_u128_into(src, unsafe { transmute(dst) });
+ let dst = unsafe {
+ slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u128, dst.len())
+ };
+ Self::read_u128_into(src, dst);
}
/// Reads IEEE754 single-precision (4 bytes) floating point numbers from
@@ -1081,7 +1095,10 @@ pub trait ByteOrder
/// ```
#[inline]
fn read_f32_into_unchecked(src: &[u8], dst: &mut [f32]) {
- Self::read_u32_into(src, unsafe { transmute(dst) });
+ let dst = unsafe {
+ slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u32, dst.len())
+ };
+ Self::read_u32_into(src, dst);
}
/// Reads IEEE754 single-precision (4 bytes) floating point numbers from
@@ -1108,7 +1125,10 @@ pub trait ByteOrder
/// ```
#[inline]
fn read_f64_into_unchecked(src: &[u8], dst: &mut [f64]) {
- Self::read_u64_into(src, unsafe { transmute(dst) });
+ let dst = unsafe {
+ slice::from_raw_parts_mut(dst.as_mut_ptr() as *mut u64, dst.len())
+ };
+ Self::read_u64_into(src, dst);
}
/// Writes unsigned 16 bit integers from `src` into `dst`.
@@ -1226,7 +1246,10 @@ pub trait ByteOrder
/// assert_eq!(numbers_given, numbers_got);
/// ```
fn write_i16_into(src: &[i16], dst: &mut [u8]) {
- Self::write_u16_into(unsafe { transmute(src) }, dst);
+ let src = unsafe {
+ slice::from_raw_parts(src.as_ptr() as *const u16, src.len())
+ };
+ Self::write_u16_into(src, dst);
}
/// Writes signed 32 bit integers from `src` into `dst`.
@@ -1251,7 +1274,10 @@ pub trait ByteOrder
/// assert_eq!(numbers_given, numbers_got);
/// ```
fn write_i32_into(src: &[i32], dst: &mut [u8]) {
- Self::write_u32_into(unsafe { transmute(src) }, dst);
+ let src = unsafe {
+ slice::from_raw_parts(src.as_ptr() as *const u32, src.len())
+ };
+ Self::write_u32_into(src, dst);
}
/// Writes signed 64 bit integers from `src` into `dst`.
@@ -1276,7 +1302,10 @@ pub trait ByteOrder
/// assert_eq!(numbers_given, numbers_got);
/// ```
fn write_i64_into(src: &[i64], dst: &mut [u8]) {
- Self::write_u64_into(unsafe { transmute(src) }, dst);
+ let src = unsafe {
+ slice::from_raw_parts(src.as_ptr() as *const u64, src.len())
+ };
+ Self::write_u64_into(src, dst);
}
/// Writes signed 128 bit integers from `src` into `dst`.
@@ -1302,7 +1331,10 @@ pub trait ByteOrder
/// ```
#[cfg(feature = "i128")]
fn write_i128_into(src: &[i128], dst: &mut [u8]) {
- Self::write_u128_into(unsafe { transmute(src) }, dst);
+ let src = unsafe {
+ slice::from_raw_parts(src.as_ptr() as *const u128, src.len())
+ };
+ Self::write_u128_into(src, dst);
}
/// Writes IEEE754 single-precision (4 bytes) floating point numbers from
@@ -1330,7 +1362,10 @@ pub trait ByteOrder
/// assert_eq!(numbers_given, numbers_got);
/// ```
fn write_f32_into(src: &[f32], dst: &mut [u8]) {
- Self::write_u32_into(unsafe { transmute(src) }, dst);
+ let src = unsafe {
+ slice::from_raw_parts(src.as_ptr() as *const u32, src.len())
+ };
+ Self::write_u32_into(src, dst);
}
/// Writes IEEE754 double-precision (8 bytes) floating point numbers from
@@ -1358,7 +1393,10 @@ pub trait ByteOrder
/// assert_eq!(numbers_given, numbers_got);
/// ```
fn write_f64_into(src: &[f64], dst: &mut [u8]) {
- Self::write_u64_into(unsafe { transmute(src) }, dst);
+ let src = unsafe {
+ slice::from_raw_parts(src.as_ptr() as *const u64, src.len())
+ };
+ Self::write_u64_into(src, dst);
}
/// Converts the given slice of unsigned 16 bit integers to a particular
@@ -1478,8 +1516,11 @@ pub trait ByteOrder
/// }
/// ```
#[inline]
- fn from_slice_i16(numbers: &mut [i16]) {
- Self::from_slice_u16(unsafe { transmute(numbers) });
+ fn from_slice_i16(src: &mut [i16]) {
+ let src = unsafe {
+ slice::from_raw_parts_mut(src.as_ptr() as *mut u16, src.len())
+ };
+ Self::from_slice_u16(src);
}
/// Converts the given slice of signed 32 bit integers to a particular
@@ -1504,8 +1545,11 @@ pub trait ByteOrder
/// }
/// ```
#[inline]
- fn from_slice_i32(numbers: &mut [i32]) {
- Self::from_slice_u32(unsafe { transmute(numbers) });
+ fn from_slice_i32(src: &mut [i32]) {
+ let src = unsafe {
+ slice::from_raw_parts_mut(src.as_ptr() as *mut u32, src.len())
+ };
+ Self::from_slice_u32(src);
}
/// Converts the given slice of signed 64 bit integers to a particular
@@ -1530,8 +1574,11 @@ pub trait ByteOrder
/// }
/// ```
#[inline]
- fn from_slice_i64(numbers: &mut [i64]) {
- Self::from_slice_u64(unsafe { transmute(numbers) });
+ fn from_slice_i64(src: &mut [i64]) {
+ let src = unsafe {
+ slice::from_raw_parts_mut(src.as_ptr() as *mut u64, src.len())
+ };
+ Self::from_slice_u64(src);
}
/// Converts the given slice of signed 128 bit integers to a particular
@@ -1559,8 +1606,11 @@ pub trait ByteOrder
/// ```
#[cfg(feature = "i128")]
#[inline]
- fn from_slice_i128(numbers: &mut [i128]) {
- Self::from_slice_u128(unsafe { transmute(numbers) });
+ fn from_slice_i128(src: &mut [i128]) {
+ let src = unsafe {
+ slice::from_raw_parts_mut(src.as_ptr() as *mut u128, src.len())
+ };
+ Self::from_slice_u128(src);
}
/// Converts the given slice of IEEE754 single-precision (4 bytes) floating
@@ -1692,7 +1742,7 @@ macro_rules! write_num_bytes {
assert!($size <= $dst.len());
unsafe {
// N.B. https://github.com/rust-lang/rust/issues/22776
- let bytes = transmute::<_, [u8; $size]>($n.$which());
+ let bytes = *(&$n.$which() as *const _ as *const [u8; $size]);
copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
}
});
@@ -1812,7 +1862,7 @@ impl ByteOrder for BigEndian {
assert!(pack_size(n) <= nbytes && nbytes <= 8);
assert!(nbytes <= buf.len());
unsafe {
- let bytes: [u8; 8] = transmute(n.to_be());
+ let bytes = *(&n.to_be() as *const u64 as *const [u8; 8]);
copy_nonoverlapping(
bytes.as_ptr().offset((8 - nbytes) as isize),
buf.as_mut_ptr(),
@@ -1826,7 +1876,7 @@ impl ByteOrder for BigEndian {
assert!(pack_size128(n) <= nbytes && nbytes <= 16);
assert!(nbytes <= buf.len());
unsafe {
- let bytes: [u8; 16] = transmute(n.to_be());
+ let bytes = *(&n.to_be() as *const u128 as *const [u8; 16]);
copy_nonoverlapping(
bytes.as_ptr().offset((16 - nbytes) as isize),
buf.as_mut_ptr(),
@@ -1933,8 +1983,10 @@ impl ByteOrder for BigEndian {
fn from_slice_f32(numbers: &mut [f32]) {
if cfg!(target_endian = "little") {
for n in numbers {
- let int: u32 = unsafe { transmute(*n) };
- *n = unsafe { transmute(int.to_be()) };
+ unsafe {
+ let int = *(n as *const f32 as *const u32);
+ *n = *(&int.to_be() as *const u32 as *const f32);
+ }
}
}
}
@@ -1943,8 +1995,10 @@ impl ByteOrder for BigEndian {
fn from_slice_f64(numbers: &mut [f64]) {
if cfg!(target_endian = "little") {
for n in numbers {
- let int: u64 = unsafe { transmute(*n) };
- *n = unsafe { transmute(int.to_be()) };
+ unsafe {
+ let int = *(n as *const f64 as *const u64);
+ *n = *(&int.to_be() as *const u64 as *const f64);
+ }
}
}
}
@@ -2021,7 +2075,7 @@ impl ByteOrder for LittleEndian {
assert!(pack_size(n as u64) <= nbytes && nbytes <= 8);
assert!(nbytes <= buf.len());
unsafe {
- let bytes: [u8; 8] = transmute(n.to_le());
+ let bytes = *(&n.to_le() as *const u64 as *const [u8; 8]);
copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
}
}
@@ -2032,7 +2086,7 @@ impl ByteOrder for LittleEndian {
assert!(pack_size128(n as u128) <= nbytes && nbytes <= 16);
assert!(nbytes <= buf.len());
unsafe {
- let bytes: [u8; 16] = transmute(n.to_le());
+ let bytes = *(&n.to_le() as *const u128 as *const [u8; 16]);
copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
}
}
@@ -2136,8 +2190,10 @@ impl ByteOrder for LittleEndian {
fn from_slice_f32(numbers: &mut [f32]) {
if cfg!(target_endian = "big") {
for n in numbers {
- let int: u32 = unsafe { transmute(*n) };
- *n = unsafe { transmute(int.to_le()) };
+ unsafe {
+ let int = *(n as *const f32 as *const u32);
+ *n = *(&int.to_le() as *const u32 as *const f32);
+ }
}
}
}
@@ -2146,8 +2202,10 @@ impl ByteOrder for LittleEndian {
fn from_slice_f64(numbers: &mut [f64]) {
if cfg!(target_endian = "big") {
for n in numbers {
- let int: u64 = unsafe { transmute(*n) };
- *n = unsafe { transmute(int.to_le()) };
+ unsafe {
+ let int = *(n as *const f64 as *const u64);
+ *n = *(&int.to_le() as *const u64 as *const f64);
+ }
}
}
}