arc_buffer/
buf.rs

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}