anon_vec/
vec.rs

1
2use std::any::{TypeId, Any};
3
4use crate::anon::Anon;
5use crate::iter::{
6    AnonIter, 
7    AnonIterMut
8};
9
10/// An Anonymously typed Vector.
11/// 
12/// Internally, AnonVec is a Vec<u8>. 
13/// When pushing to an AnonVec, `T` is converted to `*const u8`.
14/// When getting from an AnonVec, `*const u8` is converted to `T`.
15/// 
16/// ## Usage
17/// 
18/// Anon Vec is intended for use in data systems where the type or size of the values
19/// stored cannot be known at compile-time.  It is a more lax approach to `Box<dyn Any>`.
20/// ```
21/// use anon_vec::AnonVec;
22/// 
23/// let mut anon = AnonVec::new::<i32>();
24/// anon.push::<i32>(5);
25/// anon.push::<i32>(10);
26/// anon.push::<i32>(15);
27/// 
28/// let x = anon.get_ref::<i32>(1);
29/// ```
30/// `AnonVec` can also work with `Anon` values. 
31/// ```
32/// use anon_vec::{AnonVec, Anon};
33/// use std::mem::size_of;
34/// use std::any::TypeId;
35/// 
36/// // Create AnonVec using the size and typeid.
37/// let mut vec = AnonVec::from_size(size_of::<i32>(), TypeId::of::<i32>());
38/// vec.push_anon(Anon::new::<i32>(5));
39/// vec.push_anon(Anon::new::<i32>(10));
40/// vec.push_anon(Anon::new::<i32>(15));
41/// 
42/// // move index 1 out and into `anon`.
43/// let anon: Anon = vec.remove_get_anon(1);
44/// 
45/// let x: &i32 = anon.cast_ref::<i32>();
46/// ```
47pub struct AnonVec {
48    /// Vec<T>, represented as Vec<u8>. 
49    inner: Vec<u8>,
50    /// The `std::mem::size_of` each element.
51    size: usize,
52    /// The length of the vector, in terms of `inner.len() / size.`
53    len: usize,
54    /// The TypeId of this AnonVec. 
55    typeid: TypeId,
56}
57
58impl AnonVec {
59
60    // --- // Constructors // --- //
61
62    /// Creates a new Anonymously Typed Vector in-place.
63    /// 
64    /// ## Usage
65    /// ```
66    /// use anon_vec::AnonVec;
67    /// 
68    /// let mut anon = AnonVec::new::<i32>();
69    /// anon.push::<i32>(5);
70    /// ```
71    pub fn new<T>() -> Self 
72    where
73        T: Any + 'static,
74    {
75        Self {
76            inner: Vec::new(),
77            size: std::mem::size_of::<T>(),
78            len: 0,
79            typeid: TypeId::of::<T>(),
80        }
81    }
82
83    /// Creates a new Anonymously Typed Vector using the 
84    /// size and TypeId of the value to be stored.
85    /// 
86    /// ## Usage
87    /// ```
88    /// use anon_vec::AnonVec;
89    /// use std::mem::size_of;
90    /// use std::any::TypeId;
91    /// 
92    /// let mut anon = AnonVec::from_size(size_of::<i32>(), TypeId::of::<i32>());
93    /// anon.push::<i32>(5);
94    /// ```
95    pub fn from_size(size: usize, typeid: TypeId) -> Self {
96        Self {
97            inner: Vec::new(),
98            size,
99            len: 0,
100            typeid,
101        }
102    }
103
104    /// Creates an Uninitialized Anonymously Typed Vector
105    /// 
106    /// MUST be initialized before access by calling init::<T>. 
107    /// If you can't call init::<T>, call init_size instead.
108    /// 
109    /// ## Usage
110    /// ```
111    /// use anon_vec::AnonVec;
112    /// 
113    /// let mut vec = AnonVec::uninit();
114    /// 
115    /// if vec.is_uninit() {
116    ///     vec.init::<i32>();
117    /// }
118    /// 
119    /// // do stuff with anon_vec
120    /// ```
121    pub fn uninit() -> Self {
122        Self {
123            inner: Vec::new(),
124            size: 0,
125            len: 0,
126            typeid: TypeId::of::<i32>(),
127        }
128    }
129
130    /// Initializes a previously uninitialized AnonVec.
131    /// 
132    /// ## Usage
133    /// ```
134    /// use anon_vec::AnonVec;
135    /// 
136    /// let mut vec = AnonVec::uninit();
137    /// 
138    /// if vec.is_uninit() {
139    ///     vec.init::<i32>();
140    /// }
141    /// 
142    /// // do stuff with anon_vec
143    /// ```
144    pub fn init<T>(&mut self) 
145    where
146        T: Any + 'static,
147    {
148        self.size = std::mem::size_of::<T>();
149        self.typeid = TypeId::of::<T>();
150    }
151
152    /// Initializes a previously uninitialized AnonVec.
153    /// 
154    /// ## Usage
155    /// ```
156    /// use anon_vec::AnonVec;
157    /// use std::mem::size_of;
158    /// use std::any::TypeId;
159    /// 
160    /// let mut vec = AnonVec::uninit();
161    /// 
162    /// if vec.is_uninit() {
163    ///     vec.init_size(size_of::<i32>(), TypeId::of::<i32>());
164    /// }
165    /// 
166    /// // do stuff with anon_vec
167    /// ```
168    pub fn init_size(&mut self, size: usize, typeid: TypeId) {
169        self.size = size;
170        self.typeid = typeid;
171    }
172
173    // --- // Accessors // --- //
174
175    /// The TypeId associated with this AnonVec.
176    pub fn typeid(&self) -> TypeId {
177        self.typeid
178    }
179
180    /// The size, in bytes, each element of this AnonVec holds.
181    pub fn size(&self) -> usize {
182        self.size
183    }
184
185    /// The number of elements this AnonVec holds. (as T)
186    pub fn len(&self) -> usize {
187        self.len
188    }
189
190    /// Whether or not this AnonVec has a length of 0.
191    pub fn is_empty(&self) -> bool {
192        self.len == 0
193    }
194
195    /// Whether or not the size of this AnonVec is 0.
196    pub fn is_uninit(&self) -> bool {
197        self.size == 0
198    }
199
200    /// Get a reference to the interior value at index as T.
201    pub fn get_ref<T>(&self, index: usize) -> &T 
202    where
203        T: Any + 'static,
204    {   
205        let ptr = self.inner.as_ptr() as *const T;
206        unsafe { &*(ptr.add(index)) }
207    } 
208
209    /// Get a mutable reference to the interior value at index as T.
210    pub fn get_mut<T>(&mut self, index: usize) -> &mut T
211    where
212        T: Any + 'static,
213    {
214        let ptr = self.inner.as_mut_ptr() as *mut T;
215        unsafe { &mut *(ptr.add(index)) }
216    }
217
218    /// Reserves `additional` number of BYTES. 
219    /// If you want to reserve size_of::<T>, use `reserve` instead.
220    /// 
221    /// Reserves capacity for at least `additional` more elements to be inserted
222    /// in the given `Vec<T>`. The collection may reserve more space to
223    /// speculatively avoid frequent reallocations. After calling `reserve`,
224    /// capacity will be greater than or equal to `self.len() + additional`.
225    /// Does nothing if capacity is already sufficient.
226    ///
227    /// # Panics
228    ///
229    /// Panics if the new capacity exceeds `isize::MAX` bytes.
230    ///
231    /// # Examples
232    ///
233    /// ```
234    /// let mut vec = vec![1];
235    /// vec.reserve(10);
236    /// assert!(vec.capacity() >= 11);
237    /// ```
238    pub fn reserve_bytes(&mut self, additional: usize) {
239        self.inner.reserve(additional);
240    }
241
242    /// Reserves capacity for at least `additional` more elements to be inserted
243    /// in the given `Vec<T>`. The collection may reserve more space to
244    /// speculatively avoid frequent reallocations. After calling `reserve`,
245    /// capacity will be greater than or equal to `self.len() + additional`.
246    /// Does nothing if capacity is already sufficient.
247    ///
248    /// # Panics
249    ///
250    /// Panics if the new capacity exceeds `isize::MAX` bytes.
251    ///
252    /// # Examples
253    ///
254    /// ```
255    /// let mut vec = vec![1];
256    /// vec.reserve(10);
257    /// assert!(vec.capacity() >= 11);
258    /// ```
259    pub fn reserve(&mut self, additional: usize) {
260        if !self.is_uninit() {
261            self.inner.reserve(additional * self.size);
262        }
263    }
264
265    // --- // Operators // -- //
266
267    /// Appends an element to the back of this AnonVec.
268    pub fn push<T>(&mut self, val: T)
269    where
270        T: Any + 'static,
271    {
272        let v = &val as *const T as *const u8;
273        for i in 0..self.size {
274            unsafe {
275                self.inner.push(*(v.add(i)))
276            }
277        }
278        self.len += 1;
279    }
280
281    /// Appends an anonymous element to the back of this AnonVec.
282    pub fn push_anon(&mut self, anon: Anon) {
283        let v = anon.inner();
284        for _ in 0..self.size {
285            self.inner.extend(v.iter());
286        }
287        self.len += 1;
288    }
289
290    /// Inserts an element at `index`, moving all elements after it to the right.
291    pub fn insert<T>(&mut self, val: T, index: usize) {
292        let v = &val as *const T as *const u8;
293        let index = index * self.size;
294
295        for i in (0..self.size).rev() {
296            unsafe {
297                self.inner.insert(index, *(v.add(i)))
298            }
299        }
300        self.len += 1;
301    }
302
303    /// Inserts an anonymous element at `index`, moving all elements after it to the right.
304    pub fn insert_anon(&mut self, anon: Anon, index: usize) {
305        let v = anon.inner();
306        let index = index * self.size;
307
308        for i in (0..self.size).rev() {
309            self.inner.insert(index, v[i])
310        }
311        self.len += 1;
312    }
313
314    /// Removes an element at `index`. 
315    pub fn remove(&mut self, index: usize) {
316        let index = index * self.size;
317        for i in (index..index + self.size).rev() {
318            self.inner.remove(i);
319        }
320        self.len -= 1;
321    }
322
323    /// Removes and returns the element at `index`. 
324    pub fn remove_get<T>(&mut self, index: usize) -> T
325    where
326        T: Any + Clone + 'static,
327    {
328        let ptr = self.inner.as_mut_ptr() as *mut T;
329        let out = unsafe { &*(ptr.add(index)) }.clone();
330
331        let index = index * self.size;
332        for i in (index..index + self.size).rev() {
333            self.inner.remove(i);
334        }
335        self.len -= 1;
336        out
337    }
338
339    /// Removes and returns the element at `index` as an anonymous type.
340    pub fn remove_get_anon(&mut self, index: usize) -> Anon {
341        let ptr = self.inner.as_ptr();
342        let out = Anon::from_ptr(ptr, self.size, self.typeid);
343
344        let index = index * self.size;
345        for i in (index..index + self.size).rev() {
346            self.inner.remove(i);
347        }
348        self.len -= 1;
349        out
350    }
351
352    /// Pops off and returns the last element in the Vec.
353    pub fn pop<T>(&mut self) -> Option<T> 
354    where
355        T: Any + Clone + 'static,
356    {
357        if self.len == 0 {
358            None
359        } else {
360            self.len -= 1;
361            Some(self.remove_get::<T>(self.len() - 1))
362        }
363    }
364
365    /// Pops off and returns the last element in the Vec as an Anon. 
366    pub fn pop_anon(&mut self) -> Option<Anon> {
367        if self.len == 0 {
368            None
369        } else {
370            self.len -= 1;
371            Some(self.remove_get_anon(self.len() - 1))
372        }
373    }
374
375    /// Remove the last element after copying it into `index`. 
376    /// MUCH faster than `remove`, in certain situations. 
377    pub fn remove_swap(&mut self, index: usize) {
378        if index == self.len - 1 {
379            for _ in 0..self.size {
380                self.inner.pop();
381            }
382        } else {
383            let index = self.size * index;
384            for i in (0..self.size).rev() {
385                self.inner[index + i] = self.inner.pop().unwrap()
386            }
387        }
388        self.len -= 1;
389    }
390
391    /// Immutably Iterate over this AnonVec as T.
392    pub fn iter<T>(&self) -> AnonIter<T> {
393        AnonIter {
394            data: self.inner.as_ptr() as *const T,
395            curr: 0,
396            len: self.inner.len(),
397        }
398    } 
399
400    /// Mutably Iterate over this AnonVec as T. 
401    pub fn iter_mut<T>(&mut self) -> AnonIterMut<T> {
402        AnonIterMut {
403            data: self.inner.as_mut_ptr() as *mut T,
404            curr: 0,
405            len: self.inner.len(),
406        }
407    }
408}
409
410#[cfg(test)]
411mod tests {
412
413    use std::any::TypeId;
414
415    use crate::vec::AnonVec;
416
417    const THING: Thing = Thing { a: 1, b: 2, c: 3 };
418
419    #[repr(C)]
420    #[derive(PartialEq, Debug, Clone)]
421    struct Thing {
422        pub a: i32,
423        pub b: i32,
424        pub c: i32,
425    }
426
427    impl Thing {
428        fn sum(&self) -> i32 {
429            self.a + self.b + self.c
430        }
431    }
432
433    #[test]
434    fn new() {
435        let mut anon = AnonVec::new::<Thing>();
436
437        {
438            anon.push::<Thing>(THING);
439            anon.push::<Thing>(THING);
440            anon.push::<Thing>(THING);
441        }
442
443        let t1 = anon.get_ref::<Thing>(0);
444        let t2 = anon.get_ref::<Thing>(1);
445        let t3 = anon.get_ref::<Thing>(2);
446
447        let v = t1.sum() + t2.sum() + t3.sum();
448
449        assert_eq!(v, 18);
450    }
451
452    #[test]
453    fn from_size() {
454        let mut anon = AnonVec::from_size(std::mem::size_of::<Thing>(), TypeId::of::<Thing>());
455
456        {
457            anon.push::<Thing>(THING);
458            anon.push::<Thing>(THING);
459            anon.push::<Thing>(THING);
460        }
461
462        let t1 = anon.get_ref::<Thing>(0);
463        let t2 = anon.get_ref::<Thing>(1);
464        let t3 = anon.get_ref::<Thing>(2);
465
466        let v = t1.sum() + t2.sum() + t3.sum();
467
468        assert_eq!(v, 18);
469    }
470
471    #[test]
472    fn uninit_init() {
473        let mut anon = AnonVec::uninit();
474
475        {
476            anon.init::<Thing>();
477            anon.push::<Thing>(THING);
478            anon.push::<Thing>(THING);
479            anon.push::<Thing>(THING);
480        }
481
482        let t1 = anon.get_ref::<Thing>(0);
483        let t2 = anon.get_ref::<Thing>(1);
484        let t3 = anon.get_ref::<Thing>(2);
485
486        let v = t1.sum() + t2.sum() + t3.sum();
487
488        assert_eq!(v, 18);
489    }
490}