const_tools/
fold.rs

1#[macro_export]
2macro_rules! fold {
3    // [args] cb
4    (@parse [zip!($($iae:expr),* $(,)?), $init:expr, |$acc:pat_param, ($($iip:pat_param),* $(,)?)| $($body:tt)*] $($cb:tt)*) => {
5        $crate::__zip_left!(
6            [$(($iae, $iip, ))*]
7            [(ia0) (ia1) (ia2) (ia3) (ia4) (ia5) (ia6) (ia7) (ia8) (ia9) (ia10) (ia11)]
8            "unsupported number of inputs"
9            $($cb)*([$init] [$($body)*] [$acc] <>)
10        )
11    };
12    (@parse [$iae:expr, $init:expr, |$acc:pat_param, $iip:pat_param| $($body:tt)*] $($cb:tt)*) => {
13        $crate::__call!($($cb)*([$init] [$($body)*] [$acc] [($iae, $iip, ia0)]))
14    };
15    (@parse [$iae:expr, $init:expr, $fn:expr] $($cb:tt)*) => {
16        $crate::__call!($($cb)*([$init] [$fn(acc, ii)] [acc] [($iae, ii, ia0)]))
17    };
18    // [init] [body] [acc] [(iae, iip, ia)]
19    (@expand [$init:expr] [$body:expr] [$acc:pat_param] [$(($iae:expr, $iip:pat_param, $ia:ident))+]) => {{
20        $(
21            let $ia = ::core::mem::ManuallyDrop::new($iae);
22            let $ia = $crate::__manually_drop_inner_ref(&$ia);
23        )*
24        let len = $crate::__same_len!($($ia),*);
25        let mut acc = $init;
26        let mut index = 0;
27        while index < len {
28            $(
29                let $iip = unsafe { ::core::ptr::read(&$ia[index]) };
30            )*
31            let $acc = acc;
32            acc = $body;
33            index += 1;
34        }
35        assert!(
36            index == len,
37            "break is not allowed because a value must be written into every array element"
38        );
39        acc
40    }};
41    ($($fold_args:tt)*) => {
42        $crate::fold!(@parse [$($fold_args)*] $crate::fold!(@expand <>))
43    };
44}