From 3c582db8cb43dac1d13dd653078a68753d4baa99 Mon Sep 17 00:00:00 2001 From: Hoe Hao Cheng Date: Sun, 20 Sep 2020 15:49:43 +0800 Subject: [PATCH] Implement as_ne_bytes for floats and integers --- library/core/src/num/f32.rs | 29 ++++++++++++++++++++++++ library/core/src/num/f64.rs | 29 ++++++++++++++++++++++++ library/core/src/num/int_macros.rs | 35 +++++++++++++++++++++++++++++ library/core/src/num/uint_macros.rs | 35 +++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+) diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 043f0b14f249f..bf7c87f685d3c 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -773,6 +773,35 @@ impl f32 { self.to_bits().to_ne_bytes() } + /// Return the memory representation of this floating point number as a byte array in + /// native byte order. + /// + /// [`to_ne_bytes`] should be preferred over this whenever possible. + /// + /// [`to_ne_bytes`]: #method.to_ne_bytes + /// + /// # Examples + /// + /// ``` + /// #![feature(num_as_ne_bytes)] + /// let num = 12.5f32; + /// let bytes = num.as_ne_bytes(); + /// assert_eq!( + /// bytes, + /// if cfg!(target_endian = "big") { + /// &[0x41, 0x48, 0x00, 0x00] + /// } else { + /// &[0x00, 0x00, 0x48, 0x41] + /// } + /// ); + /// ``` + #[unstable(feature = "num_as_ne_bytes", issue = "76976")] + #[inline] + pub fn as_ne_bytes(&self) -> &[u8; 4] { + // SAFETY: `f32` is a plain old datatype so we can always transmute to it + unsafe { &*(self as *const Self as *const _) } + } + /// Create a floating point value from its representation as a byte array in big endian. /// /// # Examples diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 24624b88d59f6..e31e176ba1b0a 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -787,6 +787,35 @@ impl f64 { self.to_bits().to_ne_bytes() } + /// Return the memory representation of this floating point number as a byte array in + /// native byte order. + /// + /// [`to_ne_bytes`] should be preferred over this whenever possible. + /// + /// [`to_ne_bytes`]: #method.to_ne_bytes + /// + /// # Examples + /// + /// ``` + /// #![feature(num_as_ne_bytes)] + /// let num = 12.5f64; + /// let bytes = num.as_ne_bytes(); + /// assert_eq!( + /// bytes, + /// if cfg!(target_endian = "big") { + /// &[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + /// } else { + /// &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40] + /// } + /// ); + /// ``` + #[unstable(feature = "num_as_ne_bytes", issue = "76976")] + #[inline] + pub fn as_ne_bytes(&self) -> &[u8; 8] { + // SAFETY: `f64` is a plain old datatype so we can always transmute to it + unsafe { &*(self as *const Self as *const _) } + } + /// Create a floating point value from its representation as a byte array in big endian. /// /// # Examples diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 369175fb6ab1e..33fa26675f610 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2054,6 +2054,41 @@ assert_eq!( } } + doc_comment! { + concat!(" +Return the memory representation of this integer as a byte array in +native byte order. + +[`to_ne_bytes`] should be preferred over this whenever possible. + +[`to_ne_bytes`]: #method.to_ne_bytes +", + +" +# Examples + +``` +#![feature(num_as_ne_bytes)] +let num = ", $swap_op, stringify!($SelfT), "; +let bytes = num.as_ne_bytes(); +assert_eq!( + bytes, + if cfg!(target_endian = \"big\") { + &", $be_bytes, " + } else { + &", $le_bytes, " + } +); +```"), + #[unstable(feature = "num_as_ne_bytes", issue = "76976")] + #[inline] + pub fn as_ne_bytes(&self) -> &[u8; mem::size_of::()] { + // SAFETY: integers are plain old datatypes so we can always transmute them to + // arrays of bytes + unsafe { &*(self as *const Self as *const _) } + } + } + doc_comment! { concat!("Create an integer value from its representation as a byte array in big endian. diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 234c309961c9c..0de1cc6b1654a 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1812,6 +1812,41 @@ assert_eq!( } } + doc_comment! { + concat!(" +Return the memory representation of this integer as a byte array in +native byte order. + +[`to_ne_bytes`] should be preferred over this whenever possible. + +[`to_ne_bytes`]: #method.to_ne_bytes +", + +" +# Examples + +``` +#![feature(num_as_ne_bytes)] +let num = ", $swap_op, stringify!($SelfT), "; +let bytes = num.as_ne_bytes(); +assert_eq!( + bytes, + if cfg!(target_endian = \"big\") { + &", $be_bytes, " + } else { + &", $le_bytes, " + } +); +```"), + #[unstable(feature = "num_as_ne_bytes", issue = "76976")] + #[inline] + pub fn as_ne_bytes(&self) -> &[u8; mem::size_of::()] { + // SAFETY: integers are plain old datatypes so we can always transmute them to + // arrays of bytes + unsafe { &*(self as *const Self as *const _) } + } + } + doc_comment! { concat!("Create a native endian integer value from its representation as a byte array in big endian.