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}