1use crate::simd::{
2 num::{SimdFloat, SimdInt, SimdUint},
3 LaneCount, Simd, SimdElement, SupportedLaneCount,
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/// Convert 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 /// Return 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 /// Return 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 /// Return 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 /// Create 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 /// Create an integer value from its representation as a byte array in big endian.
42 fn from_be_bytes(bytes: Self::Bytes) -> Self;
43
44 /// Create 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 }
146