Skip to content

Commit 3ac6418

Browse files
Merge pull request #12 from LukasKalbertodt/impl-atom-for-arrays
Implement `Atom` & `AtomLogic` for small, pow2-sized integer arrays
2 parents 8f6553e + ff56689 commit 3ac6418

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

src/impls.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,58 @@ macro_rules! impl_option_non_zero {
429429
#[cfg(target_has_atomic = "ptr")] impl_option_non_zero!(NonZeroUsize = usize);
430430
#[cfg(target_has_atomic = "ptr")] impl_option_non_zero!(NonZeroIsize = isize);
431431

432+
macro_rules! impl_int8_arrays {
433+
($elem:ident, $len:literal, $repr:ident) => {
434+
impl Atom for [$elem; $len] {
435+
type Repr = $repr;
436+
fn pack(self) -> Self::Repr {
437+
$repr::from_ne_bytes(self.map(|e| e as _))
438+
}
439+
fn unpack(src: Self::Repr) -> Self {
440+
src.to_ne_bytes().map(|e| e as _)
441+
}
442+
}
443+
impl AtomLogic for [$elem; $len] {}
444+
};
445+
}
446+
447+
#[cfg(target_has_atomic = "16")] impl_int8_arrays!(u8, 2, u16);
448+
#[cfg(target_has_atomic = "32")] impl_int8_arrays!(u8, 4, u32);
449+
#[cfg(target_has_atomic = "64")] impl_int8_arrays!(u8, 8, u64);
450+
#[cfg(target_has_atomic = "16")] impl_int8_arrays!(i8, 2, u16);
451+
#[cfg(target_has_atomic = "32")] impl_int8_arrays!(i8, 4, u32);
452+
#[cfg(target_has_atomic = "64")] impl_int8_arrays!(i8, 8, u64);
453+
454+
macro_rules! impl_int_arrays {
455+
($unsigned_elem:ident, $signed_elem:ident, $len:literal, $repr:ident, $nested:tt, $flat:tt) => {
456+
impl_small_primitive_array!($unsigned_elem, $len, $repr, $nested, $flat);
457+
impl_small_primitive_array!($signed_elem, $len, $repr, $nested, $flat);
458+
};
459+
}
460+
461+
macro_rules! impl_small_primitive_array {
462+
($elem:ident, $len:literal, $repr:ident, $nested:tt, $flat:tt) => {
463+
impl Atom for [$elem; $len] {
464+
type Repr = $repr;
465+
fn pack(self) -> Self::Repr {
466+
let $nested = self.map(|x| x.to_ne_bytes());
467+
Self::Repr::from_ne_bytes($flat)
468+
}
469+
fn unpack(src: Self::Repr) -> Self {
470+
let $flat = src.to_ne_bytes();
471+
$nested.map($elem::from_ne_bytes)
472+
}
473+
}
474+
impl AtomLogic for [$elem; $len] {}
475+
};
476+
}
477+
#[cfg(target_has_atomic = "32")] impl_int_arrays!(u16, i16, 2, u32,
478+
[[b0, b1], [b2, b3]], [b0, b1, b2, b3]);
479+
#[cfg(target_has_atomic = "64")] impl_int_arrays!(u16, i16, 4, u64,
480+
[[b0, b1], [b2, b3], [b4, b5], [b6, b7]], [b0, b1, b2, b3, b4, b5, b6, b7]);
481+
#[cfg(target_has_atomic = "64")] impl_int_arrays!(u32, i32, 2, u64,
482+
[[b0, b1, b2, b3], [b4, b5, b6, b7]], [b0, b1, b2, b3, b4, b5, b6, b7]);
483+
432484
/// This is just a dummy module to have doc tests.
433485
///
434486
/// ```
@@ -468,6 +520,19 @@ macro_rules! impl_option_non_zero {
468520
/// assert_impl_atom::<f32>();
469521
/// assert_impl_atom::<f64>();
470522
///
523+
/// assert_impl_atom::<[u8; 2]>();
524+
/// assert_impl_atom::<[u8; 4]>();
525+
/// assert_impl_atom::<[u8; 8]>();
526+
/// assert_impl_atom::<[i8; 2]>();
527+
/// assert_impl_atom::<[i8; 4]>();
528+
/// assert_impl_atom::<[i8; 8]>();
529+
/// assert_impl_atom::<[u16; 2]>();
530+
/// assert_impl_atom::<[u16; 4]>();
531+
/// assert_impl_atom::<[i16; 2]>();
532+
/// assert_impl_atom::<[i16; 4]>();
533+
/// assert_impl_atom::<[u32; 2]>();
534+
/// assert_impl_atom::<[i32; 2]>();
535+
///
471536
/// assert_impl_atom::<core::num::NonZeroU8>();
472537
/// assert_impl_atom::<core::num::NonZeroI8>();
473538
/// assert_impl_atom::<core::num::NonZeroU16>();

src/tests.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,26 @@ gen_tests_for_primitives!(_f32, f32, 7.0f32, 33.0f32, [n n]);
160160
gen_tests_for_primitives!(_f64, f64, 7.0f64, 33.0f64, [n n]);
161161
gen_tests_for_primitives!(_char, char, 'x', '♥', [n n]);
162162

163+
// Arrays. They do implement `AtomLogic` but the logic tests don't work with them.
164+
// mod ty val0 val1 [logic int]
165+
gen_tests_for_primitives!(_u8array2, [u8; 2], [3u8, 79], [17u8, 240], [n n]);
166+
gen_tests_for_primitives!(_u8array4, [u8; 4], [3u8, 79, 13, 230], [17u8, 240, 59, 184], [n n]);
167+
gen_tests_for_primitives!(_u8array8, [u8; 8], [3u8, 79, 13, 230, 4, 80, 14, 231],
168+
[17u8, 240, 59, 184, 18, 241, 60, 185], [n n]);
169+
gen_tests_for_primitives!(_u16array2, [u16; 2], [3u16, 257], [17u16, 9999], [n n]);
170+
gen_tests_for_primitives!(_u16array4, [u16; 4], [3u16, 257, 13, 230],
171+
[17u16, 9999, 59, 17003], [n n]);
172+
gen_tests_for_primitives!(_u32array2, [u32; 2], [3u32, 77977], [17u32, 190247], [n n]);
173+
gen_tests_for_primitives!(_i8array2, [i8; 2], [3i8, -79], [-17i8, 113], [n n]);
174+
gen_tests_for_primitives!(_i8array4, [i8; 4], [3i8, -79, 13, -120],
175+
[-17i8, 113, -59, -98], [n n]);
176+
gen_tests_for_primitives!(_i8array8, [i8; 8], [3i8, -79, 13, -120, 4, 80, -14, 111],
177+
[-17i8, 113, -59, -98, -18, 114, 60, -128], [n n]);
178+
gen_tests_for_primitives!(_i16array2, [i16; 2], [3i16, -257], [17i16, -9999], [n n]);
179+
gen_tests_for_primitives!(_i16array4, [i16; 4], [3i16, -257, 13, 230],
180+
[17i16, -9999, -59, 17003], [n n]);
181+
gen_tests_for_primitives!(_i32array2, [i32; 2], [3i32, -77977], [-17i32, 190247], [n n]);
182+
163183
mod _ptr {
164184
use super::*;
165185
generic_tests!(Foo, Foo::Nothing, Foo::Set(0b101));

0 commit comments

Comments
 (0)