dync/
vec_copy.rs

1//! This module defines a typeless homogeneous vector data structure optimized to be written to and
2//! read from standard `Vec`s. It is not unlike `Vec<dyn Trait>` but stores only a single vtable
3//! for all the values in the vector producing better data locality.
4//!
5//! [`VecCopy`] is particularly useful when dealing with plain data whose type is determined at
6//! run time.  Note that data is stored in the underlying byte vectors in native endian form,
7//! endianness is not handled by this type.
8//!
9//! # Caveats
10//!
11//! [`VecCopy`] doesn't support zero-sized types.
12//!
13//! [`VecCopy`]: struct.VecCopy
14
15use std::{
16    any::{Any, TypeId},
17    mem::{size_of, MaybeUninit},
18    slice,
19};
20
21// At the time of this writing, there is no evidence that there is a
22// significant benefit in sharing vtables via Rc or Arc, but to make potential
23// future refactoring easier we use the Ptr alias.
24use std::boxed::Box as Ptr;
25
26#[cfg(feature = "numeric")]
27use std::fmt;
28
29#[cfg(feature = "numeric")]
30use num_traits::{cast, NumCast, Zero};
31
32use crate::copy_value::*;
33use crate::elem::*;
34use crate::slice_copy::*;
35use crate::vec_void::*;
36use crate::vtable::*;
37use crate::{ElementBytes, ElementBytesMut};
38
39/// Buffer of untyped `Copy` values.
40///
41/// `VecCopy` keeps track of the type stored within via an explicit `TypeId` member. This allows
42/// one to hide the type from the compiler and check it only when necessary. It is particularly
43/// useful when the type of data is determined at runtime (e.g. when parsing numeric data).
44///
45/// # Safety
46///
47/// The data representing a type is never interpreted as anything
48/// other than a type with an identical `TypeId`, which are assumed to have an
49/// identical memory layout throughout the execution of the program.
50///
51/// It is an error to share this type between independently compiled binaries since `TypeId`s
52/// are not stable, and thus reinterpreting the values may not work as expected.
53#[derive(Clone)]
54pub struct VecCopy<V = ()>
55where
56    V: ?Sized,
57{
58    /// Raw data.
59    pub(crate) data: VecVoid,
60
61    /// VTable pointer.
62    pub(crate) vtable: Ptr<V>,
63}
64
65impl<V> VecCopy<V> {
66    /// Construct an empty `VecCopy` with a specific type.
67    #[inline]
68    pub fn with_type<T: CopyElem>() -> Self
69    where
70        V: VTable<T>,
71    {
72        Self::from_vec(Vec::new())
73    }
74
75    /// It is unsafe to construct a `VecCopy` if `T` is not a `CopyElem`.
76    #[cfg(feature = "traits")]
77    #[inline]
78    pub(crate) unsafe fn with_type_non_copy<T: Any>() -> Self
79    where
80        V: VTable<T>,
81    {
82        Self::from_vec_non_copy(Vec::new())
83    }
84
85    /// Construct an empty `VecCopy` with a capacity for a given number of typed elements. For
86    /// setting byte capacity use `with_byte_capacity`.
87    #[inline]
88    pub fn with_capacity<T: CopyElem>(n: usize) -> Self
89    where
90        V: VTable<T>,
91    {
92        Self::from_vec(Vec::with_capacity(n))
93    }
94
95    /// It is unsafe to construct a `VecCopy` if `T` is not `Copy`.
96    #[cfg(feature = "traits")]
97    #[inline]
98    pub(crate) unsafe fn with_capacity_non_copy<T: Any>(n: usize) -> Self
99    where
100        V: VTable<T>,
101    {
102        Self::from_vec_non_copy(Vec::with_capacity(n))
103    }
104
105    /// Construct a typed `VecCopy` with a given size and filled with the specified default
106    /// value.
107    ///
108    /// #  Examples
109    /// ```
110    /// use dync::VecCopy;
111    /// let buf: VecCopy = VecCopy::with_size(8, 42usize); // Create buffer
112    /// let buf_vec: Vec<usize> = buf.into_vec().unwrap(); // Convert into `Vec`
113    /// assert_eq!(buf_vec, vec![42usize; 8]);
114    /// ```
115    #[inline]
116    pub fn with_size<T: CopyElem>(n: usize, def: T) -> Self
117    where
118        V: VTable<T>,
119    {
120        Self::from_vec(vec![def; n])
121    }
122
123    /// Construct a `VecCopy` from a given `Vec<T>` reusing the space already allocated by the
124    /// given vector.
125    ///
126    /// #  Examples
127    /// ```
128    /// use dync::VecCopy;
129    /// let vec = vec![1u8, 3, 4, 1, 2];
130    /// let buf: VecCopy = VecCopy::from_vec(vec.clone()); // Convert into buffer
131    /// let nu_vec: Vec<u8> = buf.into_vec().unwrap(); // Convert back into `Vec`
132    /// assert_eq!(vec, nu_vec);
133    /// ```
134    pub fn from_vec<T: CopyElem>(vec: Vec<T>) -> Self
135    where
136        V: VTable<T>,
137    {
138        // SAFETY: `T` is a `CopyElem`.
139        unsafe { Self::from_vec_non_copy(vec) }
140    }
141
142    /// It is unsafe to call this for `T` that is not a `CopyElem`.
143    pub(crate) unsafe fn from_vec_non_copy<T: Any>(vec: Vec<T>) -> Self
144    where
145        V: VTable<T>,
146    {
147        assert_ne!(
148            size_of::<T>(),
149            0,
150            "VecCopy doesn't support zero sized types."
151        );
152
153        VecCopy {
154            data: VecVoid::from_vec(vec),
155            vtable: Ptr::new(V::build_vtable()),
156        }
157    }
158
159    /// Construct a `VecCopy` from a given slice by copying the data.
160    #[inline]
161    pub fn from_slice<T: CopyElem>(slice: &[T]) -> Self
162    where
163        V: VTable<T>,
164    {
165        let mut vec = Vec::with_capacity(slice.len());
166        vec.extend_from_slice(slice);
167        Self::from_vec(vec)
168    }
169
170    /// It is unsafe to call this for `T` that is not a `CopyElem`.
171    #[cfg(feature = "traits")]
172    #[inline]
173    pub(crate) unsafe fn from_slice_non_copy<T: Any + Clone>(slice: &[T]) -> Self
174    where
175        V: VTable<T>,
176    {
177        let mut vec = Vec::with_capacity(slice.len());
178        vec.extend_from_slice(slice);
179        Self::from_vec_non_copy(vec)
180    }
181}
182
183impl<V: ?Sized> VecCopy<V> {
184    /// Construct a `VecCopy` with the same type as the given buffer without copying its data.
185    #[inline]
186    pub fn with_type_from<'a>(other: impl Into<crate::meta::Meta<VTableRef<'a, V>>>) -> Self
187    where
188        V: Clone + 'a,
189    {
190        let mut other = other.into();
191
192        fn new<T: 'static>(elem: &mut ElemInfo) -> VecVoid {
193            unsafe { VecVoid::from_vec_override(Vec::<T>::with_capacity(elem.size), *elem) }
194        }
195
196        VecCopy {
197            data: eval_align!(other.elem.alignment; new::<_>(&mut other.elem)),
198            vtable: other.vtable.into_owned(),
199        }
200    }
201
202    /// Construct a `SliceCopy` from raw bytes and type metadata.
203    ///
204    /// # Safety
205    ///
206    /// Almost exclusively the only inputs that are safe here are the ones returned by
207    /// `into_raw_parts`.
208    ///
209    /// This function should not be used other than in internal APIs. It exists to enable the
210    /// `into_dyn` macro until `CoerceUsize` is stabilized.
211    #[inline]
212    pub unsafe fn from_raw_parts(data: VecVoid, vtable: Ptr<V>) -> VecCopy<V> {
213        VecCopy { data, vtable }
214    }
215
216    /// Convert this collection into its raw components.
217    ///
218    /// This function exists mainly to enable the `into_dyn` macro until `CoerceUnsized` is
219    /// stabilized.
220    #[inline]
221    pub fn into_raw_parts(self) -> (VecVoid, Ptr<V>) {
222        let VecCopy { data, vtable } = self;
223        (data, vtable)
224    }
225
226    /// Upcast the `VecCopy` into a more general base `VecCopy`.
227    ///
228    /// This function converts the underlying virtual function table into a subset of the existing
229    #[inline]
230    pub fn upcast<U: From<V>>(self) -> VecCopy<U>
231    where
232        V: Clone,
233    {
234        self.upcast_with(U::from)
235    }
236
237    // Helper for upcasts
238    #[inline]
239    pub fn upcast_with<U>(self, f: impl FnOnce(V) -> U) -> VecCopy<U>
240    where
241        V: Clone,
242    {
243        VecCopy {
244            data: self.data,
245            vtable: Ptr::new(f((*self.vtable).clone())),
246        }
247    }
248
249    /// Reserve `additional` extra elements.
250    #[inline]
251    pub fn reserve(&mut self, additional: usize) {
252        self.data.reserve(additional)
253    }
254
255    /// Resizes the buffer in-place to store `new_len` elements and returns an optional
256    /// mutable reference to `Self`.
257    ///
258    /// If `T` does not correspond to the underlying element type, then `None` is returned and the
259    /// `VecCopy` is left unchanged.
260    ///
261    /// This function has the similar properties to `Vec::resize`.
262    #[inline]
263    pub fn resize<T: CopyElem>(&mut self, new_len: usize, value: T) -> Option<&mut Self> {
264        self.check_ref::<T>()?;
265        if new_len >= self.len() {
266            let diff = new_len - self.len();
267            self.data.reserve(diff);
268            for _ in 0..diff {
269                self.push_as(value);
270            }
271        } else {
272            self.data.truncate(new_len);
273        }
274        Some(self)
275    }
276
277    /// Copy data from a given slice into the current buffer.
278    ///
279    /// The `VecCopy` is extended if the given slice is larger than the number of elements
280    /// already stored in this `VecCopy`.
281    #[inline]
282    pub fn copy_from_slice<T: CopyElem>(&mut self, slice: &[T]) -> Option<&mut Self> {
283        let mut this_slice = self.as_mut_slice();
284        match this_slice.copy_from_slice(slice) {
285            Some(_) => Some(self),
286            None => None,
287        }
288    }
289
290    /// Clear the data buffer without destroying its type information.
291    #[inline]
292    pub fn clear(&mut self) {
293        self.data.clear();
294    }
295
296    /// Fill the current buffer with copies of the given value. The size of the buffer is left
297    /// unchanged. If the given type doesn't patch the internal type, `None` is returned, otherwise
298    /// a mut reference to the modified buffer is returned.
299    ///
300    /// #  Examples
301    /// ```
302    /// use dync::VecCopy;
303    /// let vec = vec![1u8, 3, 4, 1, 2];
304    /// let mut buf: VecCopy = VecCopy::from_vec(vec.clone()); // Convert into buffer
305    /// buf.fill(0u8);
306    /// assert_eq!(buf.into_vec::<u8>().unwrap(), vec![0u8, 0, 0, 0, 0]);
307    /// ```
308    #[inline]
309    pub fn fill<T: CopyElem>(&mut self, def: T) -> Option<&mut Self> {
310        for v in self.iter_mut_as::<T>()? {
311            *v = def;
312        }
313        Some(self)
314    }
315
316    /// Add an element to this buffer.
317    ///
318    /// If the type of the given element coincides with the type
319    /// stored by this buffer, then the modified buffer is returned via a mutable reference.
320    /// Otherwise, `None` is returned.
321    #[inline]
322    pub fn push_as<T: Any>(&mut self, element: T) -> Option<&mut Self> {
323        self.check_mut::<T>().map(|s| {
324            // SAFETY: Checked using `check_mut`.
325            unsafe {
326                s.data.apply_unchecked(|v| {
327                    v.push(element);
328                });
329            }
330            s
331        })
332    }
333
334    /// Check if the current buffer contains elements of the specified type. Returns `Some(self)`
335    /// if the type matches and `None` otherwise.
336    #[inline]
337    pub fn check<T: Any>(self) -> Option<Self> {
338        if TypeId::of::<T>() != self.element_type_id() {
339            None
340        } else {
341            Some(self)
342        }
343    }
344
345    /// Check if the current buffer contains elements of the specified type. Returns `None` if the
346    /// check fails, otherwise a reference to self is returned.
347    #[inline]
348    pub fn check_ref<T: Any>(&self) -> Option<&Self> {
349        if TypeId::of::<T>() != self.element_type_id() {
350            None
351        } else {
352            Some(self)
353        }
354    }
355
356    /// Check if the current buffer contains elements of the specified type. Same as `check_ref`
357    /// but consumes and produces a mut reference to self.
358    #[inline]
359    pub fn check_mut<T: Any>(&mut self) -> Option<&mut Self> {
360        if TypeId::of::<T>() != self.element_type_id() {
361            None
362        } else {
363            Some(self)
364        }
365    }
366
367    /*
368     * Accessors
369     */
370
371    /// Get the `TypeId` of data stored within this buffer.
372    #[inline]
373    pub fn element_type_id(&self) -> TypeId {
374        self.data.elem.type_id
375    }
376
377    /// Get the number of elements stored in this buffer.
378    #[inline]
379    pub fn len(&self) -> usize {
380        self.data.len()
381    }
382
383    /// Check if there are any elements stored in this buffer.
384    #[inline]
385    pub fn is_empty(&self) -> bool {
386        self.data.is_empty()
387    }
388
389    /// Get the capacity of this buffer.
390    #[inline]
391    pub fn capacity(&self) -> usize {
392        self.data.capacity()
393    }
394
395    /// Return an iterator to a slice representing typed data.
396    /// Returs `None` if the given type `T` doesn't match the internal.
397    ///
398    /// # Examples
399    /// ```
400    /// use dync::VecCopy;
401    /// let vec = vec![1.0_f32, 23.0, 0.01, 42.0, 11.43];
402    /// let buf: VecCopy = VecCopy::from(vec.clone()); // Convert into buffer
403    /// for (i, &val) in buf.iter_as::<f32>().unwrap().enumerate() {
404    ///     assert_eq!(val, vec[i]);
405    /// }
406    /// ```
407    #[inline]
408    pub fn iter_as<T: Any>(&self) -> Option<slice::Iter<T>> {
409        self.as_slice_as::<T>().map(|x| x.iter())
410    }
411
412    /// Return an iterator to a mutable slice representing typed data.
413    /// Returns `None` if the given type `T` doesn't match the internal.
414    #[inline]
415    pub fn iter_mut_as<T: Any>(&mut self) -> Option<slice::IterMut<T>> {
416        self.as_mut_slice_as::<T>().map(|x| x.iter_mut())
417    }
418
419    /// Append copied items from this buffer to a given `Vec<T>`. Return the mutable reference
420    /// `Some(vec)` if type matched the internal type and `None` otherwise.
421    #[inline]
422    pub fn append_copy_to_vec<'a, T: CopyElem>(
423        &self,
424        vec: &'a mut Vec<T>,
425    ) -> Option<&'a mut Vec<T>> {
426        let iter = self.iter_as()?;
427        // Allocate only after we know the type is right to prevent unnecessary allocations.
428        vec.reserve(self.len());
429        vec.extend(iter);
430        Some(vec)
431    }
432
433    /// Copies contents of `self` into the given `Vec`.
434    #[inline]
435    pub fn copy_into_vec<T: CopyElem>(&self) -> Option<Vec<T>> {
436        let mut vec = Vec::new();
437        // NOTE: vec cannot be captured by closure if it's also mutably borrowed.
438        #[allow(clippy::manual_map)]
439        match self.append_copy_to_vec(&mut vec) {
440            Some(_) => Some(vec),
441            None => None,
442        }
443    }
444
445    /// Convert this vector in to a `Vec<T>`.
446    ///
447    /// This is like using the `Into` trait, but it helps the compiler
448    /// determine the type `T` automatically.
449    ///
450    /// This function returns `None` if `T` is not the same as the `T` that
451    /// this vector was created with.
452    #[inline]
453    pub fn into_vec<T: Any>(self) -> Option<Vec<T>> {
454        // SAFETY: `T` is `CopyElem` guaranteed at construction.
455        self.check::<T>()
456            .map(|s| unsafe { s.data.into_vec_unchecked::<T>() })
457    }
458
459    /// Convert this buffer into a typed slice.
460    ///
461    /// Returns `None` if the given type `T` doesn't match the internal.
462    #[inline]
463    pub fn as_slice_as<T: Any>(&self) -> Option<&[T]> {
464        let ptr = self.check_ref::<T>()?.data.ptr as *const T;
465        // SAFETY: `T` is `CopyElem` guaranteed at construction.
466        Some(unsafe { slice::from_raw_parts(ptr, self.len()) })
467    }
468
469    /// Convert this buffer into a typed slice.
470    ///
471    /// # Safety
472    ///
473    /// The underlying type must correspond to `T`.
474    #[cfg(feature = "numeric")]
475    #[inline]
476    pub(crate) unsafe fn as_slice_as_unchecked<T: Any>(&self) -> &[T] {
477        slice::from_raw_parts(self.data.ptr as *const T, self.len())
478    }
479
480    /// Convert this buffer into a typed mutable slice.
481    /// Returs `None` if the given type `T` doesn't match the internal.
482    #[inline]
483    pub fn as_mut_slice_as<T: Any>(&mut self) -> Option<&mut [T]> {
484        let ptr = self.check_mut::<T>()?.data.ptr as *mut T;
485        // SAFETY: `T` is `CopyElem` guaranteed at construction.
486        Some(unsafe { slice::from_raw_parts_mut(ptr, self.len()) })
487    }
488
489    /// Get `i`'th element of the buffer by value.
490    #[inline]
491    pub fn get_as<T: CopyElem>(&self, i: usize) -> Option<T> {
492        assert!(i < self.len());
493        let ptr = self.check_ref::<T>()?.data.ptr as *const T;
494        // SAFETY: `T` is `CopyElem` guaranteed at construction.
495        Some(unsafe { *ptr.add(i) })
496    }
497
498    /// Get a `const` reference to the `i`'th element of the buffer.
499    #[inline]
500    pub fn get_ref_as<T: Any>(&self, i: usize) -> Option<&T> {
501        assert!(i < self.len());
502        let ptr = self.check_ref::<T>()?.data.ptr as *const T;
503        // SAFETY: `T` is `CopyElem` guaranteed at construction.
504        Some(unsafe { &*ptr.add(i) })
505    }
506
507    /// Get a mutable reference to the `i`'th element of the buffer.
508    #[inline]
509    pub fn get_mut_as<T: Any>(&mut self, i: usize) -> Option<&mut T> {
510        assert!(i < self.len());
511        let ptr = self.check_mut::<T>()?.data.ptr as *mut T;
512        // SAFETY: `T` is `CopyElem` guaranteed at construction.
513        Some(unsafe { &mut *ptr.add(i) })
514    }
515
516    /// Move elements from `buf` to this buffer.
517    ///
518    /// The given buffer must have the same underlying type as `self`.
519    #[inline]
520    pub fn append(&mut self, buf: &mut VecCopy<V>) -> Option<&mut Self> {
521        if buf.element_type_id() == self.element_type_id() {
522            self.data.append(&mut buf.data);
523            Some(self)
524        } else {
525            None
526        }
527    }
528
529    /// Rotates the slice in-place such that the first `mid` elements of the slice move to the end
530    /// while the last `self.len() - mid` elements move to the front. After calling `rotate_left`,
531    /// the element previously at index `mid` will become the first element in the slice.
532    ///
533    /// # Example
534    ///
535    /// ```
536    /// use dync::*;
537    /// let mut buf: VecCopy = VecCopy::from_vec(vec![1u32,2,3,4,5]);
538    /// buf.rotate_left(3);
539    /// assert_eq!(buf.as_slice_as::<u32>().unwrap(), &[4,5,1,2,3]);
540    /// ```
541    #[inline]
542    pub fn rotate_left(&mut self, mid: usize) {
543        self.data.rotate_left(mid);
544    }
545
546    /// Rotates the slice in-place such that the first `self.len() - k` elements of the slice move
547    /// to the end while the last `k` elements move to the front. After calling `rotate_right`, the
548    /// element previously at index `k` will become the first element in the slice.
549    ///
550    /// # Example
551    ///
552    /// ```
553    /// use dync::*;
554    /// let mut buf: VecCopy = VecCopy::from_vec(vec![1u32,2,3,4,5]);
555    /// buf.rotate_right(3);
556    /// assert_eq!(buf.as_slice_as::<u32>().unwrap(), &[3,4,5,1,2]);
557    /// ```
558    #[inline]
559    pub fn rotate_right(&mut self, k: usize) {
560        self.data.rotate_right(k);
561    }
562
563    /*
564     * Value API. This allows users to manipulate contained data without knowing the element type.
565     */
566
567    /// Get a reference to a value stored in this container at index `i`.
568    #[inline]
569    pub fn get_ref(&self, i: usize) -> CopyValueRef<V> {
570        debug_assert!(i < self.len());
571        // This call is safe since our buffer guarantees that the given bytes have the
572        // corresponding TypeId.
573        let num_bytes = self.data.elem.num_bytes();
574        unsafe {
575            CopyValueRef::from_raw_parts(
576                std::slice::from_raw_parts(
577                    (self.data.ptr as *const T0).add(i * num_bytes) as *const MaybeUninit<u8>,
578                    num_bytes,
579                ),
580                self.element_type_id(),
581                self.data.elem.alignment,
582                self.vtable.as_ref(),
583            )
584        }
585    }
586
587    /// Get a mutable reference to a value stored in this container at index `i`.
588    #[inline]
589    pub fn get_mut(&mut self, i: usize) -> CopyValueMut<V> {
590        debug_assert!(i < self.len());
591        let num_bytes = self.data.elem.num_bytes();
592        unsafe {
593            CopyValueMut::from_raw_parts(
594                std::slice::from_raw_parts_mut(
595                    (self.data.ptr as *mut u8).add(i * num_bytes) as *mut MaybeUninit<u8>,
596                    num_bytes,
597                ),
598                self.element_type_id(),
599                self.data.elem.alignment,
600                self.vtable.as_ref(),
601            )
602        }
603    }
604
605    /// Return an iterator over untyped value references stored in this buffer.
606    ///
607    /// In contrast to `iter`, this function defers downcasting on a per element basis.
608    /// As a result, this type of iteration is typically less efficient if a typed value is needed
609    /// for each element.
610    ///
611    /// # Examples
612    /// ```
613    /// use dync::VecCopy;
614    /// let vec = vec![1.0_f32, 23.0, 0.01, 42.0, 11.43];
615    /// let buf: VecCopy = VecCopy::from(vec.clone()); // Convert into buffer
616    /// for (i, val) in buf.iter().enumerate() {
617    ///     assert_eq!(val.downcast::<f32>().unwrap(), &vec[i]);
618    /// }
619    /// ```
620    #[inline]
621    pub fn iter(&self) -> impl Iterator<Item = CopyValueRef<V>> {
622        self.data.byte_chunks().map(move |bytes| unsafe {
623            CopyValueRef::from_raw_parts(
624                bytes,
625                self.element_type_id(),
626                self.data.elem.alignment,
627                &*self.vtable,
628            )
629        })
630    }
631
632    /// Return an iterator over untyped value references stored in this buffer.
633    ///
634    /// In contrast to `iter`, this function defers downcasting on a per element basis.
635    /// As a result, this type of iteration is typically less efficient if a typed value is needed
636    /// for each element.
637    ///
638    /// # Examples
639    /// ```
640    /// use dync::*;
641    /// let vec = vec![1.0_f32, 23.0, 0.01, 42.0, 11.43];
642    /// let mut buf: VecCopy = VecCopy::from(vec.clone()); // Convert into buffer
643    /// for (i, val) in buf.iter_mut().enumerate() {
644    ///     val.copy(CopyValueRef::new(&100.0f32));
645    /// }
646    /// assert_eq!(buf.into_vec::<f32>().unwrap(), vec![100.0f32; 5]);
647    /// ```
648    #[inline]
649    pub fn iter_mut(&mut self) -> impl Iterator<Item = CopyValueMut<V>> {
650        let &mut VecCopy {
651            ref mut data,
652            ref vtable,
653        } = self;
654        let element_type_id = data.elem.type_id;
655        let element_alignment = data.elem.alignment;
656        let vtable = vtable.as_ref();
657        unsafe {
658            data.byte_chunks_mut().map(move |bytes| {
659                CopyValueMut::from_raw_parts(bytes, element_type_id, element_alignment, vtable)
660            })
661        }
662    }
663
664    /// Push a value to this `VecCopy` by reference and return a mutable reference to `Self`.
665    ///
666    /// If the type of the value doesn't match the internal element type, return `None`.
667    ///
668    /// Note that it is not necessary for vtables of the value and this vector to match. IF the
669    /// types coincide, we know that either of the vtables is valid, so we just stick with the one
670    /// we already have in the container.
671    ///
672    /// # Panics
673    ///
674    /// This function panics if the size of the given value doesn't match the size of the stored
675    /// value.
676    #[inline]
677    pub fn push<U>(&mut self, value: CopyValueRef<U>) -> Option<&mut Self> {
678        assert_eq!(value.size(), self.element_size());
679        if value.value_type_id() == self.element_type_id() {
680            self.data.push(value.bytes);
681            Some(self)
682        } else {
683            None
684        }
685    }
686
687    #[inline]
688    pub fn as_slice(&self) -> SliceCopy<V> {
689        let &VecCopy {
690            ref data,
691            ref vtable,
692        } = self;
693        let num_elem_bytes = data.elem.num_bytes();
694        unsafe {
695            let slice = std::slice::from_raw_parts(
696                data.ptr as *const MaybeUninit<u8>,
697                data.len * num_elem_bytes,
698            );
699            SliceCopy::from_raw_parts(slice, data.elem, vtable.as_ref())
700        }
701    }
702
703    #[inline]
704    pub fn as_mut_slice(&mut self) -> SliceCopyMut<V> {
705        let &mut VecCopy {
706            ref mut data,
707            ref vtable,
708        } = self;
709        let num_elem_bytes = data.elem.num_bytes();
710        unsafe {
711            let slice = std::slice::from_raw_parts_mut(
712                data.ptr as *mut MaybeUninit<u8>,
713                data.len * num_elem_bytes,
714            );
715            SliceCopyMut::from_raw_parts(slice, data.elem, vtable.as_ref())
716        }
717    }
718}
719
720impl<V> VecCopy<V> {
721    /*
722     * Methods specific to buffers storing numeric data
723     */
724
725    #[cfg(feature = "numeric")]
726    /// Cast a numeric `VecCopy` into the given output `Vec` type.
727    pub fn cast_into_vec<T>(&self) -> Vec<T>
728    where
729        T: CopyElem + NumCast + Zero,
730    {
731        // Helper function (generic on the input) to convert the given VecCopy into Vec.
732        unsafe fn convert_into_vec<I, O, V>(buf: &VecCopy<V>) -> Vec<O>
733        where
734            I: CopyElem + Any + NumCast,
735            O: CopyElem + NumCast + Zero,
736        {
737            debug_assert_eq!(buf.element_type_id(), TypeId::of::<I>()); // Check invariant.
738            buf.as_slice_as_unchecked()
739                .iter()
740                .map(|elem: &I| cast(*elem).unwrap_or_else(O::zero))
741                .collect()
742        }
743        call_numeric_buffer_fn!( convert_into_vec::<_, T, V>(&self) or { Vec::new() } )
744    }
745
746    #[cfg(feature = "numeric")]
747    /// Display the contents of this buffer reinterpreted in the given type.
748    unsafe fn reinterpret_display<T: CopyElem + fmt::Display>(&self, f: &mut fmt::Formatter) {
749        debug_assert_eq!(self.element_type_id(), TypeId::of::<T>()); // Check invariant.
750        for item in self.as_slice_as_unchecked::<T>().iter() {
751            write!(f, "{} ", item).expect("Error occurred while writing an VecCopy.");
752        }
753    }
754}
755
756impl<'a, V: Clone + ?Sized + 'a> std::iter::FromIterator<CopyValueRef<'a, V>> for VecCopy<V> {
757    /// Construct a `VecCopy` type from a *non-empty* iterator.
758    ///
759    /// # Panics
760    ///
761    /// This function will panic if the given iterator is empty.
762    /// This is because we don't know the element types until we see one since
763    /// the types are erased in both `CopyValueRef` and `VecCopy`.
764    #[inline]
765    fn from_iter<T: IntoIterator<Item = CopyValueRef<'a, V>>>(iter: T) -> Self {
766        let mut iter = iter.into_iter();
767        let next = iter
768            .next()
769            .expect("VecCopy cannot be built from an empty untyped iterator.");
770        let mut data = Self::with_type_from(next.clone());
771        data.push(next);
772        data.extend(iter);
773        data
774    }
775}
776
777impl<'a, V: ?Sized + 'a> Extend<CopyValueRef<'a, V>> for VecCopy<V> {
778    #[inline]
779    fn extend<T: IntoIterator<Item = CopyValueRef<'a, V>>>(&mut self, iter: T) {
780        let iter = iter.into_iter();
781        self.reserve(iter.size_hint().0);
782        for value in iter {
783            assert_eq!(value.size(), self.element_size());
784            assert_eq!(value.value_type_id(), self.element_type_id());
785            self.data.push(value.bytes);
786        }
787    }
788}
789
790/*
791 * Advanced methods to probe buffer internals.
792 */
793
794impl<V: ?Sized + Clone> VecCopy<V> {
795    /// Clones this `VecCopy` using the given function.
796    #[cfg(feature = "traits")]
797    pub(crate) fn clone_with(&self, clone: impl FnOnce(&VecVoid) -> VecVoid) -> Self {
798        VecCopy {
799            data: clone(&self.data),
800            vtable: Ptr::clone(&self.vtable),
801        }
802    }
803}
804
805impl<V: ?Sized> VecCopy<V> {
806    /// Get a `const` reference to the `i`'th element of the buffer.
807    ///
808    /// This can be used to reinterpret the internal data as a different type. Note that if the
809    /// size of the given type `T` doesn't match the size of the internal type, `i` will really
810    /// index the `i`th `T` sized chunk in the current buffer. See the implementation for details.
811    ///
812    /// # Safety
813    ///
814    /// It is assumed that that the buffer contains elements of type `T` and that `i` is strictly
815    /// less than the length of this vector, otherwise this function will cause undefined behavior.
816    #[inline]
817    pub unsafe fn get_unchecked_ref<T: Any>(&self, i: usize) -> &T {
818        let ptr = self.data.ptr as *const T;
819        &*ptr.add(i)
820    }
821
822    /// Get a mutable reference to the `i`'th element of the buffer.
823    ///
824    /// This can be used to reinterpret the internal data as a different type. Note that if the
825    /// size of the given type `T` doesn't match the size of the internal type, `i` will really
826    /// index the `i`th `T` sized chunk in the current buffer. See the implementation for details.
827    ///
828    /// # Safety
829    ///
830    /// It is assumed that that the buffer contains elements of type `T` and that `i` is strictly
831    /// less than the length of this vector, otherwise this function will cause undefined behavior.
832    #[inline]
833    pub unsafe fn get_unchecked_mut<T: Any>(&mut self, i: usize) -> &mut T {
834        let ptr = self.data.ptr as *mut T;
835        &mut *ptr.add(i)
836    }
837}
838
839impl VecVoid {
840    /// Iterate over chunks type sized chunks of bytes without interpreting them.
841    ///
842    /// This avoids needing to know what type data you're dealing with. This type of iterator is
843    /// useful for transferring data from one place to another for a generic buffer.
844    #[inline]
845    pub fn byte_chunks(&self) -> impl Iterator<Item = &[MaybeUninit<u8>]> + '_ {
846        let chunk_size = self.elem.num_bytes();
847        self.bytes().chunks_exact(chunk_size)
848    }
849
850    /// Mutably iterate over chunks type sized chunks of bytes without interpreting them. This
851    /// avoids needing to know what type data you're dealing with. This type of iterator is useful
852    /// for transferring data from one place to another for a generic buffer, or modifying the
853    /// underlying untyped bytes (e.g. bit twiddling).
854    ///
855    /// # Safety
856    ///
857    /// This function is marked as unsafe since the returned bytes may be modified
858    /// arbitrarily, which may potentially produce malformed values.
859    #[inline]
860    pub unsafe fn byte_chunks_mut(&mut self) -> impl Iterator<Item = &mut [MaybeUninit<u8>]> + '_ {
861        let chunk_size = self.elem.num_bytes();
862        let slice = std::slice::from_raw_parts_mut(
863            self.ptr as *mut MaybeUninit<u8>,
864            chunk_size * self.len(),
865        );
866        slice.chunks_exact_mut(chunk_size)
867    }
868
869    /// Get a `const` reference to the byte slice of the `i`'th element of the buffer.
870    #[inline]
871    pub fn get_bytes(&self, i: usize) -> &[MaybeUninit<u8>] {
872        debug_assert!(i < self.len());
873        let element_size = self.element_size();
874        &self.bytes()[i * element_size..(i + 1) * element_size]
875    }
876
877    /// Get a mutable reference to the byte slice of the `i`'th element of the buffer.
878    ///
879    /// # Safety
880    ///
881    /// This function is marked as unsafe since the returned bytes may be modified
882    /// arbitrarily, which may potentially produce malformed values.
883    #[inline]
884    pub unsafe fn get_bytes_mut(&mut self, i: usize) -> &mut [MaybeUninit<u8>] {
885        debug_assert!(i < self.len());
886        self.index_byte_slice_mut(i)
887    }
888}
889
890impl ElementBytes for VecVoid {
891    fn element_size(&self) -> usize {
892        self.elem.num_bytes()
893    }
894    fn bytes(&self) -> &[MaybeUninit<u8>] {
895        unsafe {
896            std::slice::from_raw_parts(
897                self.ptr as *const MaybeUninit<u8>,
898                self.len * self.elem.num_bytes(),
899            )
900        }
901    }
902}
903
904impl ElementBytesMut for VecVoid {
905    unsafe fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
906        std::slice::from_raw_parts_mut(
907            self.ptr as *mut MaybeUninit<u8>,
908            self.len * self.elem.num_bytes(),
909        )
910    }
911}
912
913impl<V: ?Sized> ElementBytes for VecCopy<V> {
914    fn element_size(&self) -> usize {
915        self.data.element_size()
916    }
917    fn bytes(&self) -> &[MaybeUninit<u8>] {
918        self.data.bytes()
919    }
920}
921
922impl<V: ?Sized> ElementBytesMut for VecCopy<V> {
923    unsafe fn bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
924        self.data.bytes_mut()
925    }
926}
927
928/// Convert a `Vec<T>` to a `VecCopy`.
929impl<T, V> From<Vec<T>> for VecCopy<V>
930where
931    T: CopyElem,
932    V: VTable<T>,
933{
934    #[inline]
935    fn from(vec: Vec<T>) -> VecCopy<V> {
936        VecCopy::from_vec(vec)
937    }
938}
939
940/// Convert a `&[T]` to a `VecCopy`.
941impl<'a, T, V> From<&'a [T]> for VecCopy<V>
942where
943    T: CopyElem,
944    V: VTable<T>,
945{
946    #[inline]
947    fn from(slice: &'a [T]) -> VecCopy<V> {
948        VecCopy::from_slice(slice)
949    }
950}
951
952/// Convert a `VecCopy` to a `Option<Vec<T>>`.
953impl<T, V: ?Sized> From<VecCopy<V>> for Option<Vec<T>>
954where
955    T: CopyElem,
956{
957    #[inline]
958    fn from(v: VecCopy<V>) -> Option<Vec<T>> {
959        v.into_vec()
960    }
961}
962
963#[cfg(feature = "numeric")]
964/// Implement pretty printing of numeric `VecCopy` data.
965impl<V> fmt::Display for VecCopy<V> {
966    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
967        call_numeric_buffer_fn!( self.reinterpret_display::<_>(f) or {
968            println!("Unknown VecCopy type for pretty printing.");
969        } );
970        write!(f, "")
971    }
972}
973
974#[cfg(test)]
975mod tests {
976    use super::*;
977    type VecUnit = super::VecCopy<()>;
978
979    /// Test various ways to create a data buffer.
980    #[test]
981    fn initialization_test() {
982        // Empty typed buffer.
983        let a = VecUnit::with_type::<f32>();
984        assert_eq!(a.len(), 0);
985        assert_eq!(a.element_type_id(), TypeId::of::<f32>());
986
987        // Empty buffer typed by the given type id.
988        #[cfg(feature = "traits")]
989        {
990            let b = VecUnit::with_type_from(&a);
991            assert_eq!(b.len(), 0);
992            assert_eq!(b.element_type_id(), TypeId::of::<f32>());
993        }
994
995        // Empty typed buffer with a given capacity.
996        let a = VecUnit::with_capacity::<f32>(4);
997        assert_eq!(a.len(), 0);
998        assert_eq!(a.element_type_id(), TypeId::of::<f32>());
999    }
1000
1001    /// Test resizing a buffer.
1002    #[test]
1003    fn resize() {
1004        let mut a = VecUnit::with_type::<f32>();
1005
1006        // Increase the size of a.
1007        a.resize(3, 1.0f32);
1008
1009        assert_eq!(a.len(), 3);
1010        for i in 0..3 {
1011            assert_eq!(a.get_as::<f32>(i).unwrap(), 1.0f32);
1012        }
1013
1014        // Truncate a.
1015        a.resize(2, 1.0f32);
1016
1017        assert_eq!(a.len(), 2);
1018        for i in 0..2 {
1019            assert_eq!(a.get_as::<f32>(i).unwrap(), 1.0f32);
1020        }
1021    }
1022
1023    #[test]
1024    #[should_panic]
1025    fn zero_size_with_type_test() {
1026        let _a = VecUnit::with_type::<()>();
1027    }
1028
1029    #[test]
1030    #[should_panic]
1031    fn zero_size_with_capacity_test() {
1032        let _a = VecUnit::with_capacity::<()>(2);
1033    }
1034
1035    #[test]
1036    #[should_panic]
1037    fn zero_size_from_vec_test() {
1038        let _a = VecUnit::from_vec(vec![(); 3]);
1039    }
1040
1041    #[test]
1042    #[should_panic]
1043    fn zero_size_with_size_test() {
1044        let _a = VecUnit::with_size(3, ());
1045    }
1046
1047    #[test]
1048    #[should_panic]
1049    fn zero_size_from_slice_test() {
1050        let v = vec![(); 3];
1051        let _a = VecUnit::from_slice(&v);
1052    }
1053
1054    #[test]
1055    //#[should_panic]
1056    fn zero_size_copy_from_slice_test() {
1057        let v = vec![(); 3];
1058        let mut a = VecUnit::with_size(0, 1i32);
1059        a.copy_from_slice(&v);
1060    }
1061
1062    #[test]
1063    fn data_integrity_u8_test() {
1064        let vec = vec![1u8, 3, 4, 1, 2];
1065        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1066        let nu_vec: Vec<u8> = buf.copy_into_vec().unwrap(); // Convert back into vec
1067        assert_eq!(vec, nu_vec);
1068
1069        let vec = vec![1u8, 3, 4, 1, 2, 52, 1, 3, 41, 23, 2];
1070        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1071        let nu_vec: Vec<u8> = buf.copy_into_vec().unwrap(); // Convert back into vec
1072        assert_eq!(vec, nu_vec);
1073    }
1074
1075    #[test]
1076    fn data_integrity_i16_test() {
1077        let vec = vec![1i16, -3, 1002, -231, 32];
1078        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1079        let nu_vec: Vec<i16> = buf.copy_into_vec().unwrap(); // Convert back into vec
1080        assert_eq!(vec, nu_vec);
1081
1082        let vec = vec![1i16, -3, 1002, -231, 32, 42, -123, 4];
1083        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1084        let nu_vec: Vec<i16> = buf.copy_into_vec().unwrap(); // Convert back into vec
1085        assert_eq!(vec, nu_vec);
1086    }
1087
1088    #[test]
1089    fn data_integrity_i32_test() {
1090        let vec = vec![1i32, -3, 1002, -231, 32];
1091        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1092        let nu_vec: Vec<i32> = buf.into_vec().unwrap(); // Convert back into vec
1093        assert_eq!(vec, nu_vec);
1094
1095        let vec = vec![1i32, -3, 1002, -231, 32, 42, -123];
1096        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1097        let nu_vec: Vec<i32> = buf.into_vec().unwrap(); // Convert back into vec
1098        assert_eq!(vec, nu_vec);
1099    }
1100
1101    #[test]
1102    fn data_integrity_f32_test() {
1103        let vec = vec![1.0_f32, 23.0, 0.01, 42.0, 11.43];
1104        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1105        let nu_vec: Vec<f32> = buf.into_vec().unwrap(); // Convert back into vec
1106        assert_eq!(vec, nu_vec);
1107
1108        let vec = vec![1.0_f32, 23.0, 0.01, 42.0, 11.43, 2e-1];
1109        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1110        let nu_vec: Vec<f32> = buf.into_vec().unwrap(); // Convert back into vec
1111        assert_eq!(vec, nu_vec);
1112    }
1113
1114    #[test]
1115    fn data_integrity_f64_test() {
1116        let vec = vec![1f64, -3.0, 10.02, -23.1, 32e-1];
1117        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1118        let nu_vec: Vec<f64> = buf.copy_into_vec().unwrap(); // Convert back into vec
1119        assert_eq!(vec, nu_vec);
1120
1121        let vec = vec![1f64, -3.1, 100.2, -2.31, 3.2, 4e2, -1e23];
1122        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1123        let nu_vec: Vec<f64> = buf.copy_into_vec().unwrap(); // Convert back into vec
1124        assert_eq!(vec, nu_vec);
1125    }
1126
1127    #[cfg(feature = "numeric")]
1128    #[test]
1129    fn convert_float_test() {
1130        let vecf64 = vec![1f64, -3.0, 10.02, -23.1, 32e-1];
1131        let buf = VecUnit::from(vecf64.clone()); // Convert into buffer
1132        let nu_vec: Vec<f32> = buf.cast_into_vec(); // Convert back into vec
1133        let vecf32 = vec![1f32, -3.0, 10.02, -23.1, 32e-1];
1134        assert_eq!(vecf32, nu_vec);
1135
1136        let buf = VecUnit::from(vecf32.clone()); // Convert into buffer
1137        let nu_vec: Vec<f64> = buf.cast_into_vec(); // Convert back into vec
1138        for (&a, &b) in vecf64.iter().zip(nu_vec.iter()) {
1139            assert!((a - b).abs() < 1e-6f64 * f64::max(a, b).abs());
1140        }
1141
1142        let vecf64 = vec![1f64, -3.1, 100.2, -2.31, 3.2, 4e2, -1e23];
1143        let buf = VecUnit::from(vecf64.clone()); // Convert into buffer
1144        let nu_vec: Vec<f32> = buf.cast_into_vec(); // Convert back into vec
1145        let vecf32 = vec![1f32, -3.1, 100.2, -2.31, 3.2, 4e2, -1e23];
1146        assert_eq!(vecf32, nu_vec);
1147        let buf = VecUnit::from(vecf32.clone()); // Convert into buffer
1148        let nu_vec: Vec<f64> = buf.cast_into_vec(); // Convert back into vec
1149        for (&a, &b) in vecf64.iter().zip(nu_vec.iter()) {
1150            assert!((a - b).abs() < 1e-6 * f64::max(a, b).abs());
1151        }
1152    }
1153
1154    #[derive(Copy, Clone, Debug, PartialEq)]
1155    struct Foo {
1156        a: u8,
1157        b: i64,
1158        c: f32,
1159    }
1160
1161    #[test]
1162    fn from_empty_vec_test() {
1163        let vec: Vec<u32> = Vec::new();
1164        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1165        let nu_vec: Vec<u32> = buf.into_vec().unwrap(); // Convert back into vec
1166        assert_eq!(vec, nu_vec);
1167
1168        let vec: Vec<Foo> = Vec::new();
1169        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1170        let nu_vec: Vec<Foo> = buf.into_vec().unwrap(); // Convert back into vec
1171        assert_eq!(vec, nu_vec);
1172    }
1173
1174    #[test]
1175    fn from_struct_test() {
1176        let f1 = Foo {
1177            a: 3,
1178            b: -32,
1179            c: 54.2,
1180        };
1181        let f2 = Foo {
1182            a: 33,
1183            b: -3342432412,
1184            c: 323454.2,
1185        };
1186        let vec = vec![f1.clone(), f2.clone()];
1187        let buf = VecUnit::from(vec.clone()); // Convert into buffer
1188        assert_eq!(f1, buf.get_ref_as::<Foo>(0).unwrap().clone());
1189        assert_eq!(f2, buf.get_ref_as::<Foo>(1).unwrap().clone());
1190        let nu_vec: Vec<Foo> = buf.into_vec().unwrap(); // Convert back into vec
1191        assert_eq!(vec, nu_vec);
1192    }
1193
1194    #[test]
1195    fn iter_test() {
1196        // Check iterating over data with a larger size than 8 bits.
1197        let vec_f32 = vec![1.0_f32, 23.0, 0.01, 42.0, 11.43];
1198        let buf = VecUnit::from(vec_f32.clone()); // Convert into buffer
1199        for (i, &val) in buf.iter_as::<f32>().unwrap().enumerate() {
1200            assert_eq!(val, vec_f32[i]);
1201        }
1202
1203        // Check iterating over data with the same size.
1204        let vec_u8 = vec![1u8, 3, 4, 1, 2, 4, 128, 32];
1205        let buf = VecUnit::from(vec_u8.clone()); // Convert into buffer
1206        for (i, &val) in buf.iter_as::<u8>().unwrap().enumerate() {
1207            assert_eq!(val, vec_u8[i]);
1208        }
1209    }
1210
1211    #[test]
1212    fn large_sizes_test() {
1213        for i in 1000000..1000010 {
1214            let vec = vec![32u8; i];
1215            let buf = VecUnit::from(vec.clone()); // Convert into buffer
1216            let nu_vec: Vec<u8> = buf.into_vec().unwrap(); // Convert back into vec
1217            assert_eq!(vec, nu_vec);
1218        }
1219    }
1220
1221    /// This test checks that an error is returned whenever the user tries to access data with the
1222    /// wrong type data.
1223    #[test]
1224    fn wrong_type_test() {
1225        let vec = vec![1.0_f32, 23.0, 0.01, 42.0, 11.43];
1226        let mut buf = VecUnit::from(vec.clone()); // Convert into buffer
1227        assert_eq!(vec, buf.copy_into_vec::<f32>().unwrap());
1228
1229        assert!(buf.copy_into_vec::<f64>().is_none());
1230        assert!(buf.as_slice_as::<f64>().is_none());
1231        assert!(buf.as_mut_slice_as::<u8>().is_none());
1232        assert!(buf.iter_as::<[f32; 3]>().is_none());
1233        assert!(buf.get_as::<i32>(0).is_none());
1234        assert!(buf.get_ref_as::<i32>(1).is_none());
1235        assert!(buf.get_mut_as::<i32>(2).is_none());
1236    }
1237
1238    /// Test pushing values and bytes to a buffer.
1239    #[test]
1240    fn push_test() {
1241        let mut vec_f32 = vec![1.0_f32, 23.0, 0.01];
1242        let mut buf = VecUnit::from(vec_f32.clone()); // Convert into buffer
1243        for (i, &val) in buf.iter_as::<f32>().unwrap().enumerate() {
1244            assert_eq!(val, vec_f32[i]);
1245        }
1246
1247        vec_f32.push(42.0f32);
1248        buf.push_as(42.0f32).unwrap(); // must provide explicit type
1249
1250        for (i, &val) in buf.iter_as::<f32>().unwrap().enumerate() {
1251            assert_eq!(val, vec_f32[i]);
1252        }
1253
1254        vec_f32.push(11.43);
1255        buf.push_as(11.43f32).unwrap();
1256
1257        for (i, &val) in buf.iter_as::<f32>().unwrap().enumerate() {
1258            assert_eq!(val, vec_f32[i]);
1259        }
1260    }
1261
1262    /// Test iterating over chunks of data without having to interpret them.
1263    #[test]
1264    fn vecvoid_byte_chunks_test() {
1265        let vec_f32 = vec![1.0_f32, 23.0, 0.01, 42.0, 11.43];
1266        let buf = VecVoid::from_vec(vec_f32.clone()); // Convert into VecVoid
1267
1268        for (i, val) in buf.byte_chunks().enumerate() {
1269            assert_eq!(val.len(), 4);
1270            // SAFETY: This is safe since the underlying bytes were initialized.
1271            // This also will not cause issues on different platforms since
1272            // conversion to and from bytes is happening on the same platform.
1273            unsafe {
1274                assert_eq!(*(val.as_ptr() as *const f32), vec_f32[i]);
1275            }
1276        }
1277    }
1278
1279    /// Check the byte getters on `VecVoid`.
1280    #[test]
1281    fn vecvoid_byte_getters() {
1282        let vec_u8 = vec![1, 2, 3, 4];
1283        let mut buf = VecVoid::from_vec(vec_u8.clone()); // Convert into VecVoid
1284
1285        // Test byte getters
1286        // SAFETY: since all bytes have been initialized, this is safe.
1287        for i in 0..4 {
1288            assert_eq!(
1289                unsafe { std::mem::transmute::<_, &[u8]>(buf.get_bytes(i)) },
1290                &[vec_u8[i]][..]
1291            );
1292            assert_eq!(
1293                unsafe { std::mem::transmute::<_, &mut [u8]>(buf.get_bytes_mut(i)) },
1294                &[vec_u8[i]][..]
1295            );
1296        }
1297    }
1298
1299    /// Test appending to a data buffer from another data buffer.
1300    #[test]
1301    fn append_test() {
1302        let mut buf = VecUnit::with_type::<f32>(); // Create an empty buffer.
1303
1304        let data = vec![1.0_f32, 23.0, 0.01, 42.0, 11.43];
1305        // Append an ordianry vector of data.
1306        let mut other_buf = VecUnit::from_vec(data.clone());
1307        buf.append(&mut other_buf);
1308
1309        assert!(other_buf.is_empty());
1310
1311        for (i, &val) in buf.iter_as::<f32>().unwrap().enumerate() {
1312            assert_eq!(val, data[i]);
1313        }
1314    }
1315
1316    /// Test that `VecCopy` can be extended by or constructed from an iterator.
1317    #[test]
1318    fn extend_and_collect() {
1319        let mut buf = VecUnit::with_type::<f32>();
1320        let other = VecUnit::from(vec![1.0_f32, 23.0, 0.01]);
1321        buf.extend(other.iter());
1322
1323        let buf2: VecUnit = other.iter().collect();
1324
1325        assert_eq!(buf.as_slice_as::<f32>(), buf2.as_slice_as::<f32>());
1326    }
1327
1328    /// Test dynamically sized vtables.
1329    #[cfg(feature = "traits")]
1330    #[test]
1331    fn dynamic_vtables() {
1332        use crate::into_dyn;
1333        let buf = VecUnit::with_type::<u8>(); // Create an empty buffer.
1334
1335        let mut buf_dyn = into_dyn![VecCopy<dyn Any>](buf);
1336
1337        buf_dyn.push(CopyValueRef::<()>::new(&1u8));
1338        buf_dyn.push(CopyValueRef::<()>::new(&100u8));
1339        buf_dyn.push(CopyValueRef::<()>::new(&23u8));
1340
1341        let vec: Vec<u8> = buf_dyn.into_vec().unwrap();
1342
1343        assert_eq!(vec, vec![1u8, 100, 23]);
1344    }
1345}