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<T>() -> Self {
19        Self {
20            ptr: ptr::dangling_mut::<T>().cast(),
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    ///
222    /// ## Note
223    /// If the smart pointer type is leaked, any values stored in the `AnyVec` will be leaked as
224    /// well and new calls will return an empty vector.
225    ///
226    /// To ensure that no values are lost, ensure that the destructor of the smart pointer can run.
227    pub fn get_mut<T: 'static>(&mut self) -> Option<AnyVecMutRef<'_, T>> {
228        if self.type_id == TypeId::of::<T>() {
229            unsafe {
230                // Safety: We just checked that the type `T` matches the type of the elements
231                // stored in the `AnyVec`, so it is safe to call `get_unchecked`.
232                Some(AnyVecMutRef::new(self))
233            }
234        } else {
235            None
236        }
237    }
238
239    /// Returns a smart pointer, dereferencing to a mutable `Vec<T>`, allowing access to the elements in
240    /// the `AnyVec` as a mutable vector of type `T`.
241    ///
242    /// ## Safety
243    /// The caller must ensure that the type `T` matches the type of the elements stored in the
244    /// `AnyVec`. If the type is different, this can lead to undefined behaviour.
245    ///
246    /// ## Note
247    /// If the smart pointer type is leaked, any values stored in the `AnyVec` will be leaked as
248    /// well and new calls will return an empty vector.
249    ///
250    /// To ensure that no values are lost, ensure that the destructor of the smart pointer can run.
251    pub unsafe fn get_mut_unchecked<T: 'static>(&mut self) -> AnyVecMutRef<'_, T> {
252        unsafe { AnyVecMutRef::new(self) }
253    }
254
255    /// Returns the number of elements in the `AnyVec`.
256    pub fn len(&self) -> usize {
257        self.raw_vec.length
258    }
259
260    /// Returns true if the `AnyVec` contains no elements.
261    pub fn is_empty(&self) -> bool {
262        self.raw_vec.length == 0
263    }
264
265    /// Consumes the `AnyVec` and returns the elements as a `Vec<T>`.
266    pub fn try_into_vec<T: 'static>(self) -> Result<Vec<T>, Self> {
267        if self.type_id == TypeId::of::<T>() {
268            Ok(unsafe { self.into_vec_unchecked::<T>() })
269        } else {
270            Err(self)
271        }
272    }
273
274    /// Consumes the `AnyVec` and returns the elements as a `Vec<T>`.
275    ///
276    /// ## Safety
277    /// The caller must ensure that the type `T` matches the type of the elements stored in the
278    /// `AnyVec`. If the type is different, this can lead to undefined behaviour.
279    pub unsafe fn into_vec_unchecked<T: 'static>(mut self) -> Vec<T> {
280        let raw_vec = mem::replace(&mut self.raw_vec, RawVec::new_dangling::<T>());
281        mem::forget(self); // No need to drop self, as we are taking ownership of the raw_vec
282        unsafe {
283            // Safety: The caller has ensured that the type `T` matches the type of the elements
284            // stored in the `AnyVec`, so it is safe to call `into_vec`.
285            raw_vec.into_vec::<T>()
286        }
287    }
288}
289
290impl fmt::Debug for AnyVec {
291    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
292        f.debug_struct("AnyVec")
293            .field("type", &self.type_name)
294            .field("length", &self.raw_vec.length)
295            .finish()
296    }
297}
298
299impl Drop for AnyVec {
300    fn drop(&mut self) {
301        let inner = mem::replace(&mut self.raw_vec, RawVec::new_dangling::<u8>());
302        unsafe {
303            // Safety: The drop function was created with the correct type when the AnyVec was
304            // created, so it is safe to call it here.
305            (self.drop)(inner);
306        }
307    }
308}
309
310/// A smart pointer that dereferences to a `Vec<T>`.
311///
312/// `AnyVecRef` is created from an `AnyVec` and provides vector-like access to
313/// the underlying values. It is returned by methods like `AnyVec::get_ref`.
314pub struct AnyVecRef<'a, T> {
315    raw: &'a AnyVec,
316    vec: ManuallyDrop<Vec<T>>,
317}
318
319/// A smart pointer that dereferences to a mutable `Vec<T>`.
320///
321/// `AnyVecMutRef` is created from a mutable `AnyVec` and provides vector-like access
322/// to the underlying values. It is returned by methods like `AnyVec::get_mut`.
323/// Upon drop, it updates the original `AnyVec` with any modifications.
324pub struct AnyVecMutRef<'a, T> {
325    raw: &'a mut AnyVec,
326    vec: ManuallyDrop<Vec<T>>,
327}
328
329unsafe impl<'a, T: Send> Send for AnyVecRef<'a, T> {}
330unsafe impl<'a, T: Sync> Sync for AnyVecRef<'a, T> {}
331unsafe impl<'a, T: Send> Send for AnyVecMutRef<'a, T> {}
332unsafe impl<'a, T: Sync> Sync for AnyVecMutRef<'a, T> {}
333
334impl<'a, T> AnyVecRef<'a, T> {
335    /// Creates a new `AnyVecRef` from an `AnyVec`.
336    ///
337    /// ## Safety
338    /// The caller must ensure that the `AnyVec` contains values of type `T`.
339    unsafe fn new(raw: &'a AnyVec) -> Self {
340        let vec = unsafe { raw.raw_vec.as_manually_drop_vec::<T>() };
341        Self { raw, vec }
342    }
343}
344
345impl<'a, T> AnyVecMutRef<'a, T> {
346    /// Creates a new `AnyVecMutRef` from a mutable `AnyVec`.
347    ///
348    /// ## Safety
349    /// The caller must ensure that the `AnyVec` contains values of type `T`.
350    unsafe fn new(raw: &'a mut AnyVec) -> Self {
351        let vec = unsafe { raw.raw_vec.as_manually_drop_vec::<T>() };
352
353        // If AnyVecMutRef is leaked, it will not update the inner raw vec with the changes.
354        // This could lead to the inner raw vec having an invalid pointer if Vec is reallocated,
355        // but the new pointer, length, and capacity are not written back.
356        // To prevent this, we replace the inner raw vec with a dangling pointer, for a zero-sized
357        // vector.
358        // This ensures that even if AnyVecMutRef is leaked, the next time AnyVec is accessed, it
359        // will just see an empty vector, instead of a pointer to potentially freed memory.
360        raw.raw_vec = RawVec::new_dangling::<T>();
361
362        Self { raw, vec }
363    }
364}
365
366impl<'a, T> Clone for AnyVecRef<'a, T> {
367    fn clone(&self) -> Self {
368        unsafe {
369            // Safety: AnyVecRef is only created from a reference to AnyVec, and the caller
370            // has already ensured upon creation that the types match.
371            Self::new(self.raw)
372        }
373    }
374}
375
376impl<'a, T> Deref for AnyVecRef<'a, T> {
377    type Target = Vec<T>;
378
379    fn deref(&self) -> &Self::Target {
380        &self.vec
381    }
382}
383
384impl<'a, T> Deref for AnyVecMutRef<'a, T> {
385    type Target = Vec<T>;
386
387    fn deref(&self) -> &Self::Target {
388        &self.vec
389    }
390}
391
392impl<'a, T> DerefMut for AnyVecMutRef<'a, T> {
393    fn deref_mut(&mut self) -> &mut Self::Target {
394        &mut self.vec
395    }
396}
397
398impl<'a, T: fmt::Debug> fmt::Debug for AnyVecRef<'a, T> {
399    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400        self.vec.fmt(f)
401    }
402}
403
404impl<'a, T: fmt::Debug> fmt::Debug for AnyVecMutRef<'a, T> {
405    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
406        self.vec.fmt(f)
407    }
408}
409
410impl<'a, T> Drop for AnyVecMutRef<'a, T> {
411    fn drop(&mut self) {
412        unsafe {
413            // Safety: AnyVecMutRef is only created from a mutable reference to AnyVec, and the caller
414            // has already ensured upon creation that the types match.
415            self.raw.raw_vec.update_from(&mut self.vec);
416        }
417    }
418}