Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit c7d9ad8

Browse files
committed
Add shift_elements_{left,right} for Simd and Masks
1 parent 5fb43ca commit c7d9ad8

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

crates/core_simd/src/swizzle.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,56 @@ where
251251
Rotate::<OFFSET>::swizzle(self)
252252
}
253253

254+
/// Shifts the vector elements to the left by `OFFSET`, padding by the
255+
/// default value (e.g., zero) to the right.
256+
#[inline]
257+
#[must_use = "method returns a new vector and does not mutate the original inputs"]
258+
fn shift_elements_left<const OFFSET: usize>(self) -> Self
259+
where
260+
T: Default,
261+
{
262+
struct Shift<const OFFSET: usize>;
263+
264+
impl<const OFFSET: usize, const N: usize> Swizzle<N> for Shift<OFFSET> {
265+
const INDEX: [usize; N] = const {
266+
let mut index = [N; N];
267+
let mut i = 0;
268+
while i + OFFSET < N {
269+
index[i] = i + OFFSET;
270+
i += 1;
271+
}
272+
index
273+
};
274+
}
275+
276+
Shift::<OFFSET>::concat_swizzle(self, Self::default())
277+
}
278+
279+
/// Shifts the vector elements to the right by `OFFSET`, padding by the
280+
/// default value (e.g., zero) from the left.
281+
#[inline]
282+
#[must_use = "method returns a new vector and does not mutate the original inputs"]
283+
fn shift_elements_right<const OFFSET: usize>(self) -> Self
284+
where
285+
T: Default,
286+
{
287+
struct Shift<const OFFSET: usize>;
288+
289+
impl<const OFFSET: usize, const N: usize> Swizzle<N> for Shift<OFFSET> {
290+
const INDEX: [usize; N] = const {
291+
let mut index = [N; N];
292+
let mut i = OFFSET;
293+
while i < N {
294+
index[i] = i - OFFSET;
295+
i += 1;
296+
}
297+
index
298+
};
299+
}
300+
301+
Shift::<OFFSET>::concat_swizzle(self, Self::default())
302+
}
303+
254304
/// Interleave two vectors.
255305
///
256306
/// The resulting vectors contain elements taken alternatively from `self` and `other`, first
@@ -451,6 +501,30 @@ where
451501
unsafe { Self::from_int_unchecked(self.to_int().rotate_elements_right::<OFFSET>()) }
452502
}
453503

504+
/// Shifts the mask elements to the left by `OFFSET`, padding by the
505+
/// default value (e.g., zero) to the right.
506+
#[inline]
507+
#[must_use = "method returns a new vector and does not mutate the original inputs"]
508+
pub fn shift_elements_left<const OFFSET: usize>(self) -> Self
509+
where
510+
T: Default,
511+
{
512+
// Safety: swizzles are safe for masks
513+
unsafe { Self::from_int_unchecked(self.to_int().shift_elements_left::<OFFSET>()) }
514+
}
515+
516+
/// Shifts the mask elements to the right by `OFFSET`, padding by the
517+
/// default value (e.g., `false`) from the left.
518+
#[inline]
519+
#[must_use = "method returns a new vector and does not mutate the original inputs"]
520+
pub fn shift_elements_right<const OFFSET: usize>(self) -> Self
521+
where
522+
T: Default,
523+
{
524+
// Safety: swizzles are safe for masks
525+
unsafe { Self::from_int_unchecked(self.to_int().shift_elements_right::<OFFSET>()) }
526+
}
527+
454528
/// Interleave two masks.
455529
///
456530
/// The resulting masks contain elements taken alternatively from `self` and `other`, first

0 commit comments

Comments
 (0)