forked from StrafesNET/strafe-project
rename fixed_wide_vectors to linear_ops
This commit is contained in:
244
linear_ops/src/macros/vector.rs
Normal file
244
linear_ops/src/macros/vector.rs
Normal file
@ -0,0 +1,244 @@
|
||||
#[doc(hidden)]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! impl_vector {
|
||||
() => {
|
||||
impl<const N:usize,T> Vector<N,T>{
|
||||
#[inline(always)]
|
||||
pub const fn new(array:[T;N])->Self{
|
||||
Self{array}
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn to_array(self)->[T;N]{
|
||||
self.array
|
||||
}
|
||||
#[inline]
|
||||
pub fn map<F,U>(self,f:F)->Vector<N,U>
|
||||
where
|
||||
F:Fn(T)->U
|
||||
{
|
||||
Vector::new(
|
||||
self.array.map(f)
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
pub fn map_zip<F,U,V>(self,other:Vector<N,U>,f:F)->Vector<N,V>
|
||||
where
|
||||
F:Fn((T,U))->V,
|
||||
{
|
||||
let mut iter=self.array.into_iter().zip(other.array);
|
||||
Vector::new(
|
||||
core::array::from_fn(|_|f(iter.next().unwrap())),
|
||||
)
|
||||
}
|
||||
}
|
||||
impl<const N:usize,T:Copy> Vector<N,T>{
|
||||
#[inline(always)]
|
||||
pub const fn from_value(value:T)->Self{
|
||||
Self::new([value;N])
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N:usize,T:Default> Default for Vector<N,T>{
|
||||
#[inline]
|
||||
fn default()->Self{
|
||||
Self::new(
|
||||
core::array::from_fn(|_|Default::default())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N:usize,T:Ord> Vector<N,T>{
|
||||
#[inline]
|
||||
pub fn min(self,rhs:Self)->Self{
|
||||
self.map_zip(rhs,|(a,b)|a.min(b))
|
||||
}
|
||||
#[inline]
|
||||
pub fn max(self,rhs:Self)->Self{
|
||||
self.map_zip(rhs,|(a,b)|a.max(b))
|
||||
}
|
||||
#[inline]
|
||||
pub fn cmp(self,rhs:Self)->Vector<N,core::cmp::Ordering>{
|
||||
self.map_zip(rhs,|(a,b)|a.cmp(&b))
|
||||
}
|
||||
#[inline]
|
||||
pub fn lt(self,rhs:Self)->Vector<N,bool>{
|
||||
self.map_zip(rhs,|(a,b)|a.lt(&b))
|
||||
}
|
||||
#[inline]
|
||||
pub fn gt(self,rhs:Self)->Vector<N,bool>{
|
||||
self.map_zip(rhs,|(a,b)|a.gt(&b))
|
||||
}
|
||||
#[inline]
|
||||
pub fn ge(self,rhs:Self)->Vector<N,bool>{
|
||||
self.map_zip(rhs,|(a,b)|a.ge(&b))
|
||||
}
|
||||
#[inline]
|
||||
pub fn le(self,rhs:Self)->Vector<N,bool>{
|
||||
self.map_zip(rhs,|(a,b)|a.le(&b))
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N:usize> Vector<N,bool>{
|
||||
#[inline]
|
||||
pub fn all(&self)->bool{
|
||||
self.array==[true;N]
|
||||
}
|
||||
#[inline]
|
||||
pub fn any(&self)->bool{
|
||||
self.array!=[false;N]
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N:usize,T:core::ops::Neg<Output=V>,V> core::ops::Neg for Vector<N,T>{
|
||||
type Output=Vector<N,V>;
|
||||
#[inline]
|
||||
fn neg(self)->Self::Output{
|
||||
Vector::new(
|
||||
self.array.map(|t|-t)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N:usize,T> Vector<N,T>
|
||||
{
|
||||
#[inline]
|
||||
pub fn dot<U,V>(self,rhs:Vector<N,U>)->V
|
||||
where
|
||||
T:core::ops::Mul<U,Output=V>,
|
||||
V:core::iter::Sum,
|
||||
{
|
||||
self.array.into_iter().zip(rhs.array).map(|(a,b)|a*b).sum()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N:usize,T,V> Vector<N,T>
|
||||
where
|
||||
T:core::ops::Mul<Output=V>+Copy,
|
||||
V:core::iter::Sum,
|
||||
{
|
||||
#[inline]
|
||||
pub fn length_squared(self)->V{
|
||||
self.array.into_iter().map(|t|t*t).sum()
|
||||
}
|
||||
}
|
||||
|
||||
// Impl arithmetic operators
|
||||
$crate::impl_vector_assign_operator!(AddAssign, add_assign );
|
||||
$crate::impl_vector_operator!(Add, add );
|
||||
$crate::impl_vector_assign_operator!(SubAssign, sub_assign );
|
||||
$crate::impl_vector_operator!(Sub, sub );
|
||||
$crate::impl_vector_assign_operator!(MulAssign, mul_assign );
|
||||
$crate::impl_vector_operator!(Mul, mul );
|
||||
$crate::impl_vector_assign_operator!(DivAssign, div_assign );
|
||||
$crate::impl_vector_operator!(Div, div );
|
||||
$crate::impl_vector_assign_operator!(RemAssign, rem_assign );
|
||||
$crate::impl_vector_operator!(Rem, rem );
|
||||
|
||||
// Impl bitwise operators
|
||||
$crate::impl_vector_assign_operator!(BitAndAssign, bitand_assign );
|
||||
$crate::impl_vector_operator!(BitAnd, bitand );
|
||||
$crate::impl_vector_assign_operator!(BitOrAssign, bitor_assign );
|
||||
$crate::impl_vector_operator!(BitOr, bitor );
|
||||
$crate::impl_vector_assign_operator!(BitXorAssign, bitxor_assign );
|
||||
$crate::impl_vector_operator!(BitXor, bitxor );
|
||||
}
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! impl_vector_operator {
|
||||
($trait: ident, $method: ident ) => {
|
||||
impl<const N:usize,T:core::ops::$trait<U,Output=V>,U,V> core::ops::$trait<Vector<N,U>> for Vector<N,T>{
|
||||
type Output=Vector<N,V>;
|
||||
#[inline]
|
||||
fn $method(self,rhs:Vector<N,U>)->Self::Output{
|
||||
self.map_zip(rhs,|(a,b)|a.$method(b))
|
||||
}
|
||||
}
|
||||
impl<const N:usize,T:core::ops::$trait<i64,Output=T>> core::ops::$trait<i64> for Vector<N,T>{
|
||||
type Output=Self;
|
||||
#[inline]
|
||||
fn $method(self,rhs:i64)->Self::Output{
|
||||
self.map(|t|t.$method(rhs))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! impl_vector_assign_operator {
|
||||
($trait: ident, $method: ident ) => {
|
||||
impl<const N:usize,T:core::ops::$trait<U>,U> core::ops::$trait<Vector<N,U>> for Vector<N,T>{
|
||||
#[inline]
|
||||
fn $method(&mut self,rhs:Vector<N,U>){
|
||||
self.array.iter_mut().zip(rhs.array)
|
||||
.for_each(|(a,b)|a.$method(b))
|
||||
}
|
||||
}
|
||||
impl<const N:usize,T:core::ops::$trait<i64>> core::ops::$trait<i64> for Vector<N,T>{
|
||||
#[inline]
|
||||
fn $method(&mut self,rhs:i64){
|
||||
self.array.iter_mut()
|
||||
.for_each(|t|t.$method(rhs))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! impl_vector_extend {
|
||||
( $size: expr ) => {
|
||||
impl<T> Vector<$size,T>{
|
||||
#[inline]
|
||||
pub fn extend(self,value:T)->Vector<{$size+1},T>{
|
||||
let mut iter=self.array.into_iter().chain(core::iter::once(value));
|
||||
Vector::new(
|
||||
core::array::from_fn(|_|iter.next().unwrap()),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! impl_vector_named_fields {
|
||||
( $struct:ident, $size: expr ) => {
|
||||
impl<T> core::ops::Deref for Vector<$size,T>{
|
||||
type Target=$struct<T>;
|
||||
#[inline]
|
||||
fn deref(&self)->&Self::Target{
|
||||
unsafe{core::mem::transmute(&self.array)}
|
||||
}
|
||||
}
|
||||
impl<T> core::ops::DerefMut for Vector<$size,T>{
|
||||
#[inline]
|
||||
fn deref_mut(&mut self)->&mut Self::Target{
|
||||
unsafe{core::mem::transmute(&mut self.array)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! impl_vector_3 {
|
||||
()=>{
|
||||
impl<T> Vector<3,T>
|
||||
{
|
||||
#[inline]
|
||||
pub fn cross<U,V>(self,rhs:Vector<3,U>)->Vector<3,<V as core::ops::Sub>::Output>
|
||||
where
|
||||
T:core::ops::Mul<U,Output=V>+Copy,
|
||||
U:Copy,
|
||||
V:core::ops::Sub,
|
||||
{
|
||||
Vector::new([
|
||||
self.y*rhs.z-self.z*rhs.y,
|
||||
self.z*rhs.x-self.x*rhs.z,
|
||||
self.x*rhs.y-self.y*rhs.x,
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user