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> Into<Vec<Type>> for Array<Type, N> {
102    fn into(self) -> Vec<Type> {return Vec::from_iter(self.into_iter())}
103}
104
105//> INTO -> FIXED ARRAY
106const impl<
107    Type, 
108    const N: usize, 
109    const LENGTH: usize
110> TryInto<[Type; LENGTH]> for Array<Type, N> where [(); N - LENGTH]: {
111    type Error = UnmatchedCapacity<LENGTH>;
112    fn try_into(self) -> Result<[Type; LENGTH], Self::Error> {
113        let (length, data) = self.into();
114        if length != LENGTH {return Err(UnmatchedCapacity {
115            present: length
116        })}
117        let (initialized, _): (
118            [MaybeUninit<Type>; LENGTH], 
119            [MaybeUninit<Type>; N - LENGTH]
120        ) = unsafe {transmute(data)};
121        return Ok(unsafe {transmute(initialized)});
122    }
123}
124
125//> INTO -> PARTS
126const impl<Type, const N: usize> Into<(usize, [MaybeUninit<Type>; N])> for Array<Type, N> {
127    fn into(self) -> (usize, [MaybeUninit<Type>; N]) {
128        let length = self.length;
129        let data = unsafe {self.data.as_ptr().cast::<[MaybeUninit<Type>; N]>().read()};
130        forget(self);
131        return (length, data);
132    }
133}