core_simd/ops/
shift_scalar.rs

1// Shift operations uniquely typically only have a scalar on the right-hand side.
2// Here, we implement shifts for scalar RHS arguments.
3
4use crate::simd::Simd;
5
6macro_rules! impl_splatted_shifts {
7    { impl $trait:ident :: $trait_fn:ident for $ty:ty } => {
8        impl<const N: usize> core::ops::$trait<$ty> for Simd<$ty, N>
9        {
10            type Output = Self;
11            #[inline]
12            fn $trait_fn(self, rhs: $ty) -> Self::Output {
13                self.$trait_fn(Simd::splat(rhs))
14            }
15        }
16
17        impl<const N: usize> core::ops::$trait<&$ty> for Simd<$ty, N>
18        {
19            type Output = Self;
20            #[inline]
21            fn $trait_fn(self, rhs: &$ty) -> Self::Output {
22                self.$trait_fn(Simd::splat(*rhs))
23            }
24        }
25
26        impl<'lhs, const N: usize> core::ops::$trait<$ty> for &'lhs Simd<$ty, N>
27        {
28            type Output = Simd<$ty, N>;
29            #[inline]
30            fn $trait_fn(self, rhs: $ty) -> Self::Output {
31                self.$trait_fn(Simd::splat(rhs))
32            }
33        }
34
35        impl<'lhs, const N: usize> core::ops::$trait<&$ty> for &'lhs Simd<$ty, N>
36        {
37            type Output = Simd<$ty, N>;
38            #[inline]
39            fn $trait_fn(self, rhs: &$ty) -> Self::Output {
40                self.$trait_fn(Simd::splat(*rhs))
41            }
42        }
43    };
44    { $($ty:ty),* } => {
45        $(
46        impl_splatted_shifts! { impl Shl::shl for $ty }
47        impl_splatted_shifts! { impl Shr::shr for $ty }
48        )*
49    }
50}
51
52// In the past there were inference issues when generically splatting arguments.
53// Enumerate them instead.
54impl_splatted_shifts! { i8, i16, i32, i64, isize, u8, u16, u32, u64, usize }