1
2#[macro_export]
4macro_rules! impl_fixed_array_like_op_binary
5{
6 ($name: ident, $dim : expr, $op_trait_name: ident, $op_trait_fn_name : ident) =>
7 {
8 impl_fixed_array_like_op_binary_composite!($name,$dim,$op_trait_name,$op_trait_fn_name);
9 impl_fixed_array_like_op_binary_non_composite!($name,$dim,$op_trait_name,$op_trait_fn_name);
10 }
11}
12
13#[macro_export]
14macro_rules! impl_fixed_array_like_op_binary_composite
15{
16 ($name: ident, $dim : expr, $op_trait_name: ident, $op_trait_fn_name : ident) =>
17 {
18 impl<T> $op_trait_name<Self> for $name<T> where T : $op_trait_name<T>
19 {
20 type Output=$name<<T as $op_trait_name<T>>::Output>;
21 fn $op_trait_fn_name(self, rhs: Self) -> Self::Output { self.map_with(rhs, T::$op_trait_fn_name) }
22 }
23 };
24}
25
26#[macro_export]
27macro_rules! impl_fixed_array_like_op_binary_non_composite
28{
29 ($name: ident, $dim : expr, $op_trait_name: ident, $op_trait_fn_name : ident) =>
30 {
31 impl<T> $op_trait_name<T> for $name<T> where T : $op_trait_name<T> + Copy
36 {
37 type Output=$name<<T as $op_trait_name<T>>::Output>;
38 fn $op_trait_fn_name(self, rhs: T) -> Self::Output { <[T;$dim]>::from(self).map(|v| v.$op_trait_fn_name(rhs)).into() }
39 }
40 };
41}
42
43
44#[macro_export]
46macro_rules! impl_generic_array_like_op_binary
47{
48 ($name: ident, $op_trait_name: ident, $op_trait_fn_name : ident) =>
49 {
50 impl_generic_array_like_op_binary_composite!($name,$op_trait_name,$op_trait_fn_name);
51 impl_generic_array_like_op_binary_non_composite!($name,$op_trait_name,$op_trait_fn_name);
52 }
53}
54
55#[macro_export]
56macro_rules! impl_generic_array_like_op_binary_composite
57{
58 ($name: ident, $op_trait_name: ident, $op_trait_fn_name : ident) =>
59 {
60 impl<T, const N : usize> $op_trait_name<Self> for $name<T, N> where T : $op_trait_name<T>
61 {
62 type Output=$name<<T as $op_trait_name<T>>::Output, N>;
63 fn $op_trait_fn_name(self, rhs: Self) -> Self::Output { self.map_with(rhs, T::$op_trait_fn_name) }
64 }
65 }
66}
67
68#[macro_export]
69macro_rules! impl_generic_array_like_op_binary_non_composite
70{
71 ($name: ident, $op_trait_name: ident, $op_trait_fn_name : ident) =>
72 {
73 impl<T, const N : usize> $op_trait_name<T> for $name<T,N> where T : $op_trait_name<T> + Copy
74 {
75 type Output=$name<<T as $op_trait_name<T>>::Output,N>;
76 fn $op_trait_fn_name(self, rhs: T) -> Self::Output { self.to_array().map(|v| v.$op_trait_fn_name(rhs)).into() }
77 }
78 }
79}
80
81
82#[macro_export]
83macro_rules! impl_fixed_array_like_op_assign
84{
85 ($name: ident, $dim : expr, $op_trait_name: ident, $op_trait_fn_name : ident) =>
86 {
87 impl<T> $op_trait_name<Self> for $name<T> where T : $op_trait_name
88 {
89 fn $op_trait_fn_name(&mut self, rhs: Self)
90 {
91 let arr : [T; $dim] = rhs.into();
92 self.array_mut().iter_mut().zip(arr.into_iter()).for_each(|(a, b)| a.$op_trait_fn_name(b));
93 }
94 }
95 }
96}
97
98#[macro_export]
99macro_rules! impl_generic_array_like_op_assign
100{
101 ($name: ident, $op_trait_name: ident, $op_trait_fn_name : ident) =>
102 {
103 impl<T, const N : usize> $op_trait_name<Self> for $name<T,N> where T : $op_trait_name
104 {
105 fn $op_trait_fn_name(&mut self, rhs: Self)
106 {
107 let arr : [T; N] = rhs.into();
108 self.array_mut().iter_mut().zip(arr.into_iter()).for_each(|(a, b)| a.$op_trait_fn_name(b));
109 }
110 }
111 }
112}
113
114#[macro_export]
115macro_rules! impl_fixed_array_like_op
116{
117 ($name: ident, $dim : expr) =>
118 {
119 impl_fixed_array_like_op_binary!($name, $dim, Add, add);
120 impl_fixed_array_like_op_assign!($name, $dim, AddAssign, add_assign);
121
122 impl_fixed_array_like_op_binary!($name, $dim, Sub, sub);
123 impl_fixed_array_like_op_assign!($name, $dim, SubAssign, sub_assign);
124
125 impl_fixed_array_like_op_binary!($name, $dim, Mul, mul);
126 impl_fixed_array_like_op_assign!($name, $dim, MulAssign, mul_assign);
127
128 impl_fixed_array_like_op_binary!($name, $dim, Div, div);
129 impl_fixed_array_like_op_assign!($name, $dim, DivAssign, div_assign);
130
131 impl_fixed_array_like_op_binary!($name, $dim, Rem, rem);
132 impl_fixed_array_like_op_assign!($name, $dim, RemAssign, rem_assign);
133
134 impl_fixed_array_like_op_binary!($name, $dim, BitAnd, bitand);
135 impl_fixed_array_like_op_assign!($name, $dim, BitAndAssign, bitand_assign);
136
137 impl_fixed_array_like_op_binary!($name, $dim, BitOr, bitor);
138 impl_fixed_array_like_op_assign!($name, $dim, BitOrAssign, bitor_assign);
139
140 impl_fixed_array_like_op_binary!($name, $dim, BitXor, bitxor);
141 impl_fixed_array_like_op_assign!($name, $dim, BitXorAssign, bitxor_assign);
142
143 impl_fixed_array_like_op_binary!($name, $dim, Shr, shr);
144 impl_fixed_array_like_op_assign!($name, $dim, ShrAssign, shr_assign);
145
146 impl_fixed_array_like_op_binary!($name, $dim, Shl, shl);
147 impl_fixed_array_like_op_assign!($name, $dim, ShlAssign, shl_assign);
148
149 impl<T> ::std::ops::Not for $name<T> where T : Not
152 {
153 type Output = $name<T::Output>;
154 fn not(self) -> Self::Output { self.map(|v| v.not()) }
155 }
156
157 impl<T> ::std::ops::Neg for $name<T> where T : Neg
158 {
159 type Output = $name<T::Output>;
160 fn neg(self) -> Self::Output { self.map(|v| v.neg()) }
161 }
162
163 impl<T> ::std::iter::Sum for $name<T> where Self : Zero + Add<Self,Output = Self>
166 {
167 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
168 iter.fold(Self::ZERO, Self::add)
169 }
170 }
171
172 impl<T> ::std::iter::Product for $name<T> where Self : One + Mul<Self,Output = Self>
173 {
174 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
175 iter.fold(Self::ONE, Self::mul)
176 }
177 }
178
179 impl_fixed_array_like_display!($name, Display);
182 impl_fixed_array_like_display!($name, Debug);
183 impl_fixed_array_like_display!($name, Octal);
184 impl_fixed_array_like_display!($name, Binary);
185 impl_fixed_array_like_display!($name, LowerHex);
186 impl_fixed_array_like_display!($name, UpperHex);
187 impl_fixed_array_like_display!($name, LowerExp);
188 impl_fixed_array_like_display!($name, UpperExp);
189 impl_fixed_array_like_display!($name, Pointer);
190 }
191}
192
193#[macro_export]
194macro_rules! impl_generic_array_like_display
195{
196 ($name: ident, $trait_name :ident) =>
197 {
198 impl<T, const N : usize> std::fmt::$trait_name for $name<T,N> where T : std::fmt::$trait_name
199 {
200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
201 {
202 write!(f, "(")?;
203 let mut it = self.array().iter().peekable();
204 while let Some(v) = it.next()
205 {
206 v.fmt(f)?;
207 if it.peek().is_some()
208 {
209 write!(f, ", ")?;
210 }
211 }
212 write!(f, ")")
213 }
214 }
215 }
216}
217
218#[macro_export]
219macro_rules! impl_fixed_array_like_display
220{
221 ($name: ident, $trait_name :ident) =>
222 {
223 impl<T> std::fmt::$trait_name for $name<T> where T : std::fmt::$trait_name
224 {
225 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
226 {
227 write!(f, "(")?;
228 let mut it = self.array().iter().peekable();
229 while let Some(v) = it.next()
230 {
231 v.fmt(f)?;
232 if it.peek().is_some()
233 {
234 write!(f, ", ")?;
235 }
236 }
237 write!(f, ")")
238 }
239 }
240 }
241}
242
243#[macro_export]
244macro_rules! impl_generic_array_like_op
245{
246 ($name: ident) =>
247 {
248 impl_generic_array_like_op_binary!($name, Add, add);
249 impl_generic_array_like_op_assign!($name, AddAssign, add_assign);
250
251 impl_generic_array_like_op_binary!($name, Sub, sub);
252 impl_generic_array_like_op_assign!($name, SubAssign, sub_assign);
253
254 impl_generic_array_like_op_binary!($name, Mul, mul);
255 impl_generic_array_like_op_assign!($name, MulAssign, mul_assign);
256
257 impl_generic_array_like_op_binary!($name, Div, div);
258 impl_generic_array_like_op_assign!($name, DivAssign, div_assign);
259
260 impl_generic_array_like_op_binary!($name, Rem, rem);
261 impl_generic_array_like_op_assign!($name, RemAssign, rem_assign);
262
263 impl_generic_array_like_op_binary!($name, BitAnd, bitand);
264 impl_generic_array_like_op_assign!($name, BitAndAssign, bitand_assign);
265
266 impl_generic_array_like_op_binary!($name, BitOr, bitor);
267 impl_generic_array_like_op_assign!($name, BitOrAssign, bitor_assign);
268
269 impl_generic_array_like_op_binary!($name, BitXor, bitxor);
270 impl_generic_array_like_op_assign!($name, BitXorAssign, bitxor_assign);
271
272 impl_generic_array_like_op_binary!($name, Shr, shr);
273 impl_generic_array_like_op_assign!($name, ShrAssign, shr_assign);
274
275 impl_generic_array_like_op_binary!($name, Shl, shl);
276 impl_generic_array_like_op_assign!($name, ShlAssign, shl_assign);
277
278 impl<T, const N : usize> ::std::ops::Not for $name<T,N> where T : Not
281 {
282 type Output = $name<T::Output,N>;
283 fn not(self) -> Self::Output { self.map(|v| v.not()) }
284 }
285
286 impl<T, const N : usize> ::std::ops::Neg for $name<T,N> where T : Neg
287 {
288 type Output = $name<T::Output,N>;
289 fn neg(self) -> Self::Output { self.map(|v| v.neg()) }
290 }
291
292 impl<T, const N : usize> ::std::iter::Sum for $name<T,N> where Self : ::hexga_number::Zero + ::std::ops::Add<Self,Output = Self>
295 {
296 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
297 iter.fold(Self::ZERO, Self::add)
298 }
299 }
300
301 impl<T, const N : usize> ::std::iter::Product for $name<T,N> where Self : ::hexga_number::One + ::std::ops::Mul<Self,Output = Self>
302 {
303 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
304 iter.fold(Self::ONE, Self::mul)
305 }
306 }
307
308 impl_generic_array_like_display!($name, Display);
311 impl_generic_array_like_display!($name, Debug);
312 impl_generic_array_like_display!($name, Octal);
313 impl_generic_array_like_display!($name, Binary);
314 impl_generic_array_like_display!($name, LowerHex);
315 impl_generic_array_like_display!($name, UpperHex);
316 impl_generic_array_like_display!($name, LowerExp);
317 impl_generic_array_like_display!($name, UpperExp);
318 impl_generic_array_like_display!($name, Pointer);
319 }
320}
321
322#[macro_export]
323macro_rules! impl_fixed_array_like
324{
325 ($name: ident, $dim : expr) =>
326 {
327 impl<T> ::std::marker::Copy for $name<T> where T : Copy {}
328 impl<T> ::std::clone::Clone for $name<T> where T : Clone
329 {
330 fn clone(&self) -> Self { self.array().clone().into() }
331 }
332
333 impl<T> ::std::cmp::PartialEq for $name<T> where T : PartialEq
334 {
335 fn eq(&self, rhs : &Self) -> bool { self.array() == rhs.array() }
336 }
337 impl<T> ::std::cmp::Eq for $name<T> where T : Eq {}
338
339 impl<T> ::std::convert::From<T> for $name<T> where T : Copy { fn from(value: T) -> Self { Self::from([value; $dim]) } }
340
341 impl<T> ::std::convert::From<[T; $dim]> for $name<T> { fn from(value: [T; $dim]) -> Self { unsafe { std::mem::transmute_copy(&value) } } }
342 impl<T> ::std::convert::From<$name<T>> for [T; $dim] { fn from(value: $name<T>) -> Self { unsafe { std::mem::transmute_copy(&value) } } }
343
344 impl<T> ::std::convert::AsRef<[T; $dim]> for $name<T> { fn as_ref(&self) -> &[T; $dim] { unsafe { std::mem::transmute(self) } } }
345 impl<T> ::std::convert::AsMut<[T; $dim]> for $name<T> { fn as_mut(&mut self) -> &mut [T; $dim] { unsafe { std::mem::transmute(self) } } }
346
347 impl<T> $crate::ArrayLike<T, $dim> for $name<T>
348 {
349 type WithType<T2>=$name<T2>;
350
351 fn array(&self) -> &[T; $dim] { unsafe { std::mem::transmute(self) } }
352 fn array_mut(&mut self) -> &mut[T; $dim] { unsafe { std::mem::transmute(self) } }
353 }
354
355 impl<T> ::std::ops::Index <usize> for $name<T> { type Output=T; fn index(&self, index: usize) -> &Self::Output { self.array().index(index) } }
356 impl<T> ::std::ops::IndexMut<usize> for $name<T> { fn index_mut(&mut self, index: usize) -> &mut Self::Output { self.array_mut().index_mut(index) } }
357
358 impl<T> ::std::iter::IntoIterator for $name<T> where [T;$dim] : ::std::iter::IntoIterator
359 {
360 type Item = <[T;$dim] as ::std::iter::IntoIterator>::Item;
361 type IntoIter = <[T;$dim] as ::std::iter::IntoIterator>::IntoIter;
362
363 fn into_iter(self) -> Self::IntoIter
364 {
365 self.to_array().into_iter()
366 }
367 }
368
369 impl<'a, T> ::std::iter::IntoIterator for &'a $name<T> where &'a [T;$dim] : ::std::iter::IntoIterator
370 {
371 type Item = <&'a [T;$dim] as ::std::iter::IntoIterator>::Item;
372 type IntoIter = <&'a [T;$dim] as ::std::iter::IntoIterator>::IntoIter;
373
374 fn into_iter(self) -> Self::IntoIter {
375 self.as_array().into_iter()
376 }
377 }
378
379 impl<'a, T> ::std::iter::IntoIterator for &'a mut $name<T> where &'a mut [T;$dim] : ::std::iter::IntoIterator
380 {
381 type Item = <&'a mut [T;$dim] as IntoIterator>::Item;
382 type IntoIter = <&'a mut [T;$dim] as IntoIterator>::IntoIter;
383
384 fn into_iter(self) -> Self::IntoIter {
385 self.as_array_mut().into_iter()
386 }
387 }
388
389 #[cfg(feature = "serde")]
390 impl<T> ::serde::Serialize for $name<T> where [T;$dim] : ::serde::Serialize
391 {
392 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer,
393 { self.as_array().serialize(serializer) }
394 }
395
396 #[cfg(feature = "serde")]
397 impl<'de, T> ::serde::Deserialize<'de> for $name<T> where [T;$dim] : ::serde::Deserialize<'de>{
398 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: ::serde::Deserializer<'de>,
399 {
400 Ok(<[T;$dim]>::deserialize(deserializer)?.into())
401 }
402 }
403 };
404}
405
406
407
408#[macro_export]
409macro_rules! impl_fixed_array_like_with_op
410{
411 ($name: ident, $dim : expr) =>
412 {
413 impl_fixed_array_like_op!($name, $dim);
414 impl_fixed_array_like!($name, $dim);
415 };
416}
417
418
419
420#[macro_export]
421macro_rules! impl_generic_array_like
422{
423 ($name: ident) =>
424 {
425 impl<T, const N : usize> ::std::marker::Copy for $name<T,N> where T : Copy {}
426 impl<T, const N : usize> ::std::clone::Clone for $name<T,N> where T : Clone
427 {
428 fn clone(&self) -> Self { self.array().clone().into() }
429 }
430
431 impl<T, const N : usize> ::std::cmp::PartialEq for $name<T,N> where T : PartialEq
432 {
433 fn eq(&self, rhs : &Self) -> bool { self.array() == rhs.array() }
434 }
435 impl<T, const N : usize> ::std::cmp::Eq for $name<T,N> where T : Eq{}
436
437 impl<T, const N : usize> ::std::convert::From<T> for $name<T,N> where T : Copy { fn from(value: T) -> Self { Self::from([value; N]) } }
438
439 impl<T, const N : usize> ::std::convert::From<[T; N]> for $name<T,N> { fn from(value: [T; N]) -> Self { unsafe { std::mem::transmute_copy(&value) } } }
440 impl<T, const N : usize> ::std::convert::From<$name<T,N>> for [T; N] { fn from(value: $name<T,N>) -> Self { unsafe { std::mem::transmute_copy(&value) } } }
441
442 impl<T, const N : usize> ::std::convert::AsRef<[T; N]> for $name<T,N> { fn as_ref(&self) -> &[T; N] { unsafe { std::mem::transmute(self) } } }
443 impl<T, const N : usize> ::std::convert::AsMut<[T; N]> for $name<T,N> { fn as_mut(&mut self) -> &mut [T; N] { unsafe { std::mem::transmute(self) } } }
444
445 impl<T, const N : usize> $crate::ArrayLike<T, N> for $name<T,N>
446 {
447 type WithType<T2>=$name<T2,N>;
448
449 fn array(&self) -> &[T; N] { unsafe { std::mem::transmute(self) } }
450 fn array_mut(&mut self) -> &mut[T; N] { unsafe { std::mem::transmute(self) } }
451 }
452
453 impl<T, const N : usize> ::std::ops::Index <usize> for $name<T,N> { type Output=T; fn index(&self, index: usize) -> &Self::Output { self.array().index(index) } }
454 impl<T, const N : usize> ::std::ops::IndexMut<usize> for $name<T,N> { fn index_mut(&mut self, index: usize) -> &mut Self::Output { self.array_mut().index_mut(index) } }
455
456 impl<T, const N : usize> ::std::iter::IntoIterator for $name<T,N> where [T;N] : ::std::iter::IntoIterator
457 {
458 type Item = <[T;N] as ::std::iter::IntoIterator>::Item;
459 type IntoIter = <[T;N] as ::std::iter::IntoIterator>::IntoIter;
460
461 fn into_iter(self) -> Self::IntoIter
462 {
463 self.to_array().into_iter()
464 }
465 }
466
467 impl<'a, T, const N : usize> ::std::iter::IntoIterator for &'a $name<T,N> where &'a [T;N] : ::std::iter::IntoIterator
468 {
469 type Item = <&'a [T;N] as ::std::iter::IntoIterator>::Item;
470 type IntoIter = <&'a [T;N] as ::std::iter::IntoIterator>::IntoIter;
471
472 fn into_iter(self) -> Self::IntoIter {
473 self.as_array().into_iter()
474 }
475 }
476
477 impl<'a, T, const N : usize> ::std::iter::IntoIterator for &'a mut $name<T,N> where &'a mut [T;N] : ::std::iter::IntoIterator
478 {
479 type Item = <&'a mut [T;N] as IntoIterator>::Item;
480 type IntoIter = <&'a mut [T;N] as IntoIterator>::IntoIter;
481
482 fn into_iter(self) -> Self::IntoIter {
483 self.as_array_mut().into_iter()
484 }
485 }
486
487 #[cfg(feature = "serde")]
488 impl<T, const N : usize> ::serde::Serialize for $name<T,N> where [T;N] : ::serde::Serialize
489 {
490 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer,
491 { self.as_array().serialize(serializer) }
492 }
493
494 #[cfg(feature = "serde")]
495 impl<'de, T, const N : usize> ::serde::Deserialize<'de> for $name<T,N> where [T;N] : ::serde::Deserialize<'de>{
496 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: ::serde::Deserializer<'de>,
497 {
498 Ok(<[T;N]>::deserialize(deserializer)?.into())
499 }
500 }
501 };
502}
503
504#[macro_export]
505macro_rules! impl_generic_array_like_with_op
506{
507 ($name: ident) =>
508 {
509 impl_generic_array_like_op!($name);
510 impl_generic_array_like!($name);
511 };
512}