Skip to main content

stack_array/
conversions.rs

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