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