linearize/
storage.rs
1use {
2 crate::Linearize,
3 core::{
4 array::TryFromSliceError,
5 borrow::{Borrow, BorrowMut},
6 cmp::Ordering,
7 hash::Hash,
8 mem::MaybeUninit,
9 ptr,
10 },
11};
12
13pub trait Storage<L, T>:
14 Sized
15 + AsRef<[T]>
16 + AsMut<[T]>
17 + Borrow<[T]>
18 + BorrowMut<[T]>
19 + IntoIterator<Item = T, IntoIter: ExactSizeIterator + DoubleEndedIterator>
20where
21 L: Linearize<Storage<T> = Self> + ?Sized,
22{
23 fn into_copy(self) -> L::CopyStorage<T>
24 where
25 T: Copy;
26
27 fn as_copy(&self) -> &L::CopyStorage<T>
28 where
29 T: Copy;
30
31 fn as_copy_mut(&mut self) -> &mut L::CopyStorage<T>
32 where
33 T: Copy;
34
35 fn into_storage(self) -> L::Storage<T>;
36
37 fn from_fn(cb: impl FnMut(usize) -> T) -> Self;
38
39 fn each_ref(&self) -> <L as Linearize>::Storage<&T>;
40
41 fn each_mut(&mut self) -> <L as Linearize>::Storage<&mut T>;
42
43 fn map<U>(self, cb: impl FnMut(usize, T) -> U) -> <L as Linearize>::Storage<U>;
44
45 fn clone(&self) -> Self
46 where
47 T: Clone;
48
49 fn clone_from(&mut self, source: &Self)
50 where
51 T: Clone;
52
53 fn default() -> Self
54 where
55 T: Default;
56
57 fn eq(&self, other: &Self) -> bool
58 where
59 T: PartialEq;
60
61 fn cmp(&self, other: &Self) -> Ordering
62 where
63 T: Ord;
64
65 fn max(self, other: Self) -> Self
66 where
67 T: Ord;
68
69 fn min(self, other: Self) -> Self
70 where
71 T: Ord;
72
73 fn clamp(self, min: Self, max: Self) -> Self
74 where
75 T: Ord;
76
77 fn partial_cmp(&self, other: &Self) -> Option<Ordering>
78 where
79 T: PartialOrd;
80
81 fn as_hash(&self) -> impl Hash
82 where
83 T: Hash;
84
85 fn ref_try_from(from: &[T]) -> Result<&Self, TryFromSliceError>;
86
87 fn mut_try_from(from: &mut [T]) -> Result<&mut Self, TryFromSliceError>;
88
89 fn copy_ref_try_from(from: &[T]) -> Result<Self, TryFromSliceError>
90 where
91 T: Copy;
92
93 fn copy_mut_try_from(from: &mut [T]) -> Result<Self, TryFromSliceError>
94 where
95 T: Copy;
96
97 #[cfg(feature = "std")]
98 fn vec_try_from(from: Vec<T>) -> Result<Self, Vec<T>>;
99}
100
101pub trait CopyStorage<L, T>: Copy
102where
103 L: Linearize<CopyStorage<T> = Self> + ?Sized,
104 T: Copy,
105{
106 fn into_storage(self) -> L::Storage<T>;
107
108 fn as_storage(&self) -> &L::Storage<T>;
109
110 fn as_storage_mut(&mut self) -> &mut L::Storage<T>;
111}
112
113impl<L, T, const N: usize> Storage<L, T> for [T; N]
114where
115 L: Linearize<Storage<T> = Self> + ?Sized,
116{
117 fn into_copy(self) -> L::CopyStorage<T>
118 where
119 T: Copy,
120 {
121 let slf = MaybeUninit::new(self);
123 unsafe {
124 ptr::read(slf.as_ptr() as *const L::CopyStorage<T>)
128 }
129 }
130
131 fn as_copy(&self) -> &L::CopyStorage<T>
132 where
133 T: Copy,
134 {
135 unsafe {
136 &*(self as *const L::Storage<T> as *const L::CopyStorage<T>)
140 }
141 }
142
143 fn as_copy_mut(&mut self) -> &mut L::CopyStorage<T>
144 where
145 T: Copy,
146 {
147 unsafe {
148 &mut *(self as *mut L::Storage<T> as *mut L::CopyStorage<T>)
152 }
153 }
154
155 fn into_storage(self) -> L::Storage<T> {
156 self
157 }
158
159 fn from_fn(cb: impl FnMut(usize) -> T) -> Self {
160 core::array::from_fn(cb)
161 }
162
163 fn each_ref(&self) -> L::Storage<&T> {
164 let res: [&T; N] = <[T; N]>::each_ref(self);
165 unsafe {
166 ptr::read(&res as *const [&T; N] as *const L::Storage<&T>)
172 }
173 }
174
175 fn each_mut(&mut self) -> L::Storage<&mut T> {
176 let res: [&mut T; N] = <[T; N]>::each_mut(self);
177 let res: MaybeUninit<[&mut T; N]> = MaybeUninit::new(res);
178 unsafe {
179 ptr::read(res.as_ptr() as *const L::Storage<&mut T>)
186 }
187 }
188
189 fn map<U>(self, mut cb: impl FnMut(usize, T) -> U) -> L::Storage<U> {
190 let mut src = MaybeUninit::<[T; N]>::new(self);
191 let src_ptr = src.as_mut_ptr() as *const T;
192 let mut res;
193 let res_ptr;
194 if size_of::<U>() <= size_of::<T>() && align_of::<U>() <= align_of::<T>() {
195 res_ptr = src_ptr as *mut U;
197 } else {
198 res = MaybeUninit::<[U; N]>::uninit();
200 res_ptr = res.as_mut_ptr() as *mut U;
201 }
202 for i in 0..N {
203 let t = unsafe {
204 ptr::read(src_ptr.add(i))
212 };
213 let u = cb(i, t);
214 unsafe {
215 ptr::write(res_ptr.add(i), u);
221 }
222 }
223 unsafe {
224 ptr::read(res_ptr as *const L::Storage<U>)
232 }
233 }
234
235 fn clone(&self) -> Self
236 where
237 T: Clone,
238 {
239 <[T; N] as Clone>::clone(self)
240 }
241
242 fn clone_from(&mut self, source: &Self)
243 where
244 T: Clone,
245 {
246 <[T; N] as Clone>::clone_from(self, source)
247 }
248
249 fn default() -> Self
250 where
251 T: Default,
252 {
253 core::array::from_fn(|_| T::default())
254 }
255
256 fn eq(&self, other: &Self) -> bool
257 where
258 T: PartialEq,
259 {
260 <[T; N] as PartialEq>::eq(self, other)
261 }
262
263 fn cmp(&self, other: &Self) -> Ordering
264 where
265 T: Ord,
266 {
267 <[T; N] as Ord>::cmp(self, other)
268 }
269
270 fn max(self, other: Self) -> Self
271 where
272 T: Ord,
273 {
274 <[T; N] as Ord>::max(self, other)
275 }
276
277 fn min(self, other: Self) -> Self
278 where
279 T: Ord,
280 {
281 <[T; N] as Ord>::min(self, other)
282 }
283
284 fn clamp(self, min: Self, max: Self) -> Self
285 where
286 T: Ord,
287 {
288 <[T; N] as Ord>::clamp(self, min, max)
289 }
290
291 fn partial_cmp(&self, other: &Self) -> Option<Ordering>
292 where
293 T: PartialOrd,
294 {
295 <[T; N] as PartialOrd>::partial_cmp(self, other)
296 }
297
298 fn as_hash(&self) -> impl Hash
299 where
300 T: Hash,
301 {
302 self
303 }
304
305 fn ref_try_from(from: &[T]) -> Result<&Self, TryFromSliceError> {
306 <&[T; N] as TryFrom<&[T]>>::try_from(from)
307 }
308
309 fn mut_try_from(from: &mut [T]) -> Result<&mut Self, TryFromSliceError> {
310 <&mut [T; N] as TryFrom<&mut [T]>>::try_from(from)
311 }
312
313 fn copy_ref_try_from(from: &[T]) -> Result<Self, TryFromSliceError>
314 where
315 T: Copy,
316 {
317 <[T; N] as TryFrom<&[T]>>::try_from(from)
318 }
319
320 fn copy_mut_try_from(from: &mut [T]) -> Result<Self, TryFromSliceError>
321 where
322 T: Copy,
323 {
324 <[T; N] as TryFrom<&mut [T]>>::try_from(from)
325 }
326
327 #[cfg(feature = "std")]
328 fn vec_try_from(from: Vec<T>) -> Result<Self, Vec<T>> {
329 <[T; N] as TryFrom<Vec<T>>>::try_from(from)
330 }
331}
332
333impl<L, T, const N: usize> CopyStorage<L, T> for [T; N]
334where
335 L: Linearize<Storage<T> = Self, CopyStorage<T> = Self> + ?Sized,
336 T: Copy,
337{
338 fn into_storage(self) -> L::Storage<T> {
339 self
340 }
341
342 fn as_storage(&self) -> &L::Storage<T> {
343 self
344 }
345
346 fn as_storage_mut(&mut self) -> &mut L::Storage<T> {
347 self
348 }
349}