Skip to main content

any_container/
vec.rs

1//! [`AnyVec`] implementation and supplemental types.
2//!
3//! See the [`AnyVec`] documentation for more information.
4//!
5
6use std::any::{TypeId, type_name};
7use std::mem::ManuallyDrop;
8use std::ops::{Deref, DerefMut};
9use std::{fmt, mem, ptr, slice};
10
11struct RawVec {
12    ptr: *mut u8,
13    length: usize,
14    cap: usize,
15}
16
17impl RawVec {
18    fn new_dangling() -> Self {
19        Self {
20            ptr: ptr::dangling_mut(),
21            length: 0,
22            cap: 0,
23        }
24    }
25
26    /// Creates a new `RawVec` from a `Vec<T>`, consuming the vector and taking ownership of its memory.
27    fn from_vec<T>(vec: Vec<T>) -> Self {
28        let (ptr, length, cap) = vec.into_raw_parts();
29        Self {
30            ptr: ptr.cast(),
31            length,
32            cap,
33        }
34    }
35
36    /// Updates the `RawVec` to point to the memory of a `ManuallyDrop<Vec<T>>`.
37    ///
38    /// ### Safety
39    /// - [`T`] must be the same type that was used to create the `RawVec`.
40    /// - The caller must ensure that passed `vec` isn't dropped while the `RawVec` is still in use.
41    unsafe fn update_from<T>(&mut self, vec: &mut ManuallyDrop<Vec<T>>) {
42        self.ptr = vec.as_mut_ptr().cast();
43        self.length = vec.len();
44        self.cap = vec.capacity();
45    }
46
47    /// Returns a slice of the elements in the `RawVec`.
48    ///
49    /// ## Safety
50    /// [`T`] must be the same type that was used to create the `RawVec`. If the type is different,
51    /// this can lead to undefined behaviour.
52    unsafe fn as_slice<T>(&self) -> &[T] {
53        unsafe {
54            // Safety: The caller has ensured that the type `T` matches the type used to create the
55            // `RawVec`, and that the memory is valid for reads.
56            slice::from_raw_parts(self.ptr.cast(), self.length)
57        }
58    }
59
60    /// Converts the `RawVec` back into a `Vec<T>`, taking ownership of the memory and ensuring
61    /// proper deallocation.
62    ///
63    /// ## Safety
64    /// [`T`] must be the same type that was used to create the `RawVec`. If the type is different,
65    /// this can lead to undefined behaviour.
66    unsafe fn into_vec<T>(self) -> Vec<T> {
67        unsafe { Vec::from_raw_parts(self.ptr.cast(), self.length, self.cap) }
68    }
69
70    /// Converts the `RawVec` into a `ManuallyDrop<Vec<T>>`, allowing manage the vector's memory
71    /// without automatically dropping it.
72    ///
73    /// ## Safety
74    /// - [`T`] must be the same type that was used to create the `RawVec`.
75    /// - The caller must ensure that the returned value does not outlive the memory.
76    /// - The caller must ensure that multiple references to the same memory do not occur, as this
77    ///   can lead to undefined behaviour.
78    unsafe fn as_manually_drop_vec<T>(&self) -> ManuallyDrop<Vec<T>> {
79        unsafe { ManuallyDrop::new(Vec::from_raw_parts(self.ptr.cast(), self.length, self.cap)) }
80    }
81}
82
83/// Drops the `RawVec`, deallocating the memory it owns.
84///
85/// ## Safety
86/// The caller must ensure that the `RawVec` was created from a `Vec<T>`. If the type is different,
87/// this can lead to undefined behaviour.
88unsafe fn drop_raw_vec<T>(raw_vec: RawVec) {
89    let vec = unsafe { raw_vec.into_vec::<T>() };
90    drop(vec);
91}
92
93/// A type-erased vector that stores values of a single type.
94///
95/// `AnyVec` enables storing and retrieving vectors of any type that implements
96/// `Send + Sync` without knowing the type at compile time. It uses a function pointer
97/// for type-specific drop semantics and `TypeId` for runtime type verification.
98///
99/// # Type Erasure Pattern
100///
101/// Values are stored behind a trait object and retrieved via type-safe downcasting.
102/// The `get::<T>()` method verifies the type at runtime before returning a slice reference.
103///
104/// # Smart Pointer Types
105///
106/// The module provides two smart pointer types for vector access:
107/// - [`AnyVecRef`] - Immutable reference to a `Vec<T>`
108/// - [`AnyVecMutRef`] - Mutable reference to a `Vec<T>`
109///
110/// # Examples
111///
112/// ```
113/// use any_container::AnyVec;
114///
115/// let mut vec = AnyVec::new::<i32>();
116/// assert!(vec.is_empty());
117///
118/// vec.get_mut::<i32>().unwrap().push(42);
119/// assert_eq!(vec.len(), 1);
120///
121/// assert_eq!(vec.get::<i32>().unwrap(), &[42]);
122/// assert!(vec.get::<f64>().is_none()); // Type mismatch returns None
123/// ```
124pub struct AnyVec {
125    raw_vec: RawVec,
126    type_id: TypeId,
127    type_name: &'static str,
128    drop: unsafe fn(RawVec),
129}
130
131// Safety: AnyVec can only be created by Send + Sync types.
132unsafe impl Send for AnyVec {}
133unsafe impl Sync for AnyVec {}
134
135impl AnyVec {
136    /// Creates a new empty `AnyVec` for elements of type `T`.
137    pub fn new<T: 'static + Send + Sync>() -> Self {
138        Self::from_vec(Vec::<T>::new())
139    }
140
141    /// Creates a new `AnyVec` with the specified capacity for elements of type `T`.
142    pub fn new_with_capacity<T: 'static + Send + Sync>(capacity: usize) -> Self {
143        Self::from_vec(Vec::<T>::with_capacity(capacity))
144    }
145
146    /// Creates a new `AnyVec` from a `Vec<T>`, consuming the vector and taking ownership of its memory.
147    pub fn from_vec<T: 'static + Send + Sync>(vec: Vec<T>) -> Self {
148        Self {
149            raw_vec: RawVec::from_vec(vec),
150            type_id: TypeId::of::<T>(),
151            type_name: type_name::<T>(),
152            drop: drop_raw_vec::<T>,
153        }
154    }
155
156    /// Returns the type id of the elements stored in the `AnyVec`.
157    pub fn elem_type_id(&self) -> TypeId {
158        self.type_id
159    }
160
161    /// Returns the type name of the elements stored in the `AnyVec`.
162    pub fn type_name(&self) -> &'static str {
163        self.type_name
164    }
165
166    /// Returns a reference to the elements in the `AnyVec` as a slice of type `T`.
167    /// Returns `None` if the stored type doesn't match `T`.
168    pub fn get<T: 'static>(&self) -> Option<&[T]> {
169        if self.type_id == TypeId::of::<T>() {
170            unsafe {
171                // Safety: We just checked that the type `T` matches the type of the elements
172                // stored in the `AnyVec`, so it is safe to call `get_unchecked`.
173                Some(self.get_unchecked::<T>())
174            }
175        } else {
176            None
177        }
178    }
179
180    /// Returns a reference to the elements in the `AnyVec` as a slice of type `T`.
181    ///
182    /// ## Safety
183    /// The caller must ensure that the type `T` matches the type of the elements stored in the
184    /// `AnyVec`. If the type is different, this can lead to undefined behaviour.
185    pub unsafe fn get_unchecked<T: 'static>(&self) -> &[T] {
186        unsafe { self.raw_vec.as_slice::<T>() }
187    }
188
189    /// Returns a smart pointer, dereferencing to a `Vec<T>`, allowing access to the elements in
190    /// the `AnyVec` as a vector of type `T`.
191    ///
192    /// ## Note
193    /// In most cases, you want [`AnyVec::get`] or [`AnyVec::get_mut`] instead.
194    pub fn get_ref<T: 'static>(&self) -> Option<AnyVecRef<'_, T>> {
195        if self.type_id == TypeId::of::<T>() {
196            unsafe {
197                // Safety: We just checked that the type `T` matches the type of the elements
198                // stored in the `AnyVec`, so it is safe to call `get_unchecked`.
199                Some(AnyVecRef::new(self))
200            }
201        } else {
202            None
203        }
204    }
205
206    /// Returns a smart pointer, dereferencing to a `Vec<T>`, allowing access to the elements in
207    /// the `AnyVec` as a vector of type `T`.
208    ///
209    /// ## Note
210    /// In most cases, you want [`AnyVec::get_unchecked`] or [`AnyVec::get_mut_unchecked`] instead.
211    ///
212    /// ## Safety
213    /// The caller must ensure that the type `T` matches the type of the elements stored in the
214    /// `AnyVec`. If the type is different, this can lead to undefined behaviour.
215    pub unsafe fn get_ref_unchecked<T: 'static>(&self) -> AnyVecRef<'_, T> {
216        unsafe { AnyVecRef::new(self) }
217    }
218
219    /// Returns a smart pointer, dereferencing to a mutable `Vec<T>`, allowing access to the elements in
220    /// the `AnyVec` as a mutable vector of type `T`.
221    pub fn get_mut<T: 'static>(&mut self) -> Option<AnyVecMutRef<'_, T>> {
222        if self.type_id == TypeId::of::<T>() {
223            unsafe {
224                // Safety: We just checked that the type `T` matches the type of the elements
225                // stored in the `AnyVec`, so it is safe to call `get_unchecked`.
226                Some(AnyVecMutRef::new(self))
227            }
228        } else {
229            None
230        }
231    }
232
233    /// Returns a smart pointer, dereferencing to a mutable `Vec<T>`, allowing access to the elements in
234    /// the `AnyVec` as a mutable vector of type `T`.
235    ///
236    /// ## Safety
237    /// The caller must ensure that the type `T` matches the type of the elements stored in the
238    /// `AnyVec`. If the type is different, this can lead to undefined behaviour.
239    pub unsafe fn get_mut_unchecked<T: 'static>(&mut self) -> AnyVecMutRef<'_, T> {
240        unsafe { AnyVecMutRef::new(self) }
241    }
242
243    /// Returns the number of elements in the `AnyVec`.
244    pub fn len(&self) -> usize {
245        self.raw_vec.length
246    }
247
248    /// Returns true if the `AnyVec` contains no elements.
249    pub fn is_empty(&self) -> bool {
250        self.raw_vec.length == 0
251    }
252
253    /// Consumes the `AnyVec` and returns the elements as a `Vec<T>`.
254    pub fn try_into_vec<T: 'static>(self) -> Result<Vec<T>, Self> {
255        if self.type_id == TypeId::of::<T>() {
256            Ok(unsafe { self.into_vec_unchecked::<T>() })
257        } else {
258            Err(self)
259        }
260    }
261
262    /// Consumes the `AnyVec` and returns the elements as a `Vec<T>`.
263    ///
264    /// ## Safety
265    /// The caller must ensure that the type `T` matches the type of the elements stored in the
266    /// `AnyVec`. If the type is different, this can lead to undefined behaviour.
267    pub unsafe fn into_vec_unchecked<T: 'static>(mut self) -> Vec<T> {
268        let raw_vec = mem::replace(&mut self.raw_vec, RawVec::new_dangling());
269        mem::forget(self); // No need to drop self, as we are taking ownership of the raw_vec
270        unsafe {
271            // Safety: The caller has ensured that the type `T` matches the type of the elements
272            // stored in the `AnyVec`, so it is safe to call `into_vec`.
273            raw_vec.into_vec::<T>()
274        }
275    }
276}
277
278impl fmt::Debug for AnyVec {
279    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
280        f.debug_struct("AnyVec")
281            .field("type", &self.type_name)
282            .field("length", &self.raw_vec.length)
283            .finish()
284    }
285}
286
287impl Drop for AnyVec {
288    fn drop(&mut self) {
289        let inner = mem::replace(&mut self.raw_vec, RawVec::new_dangling());
290        unsafe {
291            // Safety: The drop function was created with the correct type when the AnyVec was
292            // created, so it is safe to call it here.
293            (self.drop)(inner);
294        }
295    }
296}
297
298/// A smart pointer that dereferences to a `Vec<T>`.
299///
300/// `AnyVecRef` is created from an `AnyVec` and provides vector-like access to
301/// the underlying values. It is returned by methods like `AnyVec::get_ref`.
302pub struct AnyVecRef<'a, T> {
303    raw: &'a AnyVec,
304    vec: ManuallyDrop<Vec<T>>,
305}
306
307/// A smart pointer that dereferences to a mutable `Vec<T>`.
308///
309/// `AnyVecMutRef` is created from a mutable `AnyVec` and provides vector-like access
310/// to the underlying values. It is returned by methods like `AnyVec::get_mut`.
311/// Upon drop, it updates the original `AnyVec` with any modifications.
312pub struct AnyVecMutRef<'a, T> {
313    raw: &'a mut AnyVec,
314    vec: ManuallyDrop<Vec<T>>,
315}
316
317unsafe impl<'a, T: Send> Send for AnyVecRef<'a, T> {}
318unsafe impl<'a, T: Sync> Sync for AnyVecRef<'a, T> {}
319unsafe impl<'a, T: Send> Send for AnyVecMutRef<'a, T> {}
320unsafe impl<'a, T: Sync> Sync for AnyVecMutRef<'a, T> {}
321
322impl<'a, T> AnyVecRef<'a, T> {
323    /// Creates a new `AnyVecRef` from an `AnyVec`.
324    ///
325    /// ## Safety
326    /// The caller must ensure that the `AnyVec` contains values of type `T`.
327    unsafe fn new(raw: &'a AnyVec) -> Self {
328        let vec = unsafe { raw.raw_vec.as_manually_drop_vec::<T>() };
329        Self { raw, vec }
330    }
331}
332
333impl<'a, T> AnyVecMutRef<'a, T> {
334    /// Creates a new `AnyVecMutRef` from a mutable `AnyVec`.
335    ///
336    /// ## Safety
337    /// The caller must ensure that the `AnyVec` contains values of type `T`.
338    unsafe fn new(raw: &'a mut AnyVec) -> Self {
339        let vec = unsafe { raw.raw_vec.as_manually_drop_vec::<T>() };
340        Self { raw, vec }
341    }
342}
343
344impl<'a, T> Clone for AnyVecRef<'a, T> {
345    fn clone(&self) -> Self {
346        unsafe {
347            // Safety: AnyVecRef is only created from a reference to AnyVec, and the caller
348            // has already ensured upon creation that the types match.
349            Self::new(self.raw)
350        }
351    }
352}
353
354impl<'a, T> Deref for AnyVecRef<'a, T> {
355    type Target = Vec<T>;
356
357    fn deref(&self) -> &Self::Target {
358        &self.vec
359    }
360}
361
362impl<'a, T> Deref for AnyVecMutRef<'a, T> {
363    type Target = Vec<T>;
364
365    fn deref(&self) -> &Self::Target {
366        &self.vec
367    }
368}
369
370impl<'a, T> DerefMut for AnyVecMutRef<'a, T> {
371    fn deref_mut(&mut self) -> &mut Self::Target {
372        &mut self.vec
373    }
374}
375
376impl<'a, T: fmt::Debug> fmt::Debug for AnyVecRef<'a, T> {
377    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378        self.vec.fmt(f)
379    }
380}
381
382impl<'a, T: fmt::Debug> fmt::Debug for AnyVecMutRef<'a, T> {
383    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
384        self.vec.fmt(f)
385    }
386}
387
388impl<'a, T> Drop for AnyVecMutRef<'a, T> {
389    fn drop(&mut self) {
390        unsafe {
391            // Safety: AnyVecMutRef is only created from a mutable reference to AnyVec, and the caller
392            // has already ensured upon creation that the types match.
393            self.raw.raw_vec.update_from(&mut self.vec);
394        }
395    }
396}