konst_kernel/macros/
array_macros.rs

1use core::mem::MaybeUninit;
2
3#[macro_export]
4macro_rules! array_map {
5    ($array:expr, $($closure:tt)* ) => (
6        match $array {
7            ref array => {
8                let array = $crate::__::assert_array(array);
9
10                $crate::utils::__parse_closure_1!{
11                    ($crate::__array_map) (array, |i| array[i],) (array_map),
12                    $($closure)*
13                }
14            }
15        }
16    );
17}
18
19#[doc(hidden)]
20#[macro_export]
21macro_rules! __array_map {
22    (
23        $array:ident,
24        |$i:ident| $get_input:expr,
25        ($($pattern:tt)*) $(-> $ret:ty)? $mapper:block $(,)?
26    ) => ({
27        let len = $array.len();
28        let mut out = $crate::__::uninit_array_of_len(&$array);
29
30        let mut $i = 0usize;
31        while $i < len {
32            let $($pattern)* = $get_input;
33            out[$i] = $crate::__::MaybeUninit $(::<$ret>)? ::new($mapper);
34            $i += 1;
35        }
36        // protecting against malicious `$mapper`s that break out of the `while` loop
37        $crate::__::assert!($i == len);
38
39        unsafe{
40            $crate::__::array_assume_init(out)
41        }
42    })
43}
44
45////////////////////////////////////////////////////////////////////////////////
46
47#[macro_export]
48macro_rules! array_from_fn {
49    ($($args:tt)*) => ({
50        $crate::__split_array_type_and_closure!{
51            (($crate::__array_from_fn_inner) ())
52            ()
53            ($($args)*)
54        }
55    });
56}
57
58#[macro_export]
59macro_rules! __array_from_fn_inner {
60    (($($($type:tt)+)?) $($closure_unparsed:tt)*) => ({
61        let input = $crate::__::unit_array();
62
63        let arr $(: $crate::__unparenthesize_ty!($($type)*))? =
64            $crate::utils::__parse_closure_1!{
65                ($crate::__array_map) (input, |i| i,) (array_from_fn),
66                $($closure_unparsed)*
67            };
68
69        arr
70    });
71}
72
73#[doc(hidden)]
74#[macro_export]
75macro_rules! __split_array_type_and_closure {
76    ((($($callback:tt)*) ($($args:tt)*)) $before:tt (=> $($rem:tt)*)) => {
77        $($callback)* ! {$($args)* $before $($rem)*}
78    };
79    ((($($callback:tt)*) ($($args:tt)*)) ($($before:tt)*) ($(| $($rem:tt)*)?)) => {
80        $($callback)* ! {$($args)* () $($before)* $(| $($rem)*)?}
81    };
82    ($callback:tt ($($before:tt)*) ($token:tt $($rem:tt)*)) => {
83        $crate::__split_array_type_and_closure! {$callback ($($before)* $token) ($($rem)*)}
84    };
85}
86
87////////////////////////////////////////////////////////////////////////////////
88
89#[inline(always)]
90pub const fn assert_array<T, const N: usize>(array: &[T; N]) -> &[T; N] {
91    array
92}
93
94#[inline(always)]
95pub const fn uninit_array_of_len<T, U, const N: usize>(_input: &[T; N]) -> [MaybeUninit<U>; N] {
96    crate::maybe_uninit::uninit_array()
97}
98
99#[inline(always)]
100pub const fn unit_array<const N: usize>() -> [(); N] {
101    [(); N]
102}