1use approx::{AbsDiffEq, RelativeEq};
7use core::ops::{
8 Add, AddAssign, BitAnd, BitOr, BitXor, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Shl,
9 Shr, Sub, SubAssign,
10};
11
12use nalgebra::DMatrix;
13
14use crate::BlockData;
15use crate::BlockTypeRelationship;
16
17impl Sub for &BlockData {
18 type Output = BlockData;
19 fn sub(self, rhs: Self) -> Self::Output {
20 match self.compare(rhs) {
21 BlockTypeRelationship::SameSizes => {
22 BlockData::from_data(self.get_data() - rhs.get_data(), self.get_type())
23 }
24 BlockTypeRelationship::FirstIsScalar => BlockData::from_data(
25 BlockData::scalar_sizeof(self.scalar(), rhs).get_data() - rhs.get_data(),
26 rhs.get_type(),
27 ),
28 BlockTypeRelationship::SecondIsScalar => BlockData::from_data(
29 self.get_data() - BlockData::scalar_sizeof(rhs.scalar(), self).get_data(),
30 self.get_type(),
31 ),
32 _ => panic!("Cannot add unless sizes match or one is scalar."),
33 }
34 }
35}
36
37impl Sub<&BlockData> for BlockData {
38 type Output = Self;
39 fn sub(self, rhs: &BlockData) -> Self::Output {
40 &self - rhs
41 }
42}
43
44impl Sub<BlockData> for &BlockData {
45 type Output = BlockData;
46 fn sub(self, rhs: BlockData) -> Self::Output {
47 self - &rhs
48 }
49}
50
51impl SubAssign<&BlockData> for BlockData {
52 fn sub_assign(&mut self, rhs: &BlockData) {
53 match self.compare(rhs) {
54 BlockTypeRelationship::SameSizes => self.set_data(self.get_data() - rhs.get_data()),
55 BlockTypeRelationship::FirstIsScalar => {
56 self.set_data(
57 BlockData::scalar_sizeof(self.scalar(), rhs).get_data() - rhs.get_data(),
58 );
59 self.set_type(rhs.get_type());
60 }
61 BlockTypeRelationship::SecondIsScalar => self.set_data(
62 self.get_data() - BlockData::scalar_sizeof(rhs.scalar(), self).get_data(),
63 ),
64 _ => panic!("Cannot add unless sizes match or one is scalar."),
65 }
66 }
67}
68
69impl Add for &BlockData {
70 type Output = BlockData;
71 fn add(self, rhs: &BlockData) -> Self::Output {
72 match self.compare(rhs) {
73 BlockTypeRelationship::SameSizes => {
74 BlockData::from_data(self.get_data() + rhs.get_data(), self.get_type())
75 }
76 BlockTypeRelationship::FirstIsScalar => BlockData::from_data(
77 BlockData::scalar_sizeof(self.scalar(), rhs).get_data() + rhs.get_data(),
78 rhs.get_type(),
79 ),
80 BlockTypeRelationship::SecondIsScalar => BlockData::from_data(
81 BlockData::scalar_sizeof(rhs.scalar(), self).get_data() + self.get_data(),
82 self.get_type(),
83 ),
84 _ => panic!("Cannot add unless sizes match or one is scalar."),
85 }
86 }
87}
88
89impl Add<&BlockData> for BlockData {
90 type Output = BlockData;
91 fn add(self, rhs: &BlockData) -> Self::Output {
92 &self + rhs
93 }
94}
95
96impl AddAssign<&BlockData> for BlockData {
97 fn add_assign(&mut self, rhs: &BlockData) {
98 match self.compare(rhs) {
99 BlockTypeRelationship::SameSizes => self.set_data(self.get_data() + rhs.get_data()),
100 BlockTypeRelationship::FirstIsScalar => {
101 self.set_data(
102 BlockData::scalar_sizeof(self.scalar(), rhs).get_data() + rhs.get_data(),
103 );
104 self.set_type(rhs.get_type());
105 }
106 BlockTypeRelationship::SecondIsScalar => self.set_data(
107 self.get_data() + BlockData::scalar_sizeof(rhs.scalar(), self).get_data(),
108 ),
109 _ => panic!("Cannot add unless sizes match or one is scalar."),
110 }
111 }
112}
113
114impl Mul for &BlockData {
115 type Output = BlockData;
116 fn mul(self, rhs: &BlockData) -> Self::Output {
117 BlockData::from_data(self.get_data() * rhs.get_data(), self.get_type())
118 }
119}
120
121impl Mul<f64> for &BlockData {
122 type Output = BlockData;
123 fn mul(self, rhs: f64) -> Self::Output {
124 BlockData::from_data(self.get_data() * rhs, self.get_type())
125 }
126}
127
128impl Mul<f64> for BlockData {
129 type Output = Self;
130 fn mul(self, rhs: f64) -> Self::Output {
131 &self * rhs
132 }
133}
134
135impl Mul<&BlockData> for f64 {
136 type Output = BlockData;
137 fn mul(self, rhs: &BlockData) -> Self::Output {
138 rhs * self
139 }
140}
141
142impl Mul<BlockData> for f64 {
143 type Output = BlockData;
144 fn mul(self, rhs: BlockData) -> Self::Output {
145 &rhs * self
146 }
147}
148
149impl MulAssign<&BlockData> for BlockData {
150 fn mul_assign(&mut self, rhs: &BlockData) {
151 self.set_data(self.get_data() * rhs.get_data());
152 }
153}
154
155impl Index<usize> for BlockData {
156 type Output = f64;
157 fn index(&self, index: usize) -> &Self::Output {
158 self.ref_at(index)
159 }
160}
161
162impl IndexMut<usize> for BlockData {
163 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
164 self.ref_at_mut(index)
165 }
166}
167
168impl Div<f64> for BlockData {
169 type Output = Self;
170 fn div(self, rhs: f64) -> Self::Output {
171 Self::from_data(self.get_data() / rhs, self.get_type())
172 }
173}
174
175impl Div<f64> for &BlockData {
176 type Output = BlockData;
177 fn div(self, rhs: f64) -> Self::Output {
178 BlockData::from_data(self.get_data() / rhs, self.get_type())
179 }
180}
181
182impl DivAssign<f64> for BlockData {
183 fn div_assign(&mut self, rhs: f64) {
184 self.set_data(self.get_data() / rhs);
185 }
186}
187
188impl Div for &BlockData {
189 type Output = BlockData;
190 fn div(self, rhs: &BlockData) -> Self::Output {
191 match self.compare(rhs) {
192 BlockTypeRelationship::SameSizes => BlockData::from_data(
193 self.get_data().component_div(rhs.get_data()),
194 self.get_type(),
195 ),
196 BlockTypeRelationship::FirstIsScalar => BlockData::from_data(
197 BlockData::scalar_sizeof(self.scalar(), rhs)
198 .get_data()
199 .component_div(rhs.get_data()),
200 rhs.get_type(),
201 ),
202 BlockTypeRelationship::SecondIsScalar => BlockData::from_data(
203 self.get_data()
204 .component_div(BlockData::scalar_sizeof(rhs.scalar(), self).get_data()),
205 self.get_type(),
206 ),
207 _ => panic!("Cannot add unless sizes match or one is scalar."),
208 }
209 }
210}
211impl Div for BlockData {
212 type Output = BlockData;
213 fn div(self, rhs: BlockData) -> Self::Output {
214 &self / &rhs
215 }
216}
217
218impl DivAssign<&BlockData> for BlockData {
219 fn div_assign(&mut self, rhs: &BlockData) {
220 match self.compare(rhs) {
221 BlockTypeRelationship::SameSizes => {
222 self.set_data(self.get_data().component_div(rhs.get_data()))
223 }
224 BlockTypeRelationship::FirstIsScalar => self.set_data(
225 BlockData::scalar_sizeof(self.scalar(), rhs)
226 .get_data()
227 .component_div(rhs.get_data()),
228 ),
229 BlockTypeRelationship::SecondIsScalar => self.set_data(
230 self.get_data()
231 .component_div(BlockData::scalar_sizeof(rhs.scalar(), self).get_data()),
232 ),
233 _ => panic!("Cannot add unless sizes match or one is scalar."),
234 }
235 }
236}
237
238impl BitAnd for &BlockData {
239 type Output = BlockData;
240 fn bitand(self, rhs: &BlockData) -> Self::Output {
241 match self.compare(rhs) {
242 BlockTypeRelationship::SameSizes => self.component_bitand(rhs),
243 BlockTypeRelationship::FirstIsScalar => {
244 BlockData::scalar_sizeof(self.scalar(), rhs).component_bitand(rhs)
245 }
246 BlockTypeRelationship::SecondIsScalar => {
247 self.component_bitand(&BlockData::scalar_sizeof(rhs.scalar(), self))
248 }
249 _ => panic!("Cannot AND unless sizes match or one is scalar."),
250 }
251 }
252}
253
254impl BitAnd for BlockData {
255 type Output = BlockData;
256 fn bitand(self, rhs: BlockData) -> Self::Output {
257 &self & &rhs
258 }
259}
260
261impl BitOr for &BlockData {
262 type Output = BlockData;
263 fn bitor(self, rhs: &BlockData) -> Self::Output {
264 match self.compare(rhs) {
265 BlockTypeRelationship::SameSizes => self.component_bitor(rhs),
266 BlockTypeRelationship::FirstIsScalar => {
267 BlockData::scalar_sizeof(self.scalar(), rhs).component_bitor(rhs)
268 }
269 BlockTypeRelationship::SecondIsScalar => {
270 self.component_bitor(&BlockData::scalar_sizeof(rhs.scalar(), self))
271 }
272 _ => panic!("Cannot OR unless sizes match or one is scalar."),
273 }
274 }
275}
276
277impl BitOr for BlockData {
278 type Output = BlockData;
279 fn bitor(self, rhs: BlockData) -> Self::Output {
280 &self | &rhs
281 }
282}
283
284impl BitXor for &BlockData {
285 type Output = BlockData;
286 fn bitxor(self, rhs: &BlockData) -> Self::Output {
287 match self.compare(rhs) {
288 BlockTypeRelationship::SameSizes => self.component_bitxor(rhs),
289 BlockTypeRelationship::FirstIsScalar => {
290 BlockData::scalar_sizeof(self.scalar(), rhs).component_bitxor(rhs)
291 }
292 BlockTypeRelationship::SecondIsScalar => {
293 self.component_bitxor(&BlockData::scalar_sizeof(rhs.scalar(), self))
294 }
295 _ => panic!("Cannot XOR unless sizes match or one is scalar."),
296 }
297 }
298}
299
300impl BitXor for BlockData {
301 type Output = BlockData;
302 fn bitxor(self, rhs: BlockData) -> Self::Output {
303 &self ^ &rhs
304 }
305}
306
307impl Shl<i32> for &BlockData {
308 type Output = BlockData;
309 fn shl(self, rhs: i32) -> Self::Output {
310 self.component_lshift(rhs)
311 }
312}
313
314impl Shl<i32> for BlockData {
315 type Output = BlockData;
316 fn shl(self, rhs: i32) -> Self::Output {
317 &self << rhs
318 }
319}
320
321impl Shr<i32> for &BlockData {
322 type Output = BlockData;
323 fn shr(self, rhs: i32) -> Self::Output {
324 self.component_rshift(rhs)
325 }
326}
327
328impl Shr<i32> for BlockData {
329 type Output = BlockData;
330 fn shr(self, rhs: i32) -> Self::Output {
331 &self >> rhs
332 }
333}
334
335impl AbsDiffEq for BlockData {
336 type Epsilon = f64;
337
338 fn default_epsilon() -> Self::Epsilon {
339 DMatrix::<f64>::default_epsilon()
340 }
341
342 fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
343 self.get_data().abs_diff_eq(other.get_data(), epsilon)
344 }
345
346 fn abs_diff_ne(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
347 self.get_data().abs_diff_ne(other.get_data(), epsilon)
348 }
349}
350
351impl RelativeEq for BlockData {
352 fn default_max_relative() -> Self::Epsilon {
353 DMatrix::<f64>::default_max_relative()
354 }
355
356 fn relative_eq(
357 &self,
358 other: &Self,
359 epsilon: Self::Epsilon,
360 max_relative: Self::Epsilon,
361 ) -> bool {
362 self.get_data()
363 .relative_eq(other.get_data(), epsilon, max_relative)
364 }
365
366 fn relative_ne(
367 &self,
368 other: &Self,
369 epsilon: Self::Epsilon,
370 max_relative: Self::Epsilon,
371 ) -> bool {
372 self.get_data()
373 .relative_ne(other.get_data(), epsilon, max_relative)
374 }
375}