Skip to content

Commit

Permalink
Auto merge of rust-lang#76610 - hch12907:master, r=LukasKalbertodt
Browse files Browse the repository at this point in the history
Implement as_ne_bytes() for integers and floats

This is related to issue rust-lang#64464.

I am pretty sure that these functions are actually const-ify-able, and technically as_bits() can also be implemented for floats, but I might need some comments on both.
  • Loading branch information
bors committed Oct 4, 2020
2 parents 0d37dca + 3c582db commit 0644cc1
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 0 deletions.
29 changes: 29 additions & 0 deletions library/core/src/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions library/core/src/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Self>()] {
// 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.
Expand Down
35 changes: 35 additions & 0 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Self>()] {
// 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.
Expand Down

0 comments on commit 0644cc1

Please sign in to comment.