strafe-client-jed/fixed_wide_vectors/src/macros/vector.rs

171 lines
4.4 KiB
Rust
Raw Normal View History

2024-09-05 20:36:38 +00:00
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! impl_vector {
() => {
2024-09-05 20:52:54 +00:00
impl<const N:usize,T> Vector<N,T>{
2024-09-05 22:41:39 +00:00
#[inline(always)]
2024-09-05 20:52:54 +00:00
pub const fn new(array:[T;N])->Self{
Self{array}
}
2024-09-05 22:41:39 +00:00
#[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{
array: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{
array:core::array::from_fn(|_|f(iter.next().unwrap())),
}
}
2024-09-05 20:52:54 +00:00
}
impl<const N:usize,T:Copy> Vector<N,T>{
2024-09-05 22:41:39 +00:00
#[inline(always)]
2024-09-05 20:52:54 +00:00
pub const fn from_value(value:T)->Self{
Self{
array:[value;N]
}
}
}
2024-09-05 22:41:39 +00:00
impl<const N:usize,T:Default> Default for Vector<N,T>{
fn default()->Self{
Self{
array: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>{
const ALL:[bool;N]=[true;N];
const NONE:[bool;N]=[false;N];
#[inline]
pub fn all(&self)->bool{
core::matches!(self.array,ALL)
}
#[inline]
pub fn any(&self)->bool{
!core::matches!(self.array,NONE)
}
}
2024-09-05 22:56:35 +00:00
impl<const N:usize,T:core::ops::Neg<Output=V>,V> core::ops::Neg for Vector<N,T>{
type Output=Vector<N,V>;
2024-09-05 22:41:39 +00:00
fn neg(self)->Self::Output{
2024-09-05 22:56:35 +00:00
Vector{
2024-09-05 22:41:39 +00:00
array:self.array.map(|t|-t)
}
}
}
2024-09-05 22:56:44 +00:00
// 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!( $struct { $($field), + }, $size );
}
}
#[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>;
fn $method(self,rhs:Vector<N,U>)->Self::Output{
self.map_zip(rhs,|(a,b)|a.$method(b))
}
}
}
}
#[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>{
fn $method(&mut self,rhs:Vector<N,U>){
self.array.iter_mut().zip(rhs.array)
.for_each(|(a,b)|a.$method(b))
}
}
2024-09-05 20:36:38 +00:00
}
}
2024-08-30 19:05:52 +00:00
2024-09-05 20:36:38 +00:00
#[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>;
fn deref(&self)->&Self::Target{
unsafe{core::mem::transmute(&self.array)}
}
}
impl<T> core::ops::DerefMut for Vector<$size,T>{
fn deref_mut(&mut self)->&mut Self::Target{
unsafe{core::mem::transmute(&mut self.array)}
}
}
}
}