Skip to content

Commit

Permalink
Rollup merge of rust-lang#51919 - tbu-:pr_num_to_from_bytes2, r=Simon…
Browse files Browse the repository at this point in the history
…Sapin

Provide `{to,from}_{ne,le,be}_bytes` functions on integers

If one doesn't view integers as containers of bytes, converting them to
bytes necessarily needs the specfication of encoding.

I think Rust is a language that wants to be explicit. The `to_bytes`
function is basically the opposite of that – it converts an integer into
the native byte representation, but there's no mention (in the function
name) of it being very much platform dependent. Therefore, I think it
would be better to replace that method by three methods, the explicit
`to_ne_bytes` ("native endian") which does the same thing and
`to_{le,be}_bytes` which return the little- resp. big-endian encoding.
  • Loading branch information
kennytm committed Aug 4, 2018
2 parents aefa307 + 0ddfae5 commit 52db0ed
Showing 1 changed file with 90 additions and 18 deletions.
108 changes: 90 additions & 18 deletions src/libcore/num/mod.rs
Expand Up @@ -1892,47 +1892,119 @@ $EndFeature, "
pub fn is_negative(self) -> bool { self < 0 }
}

/// Return the memory representation of this integer as a byte array.
/// Return the memory representation of this integer as a byte array in
/// big-endian (network) byte order.
///
/// The target platform’s native endianness is used.
/// Portable code likely wants to use this after [`to_be`] or [`to_le`].
/// # Examples
///
/// [`to_be`]: #method.to_be
/// [`to_le`]: #method.to_le
/// ```
/// #![feature(int_to_from_bytes)]
///
/// let bytes = 0x12345678i32.to_be_bytes();
/// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
/// ```
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[inline]
pub fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
self.to_be().to_ne_bytes()
}

/// Return the memory representation of this integer as a byte array in
/// little-endian byte order.
///
/// # Examples
///
/// ```
/// #![feature(int_to_from_bytes)]
///
/// let bytes = 0x12345678i32.to_le_bytes();
/// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]);
/// ```
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[inline]
pub fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
self.to_le().to_ne_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
///
/// ```
/// #![feature(int_to_from_bytes)]
///
/// let bytes = i32::min_value().to_be().to_bytes();
/// let bytes = i32::min_value().to_be().to_ne_bytes();
/// assert_eq!(bytes, [0x80, 0, 0, 0]);
/// ```
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[inline]
pub fn to_bytes(self) -> [u8; mem::size_of::<Self>()] {
pub fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
unsafe { mem::transmute(self) }
}

/// Create an integer value from its memory representation as a byte array.
/// Create an integer value from its representation as a byte array in
/// big endian.
///
/// The target platform’s native endianness is used.
/// Portable code likely wants to use [`from_be`] or [`from_le`] after this.
/// # Examples
///
/// [`from_be`]: #method.from_be
/// [`from_le`]: #method.from_le
/// ```
/// #![feature(int_to_from_bytes)]
///
/// let int = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]);
/// assert_eq!(int, 0x12_34_56_78);
/// ```
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[inline]
pub fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
Self::from_be(Self::from_ne_bytes(bytes))
}

/// Create an integer value from its representation as a byte array in
/// little endian.
///
/// # Examples
///
/// ```
/// #![feature(int_to_from_bytes)]
///
/// let int = i32::from_be(i32::from_bytes([0x80, 0, 0, 0]));
/// let int = i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]);
/// assert_eq!(int, 0x78_56_34_12);
/// ```
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[inline]
pub fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
Self::from_le(Self::from_ne_bytes(bytes))
}

/// 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
///
/// ```
/// #![feature(int_to_from_bytes)]
///
/// let int = i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0]));
/// assert_eq!(int, i32::min_value());
/// ```
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[inline]
pub fn from_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
pub fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
unsafe { mem::transmute(bytes) }
}
}
Expand Down Expand Up @@ -3517,7 +3589,7 @@ $EndFeature, "
/// let bytes = 0x1234_5678_u32.to_be().to_bytes();
/// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
/// ```
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[inline]
pub fn to_bytes(self) -> [u8; mem::size_of::<Self>()] {
unsafe { mem::transmute(self) }
Expand All @@ -3539,7 +3611,7 @@ $EndFeature, "
/// let int = u32::from_be(u32::from_bytes([0x12, 0x34, 0x56, 0x78]));
/// assert_eq!(int, 0x1234_5678_u32);
/// ```
#[unstable(feature = "int_to_from_bytes", issue = "49792")]
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[inline]
pub fn from_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
unsafe { mem::transmute(bytes) }
Expand Down

0 comments on commit 52db0ed

Please sign in to comment.