ladata/list/array/
core_impls.rs1use crate::all::{Array, Direct, Storage};
7#[cfg(feature = "unsafe_init")]
8use core::mem::{self, MaybeUninit};
9use core::{
10 fmt,
11 ops::{Deref, DerefMut},
12};
13
14#[cfg(feature = "alloc")]
15use {
16 crate::mem::Boxed,
17 alloc::{boxed::Box, vec::Vec},
18};
19
20impl<T, S: Storage, const LEN: usize> Deref for Array<T, S, LEN> {
22 type Target = [T];
23
24 fn deref(&self) -> &Self::Target {
25 self.array.deref()
26 }
27}
28impl<T, S: Storage, const LEN: usize> DerefMut for Array<T, S, LEN> {
30 fn deref_mut(&mut self) -> &mut Self::Target {
31 self.array.deref_mut()
32 }
33}
34
35impl<T: Clone, S: Storage, const LEN: usize> Clone for Array<T, S, LEN>
37where
38 S::Stored<[T; LEN]>: Clone,
39{
40 fn clone(&self) -> Self {
41 Self {
42 array: self.array.clone(),
43 }
44 }
45}
46
47impl<T: Copy, S: Storage, const LEN: usize> Copy for Array<T, S, LEN> where S::Stored<[T; LEN]>: Copy
49{}
50
51impl<T: fmt::Debug, S: Storage, const LEN: usize> fmt::Debug for Array<T, S, LEN>
53where
54 S::Stored<[T; LEN]>: fmt::Debug,
55{
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 let mut debug = f.debug_struct(stringify![Array]);
58 debug.field("LEN", &LEN);
59 debug.field("", &self.array);
60 debug.finish()
61 }
62}
63
64impl<T: PartialEq, S: Storage, const LEN: usize> PartialEq for Array<T, S, LEN>
66where
67 S::Stored<[T; LEN]>: PartialEq,
68{
69 fn eq(&self, other: &Self) -> bool {
70 self.array == other.array && self.len() == other.len()
71 }
72}
73impl<T: Eq, S: Storage, const LEN: usize> Eq for Array<T, S, LEN> where S::Stored<[T; LEN]>: Eq {}
75
76impl<T: Default, const LEN: usize> Default for Array<T, (), LEN> {
78 fn default() -> Self {
81 #[cfg(feature = "unsafe_init")]
82 let data = {
83 let mut arr: [MaybeUninit<T>; LEN] = unsafe { MaybeUninit::uninit().assume_init() };
84 for i in &mut arr[..] {
85 let _ = i.write(T::default());
86 }
87 unsafe { mem::transmute_copy::<_, [T; LEN]>(&arr) }
88 };
89
90 #[cfg(not(feature = "unsafe_init"))]
91 let data = core::array::from_fn(|_| T::default());
92
93 Array {
94 array: Direct::new(data),
95 }
96 }
97}
98
99#[cfg(feature = "alloc")]
101#[cfg_attr(feature = "nightly", doc(cfg(feature = "alloc")))]
102impl<T: Default, const LEN: usize> Default for Array<T, Boxed, LEN> {
103 fn default() -> Self {
113 #[cfg(not(feature = "unsafe_init"))]
114 let data = {
115 let mut v = Vec::<T>::with_capacity(LEN);
116
117 for _ in 0..LEN {
118 v.push(T::default());
119 }
120
121 let Ok(array) = v.into_boxed_slice().try_into() else {
122 panic!("Can't turn the boxed slice into a boxed array");
123 };
124 array
125 };
126
127 #[cfg(feature = "unsafe_init")]
128 let data = {
129 let mut v = Vec::<T>::with_capacity(LEN);
130
131 for _ in 0..LEN {
132 v.push(T::default());
133 }
134
135 let slice = v.into_boxed_slice();
136 let raw_slice = Box::into_raw(slice);
137 unsafe { Box::from_raw(raw_slice as *mut [T; LEN]) }
139 };
140
141 Array { array: data }
142 }
143}
144
145impl<T, const LEN: usize> From<Array<T, (), LEN>> for [T; LEN] {
146 fn from(array: Array<T, (), LEN>) -> [T; LEN] {
147 array.array.0
148 }
149}
150#[cfg(feature = "alloc")]
151#[cfg_attr(feature = "nightly", doc(cfg(feature = "alloc")))]
152impl<T, const LEN: usize> From<Array<T, Boxed, LEN>> for Box<[T; LEN]> {
153 fn from(array: Array<T, Boxed, LEN>) -> Box<[T; LEN]> {
154 array.array
155 }
156}
157
158impl<T: Default, I, const LEN: usize> From<I> for Array<T, (), LEN>
159where
160 I: IntoIterator<Item = T>,
161{
162 fn from(iterator: I) -> Array<T, (), LEN> {
176 let mut iterator = iterator.into_iter();
177
178 #[cfg(feature = "unsafe_init")]
179 let data = {
180 let mut arr: [MaybeUninit<T>; LEN] = unsafe { MaybeUninit::uninit().assume_init() };
181 for i in &mut arr[..] {
182 if let Some(e) = iterator.next() {
183 let _ = i.write(e);
184 } else {
185 let _ = i.write(T::default());
186 }
187 }
188 unsafe { mem::transmute_copy::<_, [T; LEN]>(&arr) }
189 };
190
191 #[cfg(not(feature = "unsafe_init"))]
192 let data = core::array::from_fn(|_| {
193 if let Some(e) = iterator.next() {
194 e
195 } else {
196 T::default()
197 }
198 });
199
200 Array {
201 array: Direct::new(data),
202 }
203 }
204}
205
206#[cfg(feature = "alloc")]
207#[cfg_attr(feature = "nightly", doc(cfg(feature = "alloc")))]
208impl<T: Default, I, const LEN: usize> From<I> for Array<T, Boxed, LEN>
209where
210 I: IntoIterator<Item = T>,
211{
212 fn from(iterator: I) -> Array<T, Boxed, LEN> {
223 let mut iterator = iterator.into_iter();
224
225 #[cfg(not(feature = "unsafe_init"))]
226 let data = {
227 let mut v = Vec::<T>::with_capacity(LEN);
228
229 for _ in 0..LEN {
230 if let Some(e) = iterator.next() {
231 v.push(e);
232 } else {
233 v.push(T::default());
234 }
235 }
236 let Ok(array) = v.into_boxed_slice().try_into() else {
237 panic!("Can't turn the boxed slice into a boxed array");
238 };
239 array
240 };
241
242 #[cfg(feature = "unsafe_init")]
243 let data = {
244 let mut v = Vec::<T>::with_capacity(LEN);
245
246 for _ in 0..LEN {
247 if let Some(e) = iterator.next() {
248 v.push(e);
249 } else {
250 v.push(T::default());
251 }
252 }
253 let slice = v.into_boxed_slice();
254 let raw_slice = Box::into_raw(slice);
255 unsafe { Box::from_raw(raw_slice as *mut [T; LEN]) }
257 };
258
259 Array { array: data }
260 }
261}