Skip to main content

any_container/
vec.rs

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