Skip to main content

stack_array/
conversions.rs

1//^
2//^ HEAD
3//^
4
5//> HEAD -> IMPORTS
6use {
7    super::{
8        Array,
9        errors::{
10            UnmatchedCapacity,
11            CapacityExceeded
12        }
13    },
14    alloc::vec::Vec,
15    constrangeiter::ConstIntoIterator,
16    core::{
17        mem::{
18            MaybeUninit,
19            transmute_neo as transmute,
20            forget
21        },
22        array::from_fn as arrayfn,
23        marker::Destruct
24    }
25};
26
27
28//^
29//^ FROM
30//^
31
32//> FROM -> FIXED ARRAY
33const impl<
34    Type: [const] Destruct, 
35    const M: usize, 
36    const N: usize
37> From<[Type; N]> for Array<Type, M> where [(); M - N]: {
38    fn from(value: [Type; N]) -> Self {
39        let mut data = MaybeUninit::<[Type; M]>::uninit().transpose();
40        let mut index = 0;
41        let _ = value.map(const |element| {
42            data[index].write(element); 
43            index += 1;
44        });
45        return Array {
46            length: N,
47            data: data
48        };
49    }
50}
51
52//> FROM -> FUNCTION
53const impl<
54    Type: [const] Destruct, 
55    Generator: [const] FnMut(usize) -> Type + [const] Destruct,
56    const N: usize,
57> From<Generator> for Array<Type, N> {
58    fn from(mut value: Generator) -> Self {return Array {
59        length: N,
60        data: arrayfn(const |index| MaybeUninit::new(value(index)))
61    }}
62}
63
64//> FROM -> PARTS
65const impl<Type, const N: usize> From<(usize, [MaybeUninit<Type>; N])> for Array<Type, N> {
66    fn from((length, data): (usize, [MaybeUninit<Type>; N])) -> Self {return Array {
67        length: length,
68        data: data
69    }}
70}
71
72
73//^
74//^ TRYFROM
75//^
76
77//> TRYFROM -> VEC
78const impl<Type, const N: usize> TryFrom<Vec<Type>> for Array<Type, N> {
79    type Error = CapacityExceeded<N>;
80    fn try_from(value: Vec<Type>) -> Result<Self, Self::Error> {
81        let (pointer, length, _) = value.into_parts();
82        if length > N {return Err(CapacityExceeded {
83            expected: length
84        })}
85        let mut array = Array {
86            length: length,
87            data: MaybeUninit::uninit().transpose()
88        };
89        for index in (0..length).const_into_iter() {
90            array.data[index].write(unsafe {pointer.add(index).read()});
91        }
92        return Ok(array);
93    }
94}
95
96
97//^
98//^ INTO
99//^
100
101//> INTO -> VEC
102impl<Type, const N: usize> From<Array<Type, N>> for Vec<Type> {
103    fn from(value: Array<Type, N>) -> Self {return Vec::from_iter(value.into_iter())}
104}
105
106//> INTO -> PARTS
107const impl<Type, const N: usize> From<Array<Type, N>> for (usize, [MaybeUninit<Type>; N]) {
108    fn from(value: Array<Type, N>) -> Self {
109        let length = value.length;
110        let data = unsafe {value.data.as_ptr().cast::<[MaybeUninit<Type>; N]>().read()};
111        forget(value);
112        return (length, data);
113    }
114}
115
116
117//^
118//^ TRYINTO
119//^
120
121//> TRYINTO -> FIXED ARRAY
122const impl<
123    Type,
124    const N: usize,
125    const LENGTH: usize
126> TryFrom<Array<Type, N>> for [Type; LENGTH] where [(); N - LENGTH]: {
127    type Error = UnmatchedCapacity<LENGTH>;
128    fn try_from(value: Array<Type, N>) -> Result<Self, Self::Error> {
129        let (length, data) = value.into();
130        if length != LENGTH {return Err(UnmatchedCapacity {
131            present: length
132        })}
133        let (initialized, _): (
134            [MaybeUninit<Type>; LENGTH],
135            [MaybeUninit<Type>; N - LENGTH]
136        ) = unsafe {transmute(data)};
137        return Ok(unsafe {transmute(initialized)});
138    }
139}