dync/
vec_dyn.rs

1//! This module extends the `VecCopy` type to more general non-`Copy` types that can be `Drop`ped.
2//!
3//! This module is enabled by the `traits` feature.
4//!
5//! # Examples
6//!
7//! Create homogeneous untyped `Vec`s that store a single virtual function table for all contained
8//! elements:
9//! ```
10//! use dync::VecDrop;
11//! // Create an untyped `Vec`.
12//! let vec: VecDrop = vec![1_i32,2,3,4].into();
13//! // Access elements either by downcasting to the underlying type.
14//! for value_ref in vec.iter() {
15//!     let int = value_ref.downcast::<i32>().unwrap();
16//!     println!("{}", int);
17//! }
18//! // Or downcast the iterator directly for more efficient traversal.
19//! for int in vec.iter_as::<i32>().unwrap() {
20//!     println!("{}", int);
21//! }
22//! ```
23//!
24//! The `VecDrop` type defaults to the empty virtual table (with the exception of the drop
25//! function), which is not terribly useful when the contained values need to be processed in
26//! some way.  `dync` provides support for common standard library traits such as:
27//! - `Drop`
28//! - `Clone`
29//! - `PartialEq`
30//! - `std::hash::Hash`
31//! - `std::fmt::Debug`
32//! - `Send` and `Sync`
33//! - more to come
34//!
35//! So to produce a `VecDrop` of a printable type, we could instead do
36//! ```
37//! use dync::{VecDyn, traits::DebugVTable};
38//! // Create an untyped `Vec` of `std::fmt::Debug` types.
39//! let vec: VecDyn<DebugVTable> = vec![1_i32,2,3,4].into();
40//! // We can now iterate and print value references (which inherit the VTable from the container)
41//! // without needing a downcast.
42//! for value_ref in vec.iter() {
43//!     println!("{:?}", value_ref);
44//! }
45//! ```
46
47#![allow(dead_code)]
48
49use std::{
50    any::{Any, TypeId},
51    fmt,
52    mem::ManuallyDrop,
53    slice,
54};
55
56// At the time of this writing, there is no evidence that there is a significant benefit in sharing
57// vtables via Rc or Arc, but to make potential future refactoring easier we use the Ptr alias.
58use std::boxed::Box as Ptr;
59
60#[cfg(feature = "numeric")]
61use num_traits::{cast, NumCast, Zero};
62
63use crate::meta::*;
64use crate::slice::*;
65use crate::traits::*;
66use crate::value::*;
67use crate::vec_void::VecVoid;
68use crate::vtable::*;
69use crate::VecCopy;
70use crate::{ElementBytes, ElementBytesMut};
71
72pub trait Elem: Any + DropBytes {}
73impl<T> Elem for T where T: Any + DropBytes {}
74
75pub struct VecDyn<V>
76where
77    V: ?Sized + HasDrop,
78{
79    data: ManuallyDrop<VecCopy<V>>,
80}
81
82pub type VecDrop = VecDyn<DropVTable>;
83
84impl<V: ?Sized + HasDrop> Drop for VecDyn<V> {
85    fn drop(&mut self) {
86        unsafe {
87            {
88                // Drop the contents using the associated drop function
89                let VecCopy { data, vtable, .. } = &mut *self.data;
90                for elem_bytes in data.byte_chunks_mut() {
91                    vtable.drop_fn()(elem_bytes);
92                }
93            }
94
95            // Drop the vec itself
96            ManuallyDrop::drop(&mut self.data);
97        }
98    }
99}
100
101impl<V: ?Sized + Clone + HasDrop + HasClone> Clone for VecDyn<V> {
102    fn clone(&self) -> Self {
103        let data_clone = |vec_void: &VecVoid| {
104            let mut new_data = vec_void.clone();
105            unsafe {
106                vec_void
107                    .byte_chunks()
108                    .zip(new_data.byte_chunks_mut())
109                    .for_each(|(src, dst)| {
110                        // This is safe since `clone_into_raw_fn` ensures that the
111                        // bytes in dst are not dropped before cloning, which is essential, since they
112                        // are just copied by the `.to_vec()` call above.
113                        self.data.vtable.clone_into_raw_fn()(src, dst)
114                    });
115            }
116            new_data
117        };
118        VecDyn {
119            data: ManuallyDrop::new(self.data.clone_with(data_clone)),
120        }
121    }
122}
123
124impl<V: ?Sized + HasDrop + HasPartialEq> PartialEq for VecDyn<V> {
125    fn eq(&self, other: &Self) -> bool {
126        self.iter()
127            .zip(other.iter())
128            .all(|(this, that)| this == that)
129    }
130}
131
132impl<V: ?Sized + HasDrop + HasEq> Eq for VecDyn<V> {}
133
134impl<V: ?Sized + HasDrop + HasHash> std::hash::Hash for VecDyn<V> {
135    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
136        self.iter().for_each(|elem| elem.hash(state));
137    }
138}
139
140impl<V: ?Sized + HasDrop + HasDebug> fmt::Debug for VecDyn<V> {
141    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142        f.debug_list().entries(self.iter()).finish()
143    }
144}
145
146unsafe impl<V: ?Sized + HasDrop + HasSend> Send for VecDyn<V> {}
147unsafe impl<V: ?Sized + HasDrop + HasSync> Sync for VecDyn<V> {}
148
149impl<V: HasDrop> VecDyn<V> {
150    /// Construct an empty vector with a specific pointed-to element type.
151    #[inline]
152    pub fn with_type<T: Elem>() -> Self
153    where
154        V: VTable<T>,
155    {
156        VecDyn {
157            // This is safe because we are handling the additional processing needed
158            // by `Clone` types in this container.
159            data: ManuallyDrop::new(unsafe { VecCopy::with_type_non_copy::<T>() }),
160        }
161    }
162
163    /// Construct an empty vector with a capacity for a given number of typed pointed-to elements.
164    #[inline]
165    pub fn with_capacity<T: Elem>(n: usize) -> Self
166    where
167        V: VTable<T>,
168    {
169        VecDyn {
170            // This is safe because we are handling the additional processing needed
171            // by `Clone` types in this container.
172            data: ManuallyDrop::new(unsafe { VecCopy::with_capacity_non_copy::<T>(n) }),
173        }
174    }
175
176    /// Construct a `VecDyn` from a given `Vec` reusing the space already allocated by the given
177    /// vector.
178    pub fn from_vec<T: Elem>(vec: Vec<T>) -> Self
179    where
180        V: VTable<T>,
181    {
182        VecDyn {
183            // This is safe because we are handling the additional processing needed
184            // by `Clone` types in this container.
185            data: ManuallyDrop::new(unsafe { VecCopy::from_vec_non_copy(vec) }),
186        }
187    }
188}
189
190impl<V: ?Sized + HasDrop> VecDyn<V> {
191    /// Construct a vector with the same type as the given vector without copying its data.
192    #[inline]
193    pub fn with_type_from<'a>(other: impl Into<Meta<VTableRef<'a, V>>>) -> Self
194    where
195        V: Clone + 'a,
196    {
197        VecDyn {
198            data: ManuallyDrop::new(VecCopy::with_type_from(other.into())),
199        }
200    }
201
202    /// Construct a `VecDyn` 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    /// `VecDyn::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>) -> VecDyn<V> {
213        VecDyn {
214            data: ManuallyDrop::new(VecCopy { data, vtable }),
215        }
216    }
217
218    /// Convert this collection into its raw components.
219    ///
220    /// This function exists mainly to enable the `into_dyn` macro until `CoerceUnsized` is
221    /// stabilized.
222    #[inline]
223    pub fn into_raw_parts(self) -> (VecVoid, Ptr<V>) {
224        unsafe {
225            // Inhibit dropping self.
226            let mut md = ManuallyDrop::new(self);
227            // Taking is safe here because data will not be used after this call since self is
228            // consumed, and self will not be dropped.
229            let VecCopy { data, vtable } = ManuallyDrop::take(&mut md.data);
230            (data, vtable)
231        }
232    }
233
234    /// Retrieve the associated virtual function table.
235    pub fn vtable(&self) -> &V {
236        &self.data.vtable
237    }
238
239    /// Upcast the `VecDyn` into a more general base `VecDyn`.
240    ///
241    /// This function converts the underlying virtual function table into a subset of the existing
242    #[inline]
243    pub fn upcast<U: HasDrop + From<V>>(self) -> VecDyn<U>
244    where
245        V: Clone,
246    {
247        // Inhibit dropping. The output vec takes ownership.
248        let mut md = ManuallyDrop::new(self);
249        // This is safe since self will not be dropped, so md.data will not be dropped.
250        let data = unsafe { ManuallyDrop::take(&mut md.data) };
251        VecDyn {
252            data: ManuallyDrop::new(data.upcast()), //_with(|(drop, v)| (drop, U::from(v)))),
253        }
254    }
255
256    /// Clear the data buffer without destroying its type information.
257    #[inline]
258    pub fn clear(&mut self) {
259        // Drop all elements manually.
260        unsafe {
261            let VecCopy { data, vtable, .. } = &mut *self.data;
262            for elem_bytes in data.byte_chunks_mut() {
263                vtable.drop_fn()(elem_bytes);
264            }
265            data.clear();
266        }
267    }
268
269    /// Add an element to this buffer.
270    ///
271    /// If the type of the given element coincides with the type stored by this buffer,
272    /// then the modified buffer is returned via a mutable reference.  Otherwise, `None` is
273    /// returned.
274    #[inline]
275    pub fn push_as<T: Elem>(&mut self, element: T) -> Option<&mut Self> {
276        let _ = self.data.push_as(element)?;
277        Some(self)
278    }
279
280    /// Check if the current buffer contains elements of the specified type. Returns `Some(self)`
281    /// if the type matches and `None` otherwise.
282    #[inline]
283    pub fn check<T: Elem>(self) -> Option<Self> {
284        self.data.check_ref::<T>()?;
285        Some(self)
286    }
287
288    /// Check if the current buffer contains elements of the specified type. Returns `None` if the
289    /// check fails, otherwise a reference to self is returned.
290    #[inline]
291    pub fn check_ref<T: Elem>(&self) -> Option<&Self> {
292        self.data.check_ref::<T>().map(|_| self)
293    }
294
295    /// Check if the current buffer contains elements of the specified type. Same as `check_ref`
296    /// but consumes and produces a mut reference to self.
297    #[inline]
298    pub fn check_mut<T: Elem>(&mut self) -> Option<&mut Self> {
299        self.data.check_mut::<T>()?;
300        Some(self)
301    }
302
303    /*
304     * Accessors
305     */
306
307    /// Get the `TypeId` of data stored within this buffer.
308    #[inline]
309    pub fn element_type_id(&self) -> TypeId {
310        self.data.element_type_id()
311    }
312
313    /// Get the number of elements stored in this buffer.
314    #[inline]
315    pub fn len(&self) -> usize {
316        self.data.len()
317    }
318
319    /// Check if there are any elements stored in this buffer.
320    #[inline]
321    pub fn is_empty(&self) -> bool {
322        self.data.is_empty()
323    }
324
325    /// Get the size of the element type in bytes.
326    #[inline]
327    pub fn element_size(&self) -> usize {
328        self.data.element_size()
329    }
330
331    /// Return an iterator to a slice representing typed data.
332    ///
333    /// Returns `None` if the given type `T` doesn't match the internal.
334    #[inline]
335    pub fn iter_as<T: Elem>(&self) -> Option<slice::Iter<T>> {
336        self.data.iter_as::<T>()
337    }
338
339    /// Return an iterator to a mutable slice representing typed data.
340    ///
341    /// Returns `None` if the given type `T` doesn't match the internal.
342    #[inline]
343    pub fn iter_mut_as<T: Elem>(&mut self) -> Option<slice::IterMut<T>> {
344        self.data.iter_mut_as::<T>()
345    }
346
347    /// An alternative to using the `Into` trait.
348    ///
349    /// This function helps the compiler determine the type `T` automatically.
350    #[inline]
351    pub fn into_vec<T: Elem>(self) -> Option<Vec<T>> {
352        // This is safe because self.data will not be used after this call, and the resulting
353        // Vec<T> will drop all elements correctly.
354        unsafe {
355            // Inhibit the Drop for self.
356            let mut no_drop = ManuallyDrop::new(self);
357            // Extract the value from data and turn it into a `Vec` which will handle the drop
358            // correctly.
359            ManuallyDrop::take(&mut no_drop.data).into_vec()
360        }
361    }
362
363    /// Convert this buffer into a typed slice.
364    /// Returs `None` if the given type `T` doesn't match the internal.
365    #[inline]
366    pub fn as_slice_as<T: Elem>(&self) -> Option<&[T]> {
367        self.data.as_slice_as()
368    }
369
370    /// Convert this buffer into a typed mutable slice.
371    /// Returs `None` if the given type `T` doesn't match the internal.
372    #[inline]
373    pub fn as_mut_slice_as<T: Elem>(&mut self) -> Option<&mut [T]> {
374        self.data.as_mut_slice_as()
375    }
376
377    /// Get a `const` reference to the `i`'th element of the buffer.
378    #[inline]
379    pub fn get_ref_as<T: Elem>(&self, i: usize) -> Option<&T> {
380        self.data.get_ref_as::<T>(i)
381    }
382
383    /// Get a mutable reference to the `i`'th element of the buffer.
384    #[inline]
385    pub fn get_mut_as<T: Elem>(&mut self, i: usize) -> Option<&mut T> {
386        self.data.get_mut_as::<T>(i)
387    }
388
389    /// Move bytes to this buffer.
390    ///
391    /// The given buffer must have the same underlying type as `self`.
392    #[inline]
393    pub fn append(&mut self, buf: &mut VecDyn<V>) -> Option<&mut Self> {
394        // It is sufficient to move the bytes, no clones or drops are necessary here.
395        let _ = self.data.append(&mut buf.data)?;
396        Some(self)
397    }
398
399    /// Rotates the slice in-place such that the first `mid` elements of the slice move to the end
400    /// while the last `self.len() - mid` elements move to the front.
401    ///
402    /// After calling `rotate_left`, the element previously at index `mid` will become the
403    /// first element in the slice.
404    #[inline]
405    pub fn rotate_left(&mut self, mid: usize) {
406        self.data.rotate_left(mid)
407    }
408
409    /// Rotates the slice in-place such that the first `self.len() - k` elements of the slice move
410    /// to the end while the last `k` elements move to the front.
411    ///
412    /// After calling `rotate_right`, the element previously at index `k` will become the
413    /// first element in the slice.
414    #[inline]
415    pub fn rotate_right(&mut self, k: usize) {
416        self.data.rotate_right(k)
417    }
418
419    /*
420     * Value API. This allows users to manipulate contained data without knowing the element type.
421     */
422
423    /// Push a value onto this buffer.
424    ///
425    /// If the type of the given value coincides with the type stored by this buffer,
426    /// then the modified buffer is returned via a mutable reference.  Otherwise, `None` is
427    /// returned.
428    ///
429    /// Note that the vtables need not patch, only the underlying types are required to match.
430    #[inline]
431    pub fn push<U: ?Sized + HasDrop>(&mut self, value: BoxValue<U>) -> Option<&mut Self> {
432        if value.value_type_id() == self.element_type_id() {
433            // Prevent the value from being dropped at the end of this scope since it will be later
434            // dropped by this container. The remaining fields like vtable will be dropped here.
435            let (bytes, _, _, _) = value.into_raw_parts();
436            self.data.data.push(&*bytes);
437            Some(self)
438        } else {
439            None
440        }
441    }
442
443    /// Push a clone of the referenced value to this buffer.
444    ///
445    /// If the type of the given value coincides with the type stored by this buffer,
446    /// then the modified buffer is returned via a mutable reference.  Otherwise, `None` is
447    /// returned.
448    ///
449    /// This is more efficient than `push` since it avoids an extra allocation, however it
450    /// requires the contained value to be `Clone`.
451    #[inline]
452    pub fn push_cloned(&mut self, value: ValueRef<V>) -> Option<&mut Self>
453    where
454        V: HasClone,
455    {
456        if self.element_type_id() == value.value_type_id() {
457            let VecCopy { data, vtable } = &mut *self.data;
458            let new_len = data.len() + 1;
459            // This does not leak because the copied bytes are guaranteed to be dropped by self.
460            // This will also not cause a double free since the bytes in self are not dropped by
461            // clone_into_raw_fn unlike clone_from_fn.
462            unsafe {
463                data.resize_with(new_len, |uninit_val| {
464                    vtable.clone_into_raw_fn()(value.bytes, uninit_val);
465                });
466            }
467            Some(self)
468        } else {
469            None
470        }
471    }
472
473    /// Get a reference to a value stored in this container at index `i`.
474    #[inline]
475    pub fn get(&self, i: usize) -> ValueRef<V> {
476        debug_assert!(i < self.len());
477        // This call is safe since our buffer guarantees that the given bytes have the
478        // corresponding TypeId.
479        unsafe {
480            ValueRef::from_raw_parts(
481                self.data.data.get_bytes(i),
482                self.element_type_id(),
483                self.data.data.elem.alignment,
484                self.data.vtable.as_ref(),
485            )
486        }
487    }
488
489    /// Return an iterator over untyped value references stored in this buffer.
490    ///
491    /// In contrast to `iter`, this function defers downcasting on a per element basis.
492    /// As a result, this type of iteration is typically less efficient if a typed value is
493    /// needed for each element.
494    #[inline]
495    pub fn iter(&self) -> impl Iterator<Item = ValueRef<V>> {
496        let VecCopy { data, vtable } = &*self.data;
497        data.byte_chunks().map(move |bytes| unsafe {
498            ValueRef::from_raw_parts(
499                bytes,
500                data.elem.type_id,
501                data.elem.alignment,
502                vtable.as_ref(),
503            )
504        })
505    }
506
507    /// Get a mutable reference to a value stored in this container at index `i`.
508    #[inline]
509    pub fn get_mut(&mut self, i: usize) -> ValueMut<V> {
510        debug_assert!(i < self.len());
511        // Safety is guaranteed here by the value API.
512        let Self { data, .. } = self;
513        let element_type_id = data.element_type_id();
514        let element_alignment = data.data.elem.alignment;
515        let &mut VecCopy {
516            ref mut data,
517            ref vtable,
518            ..
519        } = &mut **data;
520        // This call is safe since our buffer guarantees that the given bytes have the
521        // corresponding TypeId.
522        unsafe {
523            ValueMut::from_raw_parts(
524                data.get_bytes_mut(i),
525                element_type_id,
526                element_alignment,
527                vtable.as_ref(),
528            )
529        }
530    }
531
532    /// Return an iterator over mutable untyped value references stored in this buffer.
533    ///
534    /// In contrast to `iter_mut`, this function defers downcasting on a per element basis.  As a
535    /// result, this type of iteration is typically less efficient if a typed value is needed
536    /// for each element.
537    #[inline]
538    pub fn iter_mut(&mut self) -> impl Iterator<Item = ValueMut<V>> {
539        let VecCopy {
540            ref mut data,
541            ref vtable,
542        } = *self.data;
543        let vtable = vtable.as_ref();
544        let element_type_id = data.elem.type_id;
545        let element_alignment = data.elem.alignment;
546        unsafe {
547            data.byte_chunks_mut().map(move |bytes| {
548                ValueMut::from_raw_parts(bytes, element_type_id, element_alignment, vtable)
549            })
550        }
551    }
552
553    pub fn as_slice(&self) -> Slice<V> {
554        let VecCopy {
555            ref data,
556            ref vtable,
557        } = *self.data;
558        unsafe { Slice::from_raw_parts(data.bytes(), data.elem, vtable.as_ref()) }
559    }
560
561    pub fn as_mut_slice(&mut self) -> SliceMut<V> {
562        let VecCopy {
563            ref mut data,
564            ref vtable,
565        } = *self.data;
566        let elem = data.elem;
567        unsafe { SliceMut::from_raw_parts(data.bytes_mut(), elem, vtable.as_ref()) }
568    }
569
570    /*
571     * Advanced Accessors
572     */
573
574    /// Get a `const` reference to the `i`'th element of the vector.
575    ///
576    /// This can be used to reinterpret the internal data as a different type. Note that if the
577    /// size of the given type `T` doesn't match the size of the internal type, `i` will really
578    /// index the `i`th `T` sized chunk in the current vector. See the implementation for details.
579    ///
580    /// # Safety
581    ///
582    /// It is assumed that that the vector contains elements of type `T` and that `i` is strictly
583    /// less than the length of this vector, otherwise this function may cause undefined behavior.
584    ///
585    /// This function is a complete opt-out of all safety checks.
586    #[inline]
587    pub unsafe fn get_unchecked_ref<T: Any>(&self, i: usize) -> &T {
588        self.data.get_unchecked_ref(i)
589    }
590
591    /// Get a mutable reference to the `i`'th element of the vector.
592    ///
593    /// This can be used to reinterpret the internal data as a different type. Note that if the
594    /// size of the given type `T` doesn't match the size of the internal type, `i` will really
595    /// index the `i`th `T` sized chunk in the current vector. See the implementation for details.
596    ///
597    /// # Safety
598    ///
599    /// It is assumed that that the vector contains elements of type `T` and that `i` is strictly
600    /// less than the length of this vector, otherwise this function may cause undefined behavior.
601    ///
602    /// This function is opts-out of all safety checks.
603    #[inline]
604    pub unsafe fn get_unchecked_mut<T: Any>(&mut self, i: usize) -> &mut T {
605        self.data.get_unchecked_mut(i)
606    }
607}
608
609// Additional functionality of VecDyns that implement Clone.
610impl<V: HasDrop + HasClone> VecDyn<V> {
611    /// Construct a typed `VecDyn` with a given size and filled with the specified default
612    /// value.
613    #[inline]
614    pub fn with_size<T: Elem + Clone>(n: usize, def: T) -> Self
615    where
616        V: VTable<T>,
617    {
618        VecDyn {
619            // This is safe because we are handling the additional processing needed
620            // by `Clone` types in this container.
621            data: ManuallyDrop::new(unsafe { VecCopy::from_vec_non_copy(vec![def; n]) }),
622        }
623    }
624
625    /// Construct a buffer from a given slice by cloning the data.
626    #[inline]
627    pub fn from_slice<T: Elem + Clone>(slice: &[T]) -> Self
628    where
629        V: VTable<T>,
630    {
631        VecDyn {
632            // This is safe because we are handling the additional processing needed
633            // by `Clone` types in this container.
634            data: ManuallyDrop::new(unsafe { VecCopy::from_slice_non_copy::<T>(slice) }),
635        }
636    }
637}
638
639impl<V: HasDrop> VecDyn<V> {
640    #[cfg(feature = "numeric")]
641    /// Cast a numeric `VecDyn` into the given output `Vec` type.
642    ///
643    /// This only works if the contained element is `Copy`.
644    pub fn cast_into_vec<T>(&self) -> Option<Vec<T>>
645    where
646        T: Elem + Copy + NumCast + Zero,
647    {
648        use crate::CopyElem;
649        // Helper function (generic on the input) to convert the given VecDyn into Vec.
650        unsafe fn convert_into_vec<I, O, V>(buf: &VecCopy<V>) -> Option<Vec<O>>
651        where
652            I: CopyElem + Any + NumCast,
653            O: CopyElem + NumCast + Zero,
654        {
655            debug_assert_eq!(buf.element_type_id(), TypeId::of::<I>()); // Check invariant.
656            Some(
657                buf.as_slice_as_unchecked()
658                    .iter()
659                    .map(|elem: &I| cast(*elem).unwrap_or_else(O::zero))
660                    .collect(),
661            )
662        }
663        call_numeric_buffer_fn!( convert_into_vec::<_, T, V>(&self.data) or { None } )
664    }
665}
666
667impl<V: ?Sized + HasDrop + HasClone> VecDyn<V> {
668    /// Resizes the buffer in-place to store `new_len` elements and returns an optional
669    /// mutable reference to `Self`.
670    ///
671    /// If `value` does not correspond to the underlying element type, then `None` is returned and the
672    /// buffer is left unchanged.
673    ///
674    /// This function has the similar properties to `Vec::resize`.
675    #[inline]
676    pub fn resize<T: Elem + Clone>(&mut self, new_len: usize, value: T) -> Option<&mut Self> {
677        self.check_ref::<T>()?;
678        if new_len >= self.len() {
679            let diff = new_len - self.len();
680            self.data.reserve(diff);
681            for _ in 0..diff {
682                self.data.push_as(value.clone());
683            }
684        } else {
685            // Drop trailing elements manually.
686            unsafe {
687                let VecCopy { data, vtable, .. } = &mut *self.data;
688                for elem_bytes in data.byte_chunks_mut().skip(new_len) {
689                    vtable.drop_fn()(elem_bytes);
690                }
691            }
692
693            // Truncate data
694            self.data.data.truncate(new_len);
695        }
696        Some(self)
697    }
698
699    /// Fill the current buffer with clones of the given value.
700    ///
701    /// The size of the buffer is left unchanged. If the given type doesn't match the
702    /// internal type, `None` is returned, otherwise a mutable reference to the modified buffer is
703    /// returned.
704    #[inline]
705    pub fn fill<T: Elem + Clone>(&mut self, def: T) -> Option<&mut Self> {
706        for v in self.iter_mut_as::<T>()? {
707            *v = def.clone();
708        }
709        Some(self)
710    }
711
712    /// Append cloned items from this buffer to a given `Vec`.
713    ///
714    /// Return the mutable reference `Some(vec)` if type matched the internal type and
715    /// `None` otherwise.
716    #[inline]
717    pub fn append_cloned_to_vec<'a, T: Elem + Clone>(
718        &self,
719        vec: &'a mut Vec<T>,
720    ) -> Option<&'a mut Vec<T>> {
721        let slice = self.as_slice_as()?;
722        // Only allocate once we have confirmed that the given `T` matches to avoid unnecessary
723        // overhead.
724        vec.reserve(self.len());
725        vec.extend_from_slice(slice);
726        Some(vec)
727    }
728
729    /// Clones contents of `self` into the given `Vec`.
730    #[inline]
731    pub fn clone_into_vec<T: Elem + Clone>(&self) -> Option<Vec<T>> {
732        let mut vec = Vec::new();
733        // NOTE: vec cannot be captured by closure if it's also mutably borrowed.
734        #[allow(clippy::manual_map)]
735        match self.append_cloned_to_vec(&mut vec) {
736            Some(_) => Some(vec),
737            None => None,
738        }
739    }
740}
741
742/// Convert a `Vec` to a buffer.
743impl<T: Elem, V: HasDrop + VTable<T>> From<Vec<T>> for VecDyn<V> {
744    #[inline]
745    fn from(vec: Vec<T>) -> VecDyn<V> {
746        VecDyn::from_vec(vec)
747    }
748}
749
750/// Convert a slice to a `VecDyn`.
751impl<'a, T, V> From<&'a [T]> for VecDyn<V>
752where
753    T: Elem + Clone,
754    V: HasDrop + VTable<T> + HasClone,
755{
756    #[inline]
757    fn from(slice: &'a [T]) -> VecDyn<V> {
758        VecDyn::from_slice(slice)
759    }
760}
761
762/// Convert a buffer to a `Vec` with an option to fail.
763impl<T: Elem, V: ?Sized + HasDrop + VTable<T>> From<VecDyn<V>> for Option<Vec<T>> {
764    #[inline]
765    fn from(v: VecDyn<V>) -> Option<Vec<T>> {
766        v.into_vec()
767    }
768}
769
770impl<'a, V: Clone + HasDrop> From<&'a VecDyn<V>> for Meta<VTableRef<'a, V>> {
771    #[inline]
772    fn from(v: &'a VecDyn<V>) -> Self {
773        Meta::from(&*v.data)
774    }
775}
776
777#[cfg(test)]
778mod tests {
779    use super::*;
780    use dync_derive::dync_trait;
781    use rand::prelude::*;
782    use std::rc::Rc;
783
784    #[dync_trait(dync_crate_name = "crate")]
785    pub trait AllTrait: Clone + PartialEq + Eq + std::hash::Hash + std::fmt::Debug {}
786    impl<T> AllTrait for T where T: Clone + PartialEq + Eq + std::hash::Hash + std::fmt::Debug {}
787    type VecCopyAll = VecCopy<AllTraitVTable>;
788    type VecDynAll = VecDyn<AllTraitVTable>;
789    type SliceAll<'a> = Slice<'a, AllTraitVTable>;
790    type SliceMutAll<'a> = SliceMut<'a, AllTraitVTable>;
791
792    #[dync_trait(dync_crate_name = "crate")]
793    pub trait FloatTrait: Clone + PartialEq + std::fmt::Debug {}
794    impl<T> FloatTrait for T where T: Clone + PartialEq + std::fmt::Debug {}
795    type VecDynFloat = VecDyn<FloatTraitVTable>;
796
797    #[inline]
798    fn compute(x: i64, y: i64, z: i64) -> [i64; 3] {
799        [x - 2 * y + z * 2, y - 2 * z + x * 2, z - 2 * x + y * 2]
800    }
801
802    #[inline]
803    fn make_random_vec_copy(n: usize) -> VecCopyAll {
804        make_random_vec(n).into()
805    }
806
807    #[inline]
808    fn make_random_vec_dyn(n: usize) -> VecDynAll {
809        make_random_vec(n).into()
810    }
811
812    #[inline]
813    fn make_random_vec(n: usize) -> Vec<[i64; 3]> {
814        let mut rng: StdRng = SeedableRng::from_seed([3; 32]);
815        let between = rand::distr::Uniform::new(1i64, 5).unwrap();
816        (0..n).map(move |_| [between.sample(&mut rng); 3]).collect()
817    }
818
819    #[inline]
820    fn vec_copy_compute<V: Clone>(v: &mut VecCopy<V>) {
821        for a in v.iter_mut() {
822            let a = a.downcast::<[i64; 3]>().unwrap();
823            let res = compute(a[0], a[1], a[2]);
824            a[0] = res[0];
825            a[1] = res[1];
826            a[2] = res[2];
827        }
828    }
829
830    #[inline]
831    fn vec_dyn_compute<V: Clone + HasDrop>(v: &mut VecDyn<V>) {
832        for a in v.iter_mut() {
833            let a = a.downcast::<[i64; 3]>().unwrap();
834            let res = compute(a[0], a[1], a[2]);
835            a[0] = res[0];
836            a[1] = res[1];
837            a[2] = res[2];
838        }
839    }
840
841    #[inline]
842    fn vec_compute(v: &mut Vec<[i64; 3]>) {
843        for a in v.iter_mut() {
844            let res = compute(a[0], a[1], a[2]);
845            a[0] = res[0];
846            a[1] = res[1];
847            a[2] = res[2];
848        }
849    }
850
851    #[cfg_attr(miri, ignore)]
852    #[test]
853    fn downcast_value_mut() {
854        use std::time::Instant;
855        let size = 90_000;
856        let mut v: VecDynAll = make_random_vec_dyn(size);
857        let start = Instant::now();
858        vec_dyn_compute(&mut v);
859        eprintln!("vec_dyn: {} millis", start.elapsed().as_millis());
860        let mut v: VecCopyAll = make_random_vec_copy(size);
861        let start = Instant::now();
862        vec_copy_compute(&mut v);
863        eprintln!("vec_copy: {} millis", start.elapsed().as_millis());
864        let mut v: Vec<[i64; 3]> = make_random_vec(size);
865        let start = Instant::now();
866        vec_compute(&mut v);
867        eprintln!("vec: {} millis", start.elapsed().as_millis());
868    }
869
870    #[test]
871    fn clone_from_test() {
872        use std::collections::HashSet;
873
874        // Let's create a collection of `Rc`s.
875        let vec_rc: Vec<_> = vec![1, 23, 2, 42, 23, 1, 13534653]
876            .into_iter()
877            .map(Rc::new)
878            .collect();
879        let buf = VecDynAll::from(vec_rc.clone()); // Clone into VecDyn
880
881        // Construct a hashset of unique values from the VecDyn.
882        let mut hashset: HashSet<BoxValue<AllTraitVTable>> = HashSet::new();
883
884        for rc_ref in buf.iter().take(4) {
885            assert!(hashset.insert(rc_ref.clone_value()));
886        }
887
888        assert!(!hashset.insert(BoxValue::new(Rc::clone(&vec_rc[4]))));
889        assert!(!hashset.insert(BoxValue::new(Rc::clone(&vec_rc[5]))));
890
891        assert_eq!(hashset.len(), 4);
892        assert!(hashset.contains(&BoxValue::new(Rc::new(1))));
893        assert!(hashset.contains(&BoxValue::new(Rc::new(23))));
894        assert!(hashset.contains(&BoxValue::new(Rc::new(2))));
895        assert!(hashset.contains(&BoxValue::new(Rc::new(42))));
896        assert!(!hashset.contains(&BoxValue::new(Rc::new(13534653))));
897    }
898
899    #[test]
900    fn clone_from_small_test() {
901        use std::collections::HashSet;
902
903        // Let's create a collection of `Rc`s.
904        let vec_rc: Vec<_> = vec![1, 23, 2, 42, 23, 1, 13534653]
905            .into_iter()
906            .map(Rc::new)
907            .collect();
908        let buf = VecDynAll::from(vec_rc.clone()); // Clone into VecDyn
909
910        // Construct a hashset of unique values from the VecDyn.
911        let mut hashset: HashSet<SmallValue<AllTraitVTable>> = HashSet::new();
912
913        for rc_ref in buf.iter().take(4) {
914            assert!(hashset.insert(rc_ref.clone_small_value()));
915        }
916
917        assert!(!hashset.insert(SmallValue::new(Rc::clone(&vec_rc[4]))));
918        assert!(!hashset.insert(SmallValue::new(Rc::clone(&vec_rc[5]))));
919
920        assert_eq!(hashset.len(), 4);
921        assert!(hashset.contains(&SmallValue::new(Rc::new(1))));
922        assert!(hashset.contains(&SmallValue::new(Rc::new(23))));
923        assert!(hashset.contains(&SmallValue::new(Rc::new(2))));
924        assert!(hashset.contains(&SmallValue::new(Rc::new(42))));
925        assert!(!hashset.contains(&SmallValue::new(Rc::new(13534653))));
926    }
927
928    #[test]
929    fn iter() {
930        let vec: Vec<_> = vec![1, 23, 2, 42, 11].into_iter().map(Rc::new).collect();
931        {
932            let buf = VecDynAll::from(vec.clone()); // Convert into buffer
933            let orig = Rc::new(100);
934            let mut rc = Rc::clone(&orig);
935            assert_eq!(Rc::strong_count(&rc), 2);
936            for val in buf.iter() {
937                ValueMut::new(&mut rc).clone_from_other(val).unwrap();
938            }
939            assert_eq!(Rc::strong_count(&orig), 1);
940            assert_eq!(Rc::strong_count(&rc), 3);
941            assert_eq!(Rc::strong_count(&vec[4]), 3);
942            assert!(vec.iter().take(4).all(|x| Rc::strong_count(x) == 2));
943            assert_eq!(rc, Rc::new(11));
944        }
945        assert!(vec.iter().all(|x| Rc::strong_count(x) == 1));
946    }
947
948    /// Test various ways to create a `VecDyn`.
949    #[test]
950    fn initialization_test() {
951        // Empty typed buffer.
952        let a = VecDynAll::with_type::<Rc<u8>>();
953        assert_eq!(a.len(), 0);
954        assert_eq!(a.element_type_id(), TypeId::of::<Rc<u8>>());
955
956        // Empty buffer typed by the given type id.
957        let b = VecDynAll::with_type_from(&a);
958        assert_eq!(b.len(), 0);
959        assert_eq!(b.element_type_id(), TypeId::of::<Rc<u8>>());
960
961        // Empty typed buffer with a given capacity.
962        let a = VecDynAll::with_capacity::<Rc<u8>>(4);
963        assert_eq!(a.len(), 0);
964        assert_eq!(a.element_type_id(), TypeId::of::<Rc<u8>>());
965    }
966
967    /// Test resizing a buffer.
968    #[test]
969    fn resize() {
970        let mut a = VecDynAll::with_type::<Rc<u8>>();
971
972        // Increase the size of a.
973        a.resize(3, Rc::new(1u8))
974            .expect("Failed to resize VecDyn up by 3 elements");
975
976        assert_eq!(a.len(), 3);
977        for i in 0..3 {
978            assert_eq!(a.get_ref_as::<Rc<u8>>(i).unwrap(), &Rc::new(1));
979        }
980
981        // Truncate a.
982        a.resize(2, Rc::new(1u8))
983            .expect("Failed to resize VecDyn down to 2 elements");
984
985        assert_eq!(a.len(), 2);
986        for i in 0..2 {
987            assert_eq!(a.get_ref_as::<Rc<u8>>(i).unwrap(), &Rc::new(1));
988        }
989    }
990
991    #[test]
992    fn data_integrity_u8_test() {
993        let vec: Vec<Rc<u8>> = vec![1u8, 3, 4, 1, 2].into_iter().map(Rc::new).collect();
994        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
995        let nu_vec: Vec<Rc<u8>> = buf.clone_into_vec().unwrap(); // Convert back into vec
996        assert_eq!(vec, nu_vec);
997
998        let vec: Vec<Rc<u8>> = vec![1u8, 3, 4, 1, 2, 52, 1, 3, 41, 23, 2]
999            .into_iter()
1000            .map(Rc::new)
1001            .collect();
1002        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1003        let nu_vec: Vec<Rc<u8>> = buf.clone_into_vec().unwrap(); // Convert back into vec
1004        assert_eq!(vec, nu_vec);
1005    }
1006
1007    #[test]
1008    fn data_integrity_i16_test() {
1009        let vec: Vec<Rc<i16>> = vec![1i16, -3, 1002, -231, 32]
1010            .into_iter()
1011            .map(Rc::new)
1012            .collect();
1013        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1014        let nu_vec: Vec<Rc<i16>> = buf.clone_into_vec().unwrap(); // Convert back into vec
1015        assert_eq!(vec, nu_vec);
1016
1017        let vec: Vec<Rc<i16>> = vec![1i16, -3, 1002, -231, 32, 42, -123, 4]
1018            .into_iter()
1019            .map(Rc::new)
1020            .collect();
1021        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1022        let nu_vec: Vec<Rc<i16>> = buf.clone_into_vec().unwrap(); // Convert back into vec
1023        assert_eq!(vec, nu_vec);
1024    }
1025
1026    #[test]
1027    fn data_integrity_i32_test() {
1028        let vec: Vec<Rc<i32>> = vec![1i32, -3, 1002, -231, 32]
1029            .into_iter()
1030            .map(Rc::new)
1031            .collect();
1032        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1033        let nu_vec: Vec<Rc<i32>> = buf.into_vec().unwrap(); // Convert back into vec
1034        assert_eq!(vec, nu_vec);
1035
1036        let vec: Vec<Rc<i32>> = vec![1i32, -3, 1002, -231, 32, 42, -123]
1037            .into_iter()
1038            .map(Rc::new)
1039            .collect();
1040        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1041        let nu_vec: Vec<Rc<i32>> = buf.into_vec().unwrap(); // Convert back into vec
1042        assert_eq!(vec, nu_vec);
1043    }
1044
1045    // Pushing to an empty buffer must be done carefully. This previously caused memory issues.
1046    #[test]
1047    fn f32x3_push_clone_from_empty() {
1048        // When a VecDyn/VecCopy/VecVoid is created from a Vec<T>, it forfeits knowledge about
1049        // allocation strategy. If items have already been allocated, we can expect further allocations
1050        // to be in sizes at least multiple of the original item, however when an empty Vec<T> is
1051        // converted, further allocations can create capacities that are not multiples of the original element
1052        // size, which would cause problems. This test ensures there are no panics or undefined behaviour
1053        // when converting empty vecs.
1054
1055        // Triplet of u32
1056        let mut vec = vec![];
1057        let mut buf = VecDynFloat::from(vec.clone()); // Convert into buffer
1058        buf.push_cloned(ValueRef::new(&[2_u32; 3]));
1059        vec.push([2; 3]);
1060        let nu_vec: Vec<[u32; 3]> = buf.clone_into_vec().unwrap(); // Convert back into vec
1061        assert_eq!(vec, nu_vec);
1062
1063        // Triplet of f64
1064        let mut vec = vec![];
1065        let mut buf = VecDynFloat::from(vec.clone()); // Convert into buffer
1066        buf.push_cloned(ValueRef::new(&[2.0_f64; 3]));
1067        vec.push([2.0; 3]);
1068        let nu_vec: Vec<[f64; 3]> = buf.clone_into_vec().unwrap(); // Convert back into vec
1069        assert_eq!(vec, nu_vec);
1070
1071        // With capacity
1072        let mut vec = Vec::<[f64; 3]>::with_capacity(2);
1073        let mut buf = VecDynFloat::from(vec.clone()); // Clone here can reset the capacity to 0
1074        buf.push_cloned(ValueRef::new(&[2.0_f64; 3]));
1075        vec.push([2.0; 3]);
1076        let nu_vec: Vec<[f64; 3]> = buf.clone_into_vec().unwrap(); // Convert back into vec
1077        assert_eq!(vec, nu_vec);
1078
1079        // Cloned empty
1080        let mut vec = Vec::new();
1081        let buf = VecDynFloat::from(vec.clone());
1082        // Clone below resests the capacity to 0 and follows a different codepath than the conversion
1083        // above.
1084        let mut buf2 = VecDynFloat::from(buf.clone());
1085        buf2.push_cloned(ValueRef::new(&[2.0_f64; 3]));
1086        vec.push([2.0; 3]);
1087        let nu_vec: Vec<[f64; 3]> = buf2.clone_into_vec().unwrap(); // Convert back into vec
1088        assert_eq!(vec, nu_vec);
1089
1090        // Empty from type
1091        let mut vec = Vec::new();
1092        let buf = VecDynFloat::from(vec.clone());
1093        // Clone below resests the capacity to 0 and follows a different codepath than the conversion
1094        // above.
1095        let mut buf2 = VecDynFloat::with_type_from(buf.as_slice());
1096        buf2.push_cloned(ValueRef::new(&[2.0_f64; 3]));
1097        vec.push([2.0; 3]);
1098        let nu_vec: Vec<[f64; 3]> = buf2.clone_into_vec().unwrap(); // Convert back into vec
1099        assert_eq!(vec, nu_vec);
1100    }
1101
1102    #[derive(Clone, Debug, PartialEq, Eq, Hash)]
1103    struct Foo {
1104        a: u8,
1105        b: i64,
1106    }
1107
1108    #[test]
1109    fn from_empty_vec_test() {
1110        let vec: Vec<Rc<u32>> = Vec::new();
1111        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1112        let nu_vec: Vec<Rc<u32>> = buf.into_vec().unwrap(); // Convert back into vec
1113        assert_eq!(vec, nu_vec);
1114
1115        let vec: Vec<Rc<String>> = Vec::new();
1116        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1117        let nu_vec: Vec<Rc<String>> = buf.into_vec().unwrap(); // Convert back into vec
1118        assert_eq!(vec, nu_vec);
1119
1120        let vec: Vec<Rc<Foo>> = Vec::new();
1121        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1122        let nu_vec: Vec<Rc<Foo>> = buf.into_vec().unwrap(); // Convert back into vec
1123        assert_eq!(vec, nu_vec);
1124    }
1125
1126    #[test]
1127    fn from_struct_test() {
1128        let f1 = Foo { a: 3, b: -32 };
1129        let f2 = Foo {
1130            a: 33,
1131            b: -3342432412,
1132        };
1133        let vec: Vec<Rc<Foo>> = vec![Rc::new(f1.clone()), Rc::new(f2.clone())];
1134        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1135        assert_eq!(Rc::new(f1), buf.get_ref_as::<Rc<Foo>>(0).unwrap().clone());
1136        assert_eq!(Rc::new(f2), buf.get_ref_as::<Rc<Foo>>(1).unwrap().clone());
1137        let nu_vec: Vec<Rc<Foo>> = buf.into_vec().unwrap(); // Convert back into vec
1138        assert_eq!(vec, nu_vec);
1139    }
1140
1141    #[test]
1142    fn from_strings_test() {
1143        let vec: Vec<Rc<String>> = vec![
1144            String::from("hi"),
1145            String::from("hello"),
1146            String::from("goodbye"),
1147            String::from("bye"),
1148            String::from("supercalifragilisticexpialidocious"),
1149            String::from("42"),
1150        ]
1151        .into_iter()
1152        .map(Rc::new)
1153        .collect();
1154        let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1155        assert_eq!(
1156            &Rc::new("hi".to_string()),
1157            buf.get_ref_as::<Rc<String>>(0).unwrap()
1158        );
1159        assert_eq!(
1160            &Rc::new("hello".to_string()),
1161            buf.get_ref_as::<Rc<String>>(1).unwrap()
1162        );
1163        assert_eq!(
1164            &Rc::new("goodbye".to_string()),
1165            buf.get_ref_as::<Rc<String>>(2).unwrap()
1166        );
1167        let nu_vec: Vec<Rc<String>> = buf.into_vec().unwrap(); // Convert back into vec
1168        assert_eq!(vec, nu_vec);
1169    }
1170
1171    #[test]
1172    fn iter_test() {
1173        let vec_u8: Vec<Rc<u8>> = vec![1u8, 3, 4, 1, 2, 4, 128, 32]
1174            .into_iter()
1175            .map(Rc::new)
1176            .collect();
1177        let buf = VecDynAll::from(vec_u8.clone()); // Convert into buffer
1178        for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
1179            assert_eq!(val, &vec_u8[i]);
1180        }
1181    }
1182
1183    #[cfg_attr(miri, ignore)]
1184    #[test]
1185    fn large_sizes_clone() {
1186        for i in 100000..100010 {
1187            let vec: Vec<Rc<u8>> = vec![32u8; i].into_iter().map(Rc::new).collect();
1188            let buf = VecDynAll::from(vec.clone()); // Convert into buffer
1189            let nu_vec: Vec<Rc<u8>> = buf.into_vec().unwrap(); // Convert back into vec
1190            assert_eq!(vec, nu_vec);
1191        }
1192    }
1193
1194    /// This test checks that an error is returned whenever the user tries to access data with the
1195    /// wrong type data.
1196    #[test]
1197    fn wrong_type_test() {
1198        let vec: Vec<Rc<u8>> = vec![1, 23, 2, 42, 11].into_iter().map(Rc::new).collect();
1199        let mut buf = VecDynAll::from(vec.clone()); // Convert into buffer
1200        assert_eq!(vec, buf.clone_into_vec::<Rc<u8>>().unwrap());
1201
1202        assert!(buf.clone_into_vec::<Rc<f64>>().is_none());
1203        assert!(buf.as_slice_as::<Rc<f64>>().is_none());
1204        assert!(buf.as_mut_slice_as::<Rc<f64>>().is_none());
1205        assert!(buf.iter_as::<Rc<[u8; 3]>>().is_none());
1206        assert!(buf.get_ref_as::<Rc<i32>>(1).is_none());
1207        assert!(buf.get_mut_as::<Rc<i32>>(2).is_none());
1208    }
1209
1210    /// Test pushing values and bytes to a buffer.
1211    #[test]
1212    fn push_test() {
1213        let mut vec_u8: Vec<Rc<u8>> = vec![1u8, 23, 2].into_iter().map(Rc::new).collect();
1214        let mut buf = VecDynAll::from(vec_u8.clone()); // Convert into buffer
1215        for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
1216            assert_eq!(val, &vec_u8[i]);
1217        }
1218
1219        vec_u8.push(Rc::new(42u8));
1220        buf.push_as(Rc::new(42u8)).unwrap(); // must provide explicit type
1221
1222        for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
1223            assert_eq!(val, &vec_u8[i]);
1224        }
1225
1226        vec_u8.push(Rc::new(11u8));
1227        buf.push_as(Rc::new(11u8)).unwrap();
1228
1229        // Check that we can't push something else onto the buffer.
1230        assert!(buf.push_as("other").is_none());
1231
1232        for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
1233            assert_eq!(val, &vec_u8[i]);
1234        }
1235    }
1236
1237    /// Test appending to a buffer from another buffer.
1238    #[test]
1239    fn append_test() {
1240        let mut buf = VecDynAll::with_type::<Rc<u8>>(); // Create an empty buffer.
1241
1242        let data: Vec<Rc<u8>> = vec![1, 23, 2, 42, 11].into_iter().map(Rc::new).collect();
1243        // Append an ordianry vector of data.
1244        let mut other_buf = VecDynAll::from_vec(data.clone());
1245        buf.append(&mut other_buf);
1246
1247        assert!(other_buf.is_empty());
1248
1249        for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
1250            assert_eq!(val, &data[i]);
1251        }
1252    }
1253
1254    #[test]
1255    fn dynamic_vtables_assignment() {
1256        use crate::{from_dyn, into_dyn};
1257
1258        let buf = VecDynAll::with_type::<u8>(); // Create an empty buffer.
1259
1260        let mut buf_dyn = into_dyn![VecDyn<dyn HasAllTrait>](buf);
1261
1262        buf_dyn.push(BoxValue::<AllTraitVTable>::new(1u8));
1263        buf_dyn.push(BoxValue::<AllTraitVTable>::new(100u8));
1264        buf_dyn.push(BoxValue::<AllTraitVTable>::new(23u8));
1265
1266        // Check that we can't push other types
1267        assert!(buf_dyn
1268            .push(BoxValue::<AllTraitVTable>::new(2u32))
1269            .is_none());
1270
1271        let buf = from_dyn![VecDyn<dyn HasAllTrait as AllTraitVTable>](buf_dyn);
1272        let vec: Vec<u8> = buf.into_vec().unwrap();
1273
1274        assert_eq!(vec, vec![1u8, 100, 23]);
1275    }
1276
1277    // This test checks that cloning and dropping clones works correctly.
1278    #[test]
1279    fn clone_test() {
1280        let buf = VecDynAll::with_size::<Rc<u8>>(3, Rc::new(1u8));
1281        assert_eq!(&buf, &buf.clone());
1282    }
1283
1284    #[cfg(feature = "numeric")]
1285    #[test]
1286    fn convert_float_test() {
1287        let vecf64 = vec![1f64, -3.0, 10.02, -23.1, 32e-1];
1288        let buf: VecDrop = VecDyn::from(vecf64.clone()); // Convert into buffer
1289        let nu_vec: Vec<f32> = buf.cast_into_vec().unwrap(); // Convert back into vec
1290        let vecf32 = vec![1f32, -3.0, 10.02, -23.1, 32e-1];
1291        assert_eq!(vecf32, nu_vec);
1292
1293        let buf: VecDrop = VecDyn::from(vecf32.clone()); // Convert into buffer
1294        let nu_vec: Vec<f64> = buf.cast_into_vec().unwrap(); // Convert back into vec
1295        for (&a, &b) in vecf64.iter().zip(nu_vec.iter()) {
1296            assert!((a - b).abs() < 1e-6f64 * f64::max(a, b).abs());
1297        }
1298
1299        let vecf64 = vec![1f64, -3.1, 100.2, -2.31, 3.2, 4e2, -1e23];
1300        let buf: VecDrop = VecDyn::from(vecf64.clone()); // Convert into buffer
1301        let nu_vec: Vec<f32> = buf.cast_into_vec().unwrap(); // Convert back into vec
1302        let vecf32 = vec![1f32, -3.1, 100.2, -2.31, 3.2, 4e2, -1e23];
1303        assert_eq!(vecf32, nu_vec);
1304        let buf: VecDrop = VecDyn::from(vecf32.clone()); // Convert into buffer
1305        let nu_vec: Vec<f64> = buf.cast_into_vec().unwrap(); // Convert back into vec
1306        for (&a, &b) in vecf64.iter().zip(nu_vec.iter()) {
1307            assert!((a - b).abs() < 1e-6 * f64::max(a, b).abs());
1308        }
1309    }
1310
1311    #[test]
1312    fn print_debug() {
1313        let v = VecDynAll::from(vec![1, 2, 3]);
1314        assert_eq!("[1, 2, 3]", format!("{:?}", v));
1315    }
1316
1317    #[test]
1318    fn hash() {
1319        use std::collections::hash_map::DefaultHasher;
1320        use std::hash::{Hash, Hasher};
1321        let v = VecDynAll::from(vec![1, 2, 3]);
1322        let mut hasher = DefaultHasher::new();
1323        v.hash(&mut hasher);
1324        let vhash = hasher.finish();
1325        let v2 = v.clone();
1326        let mut hasher = DefaultHasher::new();
1327        v2.hash(&mut hasher);
1328        let v2hash = hasher.finish();
1329        assert_eq!(vhash, v2hash);
1330    }
1331
1332    #[test]
1333    fn fill() {
1334        let mut v = VecDynAll::from(&[1u32, 2, 3][..]);
1335        v.fill(4u32).unwrap();
1336        let vec: Option<Vec<u32>> = v.into();
1337        assert_eq!(vec.unwrap(), vec![4, 4, 4]);
1338    }
1339
1340    #[test]
1341    fn unsafe_api() {
1342        let mut v = VecDynAll::from(vec![1u32, 2, 3]);
1343        unsafe {
1344            assert_eq!(*v.get_unchecked_ref::<u32>(1), 2);
1345            assert_eq!(*v.get_unchecked_mut::<u32>(2), 3);
1346        }
1347    }
1348
1349    #[test]
1350    fn as_slice() {
1351        // Untyped as slice calls
1352        let mut vec = vec![1u32, 2, 3];
1353        let mut v = VecDynAll::from(vec.clone());
1354        let s = SliceAll::from_slice(vec.as_slice());
1355        let s_from_v = v.as_slice();
1356        assert_eq!(s, s_from_v);
1357        let sm = SliceMutAll::from_slice(vec.as_mut_slice());
1358        let s_from_v_mut = v.as_mut_slice();
1359        assert_eq!(sm, s_from_v_mut);
1360
1361        // Typed as slice
1362        assert_eq!(vec.as_slice(), v.as_slice_as::<u32>().unwrap());
1363        assert_eq!(vec.as_mut_slice(), v.as_mut_slice_as::<u32>().unwrap());
1364    }
1365
1366    #[test]
1367    fn get() {
1368        let vec = vec![1u32, 2, 3];
1369        let mut v = VecDynAll::from(vec);
1370        assert_eq!(v.get(0), ValueRef::new(&1u32));
1371        assert_eq!(v.get_mut(1), ValueMut::new(&mut 2u32));
1372    }
1373
1374    #[test]
1375    fn push_cloned() {
1376        let vec = vec![1u32, 2, 3];
1377        let mut v = VecDynAll::from(vec);
1378        v.push_cloned(ValueRef::new(&4u32));
1379
1380        // This should not work but it wont cause panics or safety issues:
1381        assert!(v.push_cloned(ValueRef::new(&4u64)).is_none());
1382
1383        assert_eq!(v.into_vec::<u32>().unwrap(), vec![1u32, 2, 3, 4]);
1384    }
1385
1386    #[test]
1387    fn rotate() {
1388        let vec = vec![1u32, 2, 3];
1389        let mut v = VecDynAll::from(vec);
1390        v.rotate_left(2);
1391        assert_eq!(v.clone().into_vec::<u32>().unwrap(), vec![3, 1, 2]);
1392        v.rotate_right(1);
1393        assert_eq!(v.clone().into_vec::<u32>().unwrap(), vec![2, 3, 1]);
1394    }
1395
1396    #[test]
1397    fn element_size() {
1398        let v = VecDynAll::from(vec![1u32, 2, 3]);
1399        assert_eq!(v.element_size(), 4);
1400    }
1401
1402    #[test]
1403    fn check() {
1404        let mut v = VecDynAll::from(vec![1u32, 2, 3]);
1405        assert!(v.clone().check::<u32>().is_some());
1406        assert!(v.clone().check::<i32>().is_none());
1407        assert!(v.check_ref::<u32>().is_some());
1408        assert!(v.check_ref::<i32>().is_none());
1409        assert!(v.check_mut::<u32>().is_some());
1410        assert!(v.check_mut::<i32>().is_none());
1411    }
1412
1413    #[test]
1414    fn clear() {
1415        let mut v = VecDynAll::from(vec![1u32, 2, 3]);
1416        assert_eq!(v.len(), 3);
1417        v.clear();
1418        assert_eq!(v.len(), 0);
1419    }
1420
1421    #[test]
1422    fn vtable() {
1423        // Create a VecDyn with the default vtable.
1424        let v: VecDrop = VecDyn::from(vec![1u32, 2, 3]);
1425
1426        let vtable: DropVTable = VTable::<u32>::build_vtable();
1427        assert_eq!(v.vtable().type_id(), vtable.type_id());
1428    }
1429
1430    #[test]
1431    fn upcast() {
1432        // Create a VecDyn with all traits.
1433        let v_all = VecDynAll::from(vec![1u32, 2, 3]);
1434        // Upcast to a more general VecDyn with just the Drop trait.
1435        let _: VecDyn<DropVTable> = v_all.upcast();
1436    }
1437}