flatk/
array.rs

1//!
2//! Implementation of generic array manipulation.
3//!
4
5use super::*;
6
7/// Wrapper around `typenum` types to prevent downstream trait implementations.
8#[derive(Copy, Clone, PartialEq, PartialOrd)]
9pub struct U<N>(N);
10
11impl<N: Unsigned> std::fmt::Debug for U<N> {
12    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13        f.debug_struct(&format!("U{}", N::to_usize())).finish()
14    }
15}
16
17impl<N: Default> Default for U<N> {
18    #[inline]
19    fn default() -> Self {
20        U(N::default())
21    }
22}
23
24macro_rules! impl_array_for_typenum {
25    ($nty:ident, $n:expr) => {
26        pub type $nty = U<consts::$nty>;
27        impl<T> Set for [T; $n] {
28            type Elem = T;
29            type Atom = T;
30            #[inline]
31            fn len(&self) -> usize {
32                $n
33            }
34        }
35        impl<T> AsFlatSlice<T> for [T; $n] {
36            #[inline]
37            fn as_flat_slice(&self) -> &[T] {
38                &self[..]
39            }
40        }
41        impl<'a, T: 'a> View<'a> for [T; $n] {
42            type Type = &'a [T; $n];
43            #[inline]
44            fn view(&'a self) -> Self::Type {
45                self
46            }
47        }
48        impl<T> Viewed for &[T; $n] {}
49        impl<T> Viewed for &mut [T; $n] {}
50
51        impl<'a, T: 'a> ViewMut<'a> for [T; $n] {
52            type Type = &'a mut [T; $n];
53            #[inline]
54            fn view_mut(&'a mut self) -> Self::Type {
55                self
56            }
57        }
58        impl<T: Dummy + Copy> Dummy for [T; $n] {
59            #[inline]
60            unsafe fn dummy() -> Self {
61                [Dummy::dummy(); $n]
62            }
63        }
64
65        impl<'a, T, N> GetIndex<'a, &'a [T; $n]> for StaticRange<N>
66        where
67            N: Unsigned + Array<T>,
68            <N as Array<T>>::Array: 'a,
69        {
70            type Output = &'a N::Array;
71            #[inline]
72            fn get(self, set: &&'a [T; $n]) -> Option<Self::Output> {
73                if self.end() <= set.len() {
74                    let slice = *set;
75                    Some(unsafe { &*(slice.as_ptr().add(self.start()) as *const N::Array) })
76                } else {
77                    None
78                }
79            }
80        }
81
82        impl<'a, T, N> IsolateIndex<&'a [T; $n]> for StaticRange<N>
83        where
84            N: Unsigned + Array<T>,
85            <N as Array<T>>::Array: 'a,
86        {
87            type Output = &'a N::Array;
88            #[inline]
89            unsafe fn isolate_unchecked(self, set: &'a [T; $n]) -> Self::Output {
90                &*(set.as_ptr().add(self.start()) as *const N::Array)
91            }
92            #[inline]
93            fn try_isolate(self, set: &'a [T; $n]) -> Option<Self::Output> {
94                if self.end() <= set.len() {
95                    Some(unsafe { IsolateIndex::isolate_unchecked(self, set) })
96                } else {
97                    None
98                }
99            }
100        }
101
102        impl<T: bytemuck::Pod> Array<T> for consts::$nty {
103            type Array = [T; $n];
104
105            #[inline]
106            fn iter_mut(array: &mut Self::Array) -> std::slice::IterMut<T> {
107                array.iter_mut()
108            }
109            #[inline]
110            fn iter(array: &Self::Array) -> std::slice::Iter<T> {
111                array.iter()
112            }
113            #[inline]
114            fn as_slice(array: &Self::Array) -> &[T] {
115                array
116            }
117        }
118
119        impl<'a, T, N> ReinterpretAsGrouped<N> for &'a [T; $n]
120        where
121            T: bytemuck::Pod,
122            N: Unsigned + Array<T>,
123            consts::$nty: PartialDiv<N>,
124            <consts::$nty as PartialDiv<N>>::Output: Array<N::Array> + Unsigned,
125            <<consts::$nty as PartialDiv<N>>::Output as Array<N::Array>>::Array: 'a,
126        {
127            type Output = &'a <<consts::$nty as PartialDiv<N>>::Output as Array<N::Array>>::Array;
128            #[inline]
129            fn reinterpret_as_grouped(self) -> Self::Output {
130                assert_eq!(
131                    $n,
132                    N::to_usize()
133                        * <<consts::$nty as PartialDiv<N>>::Output as Unsigned>::to_usize()
134                );
135                //unsafe {
136                //    &*(self as *const [T; $n]
137                //        as *const <<consts::$nty as PartialDiv<N>>::Output as Array<N::Array>>::Array)
138                //}
139                bytemuck::cast_ref(self)
140            }
141        }
142
143        impl<'a, T, N> ReinterpretAsGrouped<N> for &'a mut [T; $n]
144        where
145            T: bytemuck::Pod,
146            N: Unsigned + Array<T>,
147            consts::$nty: PartialDiv<N>,
148            <consts::$nty as PartialDiv<N>>::Output: Array<N::Array> + Unsigned,
149            <<consts::$nty as PartialDiv<N>>::Output as Array<N::Array>>::Array: 'a,
150        {
151            type Output =
152                &'a mut <<consts::$nty as PartialDiv<N>>::Output as Array<N::Array>>::Array;
153            #[inline]
154            fn reinterpret_as_grouped(self) -> Self::Output {
155                assert_eq!(
156                    $n,
157                    N::to_usize()
158                        * <<consts::$nty as PartialDiv<N>>::Output as Unsigned>::to_usize()
159                );
160                //unsafe {
161                //    &mut *(self as *mut [T; $n]
162                //        as *mut <<consts::$nty as PartialDiv<N>>::Output as Array<N::Array>>::Array)
163                //}
164                bytemuck::cast_mut(self)
165            }
166        }
167
168        impl<T, N: Array<T>> UniChunkable<N> for [T; $n] {
169            type Chunk = N::Array;
170        }
171
172        impl<'a, T, N: Array<T>> UniChunkable<N> for &'a [T; $n]
173        where
174            <N as Array<T>>::Array: 'a,
175        {
176            type Chunk = &'a N::Array;
177        }
178
179        impl<'a, T, N: Array<T>> UniChunkable<N> for &'a mut [T; $n]
180        where
181            <N as Array<T>>::Array: 'a,
182        {
183            type Chunk = &'a mut N::Array;
184        }
185
186        impl<'a, T, N> IntoStaticChunkIterator<N> for &'a [T; $n]
187        where
188            N: Unsigned + Array<T>,
189        {
190            type Item = <&'a [T] as SplitPrefix<N>>::Prefix;
191            type IterType = UniChunkedIter<&'a [T], N>;
192            #[inline]
193            fn into_static_chunk_iter(self) -> Self::IterType {
194                (&self[..]).into_generic_static_chunk_iter()
195            }
196        }
197
198        impl<'a, T, N> IntoStaticChunkIterator<N> for &'a mut [T; $n]
199        where
200            N: Unsigned + Array<T>,
201        {
202            type Item = <&'a mut [T] as SplitPrefix<N>>::Prefix;
203            type IterType = UniChunkedIter<&'a mut [T], N>;
204            #[inline]
205            fn into_static_chunk_iter(self) -> Self::IterType {
206                (&mut self[..]).into_generic_static_chunk_iter()
207            }
208        }
209
210        impl<T: Clone> CloneIntoOther<[T; $n]> for [T; $n] {
211            #[inline]
212            fn clone_into_other(&self, other: &mut [T; $n]) {
213                other.clone_from(self);
214            }
215        }
216
217        impl<T: Clone> CloneIntoOther<&mut [T; $n]> for [T; $n] {
218            #[inline]
219            fn clone_into_other(&self, other: &mut &mut [T; $n]) {
220                (*other).clone_from(self);
221            }
222        }
223
224        impl<'a, T: 'a> AtomIterator<'a> for [T; $n] {
225            type Item = &'a T;
226            type Iter = std::slice::Iter<'a, T>;
227            #[inline]
228            fn atom_iter(&'a self) -> Self::Iter {
229                self.iter()
230            }
231        }
232
233        impl<'a, T: 'a> AtomMutIterator<'a> for [T; $n] {
234            type Item = &'a mut T;
235            type Iter = std::slice::IterMut<'a, T>;
236            #[inline]
237            fn atom_mut_iter(&'a mut self) -> Self::Iter {
238                self.iter_mut()
239            }
240        }
241
242        // TODO: Figure out how to compile the below code.
243        //        impl<T, N> ReinterpretAsGrouped<N> for [T; $n]
244        //        where
245        //            N: Unsigned + Array<T>,
246        //            consts::$nty: PartialDiv<N>,
247        //            <consts::$nty as PartialDiv<N>>::Output: Array<N::Array> + Unsigned,
248        //        {
249        //            type Output = <<consts::$nty as PartialDiv<N>>::Output as Array<N::Array>>::Array;
250        //            #[inline]
251        //            fn reinterpret_as_grouped(self) -> Self::Output {
252        //                assert_eq!(
253        //                    $n / N::to_usize(),
254        //                    <<consts::$nty as PartialDiv<N>>::Output as Unsigned>::to_usize()
255        //                );
256        //                unsafe {
257        //                    std::mem::transmute::<
258        //                        Self,
259        //                        <<consts::$nty as PartialDiv<N>>::Output as Array<N::Array>>::Array,
260        //                    >(self)
261        //                }
262        //            }
263        //        }
264    };
265}
266
267impl_array_for_typenum!(U1, 1);
268impl_array_for_typenum!(U2, 2);
269impl_array_for_typenum!(U3, 3);
270impl_array_for_typenum!(U4, 4);
271impl_array_for_typenum!(U5, 5);
272impl_array_for_typenum!(U6, 6);
273impl_array_for_typenum!(U7, 7);
274impl_array_for_typenum!(U8, 8);
275impl_array_for_typenum!(U9, 9);
276impl_array_for_typenum!(U10, 10);
277impl_array_for_typenum!(U11, 11);
278impl_array_for_typenum!(U12, 12);
279impl_array_for_typenum!(U13, 13);
280impl_array_for_typenum!(U14, 14);
281impl_array_for_typenum!(U15, 15);
282impl_array_for_typenum!(U16, 16);
283
284macro_rules! impl_as_slice_for_2d_array {
285    ($r:expr, $c:expr) => {
286        impl<T: bytemuck::Pod> AsFlatSlice<T> for [[T; $c]; $r] {
287            #[inline]
288            fn as_flat_slice(&self) -> &[T] {
289                //unsafe { reinterpret::reinterpret_slice(&self[..]) }
290                bytemuck::cast_slice(self)
291            }
292        }
293    };
294}
295
296impl_as_slice_for_2d_array!(1, 1);
297impl_as_slice_for_2d_array!(1, 2);
298impl_as_slice_for_2d_array!(1, 3);
299impl_as_slice_for_2d_array!(1, 4);
300impl_as_slice_for_2d_array!(1, 5);
301impl_as_slice_for_2d_array!(1, 6);
302impl_as_slice_for_2d_array!(1, 7);
303impl_as_slice_for_2d_array!(1, 8);
304impl_as_slice_for_2d_array!(1, 9);
305
306impl_as_slice_for_2d_array!(2, 1);
307impl_as_slice_for_2d_array!(2, 2);
308impl_as_slice_for_2d_array!(2, 3);
309impl_as_slice_for_2d_array!(2, 4);
310impl_as_slice_for_2d_array!(2, 5);
311impl_as_slice_for_2d_array!(2, 6);
312impl_as_slice_for_2d_array!(2, 7);
313impl_as_slice_for_2d_array!(2, 8);
314impl_as_slice_for_2d_array!(2, 9);
315
316impl_as_slice_for_2d_array!(3, 1);
317impl_as_slice_for_2d_array!(3, 2);
318impl_as_slice_for_2d_array!(3, 3);
319impl_as_slice_for_2d_array!(3, 4);
320impl_as_slice_for_2d_array!(3, 5);
321impl_as_slice_for_2d_array!(3, 6);
322impl_as_slice_for_2d_array!(3, 7);
323impl_as_slice_for_2d_array!(3, 8);
324impl_as_slice_for_2d_array!(3, 9);
325
326impl_as_slice_for_2d_array!(4, 1);
327impl_as_slice_for_2d_array!(4, 2);
328impl_as_slice_for_2d_array!(4, 3);
329impl_as_slice_for_2d_array!(4, 4);
330impl_as_slice_for_2d_array!(4, 5);
331impl_as_slice_for_2d_array!(4, 6);
332impl_as_slice_for_2d_array!(4, 7);
333impl_as_slice_for_2d_array!(4, 8);
334impl_as_slice_for_2d_array!(4, 9);
335
336impl_as_slice_for_2d_array!(5, 1);
337impl_as_slice_for_2d_array!(5, 2);
338impl_as_slice_for_2d_array!(5, 3);
339impl_as_slice_for_2d_array!(5, 4);
340impl_as_slice_for_2d_array!(5, 5);
341impl_as_slice_for_2d_array!(5, 6);
342impl_as_slice_for_2d_array!(5, 7);
343impl_as_slice_for_2d_array!(5, 8);
344impl_as_slice_for_2d_array!(5, 9);
345
346impl_as_slice_for_2d_array!(6, 1);
347impl_as_slice_for_2d_array!(6, 2);
348impl_as_slice_for_2d_array!(6, 3);
349impl_as_slice_for_2d_array!(6, 4);
350impl_as_slice_for_2d_array!(6, 5);
351impl_as_slice_for_2d_array!(6, 6);
352impl_as_slice_for_2d_array!(6, 7);
353impl_as_slice_for_2d_array!(6, 8);
354impl_as_slice_for_2d_array!(6, 9);
355
356impl_as_slice_for_2d_array!(7, 1);
357impl_as_slice_for_2d_array!(7, 2);
358impl_as_slice_for_2d_array!(7, 3);
359impl_as_slice_for_2d_array!(7, 4);
360impl_as_slice_for_2d_array!(7, 5);
361impl_as_slice_for_2d_array!(7, 6);
362impl_as_slice_for_2d_array!(7, 7);
363impl_as_slice_for_2d_array!(7, 8);
364impl_as_slice_for_2d_array!(7, 9);
365
366impl_as_slice_for_2d_array!(8, 1);
367impl_as_slice_for_2d_array!(8, 2);
368impl_as_slice_for_2d_array!(8, 3);
369impl_as_slice_for_2d_array!(8, 4);
370impl_as_slice_for_2d_array!(8, 5);
371impl_as_slice_for_2d_array!(8, 6);
372impl_as_slice_for_2d_array!(8, 7);
373impl_as_slice_for_2d_array!(8, 8);
374impl_as_slice_for_2d_array!(8, 9);
375
376impl_as_slice_for_2d_array!(9, 1);
377impl_as_slice_for_2d_array!(9, 2);
378impl_as_slice_for_2d_array!(9, 3);
379impl_as_slice_for_2d_array!(9, 4);
380impl_as_slice_for_2d_array!(9, 5);
381impl_as_slice_for_2d_array!(9, 6);
382impl_as_slice_for_2d_array!(9, 7);
383impl_as_slice_for_2d_array!(9, 8);
384impl_as_slice_for_2d_array!(9, 9);