Skip to content

Commit 1c18f8f

Browse files
calebzulawskiworkingjubilee
authored andcommitted
Add byte conversions
1 parent ce92300 commit 1c18f8f

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

crates/core_simd/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ mod reduction;
1717
mod select;
1818
pub use select::Select;
1919

20+
mod to_bytes;
21+
pub use to_bytes::ToBytes;
22+
2023
mod comparisons;
2124
mod fmt;
2225
mod intrinsics;

crates/core_simd/src/to_bytes.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
mod sealed {
2+
pub trait Sealed {}
3+
}
4+
use sealed::Sealed;
5+
6+
/// Supporting trait for byte conversion functions.
7+
pub trait ToBytes: Sealed {
8+
/// The bytes representation of this type.
9+
type Bytes;
10+
11+
#[doc(hidden)]
12+
fn to_bytes_impl(self) -> Self::Bytes;
13+
14+
#[doc(hidden)]
15+
fn from_bytes_impl(bytes: Self::Bytes) -> Self;
16+
}
17+
18+
macro_rules! impl_to_bytes {
19+
{ $name:ident, $($int_width:literal -> $byte_width:literal),* } => {
20+
$(
21+
impl Sealed for crate::$name<$int_width> where Self: crate::LanesAtMost32 {}
22+
impl ToBytes for crate::$name<$int_width>
23+
where
24+
Self: crate::LanesAtMost32,
25+
crate::SimdU8<$byte_width>: crate::LanesAtMost32,
26+
{
27+
type Bytes = crate::SimdU8<$byte_width>;
28+
fn to_bytes_impl(self) -> Self::Bytes {
29+
unsafe { core::mem::transmute(self) }
30+
}
31+
fn from_bytes_impl(bytes: Self::Bytes) -> Self {
32+
unsafe { core::mem::transmute(bytes) }
33+
}
34+
}
35+
)*
36+
37+
impl<const LANES: usize> crate::$name<LANES>
38+
where
39+
Self: ToBytes + crate::LanesAtMost32,
40+
{
41+
/// Return the memory representation of this integer as a byte array in native byte
42+
/// order.
43+
pub fn to_ne_bytes(self) -> <Self as ToBytes>::Bytes { self.to_bytes_impl() }
44+
45+
/// Create a native endian integer value from its memory representation as a byte array
46+
/// in native endianness.
47+
pub fn from_ne_bytes(bytes: <Self as ToBytes>::Bytes) -> Self { Self::from_bytes_impl(bytes) }
48+
}
49+
}
50+
}
51+
52+
impl_to_bytes! { SimdU8, 1 -> 1, 2 -> 2, 4 -> 4, 8 -> 8, 16 -> 16, 32 -> 32 }
53+
impl_to_bytes! { SimdU16, 1 -> 2, 2 -> 4, 4 -> 8, 8 -> 16, 16 -> 32 }
54+
impl_to_bytes! { SimdU32, 1 -> 4, 2 -> 8, 4 -> 16, 8 -> 32 }
55+
impl_to_bytes! { SimdU64, 1 -> 8, 2 -> 16, 4 -> 32 }
56+
#[cfg(target_pointer_width = "32")]
57+
impl_to_bytes! { SimdUsize, 1 -> 4, 2 -> 8, 4 -> 16, 8 -> 32 }
58+
#[cfg(target_pointer_width = "64")]
59+
impl_to_bytes! { SimdUsize, 1 -> 8, 2 -> 16, 4 -> 32 }
60+
61+
impl_to_bytes! { SimdI8, 1 -> 1, 2 -> 2, 4 -> 4, 8 -> 8, 16 -> 16, 32 -> 32 }
62+
impl_to_bytes! { SimdI16, 1 -> 2, 2 -> 4, 4 -> 8, 8 -> 16, 16 -> 32 }
63+
impl_to_bytes! { SimdI32, 1 -> 4, 2 -> 8, 4 -> 16, 8 -> 32 }
64+
impl_to_bytes! { SimdI64, 1 -> 8, 2 -> 16, 4 -> 32 }
65+
#[cfg(target_pointer_width = "32")]
66+
impl_to_bytes! { SimdIsize, 1 -> 4, 2 -> 8, 4 -> 16, 8 -> 32 }
67+
#[cfg(target_pointer_width = "64")]
68+
impl_to_bytes! { SimdIsize, 1 -> 8, 2 -> 16, 4 -> 32 }

crates/core_simd/tests/to_bytes.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use core_simd::SimdU32;
2+
3+
#[test]
4+
fn byte_convert() {
5+
let int = SimdU32::from_array([0xdeadbeef, 0x8badf00d]);
6+
let bytes = int.to_ne_bytes();
7+
assert_eq!(int[0].to_ne_bytes(), bytes[..4]);
8+
assert_eq!(int[1].to_ne_bytes(), bytes[4..]);
9+
assert_eq!(SimdU32::from_ne_bytes(bytes), int);
10+
}

0 commit comments

Comments
 (0)