bulks/
impl_array.rs

1use core::{marker::Destruct, mem::MaybeUninit, ops::Try};
2
3use crate::{Bulk, DoubleEndedBulk, Guard, IntoBulk, SplitBulk, StaticBulk, util::{self, LengthSpec, Same}};
4
5pub mod array
6{
7    #[derive(Clone, Debug)]
8    pub struct IntoBulk<T, const N: usize>
9    {
10        pub(super) array: [T; N]
11    }
12
13    #[derive(Clone, Debug)]
14    pub struct Bulk<'a, T, const N: usize>
15    {
16        pub(super) array: &'a [T; N]
17    }
18
19    #[derive(Debug)]
20    pub struct BulkMut<'a, T, const N: usize>
21    {
22        pub(super) array: &'a mut [T; N]
23    }
24}
25
26macro_rules! impl_bulk {
27    (
28        impl $bulk:ident<$($a:lifetime,)? $t:ident, const $n:ident: usize>; for $item:ty; in $array:ty;
29        {
30            fn for_each($self_for_each:ident, $f_for_each:ident) -> _
31            $for_each:block
32
33            fn try_for_each($self_try_for_each:ident, $f_try_for_each:ident) -> _
34            $try_for_each:block
35
36            fn rev_for_each($self_rev_for_each:ident, $f_rev_for_each:ident) -> _
37            $rev_for_each:block
38
39            fn try_rev_for_each($self_try_rev_for_each:ident, $f_try_rev_for_each:ident) -> _
40            $try_rev_for_each:block
41
42            fn collect_array($self_collect_array:ident) -> _
43            $collect_array:block
44
45            fn split_at($self_split_at_dyn:ident, $n_split_at_dyn:ident) -> _
46            $split_at_dyn:block
47
48            $(fn nth($self_nth:ident, $n_nth:ident) -> _
49            $nth:block)?
50        }
51        {
52            $split:ident
53        }
54    ) => {
55        impl<$($a,)? $t, const $n: usize> array::$bulk<$($a,)? $t, $n>
56        {
57            #[allow(unused)]
58            #[inline]
59            pub(crate) const fn into_inner(self) -> $array
60            {
61                let Self {array} = self;
62                array
63            }
64        }
65        impl<$($a,)? $t, const $n: usize> IntoIterator for array::$bulk<$($a,)? $t, $n>
66        {
67            type Item = $item;
68            type IntoIter = <$array as IntoIterator>::IntoIter;
69
70            #[inline]
71            fn into_iter(self) -> Self::IntoIter
72            {
73                let Self {array} = self;
74                array.into_iter()
75            }
76        }
77        impl<$($a,)? $t, const $n: usize> const IntoBulk for $array
78        {
79            type IntoBulk = array::$bulk<$($a,)? $t, $n>;
80            
81            #[inline]
82            fn into_bulk(self) -> Self::IntoBulk
83            {
84                array::$bulk {
85                    array: self
86                }
87            }
88        }
89        impl<$($a,)? $t, const $n: usize> const Bulk for array::$bulk<$($a,)? $t, $n>
90        {
91            #[inline]
92            fn len(&self) -> usize
93            {
94                $n
95            }
96
97            fn first(self) -> Option<Self::Item>
98            where
99                Self::Item: ~const Destruct,
100                Self: Sized
101            {
102                self.nth([(); 0])
103            }
104            
105            $(fn nth<L>($self_nth, $n_nth: L) -> Option<Self::Item>
106            where
107                Self::Item: ~const Destruct,
108                Self: Sized,
109                L: ~const LengthSpec
110            $nth)?
111
112            #[inline]
113            fn collect_array($self_collect_array) -> <Self as StaticBulk>::Array<Self::Item>
114            $collect_array
115
116            #[inline]
117            fn for_each<F>($self_for_each, mut $f_for_each: F)
118            where
119                F: ~const FnMut($item) + ~const Destruct
120            $for_each
121
122            #[inline]
123            fn try_for_each<F, R>($self_try_for_each, mut $f_try_for_each: F) -> R
124            where
125                $item: ~const Destruct,
126                F: ~const FnMut($item) -> R + ~const Destruct,
127                R: ~const Try<Output = (), Residual: ~const Destruct>
128            $try_for_each
129        }
130        impl<$($a,)? $t, const $n: usize> const DoubleEndedBulk for array::$bulk<$($a,)? $t, $n>
131        {
132            #[inline]
133            fn rev_for_each<F>($self_rev_for_each, mut $f_rev_for_each: F)
134            where
135                F: ~const FnMut($item) + ~const Destruct
136            $rev_for_each
137
138            #[inline]
139            fn try_rev_for_each<F, R>($self_try_rev_for_each, mut $f_try_rev_for_each: F) -> R
140            where
141                $item: ~const Destruct,
142                F: ~const FnMut($item) -> R + ~const Destruct,
143                R: ~const Try<Output = (), Residual: ~const Destruct>
144            $try_rev_for_each
145        }
146        impl<$($a,)? T, const N: usize, L> SplitBulk<L> for array::$bulk<$($a,)? T, N>
147        where
148            L: LengthSpec
149        {
150            default type Left = <<$array as IntoIterator>::IntoIter as IntoBulk>::IntoBulk;
151            default type Right = <<$array as IntoIterator>::IntoIter as IntoBulk>::IntoBulk;
152
153            #[track_caller]
154            default fn split_at($self_split_at_dyn, $n_split_at_dyn: L) -> (Self::Left, Self::Right)
155            where
156                Self: Sized
157            $split_at_dyn
158        }
159        impl<$($a,)? T, const N: usize, const M: usize> const SplitBulk<[(); M]> for array::$bulk<$($a,)? T, N>
160        where
161            [(); N.saturating_sub(M)]:,
162            [(); N.min(M)]:
163        {
164            type Left = array::$bulk<$($a,)? T, {N.min(M)}>;
165            type Right = array::$bulk<$($a,)? T, {N.saturating_sub(M)}>;
166
167            #[track_caller]
168            fn split_at(self, _n: [(); M]) -> (Self::Left, Self::Right)
169            where
170                Self: Sized
171            {
172                let (left, right) = util::$split(self.array);
173                (
174                    array::$bulk {
175                        array: left
176                    },
177                    array::$bulk {
178                        array: right
179                    }
180                )
181            }
182        }
183        unsafe impl<$($a,)? $t, const $n: usize> StaticBulk for array::$bulk<$($a,)? $t, $n>
184        {
185            type Array<U> = [U; $n];
186        }
187    };
188}
189impl_bulk!(
190    impl IntoBulk<T, const N: usize>; for T; in [T; N];
191    {
192        fn for_each(self, f) -> _
193        {
194            let Self { array } = self;
195            let mut src_array = util::new_init_array(array);
196            let mut src_guard = Guard { array_mut: &mut src_array, initialized: 0..N };
197
198            while src_guard.initialized.start < src_guard.initialized.end
199            {
200                unsafe {
201                    f(src_guard.pop_front_unchecked())
202                }
203            }
204
205            core::mem::forget(src_guard);
206        }
207
208        fn try_for_each(self, f) -> _
209        {
210            let Self { array } = self;
211            let mut src_array = util::new_init_array(array);
212            let mut src_guard = Guard { array_mut: &mut src_array, initialized: 0..N };
213
214            while src_guard.initialized.start < src_guard.initialized.end
215            {
216                unsafe {
217                    f(src_guard.pop_front_unchecked())?
218                }
219            }
220
221            core::mem::forget(src_guard);
222            R::from_output(())
223        }
224
225        fn rev_for_each(self, f) -> _
226        {
227            let Self { array } = self;
228            let mut src_array = util::new_init_array(array);
229            let mut src_guard = Guard { array_mut: &mut src_array, initialized: 0..N };
230
231            while src_guard.initialized.start < src_guard.initialized.end
232            {
233                unsafe {
234                    f(src_guard.pop_back_unchecked())
235                }
236            }
237
238            core::mem::forget(src_guard);
239        }
240
241        fn try_rev_for_each(self, f) -> _
242        {
243            let Self { array } = self;
244            let mut src_array = util::new_init_array(array);
245            let mut src_guard = Guard { array_mut: &mut src_array, initialized: 0..N };
246
247            while src_guard.initialized.start < src_guard.initialized.end
248            {
249                unsafe {
250                    f(src_guard.pop_back_unchecked())?
251                }
252            }
253
254            core::mem::forget(src_guard);
255            R::from_output(())
256        }
257
258        fn collect_array(self) -> _
259        {
260            let Self {array} = self;
261            array
262        }
263
264        fn split_at(self, n) -> _
265        {
266            let n = n.len_metadata();
267            let Self {array} = self;
268            let array = MaybeUninit::new(array).transpose();
269            let mut left = array.into_iter();
270            let mut right = unsafe {
271                core::ptr::read(&left)
272            };
273            let _ = left.advance_back_by(N.saturating_sub(n));
274            let _ = right.advance_by(N.min(n));
275            let (left, right): (Self::IntoIter, Self::IntoIter) = unsafe {
276                core::intrinsics::transmute_unchecked((left, right))
277            };
278            (left.into_bulk(), right.into_bulk()).same().ok().unwrap()
279        }
280    }
281    {
282        split_array
283    }
284);
285impl_bulk!(
286    impl Bulk<'a, T, const N: usize>; for &'a T; in &'a [T; N];
287    {
288        fn for_each(self, f) -> _
289        {
290            let Self {array} = self;
291            let mut n = 0;
292            while n < N
293            {
294                f(&array[n]);
295                n += 1;
296            }
297        }
298
299        fn try_for_each(self, f) -> _
300        {
301            let Self {array} = self;
302            let mut n = 0;
303            while n < N
304            {
305                f(&array[n])?;
306                n += 1;
307            }
308            R::from_output(())
309        }
310
311        fn rev_for_each(self, f) -> _
312        {
313            let Self {array} = self;
314            let mut n = N;
315            while n > 0
316            {
317                n -= 1;
318                f(&array[n]);
319            }
320        }
321
322        fn try_rev_for_each(self, f) -> _
323        {
324            let Self {array} = self;
325            let mut n = N;
326            while n > 0
327            {
328                n -= 1;
329                f(&array[n])?;
330            }
331            R::from_output(())
332        }
333
334        fn collect_array(self) -> _
335        {
336            let Self {array} = self;
337            array.each_ref()
338        }
339
340        fn split_at(self, n) -> _
341        {
342            let n = n.len_metadata();
343            let Self {array} = self;
344            let (left, right) = array.split_at(n);
345            (left.into_bulk(), right.into_bulk()).same().ok().unwrap()
346        }
347
348        fn nth(self, n) -> _
349        {
350            let Self {array} = self;
351            array.get(n.len_metadata())
352        }
353    }
354    {
355        split_array_ref
356    }
357);
358impl_bulk!(
359    impl BulkMut<'a, T, const N: usize>; for &'a mut T; in &'a mut [T; N];
360    {
361        fn for_each(self, f) -> _
362        {
363            let Self {array} = self;
364            let mut n = 0;
365            while n < N
366            {
367                f(unsafe {&mut *(&mut array[n] as *mut _)});
368                n += 1;
369            }
370        }
371
372        fn try_for_each(self, f) -> _
373        {
374            let Self {array} = self;
375            let mut n = 0;
376            while n < N
377            {
378                f(unsafe {&mut *(&mut array[n] as *mut _)})?;
379                n += 1;
380            }
381            R::from_output(())
382        }
383
384        fn rev_for_each(self, f) -> _
385        {
386            let Self {array} = self;
387            let mut n = N;
388            while n > 0
389            {
390                n -= 1;
391                f(unsafe {&mut *(&mut array[n] as *mut _)});
392            }
393        }
394
395        fn try_rev_for_each(self, f) -> _
396        {
397            let Self {array} = self;
398            let mut n = N;
399            while n > 0
400            {
401                n -= 1;
402                f(unsafe {&mut *(&mut array[n] as *mut _)})?;
403            }
404            R::from_output(())
405        }
406
407        fn collect_array(self) -> _
408        {
409            let Self {array} = self;
410            array.each_mut()
411        }
412
413        fn split_at(self, n) -> _
414        {
415            let n = n.len_metadata();
416            let Self {array} = self;
417            let (left, right) = array.split_at_mut(n);
418            (left.into_bulk(), right.into_bulk()).same().ok().unwrap()
419        }
420
421        fn nth(self, n) -> _
422        {
423            let Self {array} = self;
424            array.get_mut(n.len_metadata())
425        }
426    }
427    {
428        split_array_mut
429    }
430);
431
432/*impl<T, const N: usize> StaticMapSpec<N> for array::IntoBulk<T, N>
433{
434    fn map_collect_array<U>(self, f: impl FnMut(Self::Item) -> U) -> [U; N]
435    {
436        let Self {array} = self;
437        array.map(f)
438    }
439}
440impl<T, const N: usize> StaticRevSpec<N> for array::IntoBulk<T, N>
441{
442    fn rev_collect_array(self) -> [T; N]
443    {
444        let Self {mut array} = self;
445        array.reverse();
446        array
447    }
448}
449
450impl<'a, T, const N: usize> StaticMapSpec<N> for Copied<array::Bulk<'a, T, N>>
451where
452    T: Copy + 'a
453{
454    fn map_collect_array<U>(self, f: impl FnMut(Self::Item) -> U) -> [U; N]
455    {
456        self.into_inner()
457            .copied_collect_array()
458            .into_bulk()
459            .map(f)
460            .collect()
461    }
462}
463impl<'a, T, const N: usize> StaticRevSpec<N> for Copied<array::Bulk<'a, T, N>>
464where
465    T: Copy + 'a
466{
467    fn rev_collect_array(self) -> [T; N]
468    {
469        self.into_inner()
470            .copied_collect_array()
471            .into_bulk()
472            .rev()
473            .collect()
474    }
475}
476
477impl<'a, T, const N: usize> StaticCopiedSpec<N> for array::Bulk<'a, T, N>
478where
479    T: Copy + 'a
480{
481    fn copied_collect_array(self) -> [T; N]
482    {
483        let Self {array} = self;
484        *array
485    }
486}*/
487
488#[cfg(test)]
489mod test
490{
491    use crate::{AsBulk, Bulk};
492
493    #[test]
494    fn it_works()
495    {
496        let a = [1, 2, 3];
497        
498        let b = a.bulk().copied().rev().map(|x| 4 - x).collect::<[_; _], _>();
499
500        println!("{:?}", b)
501    }
502}