shared_vec/
vec.rs

1use crate::counter::Counter;
2use crate::inner::Inner;
3use alloc::boxed::Box;
4use core::marker::PhantomData;
5use core::ops::{Deref, RangeBounds};
6use core::ptr::NonNull;
7use core::{fmt, ptr};
8
9/// An immutable reference-counted vector type.
10///
11/// You can borrow slices of the vector without using a life-time-bound reference,
12/// and clone the vector to create new references to the same data.
13///
14/// You can use [`crate::RcVec`] or [`crate::ArcVec`] as type aliases for common counter types.
15pub struct Vec<C: Counter<usize>, T> {
16    inner: Inner<C, [T]>,
17    ptr: NonNull<[T]>,
18    phantom: PhantomData<Inner<C, [T]>>,
19}
20
21unsafe impl<C: Counter<usize>, T> Send for Vec<C, T>
22where
23    C: Send + Sync,
24    T: Send + Sync,
25{
26}
27unsafe impl<C: Counter<usize>, T> Sync for Vec<C, T>
28where
29    C: Send + Sync,
30    T: Send + Sync,
31{
32}
33
34impl<C: Counter<usize>, T> Vec<C, T> {
35    #[inline]
36    unsafe fn from_inner(inner: Inner<C, [T]>) -> Self {
37        Self {
38            ptr: inner.data,
39            inner,
40            phantom: PhantomData,
41        }
42    }
43
44    /// Create a `Vec` from a `Box<[T]>`.
45    #[inline]
46    pub fn from_boxed_slice(data: Box<[T]>) -> Self {
47        let x: Inner<C, [T]> = Inner {
48            ref_count: Box::leak(Box::new(C::one())).into(),
49            data: Box::leak(data).into(),
50        };
51        unsafe { Self::from_inner(x) }
52    }
53
54    /// Create a new empty `Vec`.
55    #[inline]
56    pub fn new() -> Self {
57        let x: Inner<C, [T]> = Inner {
58            ref_count: Box::leak(Box::new(C::one())).into(),
59            data: Box::leak(Box::<[T; 0]>::new([]) as Box<[T]>).into(),
60        };
61        unsafe { Self::from_inner(x) }
62    }
63}
64
65impl<C: Counter<usize>, T> Clone for Vec<C, T> {
66    /// Clones the `Vec`, creating a new reference to the same data.
67    #[inline]
68    fn clone(&self) -> Self {
69        unsafe {
70            let ref_count = self.inner.ref_count.as_ref();
71            ref_count.increment();
72        }
73        Self {
74            inner: self.inner,
75            ptr: self.ptr,
76            phantom: PhantomData,
77        }
78    }
79}
80
81impl<C: Counter<usize>, T> Drop for Vec<C, T> {
82    #[inline]
83    fn drop(&mut self) {
84        unsafe {
85            let ref_count = self.inner.ref_count.as_ref();
86            if ref_count.decrement() {
87                C::fence_acquire();
88                let ref_count = Box::from_raw(self.inner.ref_count.as_ptr());
89                let data = Box::from_raw(self.inner.data.as_ptr());
90                drop(ref_count);
91                drop(data);
92            }
93        }
94    }
95}
96
97impl<C: Counter<usize>, T> Default for Vec<C, T> {
98    fn default() -> Self {
99        Self::new()
100    }
101}
102
103impl<C: Counter<usize>, T> Deref for Vec<C, T> {
104    type Target = [T];
105
106    #[inline]
107    fn deref(&self) -> &Self::Target {
108        unsafe { self.ptr.as_ref() }
109    }
110}
111
112impl<C: Counter<usize>, T> fmt::Debug for Vec<C, T>
113where
114    T: fmt::Debug,
115{
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        <[T] as fmt::Debug>::fmt(&**self, f)
118    }
119}
120
121impl<C: Counter<usize>, T> Vec<C, T> {
122    /// Returns the length of the vector.
123    #[inline]
124    pub const fn len(&self) -> usize {
125        unsafe { self.ptr.as_ref() }.len()
126    }
127
128    /// Returns true if the vector is empty.
129    #[inline]
130    pub const fn is_empty(&self) -> bool {
131        self.len() == 0
132    }
133
134    /// Returns a slice of the vector.
135    #[inline]
136    pub fn as_slice(&self) -> &[T] {
137        self
138    }
139
140    /// Returns the original slice.
141    #[inline]
142    pub fn as_original_slice(&self) -> &[T] {
143        unsafe { self.inner.data.as_ref() }
144    }
145
146    /// Return the start and length of the range without checking.
147    #[inline]
148    pub(crate) fn convert_range_unchecked(&self, range: impl RangeBounds<usize>) -> (usize, usize) {
149        let start = match range.start_bound() {
150            core::ops::Bound::Included(&s) => s,
151            core::ops::Bound::Excluded(&s) => s + 1,
152            core::ops::Bound::Unbounded => 0,
153        };
154        let end = match range.end_bound() {
155            core::ops::Bound::Included(&e) => e + 1,
156            core::ops::Bound::Excluded(&e) => e,
157            core::ops::Bound::Unbounded => self.len(),
158        };
159        (start, end - start)
160    }
161
162    /// Validate the range and return the start and length.
163    #[inline]
164    pub(crate) fn validate_range(&self, range: impl RangeBounds<usize>) -> Option<(usize, usize)> {
165        let cap = self.len();
166        let start = match range.start_bound() {
167            core::ops::Bound::Included(&s) => s,
168            core::ops::Bound::Excluded(&s) => s.checked_add(1)?,
169            core::ops::Bound::Unbounded => 0,
170        };
171        let end = match range.end_bound() {
172            core::ops::Bound::Included(&e) => e.checked_add(1)?,
173            core::ops::Bound::Excluded(&e) => e,
174            core::ops::Bound::Unbounded => cap,
175        };
176        if end > cap {
177            return None;
178        }
179        (end.checked_sub(start)).map(|len| (start, len))
180    }
181
182    /// Check if the range is valid.
183    #[inline]
184    pub fn is_valid_range(&self, range: impl RangeBounds<usize>) -> bool {
185        self.validate_range(range).is_some()
186    }
187
188    pub(crate) unsafe fn slice(&self, start: usize, len: usize) -> Self {
189        let ptr: *mut T = self.ptr.as_ptr() as *mut T;
190        let ptr = unsafe { ptr.add(start) };
191        let ptr = ptr::slice_from_raw_parts_mut(ptr, len);
192        let ptr = unsafe { NonNull::new_unchecked(ptr) };
193
194        self.inner.ref_count.as_ref().increment();
195        Self {
196            inner: self.inner,
197            ptr,
198            phantom: PhantomData,
199        }
200    }
201
202    /// Get a sub-slice of the vector.
203    #[inline]
204    pub fn get(&self, range: impl RangeBounds<usize>) -> Option<Self> {
205        let (start, len) = self.validate_range(range)?;
206        Some(unsafe { self.slice(start, len) })
207    }
208
209    /// Get a sub-slice of the vector.
210    ///
211    /// # Panics
212    ///
213    /// Panics if the range is invalid.
214    #[inline]
215    pub fn idx(&self, range: impl RangeBounds<usize>) -> Self {
216        self.get(range).expect("Invalid range")
217    }
218
219    /// Get a sub-slice of the vector without checking the range.
220    ///
221    /// # Safety
222    ///
223    /// The caller must ensure that the range is valid.
224    #[inline]
225    pub unsafe fn get_unchecked(&self, range: impl RangeBounds<usize>) -> Self {
226        let (start, len) = self.convert_range_unchecked(range);
227        self.slice(start, len)
228    }
229}