#![forbid(unsafe_code)]
use super::types::{I16x8, I32x4, U8x16};
pub trait SimdOps: Send + Sync {
fn name(&self) -> &'static str;
fn is_available(&self) -> bool;
fn add_i16x8(&self, a: I16x8, b: I16x8) -> I16x8;
fn sub_i16x8(&self, a: I16x8, b: I16x8) -> I16x8;
fn mul_i16x8(&self, a: I16x8, b: I16x8) -> I16x8;
fn add_i32x4(&self, a: I32x4, b: I32x4) -> I32x4;
fn sub_i32x4(&self, a: I32x4, b: I32x4) -> I32x4;
fn min_i16x8(&self, a: I16x8, b: I16x8) -> I16x8;
fn max_i16x8(&self, a: I16x8, b: I16x8) -> I16x8;
fn clamp_i16x8(&self, v: I16x8, min: i16, max: i16) -> I16x8;
fn min_u8x16(&self, a: U8x16, b: U8x16) -> U8x16;
fn max_u8x16(&self, a: U8x16, b: U8x16) -> U8x16;
fn clamp_u8x16(&self, v: U8x16, min: u8, max: u8) -> U8x16;
fn horizontal_sum_i16x8(&self, v: I16x8) -> i32;
fn horizontal_sum_i32x4(&self, v: I32x4) -> i32;
fn sad_u8x16(&self, a: U8x16, b: U8x16) -> u32;
fn sad_8(&self, a: &[u8], b: &[u8]) -> u32;
fn sad_16(&self, a: &[u8], b: &[u8]) -> u32;
fn widen_low_u8_to_i16(&self, v: U8x16) -> I16x8;
fn widen_high_u8_to_i16(&self, v: U8x16) -> I16x8;
fn narrow_i32x4_to_i16x8(&self, low: I32x4, high: I32x4) -> I16x8;
fn madd_i16x8(&self, a: I16x8, b: I16x8, c: I16x8) -> I16x8;
fn pmaddwd(&self, a: I16x8, b: I16x8) -> I32x4;
fn shr_i16x8(&self, v: I16x8, shift: u32) -> I16x8;
fn shl_i16x8(&self, v: I16x8, shift: u32) -> I16x8;
fn shr_i32x4(&self, v: I32x4, shift: u32) -> I32x4;
fn shl_i32x4(&self, v: I32x4, shift: u32) -> I32x4;
fn avg_u8x16(&self, a: U8x16, b: U8x16) -> U8x16;
}
pub trait SimdOpsExt: SimdOps {
fn load4_u8_to_i16x8(&self, src: &[u8]) -> I16x8;
fn load8_u8_to_i16x8(&self, src: &[u8]) -> I16x8;
fn store4_i16x8_as_u8(&self, v: I16x8, dst: &mut [u8]);
fn store8_i16x8_as_u8(&self, v: I16x8, dst: &mut [u8]);
fn transpose_4x4_i16(&self, rows: &[I16x8; 4]) -> [I16x8; 4];
fn transpose_8x8_i16(&self, rows: &[I16x8; 8]) -> [I16x8; 8];
fn butterfly_i16x8(&self, a: I16x8, b: I16x8) -> (I16x8, I16x8);
fn butterfly_i32x4(&self, a: I32x4, b: I32x4) -> (I32x4, I32x4);
}
pub trait SimdSelector {
fn select(&self) -> &dyn SimdOps;
fn select_ext(&self) -> &dyn SimdOpsExt;
}
#[cfg(test)]
mod tests {
use super::*;
fn _assert_send_sync<T: Send + Sync>() {}
#[test]
fn test_trait_bounds() {
#[allow(dead_code)]
#[allow(clippy::used_underscore_items)]
fn assert_simd_ops<T: SimdOps>() {
_assert_send_sync::<T>();
}
fn _check_bounds<T: SimdOps>(_t: &T) {
assert_simd_ops::<T>();
}
}
}