konst_kernel/slice/
slice_for_konst.rs

1#![allow(non_camel_case_types)]
2
3use core::fmt::{self, Display};
4
5#[inline]
6pub const fn try_into_array_func<T, const N: usize>(
7    slice: &[T],
8) -> Result<&[T; N], TryIntoArrayError> {
9    if slice.len() == N {
10        let ptr = slice.as_ptr() as *const [T; N];
11        unsafe { Ok(crate::utils::Dereference { ptr }.reff) }
12    } else {
13        Err(TryIntoArrayError {
14            slice_len: slice.len(),
15            array_len: N,
16        })
17    }
18}
19
20////////////////////////////////////////////////////////////////////////////////
21
22#[cfg(feature = "rust_1_83")]
23#[inline]
24pub const fn try_into_array_mut_func<T, const N: usize>(
25    slice: &mut [T],
26) -> Result<&mut [T; N], TryIntoArrayError> {
27    if slice.len() == N {
28        unsafe { Ok(&mut *(slice as *mut [T] as *mut [T; N])) }
29    } else {
30        Err(TryIntoArrayError {
31            slice_len: slice.len(),
32            array_len: N,
33        })
34    }
35}
36
37////////////////////////////////////////////////////////////////////////////////
38
39#[derive(Debug, PartialEq, Eq, Copy, Clone)]
40pub struct TryIntoArrayError {
41    slice_len: usize,
42    array_len: usize,
43}
44
45impl TryIntoArrayError {
46    /// For panicking with an error message.
47    pub const fn panic(&self) -> ! {
48        use crate::utils::PanikVal;
49
50        crate::utils::basic_panic(&[
51            PanikVal::Str("could not convert slice of length `"),
52            PanikVal::Usize(self.slice_len),
53            PanikVal::Str("` to array of length`"),
54            PanikVal::Usize(self.array_len),
55            PanikVal::Str("`"),
56        ])
57    }
58}
59
60impl Display for TryIntoArrayError {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        f.write_str("Could not cast slice to array reference")
63    }
64}
65
66////////////////////////////////////////////////////////////////////////////////
67
68#[macro_export]
69macro_rules! slice_concat {
70    ($elem_ty:ty, $slice:expr $(,)*) => {{
71        const __ARGS_81608BFNA5: &[&[$elem_ty]] = $slice;
72        {
73            const LEN: $crate::__::usize = $crate::slice::concat_sum_lengths(__ARGS_81608BFNA5);
74
75            const CONC: [$elem_ty; LEN] = $crate::slice::concat_slices(__ARGS_81608BFNA5);
76
77            CONC
78        }
79    }};
80}
81
82pub const fn concat_sum_lengths<T>(slice: &[&[T]]) -> usize {
83    let mut sum = 0usize;
84    crate::for_range! {i in 0..slice.len() =>
85        sum += slice[i].len();
86    }
87    sum
88}
89
90pub const fn concat_slices<T, const N: usize>(slices: &[&[T]]) -> [T; N]
91where
92    T: Copy,
93{
94    if let Ok(x) = try_into_array_func::<T, N>(&[]) {
95        return *x;
96    }
97
98    let mut out = [*first_elem(slices); N];
99    let mut out_i = 0usize;
100
101    crate::for_range! {si in 0..slices.len() =>
102        let slice = slices[si];
103        crate::for_range! {i in 0..slice.len() =>
104            out[out_i] = slice[i];
105            out_i += 1;
106        }
107    }
108
109    out
110}
111
112// returns the first T in a `&[&[T]]`
113const fn first_elem<'a, T>(slices: &[&'a [T]]) -> &'a T {
114    crate::for_range! {si in 0..slices.len() =>
115        if let [first, ..] = slices[si] {
116            return first;
117        }
118    }
119
120    panic!("there was no element in any slice");
121}