devela/num/geom/linear/vector/array/
ops.rs

1// devela::num::geom::linear::vector::array::ops
2//
3//! implement overloadable operators
4//
5// NOTE: Because of T: Clone bound the `_assign` ops take a reference to Rhs.
6
7#![expect(clippy::needless_range_loop, reason = "prefer using for loops")]
8
9use super::super::Vector;
10use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
11
12/* ops between vectors */
13
14impl<T: Clone + Add<Output = T>, const D: usize> Vector<T, D> {
15    /// Adds two vectors together
16    pub fn clone_add(&self, other: &Self) -> Self {
17        let mut coords: [T; D] = self.coords.clone();
18        for i in 0..D {
19            coords[i] = self.coords[i].clone() + other.coords[i].clone();
20        }
21        Vector { coords }
22    }
23}
24impl<T: Clone + Add<Output = T>, const D: usize> Add for Vector<T, D> {
25    type Output = Self;
26    fn add(self, other: Self) -> Self::Output {
27        Self::clone_add(&self, &other)
28    }
29}
30impl<T: Clone + Add<Output = T>, const D: usize> AddAssign<&Self> for Vector<T, D> {
31    fn add_assign(&mut self, other: &Self) {
32        *self = Self::clone_add(self, other);
33    }
34}
35
36impl<T: Clone + Sub<Output = T>, const D: usize> Vector<T, D> {
37    /// Subtracts two vectors together.
38    pub fn clone_sub(&self, other: &Self) -> Self {
39        let mut coords: [T; D] = self.coords.clone();
40        for i in 0..D {
41            coords[i] = self.coords[i].clone() - other.coords[i].clone();
42        }
43        Vector { coords }
44    }
45}
46impl<T: Clone + Sub<Output = T>, const D: usize> Sub for Vector<T, D> {
47    type Output = Self;
48    fn sub(self, other: Self) -> Self::Output {
49        Self::clone_sub(&self, &other)
50    }
51}
52impl<T: Clone + Sub<Output = T>, const D: usize> SubAssign<&Self> for Vector<T, D> {
53    fn sub_assign(&mut self, other: &Self) {
54        *self = Self::clone_sub(self, other);
55    }
56}
57
58/* ops between vectors and scalars */
59
60impl<T: Clone + Mul<Output = T>, const D: usize> Vector<T, D> {
61    /// Multiplies a vector by a scalar.
62    pub fn clone_mul_scalar(&self, scalar: &T) -> Self {
63        let mut coords: [T; D] = self.coords.clone();
64        for i in 0..D {
65            coords[i] = self.coords[i].clone() * scalar.clone();
66        }
67        Vector { coords }
68    }
69}
70impl<T: Clone + Mul<Output = T>, const D: usize> Mul<T> for Vector<T, D> {
71    type Output = Self;
72    fn mul(self, scalar: T) -> Self::Output {
73        Self::clone_mul_scalar(&self, &scalar)
74    }
75}
76impl<T: Clone + Mul<Output = T>, const D: usize> MulAssign<T> for Vector<T, D> {
77    fn mul_assign(&mut self, scalar: T) {
78        *self = Self::clone_mul_scalar(self, &scalar);
79    }
80}
81impl<T: Clone + Mul<Output = T>, const D: usize> Mul<&T> for Vector<T, D> {
82    type Output = Self;
83    fn mul(self, scalar: &T) -> Self::Output {
84        Self::clone_mul_scalar(&self, scalar)
85    }
86}
87impl<T: Clone + Mul<Output = T>, const D: usize> MulAssign<&T> for Vector<T, D> {
88    fn mul_assign(&mut self, scalar: &T) {
89        *self = Self::clone_mul_scalar(self, scalar);
90    }
91}
92
93impl<T: Clone + Div<Output = T>, const D: usize> Vector<T, D> {
94    /// Divides a vector by a scalar.
95    pub fn clone_div_scalar(&self, scalar: &T) -> Self {
96        let mut coords: [T; D] = self.coords.clone();
97        for i in 0..D {
98            coords[i] = self.coords[i].clone() / scalar.clone();
99        }
100        Vector { coords }
101    }
102}
103impl<T: Clone + Div<Output = T>, const D: usize> Div<T> for Vector<T, D> {
104    type Output = Self;
105    fn div(self, scalar: T) -> Self::Output {
106        Self::clone_div_scalar(&self, &scalar)
107    }
108}
109impl<T: Clone + Div<Output = T>, const D: usize> DivAssign<T> for Vector<T, D> {
110    fn div_assign(&mut self, scalar: T) {
111        *self = Self::clone_div_scalar(self, &scalar);
112    }
113}
114impl<T: Clone + Div<Output = T>, const D: usize> Div<&T> for Vector<T, D> {
115    type Output = Self;
116    fn div(self, scalar: &T) -> Self::Output {
117        Self::clone_div_scalar(&self, scalar)
118    }
119}
120impl<T: Clone + Div<Output = T>, const D: usize> DivAssign<&T> for Vector<T, D> {
121    fn div_assign(&mut self, scalar: &T) {
122        *self = Self::clone_div_scalar(self, scalar);
123    }
124}