shape_value/
aligned_vec.rs1use std::alloc::{Layout, alloc, dealloc, realloc};
7use std::marker::PhantomData;
8use std::mem;
9use std::ops::{Deref, DerefMut};
10use std::ptr::{self, NonNull};
11use std::slice;
12
13const SIMD_ALIGNMENT: usize = 32;
15
16#[derive(Debug)]
18pub struct AlignedVec<T> {
19 ptr: NonNull<T>,
20 len: usize,
21 capacity: usize,
22 _phantom: PhantomData<T>,
23}
24
25impl<T> AlignedVec<T> {
26 pub fn new() -> Self {
28 AlignedVec {
29 ptr: NonNull::dangling(),
30 len: 0,
31 capacity: 0,
32 _phantom: PhantomData,
33 }
34 }
35
36 pub fn with_capacity(capacity: usize) -> Self {
38 if capacity == 0 {
39 return Self::new();
40 }
41
42 let layout = Self::layout_for_capacity(capacity).expect("Failed to create layout");
43
44 let ptr = unsafe {
45 let raw_ptr = alloc(layout);
46 if raw_ptr.is_null() {
47 std::alloc::handle_alloc_error(layout);
48 }
49 NonNull::new_unchecked(raw_ptr as *mut T)
50 };
51
52 AlignedVec {
53 ptr,
54 len: 0,
55 capacity,
56 _phantom: PhantomData,
57 }
58 }
59
60 pub fn len(&self) -> usize {
62 self.len
63 }
64
65 pub fn is_empty(&self) -> bool {
67 self.len == 0
68 }
69
70 pub fn capacity(&self) -> usize {
72 self.capacity
73 }
74
75 pub fn push(&mut self, value: T) {
77 if self.len == self.capacity {
78 self.grow();
79 }
80
81 unsafe {
82 let end = self.ptr.as_ptr().add(self.len);
83 ptr::write(end, value);
84 self.len += 1;
85 }
86 }
87
88 pub fn pop(&mut self) -> Option<T> {
90 if self.len == 0 {
91 None
92 } else {
93 unsafe {
94 self.len -= 1;
95 Some(ptr::read(self.ptr.as_ptr().add(self.len)))
96 }
97 }
98 }
99
100 pub fn get(&self, index: usize) -> Option<&T> {
102 if index < self.len {
103 unsafe { Some(&*self.ptr.as_ptr().add(index)) }
104 } else {
105 None
106 }
107 }
108
109 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
111 if index < self.len {
112 unsafe { Some(&mut *self.ptr.as_ptr().add(index)) }
113 } else {
114 None
115 }
116 }
117
118 pub fn clear(&mut self) {
120 unsafe {
121 for i in 0..self.len {
123 ptr::drop_in_place(self.ptr.as_ptr().add(i));
124 }
125 }
126 self.len = 0;
127 }
128
129 pub fn as_slice(&self) -> &[T] {
131 unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
132 }
133
134 pub fn as_mut_slice(&mut self) -> &mut [T] {
136 unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
137 }
138
139 fn layout_for_capacity(capacity: usize) -> Option<Layout> {
141 let size = capacity.checked_mul(mem::size_of::<T>())?;
142
143 let size = size.max(1);
145 Layout::from_size_align(size, SIMD_ALIGNMENT).ok()
146 }
147
148 fn grow(&mut self) {
150 let new_capacity = if self.capacity == 0 {
151 4
152 } else {
153 self.capacity.saturating_mul(2)
154 };
155
156 self.resize_to_capacity(new_capacity);
157 }
158
159 fn resize_to_capacity(&mut self, new_capacity: usize) {
161 if new_capacity <= self.capacity {
162 return;
163 }
164
165 let new_layout = Self::layout_for_capacity(new_capacity).expect("Failed to create layout");
166
167 let new_ptr = if self.capacity == 0 {
168 unsafe {
169 let raw_ptr = alloc(new_layout);
170 if raw_ptr.is_null() {
171 std::alloc::handle_alloc_error(new_layout);
172 }
173 NonNull::new_unchecked(raw_ptr as *mut T)
174 }
175 } else {
176 let old_layout =
177 Self::layout_for_capacity(self.capacity).expect("Failed to create old layout");
178
179 unsafe {
180 let raw_ptr = realloc(self.ptr.as_ptr() as *mut u8, old_layout, new_layout.size());
181 if raw_ptr.is_null() {
182 std::alloc::handle_alloc_error(new_layout);
183 }
184 NonNull::new_unchecked(raw_ptr as *mut T)
185 }
186 };
187
188 self.ptr = new_ptr;
189 self.capacity = new_capacity;
190 }
191
192 pub fn from_vec(mut vec: Vec<T>) -> Self {
194 let len = vec.len();
195 let capacity = vec.capacity();
196
197 if len == 0 {
198 return Self::new();
199 }
200
201 let mut aligned = Self::with_capacity(capacity);
202
203 unsafe {
204 ptr::copy_nonoverlapping(vec.as_ptr(), aligned.ptr.as_ptr(), len);
206 aligned.len = len;
207
208 vec.set_len(0);
210 }
211
212 aligned
213 }
214
215 pub fn into_vec(mut self) -> Vec<T> {
217 let mut vec = Vec::with_capacity(self.len);
218
219 unsafe {
220 ptr::copy_nonoverlapping(self.ptr.as_ptr(), vec.as_mut_ptr(), self.len);
222 vec.set_len(self.len);
223
224 self.len = 0;
226 }
227
228 vec
229 }
230}
231
232impl<T> Drop for AlignedVec<T> {
233 fn drop(&mut self) {
234 if self.capacity != 0 {
235 unsafe {
236 for i in 0..self.len {
238 ptr::drop_in_place(self.ptr.as_ptr().add(i));
239 }
240
241 let layout =
243 Self::layout_for_capacity(self.capacity).expect("Failed to create layout");
244 dealloc(self.ptr.as_ptr() as *mut u8, layout);
245 }
246 }
247 }
248}
249
250impl<T> Deref for AlignedVec<T> {
251 type Target = [T];
252
253 fn deref(&self) -> &Self::Target {
254 self.as_slice()
255 }
256}
257
258impl<T> DerefMut for AlignedVec<T> {
259 fn deref_mut(&mut self) -> &mut Self::Target {
260 self.as_mut_slice()
261 }
262}
263
264impl<T: Clone> Clone for AlignedVec<T> {
265 fn clone(&self) -> Self {
266 let mut cloned = Self::with_capacity(self.capacity);
267
268 for item in self.as_slice() {
269 cloned.push(item.clone());
270 }
271
272 cloned
273 }
274}
275
276impl<T> Default for AlignedVec<T> {
277 fn default() -> Self {
278 Self::new()
279 }
280}
281
282unsafe impl<T: Send> Send for AlignedVec<T> {}
284unsafe impl<T: Sync> Sync for AlignedVec<T> {}