diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/Cargo.toml b/Cargo.toml index bcb6f75..8ef6d11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,5 +41,5 @@ version = "0.2.8" optional = true [dependencies.target-features] -version = "0.1.5" +version = "0.1.6" optional = true diff --git a/src/real/f32.rs b/src/real/f32.rs index aee7470..5e2afff 100644 --- a/src/real/f32.rs +++ b/src/real/f32.rs @@ -524,4 +524,22 @@ impl Real for f32 { fn total_cmp(&self, other: &Self) -> Ordering { self.total_cmp(other) } + + #[inline] + fn slice_as_simd(slice: &[Self]) -> (&[Self], &[Self::Simd], &[Self]) + where + LaneCount: SupportedLaneCount, + { + slice.as_simd() + } + + #[inline] + fn slice_as_simd_mut( + slice: &mut [Self], + ) -> (&mut [Self], &mut [Self::Simd], &mut [Self]) + where + LaneCount: SupportedLaneCount, + { + slice.as_simd_mut() + } } diff --git a/src/real/f64.rs b/src/real/f64.rs index aedb7b6..589cc70 100644 --- a/src/real/f64.rs +++ b/src/real/f64.rs @@ -524,4 +524,22 @@ impl Real for f64 { fn total_cmp(&self, other: &Self) -> Ordering { self.total_cmp(other) } + + #[inline] + fn slice_as_simd(slice: &[Self]) -> (&[Self], &[Self::Simd], &[Self]) + where + LaneCount: SupportedLaneCount, + { + slice.as_simd() + } + + #[inline] + fn slice_as_simd_mut( + slice: &mut [Self], + ) -> (&mut [Self], &mut [Self::Simd], &mut [Self]) + where + LaneCount: SupportedLaneCount, + { + slice.as_simd_mut() + } } diff --git a/src/real/mod.rs b/src/real/mod.rs index 71fce6a..5a8ab92 100644 --- a/src/real/mod.rs +++ b/src/real/mod.rs @@ -451,6 +451,53 @@ where { Self::Simd::splat(self) } + + /// Split a slice into a prefix, a middle of aligned SIMD types, and a suffix. + /// + /// You're only assured thatc`self.len() == prefix.len() + middle.len() * N + suffix.len()`. + /// + /// Notably, all of the following are possible: + /// + /// * `prefix.len() >= N`, + /// * `middle.is_empty()` despite `self.len() >= 3 * N`, + /// * `suffix.len() >= N`. + /// + /// That said, this is a safe method, so if you're only writing safe code, then this can at most + /// cause incorrect logic, not unsoundness. + /// + /// # Panics + /// + /// Panic if the size of the SIMD type is different from `N` times that of the scalar. + #[must_use] + fn slice_as_simd(slice: &[Self]) -> (&[Self], &[Self::Simd], &[Self]) + where + LaneCount: SupportedLaneCount; + + /// Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, and a mutable + /// suffix. + /// + /// You're only assured that `self.len() == prefix.len() + middle.len() * N + suffix.len()`. + /// + /// Notably, all of the following are possible: + /// + /// * `prefix.len() >= N`, + /// * `middle.is_empty()` despite `self.len() >= 3 * N`, + /// * `suffix.len() >= N`. + /// + /// That said, this is a safe method, so if you're only writing safe code, then this can at most + /// cause incorrect logic, not unsoundness. + /// + /// This is the mutable version of [`Self::slice_as_simd`]. + /// + /// # Panics + /// + /// Panic if the size of the SIMD type is different from `N` times that of the scalar. + #[must_use] + fn slice_as_simd_mut( + slice: &mut [Self], + ) -> (&mut [Self], &mut [Self::Simd], &mut [Self]) + where + LaneCount: SupportedLaneCount; } impl ApproxEq for R {