#![warn(missing_docs)]
#![cfg_attr(not(feature = "extern_crate_std"), no_std)]
#![cfg_attr(feature = "toolchain_nightly", feature(stdsimd))]
#![cfg_attr(feature = "toolchain_nightly", feature(core_intrinsics))]
#![allow(clippy::replace_consts)]
#![allow(clippy::inline_always)]
#![allow(clippy::expl_impl_clone_on_copy)]
#![allow(clippy::doc_markdown)]
#![allow(clippy::use_self)]
#![warn(clippy::must_use_candidate)]
pub(crate) use bytemuck::{cast, cast_mut, cast_ref, Pod, Zeroable};
pub(crate) use core::{convert::*, fmt::*, ops::*};
macro_rules! magic {
(
$(if #[cfg($($test:meta),*)] {
$($if_tokens:tt)*
})else* else {
$($else_tokens:tt)*
}
) => {
magic!{
@__forests [ ] ;
$( [ {$($test),*} {$($if_tokens)*} ], )*
[ { } {$($else_tokens)*} ],
}
};
(
if #[cfg($($if_meta:meta),*)] {
$($if_tokens:tt)*
} $(else if #[cfg($($else_meta:meta),*)] {
$($else_tokens:tt)*
})*
) => {
magic!{
@__forests [ ] ;
[ {$($if_meta),*} {$($if_tokens)*} ],
$( [ {$($else_meta),*} {$($else_tokens)*} ], )*
}
};
(
@__forests [ $($not:meta,)* ] ;
) => {
};
(
@__forests [ $($not:meta,)* ] ;
[ { $($m:meta),* } { $($tokens:tt)* } ],
$($rest:tt)*
) => {
#[cfg(all( $($m,)* not(any($($not),*)) ))]
magic!{ @__identity $($tokens)* }
magic!{
@__forests [ $($not,)* $($m,)* ] ;
$($rest)*
}
};
(
@__identity $($tokens:tt)*
) => {
$($tokens)*
};
}
pub mod arch;
magic! {
if #[cfg(all(target_arch="x86", target_feature="sse"))] {
pub(crate) use arch::x86::{m128, m128i};
} else if #[cfg(all(target_arch="x86_64", target_feature="sse"))] {
pub(crate) use arch::x86_64::{m128, m128i};
}
}
mod m_f32x4;
pub use m_f32x4::*;
mod m_i32x4;
pub use m_i32x4::*;
#[inline(always)]
#[must_use]
pub fn sqrt_f32(x: f32) -> f32 {
magic! {
if #[cfg(target_feature = "sse")] {
m128::set0(x).sqrt0().extract0()
} else if #[cfg(feature = "toolchain_nightly")] {
unsafe { core::intrinsics::sqrtf32(x) }
} else {
f32::sqrt(x)
}
}
}
#[inline(always)]
#[must_use]
pub fn sin_f32(x: f32) -> f32 {
magic! {
if #[cfg(target_feature = "sse")] {
f32x4 { sse: m128::set0(x) }.sin().sse.extract0()
} else {
f32x4 { arr: [x, 0.0, 0.0, 0.0] }.sin().arr[0]
}
}
}
#[inline(always)]
#[must_use]
pub fn cos_f32(x: f32) -> f32 {
magic! {
if #[cfg(target_feature = "sse")] {
f32x4 { sse: m128::set0(x) }.cos().sse.extract0()
} else {
f32x4 { arr: [x, 0.0, 0.0, 0.0] }.cos().arr[0]
}
}
}
#[inline(always)]
#[must_use]
pub fn tan_f32(x: f32) -> f32 {
magic! {
if #[cfg(target_feature = "sse")] {
f32x4 { sse: m128::set0(x) }.tan().sse.extract0()
} else {
f32x4 { arr: [x, 0.0, 0.0, 0.0] }.tan().arr[0]
}
}
}