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> Into<Vec<Type>> for Array<Type, N> {
102 fn into(self) -> Vec<Type> {return Vec::from_iter(self.into_iter())}
103}
104
105const 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
125const 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}