While writing helpers that are generic over the simd type, one painful part is that (afaict) there's no way to create SimdBase::Element values, because the associated type has no bounds. This means for example you can't do a T::splat of a calculated value, instead the caller has to pass values in from a context where the type is concrete.
Perhaps: add the following bounds to SimdBase::Element: From<u8> + TryFrom<u16> + TryFrom<u32> + TryFrom<u64> + TryFrom<f32> + TryFrom<f64>.
u8 is the only conversion that's guaranteed to succeed for all simd types, the others might fail on certain combinations (e.g. converting u64 to a u8x64::Element), so they have to be TryFrom. Given that simd functions have to be aggressively inlined, I think it's likely that the failure branch will be elided in most real code.
Going further, maybe define a custom conversion trait that allows all three main conversion flavors (checked, saturating, wrapping)?
pub trait FromScalar<T> {
type Err;
fn checked_from(v: T) -> Result<Self, Self::Err>;
fn saturating_from(v: T) -> Self;
fn wrapping_from(v: T) -> Self;
}
For my own code the values will never overflow so wrapping/truncating conversion would be the most efficient, I don't know if other code would benefit from the other conversion styles.
While writing helpers that are generic over the simd type, one painful part is that (afaict) there's no way to create SimdBase::Element values, because the associated type has no bounds. This means for example you can't do a
T::splatof a calculated value, instead the caller has to pass values in from a context where the type is concrete.Perhaps: add the following bounds to SimdBase::Element:
From<u8> + TryFrom<u16> + TryFrom<u32> + TryFrom<u64> + TryFrom<f32> + TryFrom<f64>.u8 is the only conversion that's guaranteed to succeed for all simd types, the others might fail on certain combinations (e.g. converting u64 to a u8x64::Element), so they have to be TryFrom. Given that simd functions have to be aggressively inlined, I think it's likely that the failure branch will be elided in most real code.
Going further, maybe define a custom conversion trait that allows all three main conversion flavors (checked, saturating, wrapping)?
For my own code the values will never overflow so wrapping/truncating conversion would be the most efficient, I don't know if other code would benefit from the other conversion styles.