hexga_array/
macro_impl.rs

1
2// Fixed Binary Operator 
3#[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        // Currently binary op are closed (only work with the same type), they are not like
32        // impl<T,O> $op_trait_name<T> for $name<T> where T : $op_trait_name<O> + Copy
33        // because this cause conflict of implementation, especially in the case of matrix multiplication by 
34        // a scalar T, a Vector<T,N>, another Matrix with the good size
35        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// Generic Binary Operator 
45#[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> 
61            where T : $op_trait_name<T>
62        {
63            type Output=$name<<T as $op_trait_name<T>>::Output, N>;
64            fn $op_trait_fn_name(self, rhs: Self) -> Self::Output { self.map_with(rhs, T::$op_trait_fn_name) }
65        }
66    }
67}
68
69#[macro_export]
70macro_rules! impl_generic_array_like_op_binary_non_composite
71{
72    ($name: ident, $op_trait_name: ident, $op_trait_fn_name : ident) =>
73    {
74        impl<T, const N : usize> $op_trait_name<T> for $name<T,N> where T : $op_trait_name<T> + Copy
75        {
76            type Output=$name<<T as $op_trait_name<T>>::Output,N>;
77            fn $op_trait_fn_name(self, rhs: T) -> Self::Output { self.to_array().map(|v| v.$op_trait_fn_name(rhs)).into() }
78        }
79    }
80}
81
82
83#[macro_export]
84macro_rules! impl_fixed_array_like_op_assign
85{
86    ($name: ident, $dim : expr, $op_trait_name: ident, $op_trait_fn_name : ident) =>
87    {
88        impl<T> $op_trait_name<Self> for $name<T> where T : $op_trait_name
89        {
90            fn $op_trait_fn_name(&mut self, rhs: Self) 
91            {
92                let arr : [T; $dim] = rhs.into();
93                self.array_mut().iter_mut().zip(arr.into_iter()).for_each(|(a, b)| a.$op_trait_fn_name(b));
94            }
95        }
96
97        impl<T> $op_trait_name<&Self> for $name<T> where T : $op_trait_name + Copy
98        {
99            fn $op_trait_fn_name(&mut self, rhs: &Self) { $op_trait_name::$op_trait_fn_name(self,*rhs) }
100        }
101    }
102}
103
104#[macro_export]
105macro_rules! impl_generic_array_like_op_assign
106{
107    ($name: ident, $op_trait_name: ident, $op_trait_fn_name : ident) =>
108    {
109        impl<T, const N : usize> $op_trait_name<Self> for $name<T,N> where T : $op_trait_name
110        {
111            fn $op_trait_fn_name(&mut self, rhs: Self) 
112            {
113                let arr : [T; N] = rhs.into();
114                self.array_mut().iter_mut().zip(arr.into_iter()).for_each(|(a, b)| a.$op_trait_fn_name(b));
115            }
116        }
117
118        impl<T, const N : usize> $op_trait_name<&Self> for $name<T,N> where T : $op_trait_name + Copy
119        {
120            fn $op_trait_fn_name(&mut self, rhs: &Self) { $op_trait_name::$op_trait_fn_name(self,*rhs) }
121        }
122    }
123}
124
125#[macro_export]
126macro_rules! impl_fixed_array_like_op
127{
128    ($name: ident, $dim : expr) => 
129    {
130        impl_fixed_array_like_op_binary!($name, $dim, Add, add);
131        impl_fixed_array_like_op_assign!($name, $dim, AddAssign, add_assign);
132
133        impl_fixed_array_like_op_binary!($name, $dim, Sub, sub);
134        impl_fixed_array_like_op_assign!($name, $dim, SubAssign, sub_assign);
135
136        impl_fixed_array_like_op_binary!($name, $dim, Mul, mul);
137        impl_fixed_array_like_op_assign!($name, $dim, MulAssign, mul_assign);
138
139        impl_fixed_array_like_op_binary!($name, $dim, Div, div);
140        impl_fixed_array_like_op_assign!($name, $dim, DivAssign, div_assign);
141
142        impl_fixed_array_like_op_binary!($name, $dim, Rem, rem);
143        impl_fixed_array_like_op_assign!($name, $dim, RemAssign, rem_assign);
144
145        impl_fixed_array_like_op_binary!($name, $dim, BitAnd, bitand);
146        impl_fixed_array_like_op_assign!($name, $dim, BitAndAssign, bitand_assign);
147
148        impl_fixed_array_like_op_binary!($name, $dim, BitOr, bitor);
149        impl_fixed_array_like_op_assign!($name, $dim, BitOrAssign, bitor_assign);
150
151        impl_fixed_array_like_op_binary!($name, $dim, BitXor, bitxor);
152        impl_fixed_array_like_op_assign!($name, $dim, BitXorAssign, bitxor_assign);
153
154        impl_fixed_array_like_op_binary!($name, $dim, Shr, shr);
155        impl_fixed_array_like_op_assign!($name, $dim, ShrAssign, shr_assign);
156
157        impl_fixed_array_like_op_binary!($name, $dim, Shl, shl);
158        impl_fixed_array_like_op_assign!($name, $dim, ShlAssign, shl_assign);
159        
160        // ================= Unary =========
161
162        impl<T> ::std::ops::Not for $name<T> where T : Not
163        {
164            type Output = $name<T::Output>;
165            fn not(self) -> Self::Output { self.map(|v| v.not()) }
166        }
167
168        impl<T> ::std::ops::Neg for $name<T> where T : Neg
169        {
170            type Output = $name<T::Output>;
171            fn neg(self) -> Self::Output { self.map(|v| v.neg()) }
172        }
173
174        // ================= Iter =========
175
176        impl<T> ::std::iter::Sum for $name<T> where Self : Zero + Add<Self,Output = Self>
177        {
178            fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
179                iter.fold(Self::ZERO, Self::add)
180            }
181        }
182
183        impl<T> ::std::iter::Product for $name<T> where Self : One + Mul<Self,Output = Self>
184        {
185            fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
186                iter.fold(Self::ONE, Self::mul)
187            }
188        }
189
190        // ================= Display =========
191
192        impl_fixed_array_like_display!($name, Display);
193        impl_fixed_array_like_display!($name, Debug);
194        impl_fixed_array_like_display!($name, Octal);
195        impl_fixed_array_like_display!($name, Binary);
196        impl_fixed_array_like_display!($name, LowerHex);
197        impl_fixed_array_like_display!($name, UpperHex);
198        impl_fixed_array_like_display!($name, LowerExp);
199        impl_fixed_array_like_display!($name, UpperExp);
200        impl_fixed_array_like_display!($name, Pointer);
201    }
202}
203
204#[macro_export]
205macro_rules! impl_generic_array_like_display
206{
207    ($name: ident, $trait_name :ident) =>
208    {
209        impl<T, const N : usize> std::fmt::$trait_name  for $name<T,N> where T : std::fmt::$trait_name  
210        { 
211            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result 
212            {
213                write!(f, "(")?;
214                let mut it = self.array().iter().peekable();
215                while let Some(v) = it.next()
216                {
217                    v.fmt(f)?;
218                    if it.peek().is_some()
219                    {
220                        write!(f, ", ")?;
221                    }
222                }
223                write!(f, ")")
224            }
225        }
226    }
227}
228
229#[macro_export]
230macro_rules! impl_fixed_array_like_display
231{
232    ($name: ident, $trait_name :ident) =>
233    {
234        impl<T> std::fmt::$trait_name  for $name<T> where T : std::fmt::$trait_name  
235        { 
236            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result 
237            {
238                write!(f, "(")?;
239                let mut it = self.array().iter().peekable();
240                while let Some(v) = it.next()
241                {
242                    v.fmt(f)?;
243                    if it.peek().is_some()
244                    {
245                        write!(f, ", ")?;
246                    }
247                }
248                write!(f, ")")
249            }
250        }
251    }
252}
253
254#[macro_export]
255macro_rules! impl_generic_array_like_op
256{
257    ($name: ident) => 
258    {
259        impl_generic_array_like_op_binary!($name, Add, add);
260        impl_generic_array_like_op_assign!($name, AddAssign, add_assign);
261
262        impl_generic_array_like_op_binary!($name, Sub, sub);
263        impl_generic_array_like_op_assign!($name, SubAssign, sub_assign);
264
265        impl_generic_array_like_op_binary!($name, Mul, mul);
266        impl_generic_array_like_op_assign!($name, MulAssign, mul_assign);
267
268        impl_generic_array_like_op_binary!($name, Div, div);
269        impl_generic_array_like_op_assign!($name, DivAssign, div_assign);
270
271        impl_generic_array_like_op_binary!($name, Rem, rem);
272        impl_generic_array_like_op_assign!($name, RemAssign, rem_assign);
273
274        impl_generic_array_like_op_binary!($name, BitAnd, bitand);
275        impl_generic_array_like_op_assign!($name, BitAndAssign, bitand_assign);
276
277        impl_generic_array_like_op_binary!($name, BitOr, bitor);
278        impl_generic_array_like_op_assign!($name, BitOrAssign, bitor_assign);
279
280        impl_generic_array_like_op_binary!($name, BitXor, bitxor);
281        impl_generic_array_like_op_assign!($name, BitXorAssign, bitxor_assign);
282
283        impl_generic_array_like_op_binary!($name, Shr, shr);
284        impl_generic_array_like_op_assign!($name, ShrAssign, shr_assign);
285
286        impl_generic_array_like_op_binary!($name, Shl, shl);
287        impl_generic_array_like_op_assign!($name, ShlAssign, shl_assign);
288
289        // ================= Unary =========
290
291        impl<T, const N : usize> ::std::ops::Not for $name<T,N> where T : Not
292        {
293            type Output = $name<T::Output,N>;
294            fn not(self) -> Self::Output { self.map(|v| v.not()) }
295        }
296
297        impl<T, const N : usize> ::std::ops::Neg for $name<T,N> where T : Neg
298        {
299            type Output = $name<T::Output,N>;
300            fn neg(self) -> Self::Output { self.map(|v| v.neg()) }
301        }
302
303        // ================= Iter =========
304        
305        impl<T, const N : usize> ::std::iter::Sum for $name<T,N> where Self : ::hexga_number::Zero + ::std::ops::Add<Self,Output = Self>
306        {
307            fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
308                iter.fold(Self::ZERO, Self::add)
309            }
310        }
311
312        impl<T, const N : usize> ::std::iter::Product for $name<T,N> where Self : ::hexga_number::One + ::std::ops::Mul<Self,Output = Self>
313        {
314            fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
315                iter.fold(Self::ONE, Self::mul)
316            }
317        }
318
319        // ================= Display =========
320
321        impl_generic_array_like_display!($name, Display);
322        impl_generic_array_like_display!($name, Debug);
323        impl_generic_array_like_display!($name, Octal);
324        impl_generic_array_like_display!($name, Binary);
325        impl_generic_array_like_display!($name, LowerHex);
326        impl_generic_array_like_display!($name, UpperHex);
327        impl_generic_array_like_display!($name, LowerExp);
328        impl_generic_array_like_display!($name, UpperExp);
329        impl_generic_array_like_display!($name, Pointer);
330    }
331}
332
333#[macro_export]
334macro_rules! impl_fixed_array_like
335{
336    ($name: ident, $dim : expr) => 
337    { 
338        impl<T> ::std::marker::Copy  for $name<T> where T : Copy {}
339        impl<T> ::std::clone::Clone for $name<T> where T : Clone
340        {
341            fn clone(&self) -> Self { self.array().clone().into() }
342        }
343
344        impl<T> ::std::cmp::PartialEq for $name<T> where T : PartialEq
345        {
346            fn eq(&self, rhs : &Self) -> bool { self.array() == rhs.array() }
347        }
348        impl<T> ::std::cmp::Eq for $name<T> where T : Eq {}
349
350        impl<T> ::std::cmp::PartialOrd for $name<T> where T : PartialOrd
351        {
352            fn partial_cmp(&self, rhs : &Self) -> ::std::option::Option<::std::cmp::Ordering> { ::std::cmp::PartialOrd::partial_cmp(self.array(), rhs.array()) }
353        }
354        impl<T> ::std::cmp::Ord for $name<T> where T : Ord 
355        {
356            fn cmp(&self, rhs : &Self) -> ::std::cmp::Ordering { ::std::cmp::Ord::cmp(self.array(), rhs.array()) }
357        }
358
359        impl<T> ::std::hash::Hash for $name<T> where T : Hash
360        {
361            fn hash<H>(&self, state: &mut H) where H: Hasher { self.as_ref().hash(state); }
362        }
363
364        impl<T> ::std::convert::From<T> for $name<T> where T : Copy { fn from(value: T) -> Self { Self::from([value; $dim]) } }
365    
366        impl<T> ::std::convert::From<[T; $dim]> for $name<T> { fn from(value: [T; $dim]) -> Self { unsafe { std::mem::transmute_copy(&value) } } }
367        impl<T> ::std::convert::From<$name<T>> for [T; $dim] { fn from(value: $name<T>) -> Self { unsafe { std::mem::transmute_copy(&value) } } }
368
369        impl<T> ::std::convert::AsRef<[T; $dim]> for $name<T> { fn as_ref(&self) -> &[T; $dim] { unsafe { std::mem::transmute(self) } } }
370        impl<T> ::std::convert::AsMut<[T; $dim]> for $name<T> { fn as_mut(&mut self) -> &mut [T; $dim] { unsafe { std::mem::transmute(self) } } }
371
372        impl<T> $crate::ArrayLike<T, $dim> for $name<T>
373        {
374            type WithType<T2>=$name<T2>;
375
376            fn array(&self) -> &[T; $dim] { unsafe { std::mem::transmute(self) } }
377            fn array_mut(&mut self) -> &mut[T; $dim] { unsafe { std::mem::transmute(self) } }
378        }
379
380        impl<T, Idx> ::std::ops::Index<Idx> for $name<T> where [T;$dim] : ::std::ops::Index<Idx>
381        { 
382            type Output=<[T;$dim] as ::std::ops::Index<Idx>>::Output; 
383            fn index(&self, index: Idx) -> &Self::Output { self.array().index(index) } 
384        }
385        impl<T, Idx> ::std::ops::IndexMut<Idx> for $name<T> where [T;$dim] : ::std::ops::IndexMut<Idx>
386        { 
387            fn index_mut(&mut self, index: Idx) -> &mut Self::Output { self.array_mut().index_mut(index) } 
388        }
389    
390        impl<T, Idx> ::hexga_core::collections::Get<Idx> for $name<T> where [T;$dim] : ::hexga_core::collections::Get<Idx>
391        { 
392            type Output = <[T;$dim] as ::hexga_core::collections::Get<Idx>>::Output;
393
394            #[inline(always)]
395            fn try_get(&self, index: Idx) -> Result<&Self::Output, ()> { ::hexga_core::collections::Get::try_get(self.array(), index) }
396            #[inline(always)]
397            fn get(&self, index: Idx) -> Option<&Self::Output> { ::hexga_core::collections::Get::get(self.array(), index) } 
398            #[inline(always)]
399            #[track_caller]
400            unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output { unsafe { ::hexga_core::collections::Get::get_unchecked(self.array(), index) } } 
401        }
402        impl<T, Idx> ::hexga_core::collections::GetMut<Idx> for $name<T> where [T;$dim] : ::hexga_core::collections::GetMut<Idx>
403        { 
404            #[inline(always)]
405            fn try_get_mut(&mut self, index: Idx) -> Result<&mut Self::Output, ()> { ::hexga_core::collections::GetMut::try_get_mut(self.array_mut(), index) } 
406            #[inline(always)]
407            fn get_mut(&mut self, index: Idx) -> Option<&mut Self::Output> { ::hexga_core::collections::GetMut::get_mut(self.array_mut(), index) } 
408            #[inline(always)]
409            #[track_caller]
410            unsafe fn get_unchecked_mut(&mut self, index: Idx) -> &mut Self::Output { unsafe { ::hexga_core::collections::GetMut::get_unchecked_mut(self.array_mut(), index) } } 
411        }
412
413        impl<T, Idx> ::hexga_core::collections::GetManyMut<Idx> for $name<T> where [T;$dim] : ::hexga_core::collections::GetManyMut<Idx>
414        {
415            #[inline(always)]
416            fn try_get_many_mut<const N: usize>(&mut self, indices: [Idx; N]) -> Result<[&mut Self::Output;N], ()> { ::hexga_core::collections::GetManyMut::try_get_many_mut(self.array_mut(), indices) }
417            #[inline(always)]
418            #[track_caller]
419            unsafe fn get_many_unchecked_mut<const N: usize>(&mut self, indices: [Idx; N]) -> [&mut Self::Output;N] { unsafe { ::hexga_core::collections::GetManyMut::get_many_unchecked_mut(self.array_mut(), indices) } }
420        }
421
422        impl<T> ::std::iter::IntoIterator for $name<T> where [T;$dim] : ::std::iter::IntoIterator
423        {
424            type Item = <[T;$dim] as ::std::iter::IntoIterator>::Item;
425            type IntoIter = <[T;$dim] as ::std::iter::IntoIterator>::IntoIter;
426        
427            fn into_iter(self) -> Self::IntoIter 
428            {
429                self.to_array().into_iter()
430            }
431        }
432        
433        impl<'a, T> ::std::iter::IntoIterator for &'a $name<T> where &'a [T;$dim] : ::std::iter::IntoIterator
434        {
435            type Item = <&'a [T;$dim] as ::std::iter::IntoIterator>::Item;
436            type IntoIter = <&'a [T;$dim] as ::std::iter::IntoIterator>::IntoIter;
437        
438            fn into_iter(self) -> Self::IntoIter {
439                self.as_array().into_iter()
440            }
441        }
442        
443        impl<'a, T> ::std::iter::IntoIterator for &'a mut $name<T> where &'a mut [T;$dim] : ::std::iter::IntoIterator
444        {
445            type Item = <&'a mut [T;$dim] as IntoIterator>::Item;
446            type IntoIter = <&'a mut [T;$dim] as IntoIterator>::IntoIter;
447        
448            fn into_iter(self) -> Self::IntoIter {
449                self.as_array_mut().into_iter()
450            }
451        }
452
453        #[cfg(feature = "serde")]
454        impl<T> ::serde::Serialize for $name<T> where [T;$dim] : ::serde::Serialize
455        {
456            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer,
457            { self.as_array().serialize(serializer) }
458        }
459
460        #[cfg(feature = "serde")]
461        impl<'de, T> ::serde::Deserialize<'de> for $name<T> where [T;$dim] : ::serde::Deserialize<'de>{
462            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: ::serde::Deserializer<'de>,
463            {
464                Ok(<[T;$dim]>::deserialize(deserializer)?.into())
465            }
466        }
467    };
468}
469
470
471
472#[macro_export]
473macro_rules! impl_fixed_array_like_with_op
474{
475    ($name: ident, $dim : expr) => 
476    { 
477        impl_fixed_array_like_op!($name, $dim);
478        impl_fixed_array_like!($name, $dim);
479    };
480}
481
482
483
484#[macro_export]
485macro_rules! impl_generic_array_like
486{
487    ($name: ident) => 
488    { 
489        impl<T, const N : usize> ::std::marker::Copy  for $name<T,N> where T : Copy  {}
490        impl<T, const N : usize> ::std::clone::Clone for $name<T,N> where T : Clone
491        {
492            fn clone(&self) -> Self { self.array().clone().into() }
493        }
494
495        impl<T, const N : usize> ::std::cmp::PartialEq for $name<T,N> where T : PartialEq
496        {
497            fn eq(&self, rhs : &Self) -> bool { self.array() == rhs.array() }
498        }
499        impl<T, const N : usize> ::std::cmp::Eq for $name<T,N> where T : Eq {}
500
501        impl<T, const N : usize> ::std::cmp::PartialOrd for $name<T,N> where T : PartialOrd
502        {
503            fn partial_cmp(&self, rhs : &Self) -> ::std::option::Option<::std::cmp::Ordering> { ::std::cmp::PartialOrd::partial_cmp(self.array(), rhs.array()) }
504        }
505        impl<T, const N : usize> ::std::cmp::Ord for $name<T,N> where T : Ord 
506        {
507            fn cmp(&self, rhs : &Self) -> ::std::cmp::Ordering { ::std::cmp::Ord::cmp(self.array(), rhs.array()) }
508        }
509
510        impl<T, const N : usize> ::std::hash::Hash for $name<T,N> where T : Hash
511        {
512            fn hash<H>(&self, state: &mut H) where H: Hasher { self.as_ref().hash(state); }
513        }
514
515        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]) } }
516
517        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) } } }
518        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) } } }
519
520        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) } } }
521        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) } } }
522
523        impl<T, const N : usize> $crate::ArrayLike<T, N> for $name<T,N>
524        {
525            type WithType<T2>=$name<T2,N>;
526
527            fn array(&self) -> &[T; N] { unsafe { std::mem::transmute(self) } }
528            fn array_mut(&mut self) -> &mut[T; N] { unsafe { std::mem::transmute(self) } }
529        }
530
531        impl<T, const N : usize, Idx> ::std::ops::Index<Idx> for $name<T,N> where [T;N] : ::std::ops::Index<Idx>
532        { 
533            type Output=<[T;N] as ::std::ops::Index<Idx>>::Output; 
534            fn index(&self, index: Idx) -> &Self::Output { self.array().index(index) } 
535        }
536        impl<T, const N : usize, Idx> ::std::ops::IndexMut<Idx> for $name<T,N> where [T;N] : ::std::ops::IndexMut<Idx>
537        { 
538            fn index_mut(&mut self, index: Idx) -> &mut Self::Output { self.array_mut().index_mut(index) } 
539        }
540    
541        impl<T, const N : usize, Idx> ::hexga_core::collections::Get<Idx> for $name<T,N> where [T;N] : ::hexga_core::collections::Get<Idx>
542        { 
543            type Output = <[T;N] as ::hexga_core::collections::Get<Idx>>::Output;
544
545            #[inline(always)]
546            fn try_get(&self, index: Idx) -> Result<&Self::Output, ()> { ::hexga_core::collections::Get::try_get(self.array(), index) }
547            #[inline(always)]
548            fn get(&self, index: Idx) -> Option<&Self::Output> { ::hexga_core::collections::Get::get(self.array(), index) } 
549            #[inline(always)]
550            #[track_caller]
551            unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output { unsafe { ::hexga_core::collections::Get::get_unchecked(self.array(), index) } } 
552        }
553        impl<T, const N : usize, Idx> ::hexga_core::collections::GetMut<Idx> for $name<T,N> where [T;N] : ::hexga_core::collections::GetMut<Idx>
554        { 
555            #[inline(always)]
556            fn try_get_mut(&mut self, index: Idx) -> Result<&mut Self::Output, ()> { ::hexga_core::collections::GetMut::try_get_mut(self.array_mut(), index) } 
557            #[inline(always)]
558            fn get_mut(&mut self, index: Idx) -> Option<&mut Self::Output> { ::hexga_core::collections::GetMut::get_mut(self.array_mut(), index) } 
559            #[inline(always)]
560            #[track_caller]
561            unsafe fn get_unchecked_mut(&mut self, index: Idx) -> &mut Self::Output { unsafe { ::hexga_core::collections::GetMut::get_unchecked_mut(self.array_mut(), index) } } 
562        }
563
564        impl<T, const N : usize, Idx> ::hexga_core::collections::GetManyMut<Idx> for $name<T,N> where [T;N] : ::hexga_core::collections::GetManyMut<Idx>
565        {
566            #[inline(always)]
567            fn try_get_many_mut<const N2: usize>(&mut self, indices: [Idx; N2]) -> Result<[&mut Self::Output;N2], ()> { ::hexga_core::collections::GetManyMut::try_get_many_mut(self.array_mut(), indices) }
568            #[inline(always)]
569            #[track_caller]
570            unsafe fn get_many_unchecked_mut<const N2: usize>(&mut self, indices: [Idx; N2]) -> [&mut Self::Output;N2] { unsafe { ::hexga_core::collections::GetManyMut::get_many_unchecked_mut(self.array_mut(), indices) } }
571        }
572
573        impl<T, const N : usize> ::std::iter::IntoIterator for $name<T,N> where [T;N] : ::std::iter::IntoIterator
574        {
575            type Item = <[T;N] as ::std::iter::IntoIterator>::Item;
576            type IntoIter = <[T;N] as ::std::iter::IntoIterator>::IntoIter;
577        
578            fn into_iter(self) -> Self::IntoIter 
579            {
580                self.to_array().into_iter()
581            }
582        }
583        
584        impl<'a, T, const N : usize> ::std::iter::IntoIterator for &'a $name<T,N> where &'a [T;N] : ::std::iter::IntoIterator
585        {
586            type Item = <&'a [T;N] as ::std::iter::IntoIterator>::Item;
587            type IntoIter = <&'a [T;N] as ::std::iter::IntoIterator>::IntoIter;
588        
589            fn into_iter(self) -> Self::IntoIter {
590                self.as_array().into_iter()
591            }
592        }
593        
594        impl<'a, T, const N : usize> ::std::iter::IntoIterator for &'a mut $name<T,N> where &'a mut [T;N] : ::std::iter::IntoIterator
595        {
596            type Item = <&'a mut [T;N] as IntoIterator>::Item;
597            type IntoIter = <&'a mut [T;N] as IntoIterator>::IntoIter;
598        
599            fn into_iter(self) -> Self::IntoIter {
600                self.as_array_mut().into_iter()
601            }
602        }
603
604        #[cfg(feature = "serde")]
605        impl<T, const N : usize> ::serde::Serialize for $name<T,N> where [T;N] : ::serde::Serialize
606        {
607            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer,
608            { self.as_array().serialize(serializer) }
609        }
610
611        #[cfg(feature = "serde")]
612        impl<'de, T, const N : usize> ::serde::Deserialize<'de> for $name<T,N> where [T;N] : ::serde::Deserialize<'de>{
613            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: ::serde::Deserializer<'de>,
614            {
615                Ok(<[T;N]>::deserialize(deserializer)?.into())
616            }
617        }
618    };
619}
620
621#[macro_export]
622macro_rules! impl_generic_array_like_with_op
623{
624    ($name: ident) => 
625    { 
626        impl_generic_array_like_op!($name);
627        impl_generic_array_like!($name);
628    };
629}