stack_array/
conversions.rs1use super::{
7 Array,
8 errors::{
9 UnmatchedCapacity,
10 CapacityExceeded
11 }
12};
13
14use alloc::vec::Vec;
16
17use constrangeiter::ConstIntoIterator;
19
20use 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
32const 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
56const 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
68const 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
87const 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
96impl<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
105const 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
116const 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}