const_tools/
unzip.rs

1#[macro_export]
2macro_rules! unzip {
3    (let ($($oap:pat_param),* $(,)?) = $($unzip_arg:tt)*) => {
4        $crate::__zip_left!(
5            [$(($oap, ))*]
6            [(oa0, oi0) (oa1, oi1) (oa2, oi2) (oa3, oi3) (oa4, oi4) (oa5, oi5) (oa6, oi6) (oa7, oi7) (oa8, oi8) (oa9, oi9) (oa10, oi10) (oa11, oi11)]
7            "unsupported number of outputs"
8            $crate::unzip!(@parse_unzip_arg [$($unzip_arg)*] <>)
9        )
10    };
11    // [iae] [(oap, oa, oi)]
12    (@parse_unzip_arg [map!($($map_args:tt)*)] $($rest:tt)*) => {
13        $crate::map!(@parse [$($map_args)*] $crate::unzip!(@parse_map_body <> $($rest)*))
14    };
15    (@parse_unzip_arg [$iae:expr] [$(($oap:pat_param, $oa:ident, $oi:ident))*]) => {
16        $crate::unzip!(@expand [
17            $crate::destructure!(let ($($oi),*) = ii);
18        ] [($iae, ii, ia)] [$(($oap, $oa, $oi))*])
19    };
20    // [map_body] [(iae, iip, ia)] [(oap, oa, oi)]
21    (@parse_map_body [{ $($body:tt)* }] $($rest:tt)*) => {
22        $crate::unzip!(@parse_map_body_block [$($body)*] [] $($rest)*)
23    };
24    (@parse_map_body [($($oie:expr),* $(,)?)] $i:tt [$(($oap:pat_param, $oa:ident, $oi:ident))*]) => {
25        $crate::unzip!(@expand [] $i [$(($oap, $oa, $oie))*])
26    };
27    (@parse_map_body [$body:expr] $i:tt [$(($oap:pat_param, $oa:ident, $oi:ident))*]) => {
28        $crate::unzip!(@expand [
29            let item = $body;
30            $crate::destructure!(let ($($oi),*) = item);
31        ] $i [$(($oap, $oa, $oi))*])
32    };
33    // [map_body_block_stmts] [body_acc] [(iae, iip, ia)] [(oap, oa, oi)]
34    (@parse_map_body_block [] [$($body:tt)*] $i:tt [$(($oap:pat_param, $oa:ident, $oi:ident))*]) => {
35        $crate::unzip!(@expand [
36            let item = {
37                $($body)*
38            };
39            $crate::destructure!(let ($($oi),*) = item);
40        ] $i [$(($oap, $oa, $oi))*])
41    };
42    (@parse_map_body_block [($($oie:expr),* $(,)?)] [$($body:tt)*] $i:tt [$(($oap:pat_param, $oa:ident, $oi:ident))*]) => {
43        $crate::unzip!(@expand [$($body)*] $i [$(($oap, $oa, $oie))*])
44    };
45    (@parse_map_body_block [$head:tt $($tail:tt)*] [$($body:tt)*] $($rest:tt)*) => {
46        $crate::unzip!(@parse_map_body_block [$($tail)*] [$($body)* $head] $($rest)*)
47    };
48    // [body]  [(iae, iip, ia)] [(oap, oa, oie)]
49    (@expand [$($body:tt)*] [$(($iae:expr, $iip:pat_param, $ia:ident))*] [$(($oap:pat_param, $oa:ident, $oie:expr))*]) => {
50        $(
51            let mut $oa = $crate::__maybe_uninit_array_uninit();
52        )*
53        $(
54            let $ia = ::core::mem::ManuallyDrop::new($iae);
55            let $ia = $crate::__manually_drop_inner_ref(&$ia);
56        )*
57        let len = $crate::__same_len!($(&$oa,)* $(&$ia,)*);
58        let mut index = 0;
59        while index < len {
60            $(
61                let $iip = unsafe { ::core::ptr::read(&$ia[index]) };
62            )*
63            $($body)*
64            $(
65                $oa[index].write($oie);
66            )*
67            index += 1;
68        }
69        assert!(
70            index == len,
71            "break is not allowed because a value must be written into every array element"
72        );
73        $(
74            let $oap = unsafe { $crate::__maybe_uninit_array_assume_init($oa) };
75        )*
76    };
77}