to_bytes.rs - source
Description: Source of the Rust file `library/core/src/../../portable-simd/crates/core_simd/src/to_bytes.rs`.

#
core/portable-simd/crates/core_simd/src/
to_bytes.rs

    1use crate::simd::{
    2    LaneCount, Simd, SimdElement, SupportedLaneCount,
    3    num::{SimdFloat, SimdInt, SimdUint},
    4};
    5
    6mod sealed {
    7    use super::*;
    8    pub trait Sealed {}
    9    impl<T: SimdElement, const N: usize> Sealed for Simd<T, N> where LaneCount<N>: SupportedLaneCount {}
    10}
    11use sealed::Sealed;
    12
    13/// Converts SIMD vectors to vectors of bytes
    14pub trait ToBytes: Sealed {
    15    /// This type, reinterpreted as bytes.
    16    type Bytes: Copy
    17        + Unpin
    18        + Send
    19        + Sync
    20        + AsRef<[u8]>
    21        + AsMut<[u8]>
    22        + SimdUint<Scalar = u8>
    23        + 'static;
    24
    25    /// Returns the memory representation of this integer as a byte array in native byte
    26    /// order.
    27    fn to_ne_bytes(self) -> Self::Bytes;
    28
    29    /// Returns the memory representation of this integer as a byte array in big-endian
    30    /// (network) byte order.
    31    fn to_be_bytes(self) -> Self::Bytes;
    32
    33    /// Returns the memory representation of this integer as a byte array in little-endian
    34    /// byte order.
    35    fn to_le_bytes(self) -> Self::Bytes;
    36
    37    /// Creates a native endian integer value from its memory representation as a byte array
    38    /// in native endianness.
    39    fn from_ne_bytes(bytes: Self::Bytes) -> Self;
    40
    41    /// Creates an integer value from its representation as a byte array in big endian.
    42    fn from_be_bytes(bytes: Self::Bytes) -> Self;
    43
    44    /// Creates an integer value from its representation as a byte array in little endian.
    45    fn from_le_bytes(bytes: Self::Bytes) -> Self;
    46}
    47
    48macro_rules! swap_bytes {
    49    { f32, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) };
    50    { f64, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) };
    51    { $ty:ty, $x:expr } => { $x.swap_bytes() }
    52}
    53
    54macro_rules! impl_to_bytes {
    55    { $ty:tt, 1  } => { impl_to_bytes! { $ty, 1  * [1, 2, 4, 8, 16, 32, 64] } };
    56    { $ty:tt, 2  } => { impl_to_bytes! { $ty, 2  * [1, 2, 4, 8, 16, 32] } };
    57    { $ty:tt, 4  } => { impl_to_bytes! { $ty, 4  * [1, 2, 4, 8, 16] } };
    58    { $ty:tt, 8  } => { impl_to_bytes! { $ty, 8  * [1, 2, 4, 8] } };
    59    { $ty:tt, 16 } => { impl_to_bytes! { $ty, 16 * [1, 2, 4] } };
    60    { $ty:tt, 32 } => { impl_to_bytes! { $ty, 32 * [1, 2] } };
    61    { $ty:tt, 64 } => { impl_to_bytes! { $ty, 64 * [1] } };
    62
    63    { $ty:tt, $size:literal * [$($elems:literal),*] } => {
    64        $(
    65        impl ToBytes for Simd<$ty, $elems> {
    66            type Bytes = Simd<u8, { $size * $elems }>;
    67
    68            #[inline]
    69            fn to_ne_bytes(self) -> Self::Bytes {
    70                // Safety: transmuting between vectors is safe
    71                unsafe {
    72                    #![allow(clippy::useless_transmute)]
    73                    core::mem::transmute(self)
    74                }
    75            }
    76
    77            #[inline]
    78            fn to_be_bytes(mut self) -> Self::Bytes {
    79                if !cfg!(target_endian = "big") {
    80                    self = swap_bytes!($ty, self);
    81                }
    82                self.to_ne_bytes()
    83            }
    84
    85            #[inline]
    86            fn to_le_bytes(mut self) -> Self::Bytes {
    87                if !cfg!(target_endian = "little") {
    88                    self = swap_bytes!($ty, self);
    89                }
    90                self.to_ne_bytes()
    91            }
    92
    93            #[inline]
    94            fn from_ne_bytes(bytes: Self::Bytes) -> Self {
    95                // Safety: transmuting between vectors is safe
    96                unsafe {
    97                    #![allow(clippy::useless_transmute)]
    98                    core::mem::transmute(bytes)
    99                }
    100            }
    101
    102            #[inline]
    103            fn from_be_bytes(bytes: Self::Bytes) -> Self {
    104                let ret = Self::from_ne_bytes(bytes);
    105                if cfg!(target_endian = "big") {
    106                    ret
    107                } else {
    108                    swap_bytes!($ty, ret)
    109                }
    110            }
    111
    112            #[inline]
    113            fn from_le_bytes(bytes: Self::Bytes) -> Self {
    114                let ret = Self::from_ne_bytes(bytes);
    115                if cfg!(target_endian = "little") {
    116                    ret
    117                } else {
    118                    swap_bytes!($ty, ret)
    119                }
    120            }
    121        }
    122        )*
    123    }
    124}
    125
    126impl_to_bytes! { u8, 1 }
    127impl_to_bytes! { u16, 2 }
    128impl_to_bytes! { u32, 4 }
    129impl_to_bytes! { u64, 8 }
    130#[cfg(target_pointer_width = "32")]
    131impl_to_bytes! { usize, 4 }
    132#[cfg(target_pointer_width = "64")]
    133impl_to_bytes! { usize, 8 }
    134
    135impl_to_bytes! { i8, 1 }
    136impl_to_bytes! { i16, 2 }
    137impl_to_bytes! { i32, 4 }
    138impl_to_bytes! { i64, 8 }
    139#[cfg(target_pointer_width = "32")]
    140impl_to_bytes! { isize, 4 }
    141#[cfg(target_pointer_width = "64")]
    142impl_to_bytes! { isize, 8 }
    143
    144impl_to_bytes! { f32, 4 }
    145impl_to_bytes! { f64, 8 }