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::{LaneCount, Simd, SupportedLaneCount};
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 where
10 LaneCount<N>: SupportedLaneCount,
11 {
12 type Output = Self;
13 #[inline]
14 fn $trait_fn(self, rhs: $ty) -> Self::Output {
15 self.$trait_fn(Simd::splat(rhs))
16 }
17 }
18
19 impl<const N: usize> core::ops::$trait<&$ty> for Simd<$ty, N>
20 where
21 LaneCount<N>: SupportedLaneCount,
22 {
23 type Output = Self;
24 #[inline]
25 fn $trait_fn(self, rhs: &$ty) -> Self::Output {
26 self.$trait_fn(Simd::splat(*rhs))
27 }
28 }
29
30 impl<'lhs, const N: usize> core::ops::$trait<$ty> for &'lhs Simd<$ty, N>
31 where
32 LaneCount<N>: SupportedLaneCount,
33 {
34 type Output = Simd<$ty, N>;
35 #[inline]
36 fn $trait_fn(self, rhs: $ty) -> Self::Output {
37 self.$trait_fn(Simd::splat(rhs))
38 }
39 }
40
41 impl<'lhs, const N: usize> core::ops::$trait<&$ty> for &'lhs Simd<$ty, N>
42 where
43 LaneCount<N>: SupportedLaneCount,
44 {
45 type Output = Simd<$ty, N>;
46 #[inline]
47 fn $trait_fn(self, rhs: &$ty) -> Self::Output {
48 self.$trait_fn(Simd::splat(*rhs))
49 }
50 }
51 };
52 { $($ty:ty),* } => {
53 $(
54 impl_splatted_shifts! { impl Shl::shl for $ty }
55 impl_splatted_shifts! { impl Shr::shr for $ty }
56 )*
57 }
58}
59
60// In the past there were inference issues when generically splatting arguments.
61// Enumerate them instead.
62impl_splatted_shifts! { i8, i16, i32, i64, isize, u8, u16, u32, u64, usize }
63