rstsr_common/
util.rs

1use crate::prelude_dev::*;
2use core::mem::{transmute, MaybeUninit};
3
4/* #region AxisIndex */
5
6/// Enum for Axes indexing
7pub enum AxesIndex<T> {
8    Val(T),
9    Vec(Vec<T>),
10}
11
12impl<T> AsRef<[T]> for AxesIndex<T> {
13    fn as_ref(&self) -> &[T] {
14        match self {
15            AxesIndex::Val(v) => core::slice::from_ref(v),
16            AxesIndex::Vec(v) => v.as_slice(),
17        }
18    }
19}
20
21/* #region AxisIndex self-type from */
22
23impl<T> From<T> for AxesIndex<T> {
24    fn from(value: T) -> Self {
25        AxesIndex::Val(value)
26    }
27}
28
29impl<T> From<&T> for AxesIndex<T>
30where
31    T: Clone,
32{
33    fn from(value: &T) -> Self {
34        AxesIndex::Val(value.clone())
35    }
36}
37
38impl<T> TryFrom<Vec<T>> for AxesIndex<T> {
39    type Error = Error;
40
41    fn try_from(value: Vec<T>) -> Result<Self> {
42        Ok(AxesIndex::Vec(value))
43    }
44}
45
46impl<T, const N: usize> TryFrom<[T; N]> for AxesIndex<T>
47where
48    T: Clone,
49{
50    type Error = Error;
51
52    fn try_from(value: [T; N]) -> Result<Self> {
53        Ok(AxesIndex::Vec(value.to_vec()))
54    }
55}
56
57impl<T> TryFrom<&Vec<T>> for AxesIndex<T>
58where
59    T: Clone,
60{
61    type Error = Error;
62
63    fn try_from(value: &Vec<T>) -> Result<Self> {
64        Ok(AxesIndex::Vec(value.clone()))
65    }
66}
67
68impl<T> TryFrom<&[T]> for AxesIndex<T>
69where
70    T: Clone,
71{
72    type Error = Error;
73
74    fn try_from(value: &[T]) -> Result<Self> {
75        Ok(AxesIndex::Vec(value.to_vec()))
76    }
77}
78
79impl<T, const N: usize> TryFrom<&[T; N]> for AxesIndex<T>
80where
81    T: Clone,
82{
83    type Error = Error;
84
85    fn try_from(value: &[T; N]) -> Result<Self> {
86        Ok(AxesIndex::Vec(value.to_vec()))
87    }
88}
89
90impl TryFrom<()> for AxesIndex<usize> {
91    type Error = Error;
92
93    fn try_from(_: ()) -> Result<Self> {
94        Ok(AxesIndex::Vec(vec![]))
95    }
96}
97
98impl TryFrom<()> for AxesIndex<isize> {
99    type Error = Error;
100
101    fn try_from(_: ()) -> Result<Self> {
102        Ok(AxesIndex::Vec(vec![]))
103    }
104}
105
106/* #endregion AxisIndex self-type from */
107
108/* #region AxisIndex other-type from */
109
110macro_rules! impl_try_from_axes_index {
111    ($t1:ty, $($t2:ty),*) => {
112        $(
113            impl TryFrom<$t2> for AxesIndex<$t1> {
114                type Error = Error;
115
116                fn try_from(value: $t2) -> Result<Self> {
117                    Ok(AxesIndex::Val(value.try_into()?))
118                }
119            }
120
121            impl TryFrom<&$t2> for AxesIndex<$t1> {
122                type Error = Error;
123
124                fn try_from(value: &$t2) -> Result<Self> {
125                    Ok(AxesIndex::Val((*value).try_into()?))
126                }
127            }
128
129            impl TryFrom<Vec<$t2>> for AxesIndex<$t1> {
130                type Error = Error;
131
132                fn try_from(value: Vec<$t2>) -> Result<Self> {
133                    let value = value
134                        .into_iter()
135                        .map(|v| v.try_into().map_err(|_| Error::TryFromIntError(String::new())))
136                        .collect::<Result<Vec<$t1>>>()?;
137                    Ok(AxesIndex::Vec(value))
138                }
139            }
140
141            impl<const N: usize> TryFrom<[$t2; N]> for AxesIndex<$t1> {
142                type Error = Error;
143
144                fn try_from(value: [$t2; N]) -> Result<Self> {
145                    value.to_vec().try_into()
146                }
147            }
148
149            impl TryFrom<&Vec<$t2>> for AxesIndex<$t1> {
150                type Error = Error;
151
152                fn try_from(value: &Vec<$t2>) -> Result<Self> {
153                    value.to_vec().try_into()
154                }
155            }
156
157            impl TryFrom<&[$t2]> for AxesIndex<$t1> {
158                type Error = Error;
159
160                fn try_from(value: &[$t2]) -> Result<Self> {
161                    value.to_vec().try_into()
162                }
163            }
164
165            impl<const N: usize> TryFrom<&[$t2; N]> for AxesIndex<$t1> {
166                type Error = Error;
167
168                fn try_from(value: &[$t2; N]) -> Result<Self> {
169                    value.to_vec().try_into()
170                }
171            }
172        )*
173    };
174}
175
176impl_try_from_axes_index!(usize, isize, u32, u64, i32, i64);
177impl_try_from_axes_index!(isize, usize, u32, u64, i32, i64);
178
179/* #endregion AxisIndex other-type from */
180
181/* #region AxisIndex tuple-type from */
182
183// it seems that this directly implementing arbitary AxesIndex<T> will cause
184// conflicting implementation so make a macro for this task
185
186#[macro_export]
187macro_rules! impl_from_tuple_to_axes_index {
188    ($t: ty) => {
189        impl<F1, F2> TryFrom<(F1, F2)> for AxesIndex<$t>
190        where
191            $t: TryFrom<F1> + TryFrom<F2>,
192        {
193            type Error = Error;
194
195            fn try_from(value: (F1, F2)) -> Result<Self> {
196                Ok(AxesIndex::Vec(vec![
197                    value.0.try_into().ok().unwrap(),
198                    value.1.try_into().ok().unwrap(),
199                ]))
200            }
201        }
202
203        impl<F1, F2, F3> TryFrom<(F1, F2, F3)> for AxesIndex<$t>
204        where
205            $t: TryFrom<F1> + TryFrom<F2> + TryFrom<F3>,
206        {
207            type Error = Error;
208
209            fn try_from(value: (F1, F2, F3)) -> Result<Self> {
210                Ok(AxesIndex::Vec(vec![
211                    value.0.try_into().ok().unwrap(),
212                    value.1.try_into().ok().unwrap(),
213                    value.2.try_into().ok().unwrap(),
214                ]))
215            }
216        }
217
218        impl<F1, F2, F3, F4> TryFrom<(F1, F2, F3, F4)> for AxesIndex<$t>
219        where
220            $t: TryFrom<F1> + TryFrom<F2> + TryFrom<F3> + TryFrom<F4>,
221        {
222            type Error = Error;
223
224            fn try_from(value: (F1, F2, F3, F4)) -> Result<Self> {
225                Ok(AxesIndex::Vec(vec![
226                    value.0.try_into().ok().unwrap(),
227                    value.1.try_into().ok().unwrap(),
228                    value.2.try_into().ok().unwrap(),
229                    value.3.try_into().ok().unwrap(),
230                ]))
231            }
232        }
233
234        impl<F1, F2, F3, F4, F5> TryFrom<(F1, F2, F3, F4, F5)> for AxesIndex<$t>
235        where
236            $t: TryFrom<F1> + TryFrom<F2> + TryFrom<F3> + TryFrom<F4> + TryFrom<F5>,
237        {
238            type Error = Error;
239
240            fn try_from(value: (F1, F2, F3, F4, F5)) -> Result<Self> {
241                Ok(AxesIndex::Vec(vec![
242                    value.0.try_into().ok().unwrap(),
243                    value.1.try_into().ok().unwrap(),
244                    value.2.try_into().ok().unwrap(),
245                    value.3.try_into().ok().unwrap(),
246                    value.4.try_into().ok().unwrap(),
247                ]))
248            }
249        }
250
251        impl<F1, F2, F3, F4, F5, F6> TryFrom<(F1, F2, F3, F4, F5, F6)> for AxesIndex<$t>
252        where
253            $t: TryFrom<F1> + TryFrom<F2> + TryFrom<F3> + TryFrom<F4> + TryFrom<F5> + TryFrom<F6>,
254        {
255            type Error = Error;
256
257            fn try_from(value: (F1, F2, F3, F4, F5, F6)) -> Result<Self> {
258                Ok(AxesIndex::Vec(vec![
259                    value.0.try_into().ok().unwrap(),
260                    value.1.try_into().ok().unwrap(),
261                    value.2.try_into().ok().unwrap(),
262                    value.3.try_into().ok().unwrap(),
263                    value.4.try_into().ok().unwrap(),
264                    value.5.try_into().ok().unwrap(),
265                ]))
266            }
267        }
268
269        impl<F1, F2, F3, F4, F5, F6, F7> TryFrom<(F1, F2, F3, F4, F5, F6, F7)> for AxesIndex<$t>
270        where
271            $t: TryFrom<F1>
272                + TryFrom<F2>
273                + TryFrom<F3>
274                + TryFrom<F4>
275                + TryFrom<F5>
276                + TryFrom<F6>
277                + TryFrom<F7>,
278        {
279            type Error = Error;
280
281            fn try_from(value: (F1, F2, F3, F4, F5, F6, F7)) -> Result<Self> {
282                Ok(AxesIndex::Vec(vec![
283                    value.0.try_into().ok().unwrap(),
284                    value.1.try_into().ok().unwrap(),
285                    value.2.try_into().ok().unwrap(),
286                    value.3.try_into().ok().unwrap(),
287                    value.4.try_into().ok().unwrap(),
288                    value.5.try_into().ok().unwrap(),
289                    value.6.try_into().ok().unwrap(),
290                ]))
291            }
292        }
293
294        impl<F1, F2, F3, F4, F5, F6, F7, F8> TryFrom<(F1, F2, F3, F4, F5, F6, F7, F8)>
295            for AxesIndex<$t>
296        where
297            $t: TryFrom<F1>
298                + TryFrom<F2>
299                + TryFrom<F3>
300                + TryFrom<F4>
301                + TryFrom<F5>
302                + TryFrom<F6>
303                + TryFrom<F7>
304                + TryFrom<F8>,
305        {
306            type Error = Error;
307
308            fn try_from(value: (F1, F2, F3, F4, F5, F6, F7, F8)) -> Result<Self> {
309                Ok(AxesIndex::Vec(vec![
310                    value.0.try_into().ok().unwrap(),
311                    value.1.try_into().ok().unwrap(),
312                    value.2.try_into().ok().unwrap(),
313                    value.3.try_into().ok().unwrap(),
314                    value.4.try_into().ok().unwrap(),
315                    value.5.try_into().ok().unwrap(),
316                    value.6.try_into().ok().unwrap(),
317                    value.7.try_into().ok().unwrap(),
318                ]))
319            }
320        }
321
322        impl<F1, F2, F3, F4, F5, F6, F7, F8, F9> TryFrom<(F1, F2, F3, F4, F5, F6, F7, F8, F9)>
323            for AxesIndex<$t>
324        where
325            $t: TryFrom<F1>
326                + TryFrom<F2>
327                + TryFrom<F3>
328                + TryFrom<F4>
329                + TryFrom<F5>
330                + TryFrom<F6>
331                + TryFrom<F7>
332                + TryFrom<F8>
333                + TryFrom<F9>,
334        {
335            type Error = Error;
336
337            fn try_from(value: (F1, F2, F3, F4, F5, F6, F7, F8, F9)) -> Result<Self> {
338                Ok(AxesIndex::Vec(vec![
339                    value.0.try_into().ok().unwrap(),
340                    value.1.try_into().ok().unwrap(),
341                    value.2.try_into().ok().unwrap(),
342                    value.3.try_into().ok().unwrap(),
343                    value.4.try_into().ok().unwrap(),
344                    value.5.try_into().ok().unwrap(),
345                    value.6.try_into().ok().unwrap(),
346                    value.7.try_into().ok().unwrap(),
347                    value.8.try_into().ok().unwrap(),
348                ]))
349            }
350        }
351
352        impl<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10>
353            TryFrom<(F1, F2, F3, F4, F5, F6, F7, F8, F9, F10)> for AxesIndex<$t>
354        where
355            $t: TryFrom<F1>
356                + TryFrom<F2>
357                + TryFrom<F3>
358                + TryFrom<F4>
359                + TryFrom<F5>
360                + TryFrom<F6>
361                + TryFrom<F7>
362                + TryFrom<F8>
363                + TryFrom<F9>
364                + TryFrom<F10>,
365        {
366            type Error = Error;
367
368            fn try_from(value: (F1, F2, F3, F4, F5, F6, F7, F8, F9, F10)) -> Result<Self> {
369                Ok(AxesIndex::Vec(vec![
370                    value.0.try_into().ok().unwrap(),
371                    value.1.try_into().ok().unwrap(),
372                    value.2.try_into().ok().unwrap(),
373                    value.3.try_into().ok().unwrap(),
374                    value.4.try_into().ok().unwrap(),
375                    value.5.try_into().ok().unwrap(),
376                    value.6.try_into().ok().unwrap(),
377                    value.7.try_into().ok().unwrap(),
378                    value.8.try_into().ok().unwrap(),
379                    value.9.try_into().ok().unwrap(),
380                ]))
381            }
382        }
383    };
384}
385
386impl_from_tuple_to_axes_index!(isize);
387impl_from_tuple_to_axes_index!(usize);
388
389/* #endregion AxisIndex tuple-type from */
390
391/* #endregion */
392
393/* #region uninitialized vector */
394
395/// Create an uninitialized vector with the given size.
396///
397/// # Safety
398///
399/// Caller must ensure that the vector is properly initialized before using it.
400pub unsafe fn uninitialized_vec<T>(size: usize) -> Vec<T> {
401    let mut v: Vec<MaybeUninit<T>> = Vec::with_capacity(size);
402    unsafe { v.set_len(size) };
403    return unsafe { transmute::<Vec<MaybeUninit<T>>, Vec<T>>(v) };
404}
405
406/* #endregion */
407
408/* #region trait for split_at */
409
410pub trait IterSplitAtAPI: Sized {
411    // Function that split the iterator at the given index.
412    // This is used for parallel iterator.
413    fn split_at(self, index: usize) -> (Self, Self);
414}
415
416/* #endregion */