1use std::{
2 alloc::{alloc_zeroed, Layout},
3 cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
4 convert::{TryFrom, TryInto},
5 fmt,
6 fmt::{Debug, Formatter},
7 ops::{Deref, DerefMut, Index, IndexMut},
8 ptr::NonNull,
9 slice::SliceIndex,
10};
11
12#[cfg_attr(feature = "packed", repr(packed))]
50pub struct Array<T, Len: Copy + Into<usize> + TryFrom<usize>> {
51 ptr: NonNull<T>,
52 len: Len,
53}
54
55unsafe impl<T: Sync, Len: Copy + Into<usize> + TryFrom<usize>> Sync for Array<T, Len> {}
56unsafe impl<T: Send, Len: Copy + Into<usize> + TryFrom<usize>> Send for Array<T, Len> {}
57
58impl<T, Len: Copy + Into<usize> + TryFrom<usize>> Drop for Array<T, Len> {
59 fn drop(&mut self) {
60 unsafe {
61 std::ptr::drop_in_place(self.deref_mut());
62 Vec::from_raw_parts(self.ptr.as_ptr(), 0, self.len.into());
63 }
64 }
65}
66
67impl<T, Len: Copy + Into<usize> + TryFrom<usize>> Array<T, Len> {
68 pub fn zeroed(len: Len) -> Self {
70 unsafe {
71 let len_u = len.into();
72 let layout = Layout::array::<T>(len_u).unwrap();
73
74 let ptr = if len_u != 0 {
75 alloc_zeroed(layout).cast::<T>()
76 } else {
77 0xdead as *mut T
79 };
80
81 Self::from_raw(ptr, len)
82 }
83 }
84
85 pub fn from_raw(raw: *mut T, len: Len) -> Self {
89 Self {
90 ptr: NonNull::new(raw).unwrap(),
91 len,
92 }
93 }
94
95 pub fn as_slice(&self) -> &[T] {
97 self
98 }
99
100 pub fn as_slice_mut(&mut self) -> &mut [T] {
102 self
103 }
104
105 pub fn from_vec(mut v: Vec<T>) -> Self
120 where
121 <Len as TryFrom<usize>>::Error: Debug,
122 {
123 let len = v.len().try_into().unwrap();
124 let ptr = v.as_mut_ptr();
125 std::mem::forget(v);
126
127 Self::from_raw(ptr, len)
128 }
129
130 pub fn into_vec(self) -> Vec<T> {
145 unsafe {
146 let size = self.len().try_into().unwrap();
147 let v = Vec::from_raw_parts(self.ptr.as_ptr(), size, size);
148 std::mem::forget(self);
149 v
150 }
151 }
152
153 pub fn len(&self) -> Len {
164 self.len
165 }
166
167 pub fn is_empty(&self) -> bool {
168 self.len().into() == 0
169 }
170}
171
172impl<T: Clone, Len: Copy + Into<usize> + TryFrom<usize>> Clone for Array<T, Len> {
176 fn clone(&self) -> Self {
177 unsafe {
178 let other = Self::zeroed(self.len);
179
180 other
182 .ptr
183 .as_ptr()
184 .copy_from_nonoverlapping(self.ptr.as_ptr(), self.len.into());
185
186 other
187 }
188 }
189}
190
191impl<T, Len: Copy + Into<usize> + TryFrom<usize>> Deref for Array<T, Len> {
192 type Target = [T];
193
194 fn deref(&self) -> &[T] {
195 unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.len.into()) }
196 }
197}
198
199impl<T, Len: Copy + Into<usize> + TryFrom<usize>> DerefMut for Array<T, Len> {
200 fn deref_mut(&mut self) -> &mut [T] {
201 unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len.into()) }
202 }
203}
204
205impl<T: Debug, Len: Copy + Into<usize> + TryFrom<usize>> Debug for Array<T, Len> {
206 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
207 fmt::Debug::fmt(self.as_slice(), f)
208 }
209}
210
211impl<T, Len: Copy + Into<usize> + TryFrom<usize>> IntoIterator for Array<T, Len> {
212 type Item = T;
213 type IntoIter = std::vec::IntoIter<T>;
214
215 fn into_iter(self) -> Self::IntoIter {
216 self.into_vec().into_iter()
217 }
218}
219
220impl<'t, T, Len: Copy + Into<usize> + TryFrom<usize>> IntoIterator for &'t Array<T, Len> {
221 type Item = &'t T;
222 type IntoIter = std::slice::Iter<'t, T>;
223
224 fn into_iter(self) -> std::slice::Iter<'t, T> {
225 self.iter()
226 }
227}
228
229impl<'t, T, Len: Copy + Into<usize> + TryFrom<usize>> IntoIterator for &'t mut Array<T, Len> {
230 type Item = &'t mut T;
231 type IntoIter = std::slice::IterMut<'t, T>;
232
233 fn into_iter(self) -> std::slice::IterMut<'t, T> {
234 self.iter_mut()
235 }
236}
237
238impl<T, Len> Eq for Array<T, Len>
239where
240 T: Eq,
241 Len: Copy + Into<usize> + TryFrom<usize>,
242{
243}
244
245impl<T, Len> PartialEq for Array<T, Len>
246where
247 T: PartialEq<T>,
248 Len: Copy + Into<usize> + TryFrom<usize>,
249{
250 #[inline]
251 fn eq(&self, other: &Self) -> bool {
252 self[..] == other[..]
253 }
254 #[inline]
255 fn ne(&self, other: &Self) -> bool {
256 self[..] != other[..]
257 }
258}
259
260impl<T, Len, U> PartialEq<[U]> for Array<T, Len>
261where
262 T: PartialEq<U>,
263 Len: Copy + Into<usize> + TryFrom<usize>,
264{
265 #[inline]
266 fn eq(&self, other: &[U]) -> bool {
267 self[..] == other[..]
268 }
269 #[inline]
270 fn ne(&self, other: &[U]) -> bool {
271 self[..] != other[..]
272 }
273}
274
275impl<T, Len, U, const N: usize> PartialEq<[U; N]> for Array<T, Len>
276where
277 T: PartialEq<U>,
278 Len: Copy + Into<usize> + TryFrom<usize>,
279{
280 #[inline]
281 fn eq(&self, other: &[U; N]) -> bool {
282 self[..] == other[..]
283 }
284 #[inline]
285 fn ne(&self, other: &[U; N]) -> bool {
286 self[..] != other[..]
287 }
288}
289
290impl<T, Len> Ord for Array<T, Len>
291where
292 T: Ord,
293 Len: Copy + Into<usize> + TryFrom<usize>,
294{
295 #[inline]
296 fn cmp(&self, other: &Self) -> Ordering {
297 Ord::cmp(&**self, &**other)
298 }
299}
300
301impl<T, Len> PartialOrd for Array<T, Len>
302where
303 T: Ord,
304 Len: Copy + Into<usize> + TryFrom<usize>,
305{
306 #[inline]
307 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
308 PartialOrd::partial_cmp(&**self, &**other)
309 }
310}
311
312impl<T, Len, I> Index<I> for Array<T, Len>
313where
314 Len: Copy + Into<usize> + TryFrom<usize>,
315 I: SliceIndex<[T]>,
316{
317 type Output = I::Output;
318
319 #[inline]
320 fn index(&self, index: I) -> &Self::Output {
321 Index::index(&**self, index)
322 }
323}
324
325impl<T, Len, I> IndexMut<I> for Array<T, Len>
326where
327 Len: Copy + Into<usize> + TryFrom<usize>,
328 I: SliceIndex<[T]>,
329{
330 fn index_mut(&mut self, index: I) -> &mut Self::Output {
331 IndexMut::index_mut(&mut **self, index)
332 }
333}
334
335#[cfg(feature = "default-derive")]
339impl<T: Default, Len: Copy + Into<usize> + TryFrom<usize>> Default for Array<T, Len>
340where
341 <Len as TryFrom<usize>>::Error: Debug,
342{
343 fn default() -> Self {
344 Self {
345 ptr: NonNull::dangling(),
346 len: 0.try_into().unwrap(),
347 }
348 }
349}
350
351#[cfg(test)]
352mod tests {
353 use super::Array;
354
355 #[cfg(feature = "packed")]
356 #[test]
357 fn packed() {
358 assert_eq!(std::mem::size_of::<Array<usize, u8>>(), 9);
359 }
360
361 #[cfg(not(feature = "packed"))]
362 #[test]
363 fn not_packed() {
364 assert_eq!(std::mem::size_of::<Array<usize, u8>>(), 16);
365 }
366
367 #[cfg(feature = "default-derive")]
368 #[test]
369 fn default() {
370 let arr = Array::<u8, u8>::default();
371 assert_eq!(arr.len(), 0);
372 }
373}