#[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector { () => { impl Vector{ #[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(self,f:F)->Vector where F:Fn(T)->U { Vector::new( self.array.map(f) ) } #[inline] pub fn map_zip(self,other:Vector,f:F)->Vector 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 Vector{ #[inline(always)] pub const fn from_value(value:T)->Self{ Self::new([value;N]) } } impl Default for Vector{ fn default()->Self{ Self::new( core::array::from_fn(|_|Default::default()) ) } } impl Vector{ #[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{ self.map_zip(rhs,|(a,b)|a.cmp(&b)) } #[inline] pub fn lt(self,rhs:Self)->Vector{ self.map_zip(rhs,|(a,b)|a.lt(&b)) } #[inline] pub fn gt(self,rhs:Self)->Vector{ self.map_zip(rhs,|(a,b)|a.gt(&b)) } #[inline] pub fn ge(self,rhs:Self)->Vector{ self.map_zip(rhs,|(a,b)|a.ge(&b)) } #[inline] pub fn le(self,rhs:Self)->Vector{ self.map_zip(rhs,|(a,b)|a.le(&b)) } } impl Vector{ #[inline] pub fn all(&self)->bool{ self.array==[true;N] } #[inline] pub fn any(&self)->bool{ self.array!=[false;N] } } impl,V> core::ops::Neg for Vector{ type Output=Vector; fn neg(self)->Self::Output{ Vector::new( self.array.map(|t|-t) ) } } impl Vector { #[inline] pub fn dot(self,rhs:Vector)->V where T:core::ops::Mul, V:core::iter::Sum, { self.array.into_iter().zip(rhs.array).map(|(a,b)|a*b).sum() } } impl Vector where T:core::ops::Mul+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 ); // Impl floating-point based methods #[cfg(feature="fixed_wide")] $crate::impl_wide_vector_operations!(); } } #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector_operator { ($trait: ident, $method: ident ) => { impl,U,V> core::ops::$trait> for Vector{ type Output=Vector; fn $method(self,rhs:Vector)->Self::Output{ self.map_zip(rhs,|(a,b)|a.$method(b)) } } impl> core::ops::$trait for Vector{ type Output=Self; 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,U> core::ops::$trait> for Vector{ fn $method(&mut self,rhs:Vector){ self.array.iter_mut().zip(rhs.array) .for_each(|(a,b)|a.$method(b)) } } impl> core::ops::$trait for Vector{ 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 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 core::ops::Deref for Vector<$size,T>{ type Target=$struct; fn deref(&self)->&Self::Target{ unsafe{core::mem::transmute(&self.array)} } } impl core::ops::DerefMut for Vector<$size,T>{ 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 Vector<3,T> { #[inline] pub fn cross(self,rhs:Vector<3,U>)->Vector<3,::Output> where T:core::ops::Mul+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, ]) } } #[cfg(feature="fixed_wide")] $crate::impl_vector_wide_3!(); } }