1use alloc::{boxed::Box, vec::Vec};
2
3use crate::{ArrayLength, GenericArray, IntrusiveArrayBuilder, LengthError};
4
5use core::{alloc::Layout, mem::MaybeUninit, ptr};
6
7struct IntrusiveBoxedArrayBuilder<T, N: ArrayLength> {
8 layout: Layout,
9 ptr: *mut GenericArray<MaybeUninit<T>, N>,
10 position: usize,
11}
12
13impl<T, N: ArrayLength> IntrusiveBoxedArrayBuilder<T, N> {
14 #[inline(always)]
15 unsafe fn iter_position(
16 &'_ mut self,
17 ) -> (core::slice::IterMut<'_, MaybeUninit<T>>, &'_ mut usize) {
18 ((&mut *self.ptr).iter_mut(), &mut self.position)
19 }
20
21 #[inline(always)]
22 unsafe fn finish(self) -> Box<GenericArray<T, N>> {
23 debug_assert!(self.position == N::USIZE);
24 let ptr = self.ptr;
25 core::mem::forget(self);
26 Box::from_raw(ptr.cast())
27 }
28}
29
30impl<T, N: ArrayLength> Drop for IntrusiveBoxedArrayBuilder<T, N> {
31 fn drop(&mut self) {
32 unsafe {
33 if self.layout.size() == 0 {
34 ptr::drop_in_place(ptr::slice_from_raw_parts_mut(
37 ptr::NonNull::<T>::dangling().as_ptr(),
38 self.position,
39 ));
40 } else {
41 ptr::drop_in_place((&mut *self.ptr).get_unchecked_mut(..self.position)
42 as *mut [MaybeUninit<T>] as *mut [T]);
43
44 alloc::alloc::dealloc(self.ptr.cast(), self.layout);
45 }
46 }
47 }
48}
49
50impl<T, N: ArrayLength> TryFrom<Vec<T>> for GenericArray<T, N> {
51 type Error = crate::LengthError;
52
53 fn try_from(v: Vec<T>) -> Result<Self, Self::Error> {
54 if v.len() != N::USIZE {
55 return Err(crate::LengthError);
56 }
57
58 unsafe {
59 let mut destination = core::mem::MaybeUninit::<GenericArray<T, N>>::uninit();
60 let mut builder = IntrusiveArrayBuilder::new_alt(&mut destination);
61
62 builder.extend(v.into_iter());
63
64 Ok(builder.finish_and_assume_init())
65 }
66 }
67}
68
69impl<T, N: ArrayLength> GenericArray<T, N> {
70 #[inline]
74 pub fn into_boxed_slice(self: Box<GenericArray<T, N>>) -> Box<[T]> {
75 unsafe {
76 Box::from_raw(core::ptr::slice_from_raw_parts_mut(
78 Box::into_raw(self) as *mut T,
79 N::USIZE,
80 ))
81 }
82 }
83
84 #[inline]
88 pub fn into_vec(self: Box<GenericArray<T, N>>) -> Vec<T> {
89 Vec::from(self.into_boxed_slice())
90 }
91
92 #[inline]
96 pub fn try_from_boxed_slice(slice: Box<[T]>) -> Result<Box<GenericArray<T, N>>, LengthError> {
97 if slice.len() != N::USIZE {
98 return Err(LengthError);
99 }
100
101 Ok(unsafe { Box::from_raw(Box::into_raw(slice) as *mut _) })
102 }
103
104 #[inline]
110 pub fn try_from_vec(vec: Vec<T>) -> Result<Box<GenericArray<T, N>>, LengthError> {
111 Self::try_from_boxed_slice(vec.into_boxed_slice())
112 }
113
114 #[inline]
120 pub fn default_boxed() -> Box<GenericArray<T, N>>
121 where
122 T: Default,
123 {
124 Box::<GenericArray<T, N>>::generate(|_| T::default())
125 }
126
127 pub fn try_boxed_from_iter<I>(iter: I) -> Result<Box<GenericArray<T, N>>, LengthError>
129 where
130 I: IntoIterator<Item = T>,
131 {
132 let mut iter = iter.into_iter();
133
134 match iter.size_hint() {
136 (n, _) if n > N::USIZE => return Err(LengthError),
138 (_, Some(n)) if n < N::USIZE => return Err(LengthError),
140 _ => {}
141 }
142
143 let mut v = Vec::with_capacity(N::USIZE);
144 v.extend((&mut iter).take(N::USIZE));
145
146 if v.len() != N::USIZE || iter.next().is_some() {
147 return Err(LengthError);
148 }
149
150 Ok(GenericArray::try_from_vec(v).unwrap())
151 }
152}
153
154impl<T, N: ArrayLength> TryFrom<Box<[T]>> for GenericArray<T, N> {
155 type Error = crate::LengthError;
156
157 #[inline]
158 fn try_from(value: Box<[T]>) -> Result<Self, Self::Error> {
159 Vec::from(value).try_into()
160 }
161}
162
163impl<T, N: ArrayLength> From<GenericArray<T, N>> for Box<[T]> {
164 #[inline]
165 fn from(value: GenericArray<T, N>) -> Self {
166 Box::new(value).into_boxed_slice()
167 }
168}
169
170impl<T, N: ArrayLength> From<GenericArray<T, N>> for Vec<T> {
171 #[inline]
172 fn from(value: GenericArray<T, N>) -> Self {
173 Box::<[T]>::from(value).into()
174 }
175}
176
177impl<T, N: ArrayLength> IntoIterator for Box<GenericArray<T, N>> {
178 type IntoIter = alloc::vec::IntoIter<T>;
179 type Item = T;
180
181 fn into_iter(self) -> Self::IntoIter {
182 GenericArray::into_vec(self).into_iter()
183 }
184}
185
186impl<T, N: ArrayLength> FromIterator<T> for Box<GenericArray<T, N>> {
187 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
193 match GenericArray::try_boxed_from_iter(iter) {
194 Ok(res) => res,
195 Err(_) => crate::from_iter_length_fail(N::USIZE),
196 }
197 }
198}
199
200use crate::functional::{FunctionalSequence, MappedGenericSequence};
201use crate::GenericSequence;
202
203unsafe impl<T, N: ArrayLength> GenericSequence<T> for Box<GenericArray<T, N>> {
204 type Length = N;
205 type Sequence = Box<GenericArray<T, N>>;
206
207 fn generate<F>(mut f: F) -> Self::Sequence
208 where
209 F: FnMut(usize) -> T,
210 {
211 unsafe {
212 let layout = Layout::new::<GenericArray<MaybeUninit<T>, N>>();
213
214 let raw_ptr: *mut GenericArray<MaybeUninit<T>, N> = if layout.size() == 0 {
215 ptr::NonNull::dangling().as_ptr()
216 } else {
217 let p = alloc::alloc::alloc(layout);
218
219 if p.is_null() {
220 alloc::alloc::handle_alloc_error(layout);
221 }
222
223 p.cast()
224 };
225
226 let mut builder = IntrusiveBoxedArrayBuilder {
227 layout,
228 ptr: raw_ptr,
229 position: 0,
230 };
231
232 {
233 let (builder_iter, position) = builder.iter_position();
234
235 builder_iter.enumerate().for_each(|(i, dst)| {
236 dst.write(f(i));
237 *position += 1;
238 });
239 }
240
241 builder.finish()
242 }
243 }
244}
245
246impl<T, U, N: ArrayLength> MappedGenericSequence<T, U> for Box<GenericArray<T, N>> {
247 type Mapped = Box<GenericArray<U, N>>;
248}
249
250impl<T, N: ArrayLength> FunctionalSequence<T> for Box<GenericArray<T, N>> where
251 Self: GenericSequence<T, Item = T, Length = N>
252{
253}
254
255use crate::sequence::{FallibleGenericSequence, FromFallibleIterator};
256
257impl<T, N: ArrayLength> FromFallibleIterator<T> for Box<GenericArray<T, N>> {
258 fn from_fallible_iter<I, E>(iter: I) -> Result<Self, E>
259 where
260 I: IntoIterator<Item = Result<T, E>>,
261 {
262 let mut iter = iter.into_iter();
263 let mut v = Vec::with_capacity(N::USIZE);
264 for item in (&mut iter).take(N::USIZE) {
265 v.push(item?);
266 }
267 if v.len() != N::USIZE || iter.next().is_some() {
268 crate::from_iter_length_fail(N::USIZE)
269 } else {
270 Ok(GenericArray::try_from_vec(v).unwrap())
271 }
272 }
273}
274
275unsafe impl<T, N: ArrayLength> FallibleGenericSequence<T> for Box<GenericArray<T, N>> {
276 type Error = crate::AllocError;
277
278 fn try_generate<F, E>(mut f: F) -> Result<Result<Self::Sequence, E>, crate::AllocError>
279 where
280 F: FnMut(usize) -> Result<T, E>,
281 {
282 unsafe {
283 let layout = Layout::new::<GenericArray<MaybeUninit<T>, N>>();
284
285 let raw_ptr: *mut GenericArray<MaybeUninit<T>, N> = if layout.size() == 0 {
286 ptr::NonNull::dangling().as_ptr()
287 } else {
288 let p = alloc::alloc::alloc(layout);
289
290 if p.is_null() {
291 return Err(crate::AllocError);
292 }
293
294 p.cast()
295 };
296
297 let mut builder = IntrusiveBoxedArrayBuilder {
298 layout,
299 ptr: raw_ptr,
300 position: 0,
301 };
302
303 let (builder_iter, position) = builder.iter_position();
304
305 if let Err(e) = builder_iter
306 .enumerate()
307 .try_for_each(|(i, dst)| match f(i) {
308 Ok(value) => {
309 dst.write(value);
310 *position += 1;
311 Ok(())
312 }
313 Err(e) => Err(e),
314 })
315 {
316 drop(builder);
317 return Ok(Err(e));
318 }
319
320 Ok(Ok(builder.finish()))
321 }
322 }
323}