#[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{ #[inline] fn default()->Self{ Self::new( core::array::from_fn(|_|Default::default()) ) } } impl core::fmt::Display for Vector{ #[inline] fn fmt(&self,f:&mut core::fmt::Formatter)->Result<(),core::fmt::Error>{ for elem in &self.array[0..N-1]{ core::write!(f,"{}, ",elem)?; } // assume we will be using vectors of length 1 or greater core::write!(f,"{}",self.array.last().unwrap()) } } 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; #[inline] 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!(RemAssign, rem_assign ); $crate::impl_vector_operator!(Rem, rem ); // mul and div are special, usually you multiply by a scalar // and implementing both vec*vec and vec*scalar is conflicting implementations Q_Q $crate::impl_vector_assign_operator_scalar!(MulAssign, mul_assign ); $crate::impl_vector_operator_scalar!(Mul, mul ); $crate::impl_vector_assign_operator_scalar!(DivAssign, div_assign ); $crate::impl_vector_operator_scalar!(Div, div ); // 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 shift operators $crate::impl_vector_shift_assign_operator!(ShlAssign, shl_assign); $crate::impl_vector_shift_operator!(Shl, shl); $crate::impl_vector_shift_assign_operator!(ShrAssign, shr_assign); $crate::impl_vector_shift_operator!(Shr, shr); } } #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector_operator_scalar { ($trait: ident, $method: ident ) => { impl,U:Copy,V> core::ops::$trait for Vector{ type Output=Vector; #[inline] fn $method(self,rhs:U)->Self::Output{ self.map(|t|t.$method(rhs)) } } } } #[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; #[inline] 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; #[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_scalar { ($trait: ident, $method: ident ) => { impl,U:Copy> core::ops::$trait for Vector{ #[inline] fn $method(&mut self,rhs:U){ self.array.iter_mut() .for_each(|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{ #[inline] 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{ #[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_shift_operator { ($trait: ident, $method: ident ) => { impl,U,V> core::ops::$trait> for Vector{ type Output=Vector; #[inline] fn $method(self,rhs:Vector)->Self::Output{ self.map_zip(rhs,|(a,b)|a.$method(b)) } } impl,V> core::ops::$trait for Vector{ type Output=Vector; #[inline] fn $method(self,rhs:u32)->Self::Output{ self.map(|t|t.$method(rhs)) } } } } #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_vector_shift_assign_operator { ($trait: ident, $method: ident ) => { impl,U> core::ops::$trait> for Vector{ #[inline] 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{ #[inline] fn $method(&mut self,rhs:u32){ 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; #[inline] fn deref(&self)->&Self::Target{ unsafe{core::mem::transmute(&self.array)} } } impl 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 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, ]) } } } }