palette/macros/
simd.rs

1macro_rules! make_recursive_tuples {
2    ($first:tt $(,$rest:tt)+) => {
3        make_recursive_tuples!(@ $first [$($rest),+])
4    };
5    (@ $tuple:tt [$first:tt $(,$rest:tt)*]) => {
6        make_recursive_tuples!(@ ($tuple, $first) [$($rest),*])
7    };
8    (@ $tuple:tt []) => {
9        $tuple
10    }
11}
12
13macro_rules! impl_simd_array_conversion {
14    (  $self_ty: ident , [$($element: ident),+] $(, $phantom: ident)?) => {
15        impl_simd_array_conversion!($self_ty<>, [$($element),+] $(, $phantom)?);
16    };
17    (  $self_ty: ident < $($ty_param: ident),* > , [$($element: ident),+] $(, $phantom: ident)?) => {
18        impl<$($ty_param,)* T, V, const N: usize> From<[$self_ty<$($ty_param,)* T>; N]> for $self_ty<$($ty_param,)* V>
19        where
20            [T; N]: Default,
21            V: crate::num::FromScalarArray<N, Scalar = T>,
22        {
23            fn from(colors: [$self_ty<$($ty_param,)* T>; N]) -> Self {
24                $(let mut $element: [T; N] = Default::default();)*
25
26                for (index, color) in IntoIterator::into_iter(colors).enumerate() {
27                    $($element[index] = color.$element;)*
28                }
29
30                $self_ty {
31                    $($element: V::from_array($element),)*
32                    $($phantom: core::marker::PhantomData,)?
33                }
34            }
35        }
36
37        impl<$($ty_param,)* T, V, const N: usize> From<[crate::Alpha<$self_ty<$($ty_param,)* T>, T>; N]> for crate::Alpha<$self_ty<$($ty_param,)* V>, V>
38        where
39            [T; N]: Default,
40            V: crate::num::FromScalarArray<N, Scalar = T>,
41        {
42            fn from(colors: [crate::Alpha<$self_ty<$($ty_param,)* T>, T>; N]) -> Self {
43                $(let mut $element: [T; N] = Default::default();)*
44                let mut alpha: [T; N] = Default::default();
45
46                for (index, color) in IntoIterator::into_iter(colors).enumerate() {
47                    $($element[index] = color.color.$element;)*
48                    alpha[index] = color.alpha
49                }
50
51                crate::Alpha {
52                    color: $self_ty {
53                        $($element: V::from_array($element),)*
54                        $($phantom: core::marker::PhantomData,)?
55                    },
56                    alpha: V::from_array(alpha),
57                }
58            }
59        }
60
61        impl<$($ty_param,)* T, V, const N: usize> From<[crate::blend::PreAlpha<$self_ty<$($ty_param,)* T>>; N]> for crate::blend::PreAlpha<$self_ty<$($ty_param,)* V>>
62        where
63            [T; N]: Default,
64            V: crate::num::FromScalarArray<N, Scalar = T>,
65            $self_ty<$($ty_param,)* T>: crate::blend::Premultiply<Scalar = T>,
66            $self_ty<$($ty_param,)* V>: crate::blend::Premultiply<Scalar = V>,
67        {
68            fn from(colors: [crate::blend::PreAlpha<$self_ty<$($ty_param,)* T>>; N]) -> Self {
69                $(let mut $element: [T; N] = Default::default();)*
70                let mut alpha: [T; N] = Default::default();
71
72                for (index, color) in IntoIterator::into_iter(colors).enumerate() {
73                    $($element[index] = color.color.$element;)*
74                    alpha[index] = color.alpha
75                }
76
77                crate::blend::PreAlpha {
78                    color: $self_ty {
79                        $($element: V::from_array($element),)*
80                        $($phantom: core::marker::PhantomData,)?
81                    },
82                    alpha: V::from_array(alpha),
83                }
84            }
85        }
86
87        impl<$($ty_param,)* T, V, const N: usize> From<$self_ty<$($ty_param,)* V>> for [$self_ty<$($ty_param,)* T>; N]
88        where
89            Self: Default,
90            V: crate::num::IntoScalarArray<N, Scalar = T>,
91        {
92            fn from(color: $self_ty<$($ty_param,)* V>) -> Self {
93                let mut colors = Self::default();
94                $(let $element = color.$element.into_array();)*
95
96                for make_recursive_tuples!(index $(,$element)*) in
97                    (0..)$(.zip($element))*
98                {
99                    colors[index] = $self_ty {
100                        $($element,)*
101                        $($phantom: core::marker::PhantomData,)?
102                    };
103                }
104
105                colors
106            }
107        }
108
109        impl<$($ty_param,)* T, V, const N: usize> From<crate::Alpha<$self_ty<$($ty_param,)* V>, V>> for [crate::Alpha<$self_ty<$($ty_param,)* T>, T>; N]
110        where
111            Self: Default,
112            V: crate::num::IntoScalarArray<N, Scalar = T>,
113        {
114            fn from(color: crate::Alpha<$self_ty<$($ty_param,)* V>, V>) -> Self {
115                let mut colors = Self::default();
116                $(let $element = color.color.$element.into_array();)*
117                let alpha = color.alpha.into_array();
118
119                for make_recursive_tuples!(index $(,$element)*, alpha) in
120                    (0..)$(.zip($element))*.zip(alpha)
121                {
122                    colors[index] = crate::Alpha {
123                        color: $self_ty {
124                            $($element,)*
125                            $($phantom: core::marker::PhantomData,)?
126                        },
127                        alpha,
128                    };
129                }
130
131                colors
132            }
133        }
134
135        impl<$($ty_param,)* T, V, const N: usize> From<crate::blend::PreAlpha<$self_ty<$($ty_param,)* V>>> for [crate::blend::PreAlpha<$self_ty<$($ty_param,)* T>>; N]
136        where
137            Self: Default,
138            V: crate::num::IntoScalarArray<N, Scalar = T>,
139            $self_ty<$($ty_param,)* T>: crate::blend::Premultiply<Scalar = T>,
140            $self_ty<$($ty_param,)* V>: crate::blend::Premultiply<Scalar = V>,
141        {
142            fn from(color: crate::blend::PreAlpha<$self_ty<$($ty_param,)* V>>) -> Self {
143                let mut colors = Self::default();
144                $(let $element = color.color.$element.into_array();)*
145                let alpha = color.alpha.into_array();
146
147                for make_recursive_tuples!(index $(,$element)*, alpha) in
148                    (0..)$(.zip($element))*.zip(alpha)
149                {
150                    colors[index] = crate::blend::PreAlpha {
151                        color: $self_ty {
152                            $($element,)*
153                            $($phantom: core::marker::PhantomData,)?
154                        },
155                        alpha,
156                    };
157                }
158
159                colors
160            }
161        }
162    };
163}
164
165macro_rules! impl_simd_array_conversion_hue {
166    (  $self_ty: ident , [$($element: ident),+] $(, $phantom: ident)?) => {
167        impl_simd_array_conversion_hue!($self_ty<>, [$($element),+] $(, $phantom)?);
168    };
169    (  $self_ty: ident < $($ty_param: ident),* > , [$($element: ident),+] $(, $phantom: ident)?) => {
170        impl<$($ty_param,)* T, V, const N: usize> From<[$self_ty<$($ty_param,)* T>; N]> for $self_ty<$($ty_param,)* V>
171        where
172            [T; N]: Default,
173            V: crate::num::FromScalarArray<N, Scalar = T>,
174        {
175            fn from(colors: [$self_ty<$($ty_param,)* T>; N]) -> Self {
176                let mut hue: [T; N] = Default::default();
177                $(let mut $element: [T; N] = Default::default();)*
178
179                for (index, color) in IntoIterator::into_iter(colors).enumerate() {
180                    hue[index] = color.hue.into_inner();
181                    $($element[index] = color.$element;)*
182                }
183
184                $self_ty {
185                    hue: V::from_array(hue).into(),
186                    $($element: V::from_array($element),)*
187                    $($phantom: core::marker::PhantomData,)?
188                }
189            }
190        }
191
192        impl<$($ty_param,)* T, V, const N: usize> From<[crate::Alpha<$self_ty<$($ty_param,)* T>, T>; N]> for crate::Alpha<$self_ty<$($ty_param,)* V>, V>
193        where
194            [T; N]: Default,
195            V: crate::num::FromScalarArray<N, Scalar = T>,
196        {
197            fn from(colors: [crate::Alpha<$self_ty<$($ty_param,)* T>, T>; N]) -> Self {
198                let mut hue: [T; N] = Default::default();
199                $(let mut $element: [T; N] = Default::default();)*
200                let mut alpha: [T; N] = Default::default();
201
202                for (index, color) in IntoIterator::into_iter(colors).enumerate() {
203                    hue[index] = color.color.hue.into_inner();
204                    $($element[index] = color.color.$element;)*
205                    alpha[index] = color.alpha
206                }
207
208                crate::Alpha {
209                    color: $self_ty {
210                        hue: V::from_array(hue).into(),
211                        $($element: V::from_array($element),)*
212                        $($phantom: core::marker::PhantomData,)?
213                    },
214                    alpha: V::from_array(alpha),
215                }
216            }
217        }
218
219        impl<$($ty_param,)* T, V, const N: usize> From<$self_ty<$($ty_param,)* V>> for [$self_ty<$($ty_param,)* T>; N]
220        where
221            Self: Default,
222            V: crate::num::IntoScalarArray<N, Scalar = T>,
223        {
224            fn from(color: $self_ty<$($ty_param,)* V>) -> Self {
225                let mut colors = Self::default();
226                let hue = color.hue.into_inner().into_array();
227                $(let $element = color.$element.into_array();)*
228
229                for make_recursive_tuples!(index, hue $(,$element)*) in
230                    (0..).zip(hue)$(.zip($element))*
231                {
232                    colors[index] = $self_ty {
233                        hue: hue.into(),
234                        $($element,)*
235                        $($phantom: core::marker::PhantomData,)?
236                    };
237                }
238
239                colors
240            }
241        }
242
243        impl<$($ty_param,)* T, V, const N: usize> From<crate::Alpha<$self_ty<$($ty_param,)* V>, V>> for [crate::Alpha<$self_ty<$($ty_param,)* T>, T>; N]
244        where
245            Self: Default,
246            V: crate::num::IntoScalarArray<N, Scalar = T>,
247        {
248            fn from(color: crate::Alpha<$self_ty<$($ty_param,)* V>, V>) -> Self {
249                let mut colors = Self::default();
250                let hue = color.color.hue.into_inner().into_array();
251                $(let $element = color.color.$element.into_array();)*
252                let alpha = color.alpha.into_array();
253
254                for make_recursive_tuples!(index, hue $(,$element)*, alpha) in
255                    (0..).zip(hue)$(.zip($element))*.zip(alpha)
256                {
257                    colors[index] = crate::Alpha {
258                        color: $self_ty {
259                            hue: hue.into(),
260                            $($element,)*
261                            $($phantom: core::marker::PhantomData,)?
262                        },
263                        alpha,
264                    };
265                }
266
267                colors
268            }
269        }
270    };
271}