1
2use alloc::boxed::Box;
3use alloc::vec::Vec;
4use core::cmp;
5use core::fmt;
6use core::iter::FromIterator;
7use core::mem::{self, MaybeUninit};
8use core::ops::{Deref, DerefMut};
9use core::ops::{Index, IndexMut};
10use core::ptr;
11use core::slice::SliceIndex;
12use core::sync::atomic::AtomicUsize;
13use core::sync::atomic::Ordering::*;
14use header_slice::HeaderVec;
15
16unsafe fn assume_init_drop<T>(un: &mut MaybeUninit<T>) {
17 ptr::drop_in_place(un.as_mut_ptr());
18}
19
20unsafe fn assume_init_ref<T>(un: &MaybeUninit<T>) -> &T {
21 &*(un as *const MaybeUninit<T> as *const T)
22}
23
24unsafe fn assume_init_mut<T>(un: &mut MaybeUninit<T>) -> &mut T {
25 &mut *(un as *mut MaybeUninit<T> as *mut T)
26}
27
28struct Header {
29 pub count: AtomicUsize,
30 #[cfg(test)]
31 pub drop_hook: Option<Box<dyn FnMut() + Send + 'static>>,
32}
33
34impl Default for Header {
35 fn default() -> Self {
36 Header {
37 count: AtomicUsize::new(1),
38 #[cfg(test)]
39 drop_hook: None,
40 }
41 }
42}
43#[cfg(test)]
44fn panic_hook() {
45 panic!("drop hook not registered");
46}
47
48#[cfg(test)]
49impl Drop for Header {
50 fn drop(&mut self) {
51 if let Some(ref mut hook) = self.drop_hook.take() {
52 hook()
53 }
54 }
55}
56
57pub struct ArcBuffer<T> {
58 inner: MaybeUninit<HeaderVec<Header, T>>,
59}
60
61impl<T> ArcBuffer<T> {
62 #[cfg(test)]
63 pub(crate) unsafe fn set_drop_hook<F: FnMut() + Send + 'static>(&mut self, hook: Option<F>) {
64 self.inner_mut().head.drop_hook = match hook {
65 Some(hook) => Some(Box::new(hook)),
66 None => None,
67 };
68 }
69 pub fn new() -> Self {
70 Self::from_inner(Default::default())
71 }
72
73 pub fn with_capacity(cap: usize) -> Self {
74 Self::from_inner(HeaderVec::with_capacity(Default::default(), cap))
75 }
76
77 fn from_inner(mut inner: HeaderVec<Header, T>) -> Self {
78 inner.head.count = AtomicUsize::new(1);
79
80 Self {
81 inner: MaybeUninit::new(inner),
82 }
83 }
84
85 fn inner(&self) -> &HeaderVec<Header, T> {
86 unsafe { assume_init_ref(&self.inner) }
87 }
88
89 unsafe fn inner_mut(&mut self) -> &mut HeaderVec<Header, T> {
90 assume_init_mut(&mut self.inner)
91 }
92
93 pub fn len(&self) -> usize {
94 self.inner().len()
95 }
96
97 pub unsafe fn copy_from_ptr_unsafe(src: *const T, len: usize) -> Self {
98 let mut uninit = ArcBuffer::new_uninit(len);
99 ptr::copy_nonoverlapping(
100 src as *const MaybeUninit<T>,
101 uninit.inner_mut().body.as_mut_ptr(),
102 len,
103 );
104 uninit.assume_init()
105 }
106}
107
108impl<T> ArcBuffer<MaybeUninit<T>> {
109 pub fn new_uninit(len: usize) -> Self {
110 Self::from_inner(HeaderVec::new_uninit_values(Default::default(), len))
111 }
112
113 pub unsafe fn assume_init(self) -> ArcBuffer<T> {
114 let new_inner = ptr::read(self.inner.as_ptr()).assume_init_values();
115 mem::forget(self);
116 ArcBuffer {
117 inner: MaybeUninit::new(new_inner),
118 }
119 }
120}
121
122impl<T: Copy> ArcBuffer<T> {
123 pub fn copy_from_slice(src: &[T]) -> Self {
124 Self {
125 inner: MaybeUninit::new(HeaderVec::copy_from_slice(Header::default(), src)),
126 }
127 }
128
129 pub fn copy_to_new(&self) -> Self {
130 Self::copy_from_slice(self)
131 }
132
133 pub fn filled(value: T, len: usize) -> Self {
134 unsafe {
135 let mut uninit = HeaderVec::new_uninit_values(Header::default(), len);
136
137 for x in &mut uninit.body {
138 *x = MaybeUninit::new(value);
139 }
140
141 Self {
142 inner: MaybeUninit::new(uninit.assume_init_values()),
143 }
144 }
145 }
146
147 fn inner_unique(&mut self) -> &mut HeaderVec<Header, T> {
148 if self.inner().head.count.load(Acquire) > 1 {
149 #[allow(unused_mut)]
150 let mut temp = self.copy_to_new();
151
152 #[cfg(test)]
153 if self.inner().head.drop_hook.is_some() {
154 unsafe {
155 temp.set_drop_hook(Some(panic_hook));
156 }
157 }
158
159 *self = temp;
160 }
161
162 unsafe { self.inner_mut() }
163 }
164
165 pub fn make_mut(&mut self) -> &mut [T] {
166 &mut self.inner_unique().body
167 }
168
169 pub fn extend_from_slice(&mut self, src: &[T]) {
170 self.inner_unique().extend_from_slice(src)
171 }
172
173 pub fn push(&mut self, value: T) {
174 self.inner_unique().push(value);
175 }
176
177 pub fn pop(&mut self) -> Option<T> {
178 self.inner_unique().pop()
179 }
180
181 pub fn insert(&mut self, index: usize, value: T) {
182 self.inner_unique().insert(index, value);
183 }
184
185 pub fn remove(&mut self, index: usize) -> Option<T> {
186 self.inner_unique().remove(index)
187 }
188
189 pub fn swap_remove(&mut self, index: usize) -> Option<T> {
190 self.inner_unique().swap_remove(index)
191 }
192}
193
194pub struct IntoIter<T> {
195 inner: ArcBuffer<T>,
196 index: usize,
197}
198
199impl<T: Copy> Iterator for IntoIter<T> {
200 type Item = T;
201 fn next(&mut self) -> Option<T> {
202 if self.index < self.inner.len() {
203 let index = self.index;
204 self.index += 1;
205 Some(self.inner[index])
206 } else {
207 None
208 }
209 }
210
211 fn size_hint(&self) -> (usize, Option<usize>) {
212 let size = self.inner.len() - self.index;
213 (size, Some(size))
214 }
215}
216
217impl<T: Copy> ExactSizeIterator for IntoIter<T> {}
218
219impl<T: Copy> IntoIterator for ArcBuffer<T> {
220 type Item = T;
221 type IntoIter = IntoIter<T>;
222 fn into_iter(self) -> Self::IntoIter {
223 IntoIter {
224 inner: self,
225 index: 0,
226 }
227 }
228}
229
230impl<'a, T> IntoIterator for &'a ArcBuffer<T> {
231 type Item = &'a T;
232 type IntoIter = core::slice::Iter<'a, T>;
233 fn into_iter(self) -> Self::IntoIter {
234 self.inner().body.iter()
235 }
236}
237
238impl<'a, T: Copy> IntoIterator for &'a mut ArcBuffer<T> {
239 type Item = &'a mut T;
240 type IntoIter = core::slice::IterMut<'a, T>;
241 fn into_iter(self) -> Self::IntoIter {
242 self.inner_unique().body.iter_mut()
243 }
244}
245
246impl<T> Clone for ArcBuffer<T> {
247 fn clone(&self) -> Self {
248 unsafe {
249 self.inner().head.count.fetch_add(1, Acquire);
250 let mut new = Self {
251 inner: MaybeUninit::uninit(),
252 };
253 ptr::copy(self.inner.as_ptr(), new.inner.as_mut_ptr(), 1);
254 new
255 }
256 }
257}
258
259impl<T> Drop for ArcBuffer<T> {
260 fn drop(&mut self) {
261 if self.inner().head.count.fetch_sub(1, Release) == 1 {
262 unsafe {
263 assume_init_drop(&mut self.inner);
264 }
265 }
266 }
267}
268
269impl<T, S: SliceIndex<[T]>> Index<S> for ArcBuffer<T> {
270 type Output = S::Output;
271 fn index(&self, i: S) -> &Self::Output {
272 self.inner().body.index(i)
273 }
274}
275
276impl<T: Copy, S: SliceIndex<[T]>> IndexMut<S> for ArcBuffer<T> {
277 fn index_mut(&mut self, i: S) -> &mut Self::Output {
278 self.inner_unique().body.index_mut(i)
279 }
280}
281
282impl<T> Deref for ArcBuffer<T> {
283 type Target = [T];
284 fn deref(&self) -> &[T] {
285 &self.inner().body
286 }
287}
288
289impl<T: Copy> DerefMut for ArcBuffer<T> {
290 fn deref_mut(&mut self) -> &mut [T] {
291 self.make_mut()
292 }
293}
294
295impl<T> FromIterator<T> for ArcBuffer<T> {
296 fn from_iter<I: IntoIterator<Item = T>>(it: I) -> Self {
297 Self::from_inner(it.into_iter().collect())
298 }
299}
300
301impl<T: Copy> Extend<T> for ArcBuffer<T> {
302 fn extend<I: IntoIterator<Item = T>>(&mut self, it: I) {
303 self.inner_unique().extend(it);
304 }
305}
306
307impl<T> From<Box<[T]>> for ArcBuffer<T> {
308 fn from(src: Box<[T]>) -> Self {
309 unsafe {
310 let new = Self::copy_from_ptr_unsafe(src.as_ptr(), src.len());
311 let box_ptr = Box::into_raw(src);
312 mem::drop(Box::from_raw(box_ptr as *mut [MaybeUninit<T>]));
313 new
314 }
315 }
316}
317
318impl<T> From<Vec<T>> for ArcBuffer<T> {
319 fn from(src: Vec<T>) -> Self {
320 src.into_boxed_slice().into()
321 }
322}
323
324impl<T> AsRef<[T]> for ArcBuffer<T> {
325 fn as_ref(&self) -> &[T] {
326 &*self
327 }
328}
329
330impl<T: Copy> AsMut<[T]> for ArcBuffer<T> {
331 fn as_mut(&mut self) -> &mut [T] {
332 &mut *self
333 }
334}
335
336impl<T, S: AsRef<[T]>> PartialEq<S> for ArcBuffer<T>
337where
338 [T]: PartialEq,
339{
340 fn eq(&self, rhs: &S) -> bool {
341 <[T] as PartialEq>::eq(self, rhs.as_ref())
342 }
343 fn ne(&self, rhs: &S) -> bool {
344 <[T] as PartialEq>::ne(self, rhs.as_ref())
345 }
346}
347
348impl<T> Eq for ArcBuffer<T> where [T]: Eq {}
349
350impl<T, S: AsRef<[T]>> PartialOrd<S> for ArcBuffer<T>
351where
352 [T]: PartialOrd,
353{
354 fn partial_cmp(&self, rhs: &S) -> Option<cmp::Ordering> {
355 <[T] as PartialOrd>::partial_cmp(self, rhs.as_ref())
356 }
357}
358
359impl<T> Ord for ArcBuffer<T>
360where
361 [T]: Ord,
362{
363 fn cmp(&self, rhs: &Self) -> cmp::Ordering {
364 <[T] as Ord>::cmp(self, rhs)
365 }
366}
367
368impl<T> fmt::Debug for ArcBuffer<T>
369where
370 [T]: fmt::Debug,
371{
372 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
373 <[T] as fmt::Debug>::fmt(self, f)
374 }
375}
376
377impl<T> fmt::Display for ArcBuffer<T>
378where
379 [T]: fmt::Display,
380{
381 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
382 <[T] as fmt::Display>::fmt(self, f)
383 }
384}
385
386unsafe impl<T> Send for ArcBuffer<T> {}
387unsafe impl<T> Sync for ArcBuffer<T> {}
388
389#[macro_export]
390macro_rules! arc_buf {
391 ($($val:expr),* $(,)?) => {{
392 let vals = [$($val),*];
393 #[allow(unused_unsafe)]
394 let v = unsafe {
395 $crate::buf::ArcBuffer::copy_from_ptr_unsafe(vals.as_ptr(), vals.len())
396 };
397 core::mem::forget(vals);
398 v
399 }};
400 ($val:expr; $len:expr) => {
401 core::iter::repeat($val).take($len).collect::<$crate::buf::ArcBuffer<_>>()
402 }
403}