1use num::{One, Zero};
2use std::ops::{
3 Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
4};
5
6use simba::scalar::{ClosedAdd, ClosedDiv, ClosedMul, ClosedNeg, ClosedSub};
7
8use crate::base::constraint::{
9 AreMultipliable, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
10};
11use crate::base::dimension::{Dim, DimName, U1};
12use crate::base::storage::Storage;
13use crate::base::{Const, Matrix, OVector, Scalar, Vector};
14
15use crate::allocator::Allocator;
16use crate::geometry::{OPoint, Point};
17use crate::DefaultAllocator;
18
19impl<T: Scalar, D: DimName> Index<usize> for OPoint<T, D>
25where
26 DefaultAllocator: Allocator<T, D>,
27{
28 type Output = T;
29
30 #[inline]
31 fn index(&self, i: usize) -> &Self::Output {
32 &self.coords[i]
33 }
34}
35
36impl<T: Scalar, D: DimName> IndexMut<usize> for OPoint<T, D>
37where
38 DefaultAllocator: Allocator<T, D>,
39{
40 #[inline]
41 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
42 &mut self.coords[i]
43 }
44}
45
46impl<T: Scalar + ClosedNeg, D: DimName> Neg for OPoint<T, D>
52where
53 DefaultAllocator: Allocator<T, D>,
54{
55 type Output = Self;
56
57 #[inline]
58 fn neg(self) -> Self::Output {
59 Self::Output::from(-self.coords)
60 }
61}
62
63impl<'a, T: Scalar + ClosedNeg, D: DimName> Neg for &'a OPoint<T, D>
64where
65 DefaultAllocator: Allocator<T, D>,
66{
67 type Output = OPoint<T, D>;
68
69 #[inline]
70 fn neg(self) -> Self::Output {
71 Self::Output::from(-&self.coords)
72 }
73}
74
75add_sub_impl!(Sub, sub, ClosedSub;
83 (D, U1), (D, U1) -> (D, U1)
84 const; for D; where D: DimName, DefaultAllocator: Allocator<T, D>;
85 self: &'a OPoint<T, D>, right: &'b OPoint<T, D>, Output = OVector<T, D>;
86 &self.coords - &right.coords; 'a, 'b);
87
88add_sub_impl!(Sub, sub, ClosedSub;
89 (D, U1), (D, U1) -> (D, U1)
90 const; for D; where D: DimName, DefaultAllocator: Allocator<T, D>;
91 self: &'a OPoint<T, D>, right: OPoint<T, D>, Output = OVector<T, D>;
92 &self.coords - right.coords; 'a);
93
94add_sub_impl!(Sub, sub, ClosedSub;
95 (D, U1), (D, U1) -> (D, U1)
96 const; for D; where D: DimName, DefaultAllocator: Allocator<T, D>;
97 self: OPoint<T, D>, right: &'b OPoint<T, D>, Output = OVector<T, D>;
98 self.coords - &right.coords; 'b);
99
100add_sub_impl!(Sub, sub, ClosedSub;
101 (D, U1), (D, U1) -> (D, U1)
102 const; for D; where D: DimName, DefaultAllocator: Allocator<T, D>;
103 self: OPoint<T, D>, right: OPoint<T, D>, Output = OVector<T, D>;
104 self.coords - right.coords; );
105
106add_sub_impl!(Sub, sub, ClosedSub;
108 (D1, U1), (D2, U1) -> (D1, U1)
109 const;
110 for D1, D2, SB;
111 where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
112 self: &'a OPoint<T, D1>, right: &'b Vector<T, D2, SB>, Output = OPoint<T, D1>;
113 Self::Output::from(&self.coords - right); 'a, 'b);
114
115add_sub_impl!(Sub, sub, ClosedSub;
116 (D1, U1), (D2, U1) -> (D1, U1)
117 const;
118 for D1, D2, SB;
119 where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
120 self: &'a OPoint<T, D1>, right: Vector<T, D2, SB>, Output = OPoint<T, D1>;
121 Self::Output::from(&self.coords - &right); 'a); add_sub_impl!(Sub, sub, ClosedSub;
124 (D1, U1), (D2, U1) -> (D1, U1)
125 const;
126 for D1, D2, SB;
127 where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
128 self: OPoint<T, D1>, right: &'b Vector<T, D2, SB>, Output = OPoint<T, D1>;
129 Self::Output::from(self.coords - right); 'b);
130
131add_sub_impl!(Sub, sub, ClosedSub;
132 (D1, U1), (D2, U1) -> (D1, U1)
133 const;
134 for D1, D2, SB;
135 where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
136 self: OPoint<T, D1>, right: Vector<T, D2, SB>, Output = OPoint<T, D1>;
137 Self::Output::from(self.coords - right); );
138
139add_sub_impl!(Add, add, ClosedAdd;
141 (D1, U1), (D2, U1) -> (D1, U1)
142 const;
143 for D1, D2, SB;
144 where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
145 self: &'a OPoint<T, D1>, right: &'b Vector<T, D2, SB>, Output = OPoint<T, D1>;
146 Self::Output::from(&self.coords + right); 'a, 'b);
147
148add_sub_impl!(Add, add, ClosedAdd;
149 (D1, U1), (D2, U1) -> (D1, U1)
150 const;
151 for D1, D2, SB;
152 where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
153 self: &'a OPoint<T, D1>, right: Vector<T, D2, SB>, Output = OPoint<T, D1>;
154 Self::Output::from(&self.coords + &right); 'a); add_sub_impl!(Add, add, ClosedAdd;
157 (D1, U1), (D2, U1) -> (D1, U1)
158 const;
159 for D1, D2, SB;
160 where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
161 self: OPoint<T, D1>, right: &'b Vector<T, D2, SB>, Output = OPoint<T, D1>;
162 Self::Output::from(self.coords + right); 'b);
163
164add_sub_impl!(Add, add, ClosedAdd;
165 (D1, U1), (D2, U1) -> (D1, U1)
166 const;
167 for D1, D2, SB;
168 where D1: DimName, D2: Dim, SB: Storage<T, D2>, DefaultAllocator: Allocator<T, D1>;
169 self: OPoint<T, D1>, right: Vector<T, D2, SB>, Output = OPoint<T, D1>;
170 Self::Output::from(self.coords + right); );
171
172macro_rules! op_assign_impl(
174 ($($TraitAssign: ident, $method_assign: ident, $bound: ident);* $(;)*) => {$(
175 impl<'b, T, D1: DimName, D2: Dim, SB> $TraitAssign<&'b Vector<T, D2, SB>> for OPoint<T, D1>
176 where T: Scalar + $bound,
177 SB: Storage<T, D2>,
178 ShapeConstraint: SameNumberOfRows<D1, D2>,
179 DefaultAllocator: Allocator<T, D1> {
180
181 #[inline]
182 fn $method_assign(&mut self, right: &'b Vector<T, D2, SB>) {
183 self.coords.$method_assign(right)
184 }
185 }
186
187 impl<T, D1: DimName, D2: Dim, SB> $TraitAssign<Vector<T, D2, SB>> for OPoint<T, D1>
188 where T: Scalar + $bound,
189 SB: Storage<T, D2>,
190 ShapeConstraint: SameNumberOfRows<D1, D2>,
191 DefaultAllocator: Allocator<T, D1> {
192
193 #[inline]
194 fn $method_assign(&mut self, right: Vector<T, D2, SB>) {
195 self.coords.$method_assign(right)
196 }
197 }
198 )*}
199);
200
201op_assign_impl!(
202 AddAssign, add_assign, ClosedAdd;
203 SubAssign, sub_assign, ClosedSub;
204);
205
206md_impl_all!(
212 Mul, mul;
213 (Const<R1>, Const<C1>), (Const<D2>, U1)
214 const D2, R1, C1;
215 for SA;
216 where SA: Storage<T, Const<R1>, Const<C1>>,
217 ShapeConstraint: AreMultipliable<Const<R1>, Const<C1>, Const<D2>, U1>;
218 self: Matrix<T, Const<R1>, Const<C1>, SA>, right: Point<T, D2>, Output = Point<T, R1>;
219 [val val] => Point::from(self * right.coords);
220 [ref val] => Point::from(self * right.coords);
221 [val ref] => Point::from(self * &right.coords);
222 [ref ref] => Point::from(self * &right.coords);
223);
224
225macro_rules! componentwise_scalarop_impl(
231 ($Trait: ident, $method: ident, $bound: ident;
232 $TraitAssign: ident, $method_assign: ident) => {
233 impl<T: Scalar + $bound, D: DimName> $Trait<T> for OPoint<T, D>
234 where DefaultAllocator: Allocator<T, D>
235 {
236 type Output = OPoint<T, D>;
237
238 #[inline]
239 fn $method(self, right: T) -> Self::Output {
240 OPoint::from(self.coords.$method(right))
241 }
242 }
243
244 impl<'a, T: Scalar + $bound, D: DimName> $Trait<T> for &'a OPoint<T, D>
245 where DefaultAllocator: Allocator<T, D>
246 {
247 type Output = OPoint<T, D>;
248
249 #[inline]
250 fn $method(self, right: T) -> Self::Output {
251 OPoint::from((&self.coords).$method(right))
252 }
253 }
254
255 impl<T: Scalar + $bound, D: DimName> $TraitAssign<T> for OPoint<T, D>
256 where DefaultAllocator: Allocator<T, D>
257 {
258 #[inline]
259 fn $method_assign(&mut self, right: T) {
260 self.coords.$method_assign(right)
261 }
262 }
263 }
264);
265
266componentwise_scalarop_impl!(Mul, mul, ClosedMul; MulAssign, mul_assign);
267componentwise_scalarop_impl!(Div, div, ClosedDiv; DivAssign, div_assign);
268
269macro_rules! left_scalar_mul_impl(
270 ($($T: ty),* $(,)*) => {$(
271 impl<D: DimName> Mul<OPoint<$T, D>> for $T
272 where DefaultAllocator: Allocator<$T, D>
273 {
274 type Output = OPoint<$T, D>;
275
276 #[inline]
277 fn mul(self, right: OPoint<$T, D>) -> Self::Output {
278 OPoint::from(self * right.coords)
279 }
280 }
281
282 impl<'b, D: DimName> Mul<&'b OPoint<$T, D>> for $T
283 where DefaultAllocator: Allocator<$T, D>
284 {
285 type Output = OPoint<$T, D>;
286
287 #[inline]
288 fn mul(self, right: &'b OPoint<$T, D>) -> Self::Output {
289 OPoint::from(self * &right.coords)
290 }
291 }
292 )*}
293);
294
295left_scalar_mul_impl!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);