style_traits/
owned_array.rs1#![allow(unsafe_code)]
6
7use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
10use std::marker::PhantomData;
11use std::ops::{Deref, DerefMut};
12use std::ptr::NonNull;
13use std::{fmt, mem};
14use to_shmem::{SharedMemoryBuilder, ToShmem};
15
16#[repr(C)]
48pub struct OwnedArray<T, const N: usize> {
49 ptr: NonNull<T>,
50 _phantom: PhantomData<T>,
51}
52
53impl<T, const N: usize> Drop for OwnedArray<T, N> {
54 #[inline]
55 fn drop(&mut self) {
56 unsafe {
57 drop(Box::from_raw(self.ptr.as_ptr() as *mut [T; N]));
58 }
59 }
60}
61
62unsafe impl<T: Send, const N: usize> Send for OwnedArray<T, N> {}
63unsafe impl<T: Sync, const N: usize> Sync for OwnedArray<T, N> {}
64
65impl<T: Clone, const N: usize> Clone for OwnedArray<T, N> {
66 #[inline]
67 fn clone(&self) -> Self {
68 std::array::from_fn(|i| self[i].clone()).into()
69 }
70}
71
72impl<T: fmt::Debug, const N: usize> fmt::Debug for OwnedArray<T, N> {
73 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
74 self.deref().fmt(formatter)
75 }
76}
77
78impl<T: PartialEq, const N: usize> PartialEq for OwnedArray<T, N> {
79 fn eq(&self, other: &Self) -> bool {
80 self.deref().eq(other.deref())
81 }
82}
83
84impl<T: Eq, const N: usize> Eq for OwnedArray<T, N> {}
85
86impl<T, const N: usize> OwnedArray<T, N> {
87 #[inline]
89 pub fn into_box(self) -> Box<[T; N]> {
90 let b = unsafe { Box::from_raw(self.ptr.as_ptr() as *mut [T; N]) };
91 mem::forget(self);
92 b
93 }
94
95 #[inline]
97 pub fn into_array(self) -> [T; N] {
98 *self.into_box()
99 }
100}
101
102impl<T, const N: usize> Deref for OwnedArray<T, N> {
103 type Target = [T; N];
104
105 #[inline(always)]
106 fn deref(&self) -> &Self::Target {
107 unsafe { &*(self.ptr.as_ptr() as *const [T; N]) }
108 }
109}
110
111impl<T, const N: usize> DerefMut for OwnedArray<T, N> {
112 #[inline(always)]
113 fn deref_mut(&mut self) -> &mut Self::Target {
114 unsafe { &mut *(self.ptr.as_ptr() as *mut [T; N]) }
115 }
116}
117
118impl<T, const N: usize> From<[T; N]> for OwnedArray<T, N> {
119 #[inline]
120 fn from(values: [T; N]) -> Self {
121 Box::new(values).into()
122 }
123}
124
125impl<T, const N: usize> From<Box<[T; N]>> for OwnedArray<T, N> {
126 #[inline]
127 fn from(b: Box<[T; N]>) -> Self {
128 let ptr = unsafe { NonNull::new_unchecked(Box::into_raw(b) as *mut T) };
129 Self {
130 ptr,
131 _phantom: PhantomData,
132 }
133 }
134}
135
136impl<T: Sized, const N: usize> MallocShallowSizeOf for OwnedArray<T, N> {
137 fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
138 unsafe { ops.malloc_size_of(self.ptr.as_ptr()) }
139 }
140}
141
142impl<T: MallocSizeOf + Sized, const N: usize> MallocSizeOf for OwnedArray<T, N> {
143 fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
144 self.shallow_size_of(ops) + (**self).size_of(ops)
145 }
146}
147
148impl<T: ToShmem + Sized, const N: usize> ToShmem for OwnedArray<T, N> {
149 fn to_shmem(&self, builder: &mut SharedMemoryBuilder) -> to_shmem::Result<Self> {
150 unsafe {
151 let dest = to_shmem::to_shmem_slice(self.iter(), builder)?;
152 Ok(mem::ManuallyDrop::new(Self::from(Box::from_raw(
153 dest as *mut [T; N],
154 ))))
155 }
156 }
157}