#![allow(dead_code)]
use std::{
any::{Any, TypeId},
fmt,
mem::ManuallyDrop,
slice,
};
use std::boxed::Box as Ptr;
#[cfg(feature = "numeric")]
use num_traits::{cast, NumCast, Zero};
use crate::meta::*;
use crate::slice::*;
use crate::traits::*;
use crate::value::*;
use crate::vec_void::VecVoid;
use crate::vtable::*;
use crate::VecCopy;
use crate::{ElementBytes, ElementBytesMut};
pub trait Elem: Any + DropBytes {}
impl<T> Elem for T where T: Any + DropBytes {}
pub struct VecDyn<V>
where
V: ?Sized + HasDrop,
{
data: ManuallyDrop<VecCopy<V>>,
}
pub type VecDrop = VecDyn<DropVTable>;
impl<V: ?Sized + HasDrop> Drop for VecDyn<V> {
fn drop(&mut self) {
unsafe {
{
let VecCopy { data, vtable, .. } = &mut *self.data;
for elem_bytes in data.byte_chunks_mut() {
vtable.drop_fn()(elem_bytes);
}
}
ManuallyDrop::drop(&mut self.data);
}
}
}
impl<V: ?Sized + Clone + HasDrop + HasClone> Clone for VecDyn<V> {
fn clone(&self) -> Self {
let data_clone = |vec_void: &VecVoid| {
let mut new_data = vec_void.clone();
unsafe {
vec_void
.byte_chunks()
.zip(new_data.byte_chunks_mut())
.for_each(|(src, dst)| {
self.data.vtable.clone_into_raw_fn()(src, dst)
});
}
new_data
};
VecDyn {
data: ManuallyDrop::new(self.data.clone_with(data_clone)),
}
}
}
impl<V: ?Sized + HasDrop + HasPartialEq> PartialEq for VecDyn<V> {
fn eq(&self, other: &Self) -> bool {
self.iter()
.zip(other.iter())
.all(|(this, that)| this == that)
}
}
impl<V: ?Sized + HasDrop + HasEq> Eq for VecDyn<V> {}
impl<V: ?Sized + HasDrop + HasHash> std::hash::Hash for VecDyn<V> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.iter().for_each(|elem| elem.hash(state));
}
}
impl<V: ?Sized + HasDrop + HasDebug> fmt::Debug for VecDyn<V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
unsafe impl<V: ?Sized + HasDrop + HasSend> Send for VecDyn<V> {}
unsafe impl<V: ?Sized + HasDrop + HasSync> Sync for VecDyn<V> {}
impl<V: HasDrop> VecDyn<V> {
#[inline]
pub fn with_type<T: Elem>() -> Self
where
V: VTable<T>,
{
VecDyn {
data: ManuallyDrop::new(unsafe { VecCopy::with_type_non_copy::<T>() }),
}
}
#[inline]
pub fn with_capacity<T: Elem>(n: usize) -> Self
where
V: VTable<T>,
{
VecDyn {
data: ManuallyDrop::new(unsafe { VecCopy::with_capacity_non_copy::<T>(n) }),
}
}
pub fn from_vec<T: Elem>(vec: Vec<T>) -> Self
where
V: VTable<T>,
{
VecDyn {
data: ManuallyDrop::new(unsafe { VecCopy::from_vec_non_copy(vec) }),
}
}
}
impl<V: ?Sized + HasDrop> VecDyn<V> {
#[inline]
pub fn with_type_from<'a>(other: impl Into<Meta<VTableRef<'a, V>>>) -> Self
where
V: Clone + 'a,
{
VecDyn {
data: ManuallyDrop::new(VecCopy::with_type_from(other.into())),
}
}
#[inline]
pub unsafe fn from_raw_parts(data: VecVoid, vtable: Ptr<V>) -> VecDyn<V> {
VecDyn {
data: ManuallyDrop::new(VecCopy { data, vtable }),
}
}
#[inline]
pub fn into_raw_parts(self) -> (VecVoid, Ptr<V>) {
unsafe {
let mut md = ManuallyDrop::new(self);
let VecCopy { data, vtable } = ManuallyDrop::take(&mut md.data);
(data, vtable)
}
}
pub fn vtable(&self) -> &V {
&self.data.vtable
}
#[inline]
pub fn upcast<U: HasDrop + From<V>>(self) -> VecDyn<U>
where
V: Clone,
{
let mut md = ManuallyDrop::new(self);
let data = unsafe { ManuallyDrop::take(&mut md.data) };
VecDyn {
data: ManuallyDrop::new(data.upcast()), }
}
#[inline]
pub fn clear(&mut self) {
unsafe {
let VecCopy { data, vtable, .. } = &mut *self.data;
for elem_bytes in data.byte_chunks_mut() {
vtable.drop_fn()(elem_bytes);
}
data.clear();
}
}
#[inline]
pub fn push_as<T: Elem>(&mut self, element: T) -> Option<&mut Self> {
let _ = self.data.push_as(element)?;
Some(self)
}
#[inline]
pub fn check<T: Elem>(self) -> Option<Self> {
self.data.check_ref::<T>()?;
Some(self)
}
#[inline]
pub fn check_ref<T: Elem>(&self) -> Option<&Self> {
self.data.check_ref::<T>().map(|_| self)
}
#[inline]
pub fn check_mut<T: Elem>(&mut self) -> Option<&mut Self> {
self.data.check_mut::<T>()?;
Some(self)
}
#[inline]
pub fn element_type_id(&self) -> TypeId {
self.data.element_type_id()
}
#[inline]
pub fn len(&self) -> usize {
self.data.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
#[inline]
pub fn element_size(&self) -> usize {
self.data.element_size()
}
#[inline]
pub fn iter_as<T: Elem>(&self) -> Option<slice::Iter<T>> {
self.data.iter_as::<T>()
}
#[inline]
pub fn iter_mut_as<T: Elem>(&mut self) -> Option<slice::IterMut<T>> {
self.data.iter_mut_as::<T>()
}
#[inline]
pub fn into_vec<T: Elem>(self) -> Option<Vec<T>> {
unsafe {
let mut no_drop = ManuallyDrop::new(self);
ManuallyDrop::take(&mut no_drop.data).into_vec()
}
}
#[inline]
pub fn as_slice_as<T: Elem>(&self) -> Option<&[T]> {
self.data.as_slice_as()
}
#[inline]
pub fn as_mut_slice_as<T: Elem>(&mut self) -> Option<&mut [T]> {
self.data.as_mut_slice_as()
}
#[inline]
pub fn get_ref_as<T: Elem>(&self, i: usize) -> Option<&T> {
self.data.get_ref_as::<T>(i)
}
#[inline]
pub fn get_mut_as<T: Elem>(&mut self, i: usize) -> Option<&mut T> {
self.data.get_mut_as::<T>(i)
}
#[inline]
pub fn append(&mut self, buf: &mut VecDyn<V>) -> Option<&mut Self> {
let _ = self.data.append(&mut buf.data)?;
Some(self)
}
#[inline]
pub fn rotate_left(&mut self, mid: usize) {
self.data.rotate_left(mid)
}
#[inline]
pub fn rotate_right(&mut self, k: usize) {
self.data.rotate_right(k)
}
#[inline]
pub fn push<U: ?Sized + HasDrop>(&mut self, value: BoxValue<U>) -> Option<&mut Self> {
if value.value_type_id() == self.element_type_id() {
let (bytes, _, _, _) = value.into_raw_parts();
self.data.data.push(&*bytes);
Some(self)
} else {
None
}
}
#[inline]
pub fn push_cloned(&mut self, value: ValueRef<V>) -> Option<&mut Self>
where
V: HasClone,
{
if self.element_type_id() == value.value_type_id() {
let VecCopy { data, vtable } = &mut *self.data;
let new_len = data.len() + 1;
unsafe {
data.resize_with(new_len, |uninit_val| {
vtable.clone_into_raw_fn()(value.bytes, uninit_val);
});
}
Some(self)
} else {
None
}
}
#[inline]
pub fn get(&self, i: usize) -> ValueRef<V> {
debug_assert!(i < self.len());
unsafe {
ValueRef::from_raw_parts(
self.data.data.get_bytes(i),
self.element_type_id(),
self.data.data.elem.alignment,
self.data.vtable.as_ref(),
)
}
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = ValueRef<V>> {
let VecCopy { data, vtable } = &*self.data;
data.byte_chunks().map(move |bytes| unsafe {
ValueRef::from_raw_parts(
bytes,
data.elem.type_id,
data.elem.alignment,
vtable.as_ref(),
)
})
}
#[inline]
pub fn get_mut(&mut self, i: usize) -> ValueMut<V> {
debug_assert!(i < self.len());
let Self { data, .. } = self;
let element_type_id = data.element_type_id();
let element_alignment = data.data.elem.alignment;
let &mut VecCopy {
ref mut data,
ref vtable,
..
} = &mut **data;
unsafe {
ValueMut::from_raw_parts(
data.get_bytes_mut(i),
element_type_id,
element_alignment,
vtable.as_ref(),
)
}
}
#[inline]
pub fn iter_mut(&mut self) -> impl Iterator<Item = ValueMut<V>> {
let VecCopy {
ref mut data,
ref vtable,
} = *self.data;
let vtable = vtable.as_ref();
let element_type_id = data.elem.type_id;
let element_alignment = data.elem.alignment;
unsafe {
data.byte_chunks_mut().map(move |bytes| {
ValueMut::from_raw_parts(bytes, element_type_id, element_alignment, vtable)
})
}
}
pub fn as_slice(&self) -> Slice<V> {
let VecCopy {
ref data,
ref vtable,
} = *self.data;
unsafe { Slice::from_raw_parts(data.bytes(), data.elem, vtable.as_ref()) }
}
pub fn as_mut_slice(&mut self) -> SliceMut<V> {
let VecCopy {
ref mut data,
ref vtable,
} = *self.data;
let elem = data.elem;
unsafe { SliceMut::from_raw_parts(data.bytes_mut(), elem, vtable.as_ref()) }
}
#[inline]
pub unsafe fn get_unchecked_ref<T: Any>(&self, i: usize) -> &T {
self.data.get_unchecked_ref(i)
}
#[inline]
pub unsafe fn get_unchecked_mut<T: Any>(&mut self, i: usize) -> &mut T {
self.data.get_unchecked_mut(i)
}
}
impl<V: HasDrop + HasClone> VecDyn<V> {
#[inline]
pub fn with_size<T: Elem + Clone>(n: usize, def: T) -> Self
where
V: VTable<T>,
{
VecDyn {
data: ManuallyDrop::new(unsafe { VecCopy::from_vec_non_copy(vec![def; n]) }),
}
}
#[inline]
pub fn from_slice<T: Elem + Clone>(slice: &[T]) -> Self
where
V: VTable<T>,
{
VecDyn {
data: ManuallyDrop::new(unsafe { VecCopy::from_slice_non_copy::<T>(slice) }),
}
}
}
impl<V: HasDrop> VecDyn<V> {
#[cfg(feature = "numeric")]
pub fn cast_into_vec<T>(&self) -> Option<Vec<T>>
where
T: Elem + Copy + NumCast + Zero,
{
use crate::CopyElem;
unsafe fn convert_into_vec<I, O, V>(buf: &VecCopy<V>) -> Option<Vec<O>>
where
I: CopyElem + Any + NumCast,
O: CopyElem + NumCast + Zero,
{
debug_assert_eq!(buf.element_type_id(), TypeId::of::<I>()); Some(
buf.as_slice_as_unchecked()
.iter()
.map(|elem: &I| cast(*elem).unwrap_or_else(O::zero))
.collect(),
)
}
call_numeric_buffer_fn!( convert_into_vec::<_, T, V>(&self.data) or { None } )
}
}
impl<V: ?Sized + HasDrop + HasClone> VecDyn<V> {
#[inline]
pub fn resize<T: Elem + Clone>(&mut self, new_len: usize, value: T) -> Option<&mut Self> {
self.check_ref::<T>()?;
if new_len >= self.len() {
let diff = new_len - self.len();
self.data.reserve(diff);
for _ in 0..diff {
self.data.push_as(value.clone());
}
} else {
unsafe {
let VecCopy { data, vtable, .. } = &mut *self.data;
for elem_bytes in data.byte_chunks_mut().skip(new_len) {
vtable.drop_fn()(elem_bytes);
}
}
self.data.data.truncate(new_len);
}
Some(self)
}
#[inline]
pub fn fill<T: Elem + Clone>(&mut self, def: T) -> Option<&mut Self> {
for v in self.iter_mut_as::<T>()? {
*v = def.clone();
}
Some(self)
}
#[inline]
pub fn append_cloned_to_vec<'a, T: Elem + Clone>(
&self,
vec: &'a mut Vec<T>,
) -> Option<&'a mut Vec<T>> {
let slice = self.as_slice_as()?;
vec.reserve(self.len());
vec.extend_from_slice(slice);
Some(vec)
}
#[inline]
pub fn clone_into_vec<T: Elem + Clone>(&self) -> Option<Vec<T>> {
let mut vec = Vec::new();
#[allow(clippy::manual_map)]
match self.append_cloned_to_vec(&mut vec) {
Some(_) => Some(vec),
None => None,
}
}
}
impl<T: Elem, V: HasDrop + VTable<T>> From<Vec<T>> for VecDyn<V> {
#[inline]
fn from(vec: Vec<T>) -> VecDyn<V> {
VecDyn::from_vec(vec)
}
}
impl<'a, T, V> From<&'a [T]> for VecDyn<V>
where
T: Elem + Clone,
V: HasDrop + VTable<T> + HasClone,
{
#[inline]
fn from(slice: &'a [T]) -> VecDyn<V> {
VecDyn::from_slice(slice)
}
}
impl<T: Elem, V: ?Sized + HasDrop + VTable<T>> From<VecDyn<V>> for Option<Vec<T>> {
#[inline]
fn from(v: VecDyn<V>) -> Option<Vec<T>> {
v.into_vec()
}
}
impl<'a, V: Clone + HasDrop> From<&'a VecDyn<V>> for Meta<VTableRef<'a, V>> {
#[inline]
fn from(v: &'a VecDyn<V>) -> Self {
Meta::from(&*v.data)
}
}
#[cfg(test)]
mod tests {
use super::*;
use dync_derive::dync_trait;
use rand::prelude::*;
use std::rc::Rc;
#[dync_trait(dync_crate_name = "crate")]
pub trait AllTrait: Clone + PartialEq + Eq + std::hash::Hash + std::fmt::Debug {}
impl<T> AllTrait for T where T: Clone + PartialEq + Eq + std::hash::Hash + std::fmt::Debug {}
type VecCopyAll = VecCopy<AllTraitVTable>;
type VecDynAll = VecDyn<AllTraitVTable>;
type SliceAll<'a> = Slice<'a, AllTraitVTable>;
type SliceMutAll<'a> = SliceMut<'a, AllTraitVTable>;
#[dync_trait(dync_crate_name = "crate")]
pub trait FloatTrait: Clone + PartialEq + std::fmt::Debug {}
impl<T> FloatTrait for T where T: Clone + PartialEq + std::fmt::Debug {}
type VecDynFloat = VecDyn<FloatTraitVTable>;
#[inline]
fn compute(x: i64, y: i64, z: i64) -> [i64; 3] {
[x - 2 * y + z * 2, y - 2 * z + x * 2, z - 2 * x + y * 2]
}
#[inline]
fn make_random_vec_copy(n: usize) -> VecCopyAll {
make_random_vec(n).into()
}
#[inline]
fn make_random_vec_dyn(n: usize) -> VecDynAll {
make_random_vec(n).into()
}
#[inline]
fn make_random_vec(n: usize) -> Vec<[i64; 3]> {
let mut rng: StdRng = SeedableRng::from_seed([3; 32]);
let between = rand::distr::Uniform::new(1i64, 5).unwrap();
(0..n).map(move |_| [between.sample(&mut rng); 3]).collect()
}
#[inline]
fn vec_copy_compute<V: Clone>(v: &mut VecCopy<V>) {
for a in v.iter_mut() {
let a = a.downcast::<[i64; 3]>().unwrap();
let res = compute(a[0], a[1], a[2]);
a[0] = res[0];
a[1] = res[1];
a[2] = res[2];
}
}
#[inline]
fn vec_dyn_compute<V: Clone + HasDrop>(v: &mut VecDyn<V>) {
for a in v.iter_mut() {
let a = a.downcast::<[i64; 3]>().unwrap();
let res = compute(a[0], a[1], a[2]);
a[0] = res[0];
a[1] = res[1];
a[2] = res[2];
}
}
#[inline]
fn vec_compute(v: &mut Vec<[i64; 3]>) {
for a in v.iter_mut() {
let res = compute(a[0], a[1], a[2]);
a[0] = res[0];
a[1] = res[1];
a[2] = res[2];
}
}
#[cfg_attr(miri, ignore)]
#[test]
fn downcast_value_mut() {
use std::time::Instant;
let size = 90_000;
let mut v: VecDynAll = make_random_vec_dyn(size);
let start = Instant::now();
vec_dyn_compute(&mut v);
eprintln!("vec_dyn: {} millis", start.elapsed().as_millis());
let mut v: VecCopyAll = make_random_vec_copy(size);
let start = Instant::now();
vec_copy_compute(&mut v);
eprintln!("vec_copy: {} millis", start.elapsed().as_millis());
let mut v: Vec<[i64; 3]> = make_random_vec(size);
let start = Instant::now();
vec_compute(&mut v);
eprintln!("vec: {} millis", start.elapsed().as_millis());
}
#[test]
fn clone_from_test() {
use std::collections::HashSet;
let vec_rc: Vec<_> = vec![1, 23, 2, 42, 23, 1, 13534653]
.into_iter()
.map(Rc::new)
.collect();
let buf = VecDynAll::from(vec_rc.clone());
let mut hashset: HashSet<BoxValue<AllTraitVTable>> = HashSet::new();
for rc_ref in buf.iter().take(4) {
assert!(hashset.insert(rc_ref.clone_value()));
}
assert!(!hashset.insert(BoxValue::new(Rc::clone(&vec_rc[4]))));
assert!(!hashset.insert(BoxValue::new(Rc::clone(&vec_rc[5]))));
assert_eq!(hashset.len(), 4);
assert!(hashset.contains(&BoxValue::new(Rc::new(1))));
assert!(hashset.contains(&BoxValue::new(Rc::new(23))));
assert!(hashset.contains(&BoxValue::new(Rc::new(2))));
assert!(hashset.contains(&BoxValue::new(Rc::new(42))));
assert!(!hashset.contains(&BoxValue::new(Rc::new(13534653))));
}
#[test]
fn clone_from_small_test() {
use std::collections::HashSet;
let vec_rc: Vec<_> = vec![1, 23, 2, 42, 23, 1, 13534653]
.into_iter()
.map(Rc::new)
.collect();
let buf = VecDynAll::from(vec_rc.clone());
let mut hashset: HashSet<SmallValue<AllTraitVTable>> = HashSet::new();
for rc_ref in buf.iter().take(4) {
assert!(hashset.insert(rc_ref.clone_small_value()));
}
assert!(!hashset.insert(SmallValue::new(Rc::clone(&vec_rc[4]))));
assert!(!hashset.insert(SmallValue::new(Rc::clone(&vec_rc[5]))));
assert_eq!(hashset.len(), 4);
assert!(hashset.contains(&SmallValue::new(Rc::new(1))));
assert!(hashset.contains(&SmallValue::new(Rc::new(23))));
assert!(hashset.contains(&SmallValue::new(Rc::new(2))));
assert!(hashset.contains(&SmallValue::new(Rc::new(42))));
assert!(!hashset.contains(&SmallValue::new(Rc::new(13534653))));
}
#[test]
fn iter() {
let vec: Vec<_> = vec![1, 23, 2, 42, 11].into_iter().map(Rc::new).collect();
{
let buf = VecDynAll::from(vec.clone()); let orig = Rc::new(100);
let mut rc = Rc::clone(&orig);
assert_eq!(Rc::strong_count(&rc), 2);
for val in buf.iter() {
ValueMut::new(&mut rc).clone_from_other(val).unwrap();
}
assert_eq!(Rc::strong_count(&orig), 1);
assert_eq!(Rc::strong_count(&rc), 3);
assert_eq!(Rc::strong_count(&vec[4]), 3);
assert!(vec.iter().take(4).all(|x| Rc::strong_count(x) == 2));
assert_eq!(rc, Rc::new(11));
}
assert!(vec.iter().all(|x| Rc::strong_count(x) == 1));
}
#[test]
fn initialization_test() {
let a = VecDynAll::with_type::<Rc<u8>>();
assert_eq!(a.len(), 0);
assert_eq!(a.element_type_id(), TypeId::of::<Rc<u8>>());
let b = VecDynAll::with_type_from(&a);
assert_eq!(b.len(), 0);
assert_eq!(b.element_type_id(), TypeId::of::<Rc<u8>>());
let a = VecDynAll::with_capacity::<Rc<u8>>(4);
assert_eq!(a.len(), 0);
assert_eq!(a.element_type_id(), TypeId::of::<Rc<u8>>());
}
#[test]
fn resize() {
let mut a = VecDynAll::with_type::<Rc<u8>>();
a.resize(3, Rc::new(1u8))
.expect("Failed to resize VecDyn up by 3 elements");
assert_eq!(a.len(), 3);
for i in 0..3 {
assert_eq!(a.get_ref_as::<Rc<u8>>(i).unwrap(), &Rc::new(1));
}
a.resize(2, Rc::new(1u8))
.expect("Failed to resize VecDyn down to 2 elements");
assert_eq!(a.len(), 2);
for i in 0..2 {
assert_eq!(a.get_ref_as::<Rc<u8>>(i).unwrap(), &Rc::new(1));
}
}
#[test]
fn data_integrity_u8_test() {
let vec: Vec<Rc<u8>> = vec![1u8, 3, 4, 1, 2].into_iter().map(Rc::new).collect();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<u8>> = buf.clone_into_vec().unwrap(); assert_eq!(vec, nu_vec);
let vec: Vec<Rc<u8>> = vec![1u8, 3, 4, 1, 2, 52, 1, 3, 41, 23, 2]
.into_iter()
.map(Rc::new)
.collect();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<u8>> = buf.clone_into_vec().unwrap(); assert_eq!(vec, nu_vec);
}
#[test]
fn data_integrity_i16_test() {
let vec: Vec<Rc<i16>> = vec![1i16, -3, 1002, -231, 32]
.into_iter()
.map(Rc::new)
.collect();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<i16>> = buf.clone_into_vec().unwrap(); assert_eq!(vec, nu_vec);
let vec: Vec<Rc<i16>> = vec![1i16, -3, 1002, -231, 32, 42, -123, 4]
.into_iter()
.map(Rc::new)
.collect();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<i16>> = buf.clone_into_vec().unwrap(); assert_eq!(vec, nu_vec);
}
#[test]
fn data_integrity_i32_test() {
let vec: Vec<Rc<i32>> = vec![1i32, -3, 1002, -231, 32]
.into_iter()
.map(Rc::new)
.collect();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<i32>> = buf.into_vec().unwrap(); assert_eq!(vec, nu_vec);
let vec: Vec<Rc<i32>> = vec![1i32, -3, 1002, -231, 32, 42, -123]
.into_iter()
.map(Rc::new)
.collect();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<i32>> = buf.into_vec().unwrap(); assert_eq!(vec, nu_vec);
}
#[test]
fn f32x3_push_clone_from_empty() {
let mut vec = vec![];
let mut buf = VecDynFloat::from(vec.clone()); buf.push_cloned(ValueRef::new(&[2_u32; 3]));
vec.push([2; 3]);
let nu_vec: Vec<[u32; 3]> = buf.clone_into_vec().unwrap(); assert_eq!(vec, nu_vec);
let mut vec = vec![];
let mut buf = VecDynFloat::from(vec.clone()); buf.push_cloned(ValueRef::new(&[2.0_f64; 3]));
vec.push([2.0; 3]);
let nu_vec: Vec<[f64; 3]> = buf.clone_into_vec().unwrap(); assert_eq!(vec, nu_vec);
let mut vec = Vec::<[f64; 3]>::with_capacity(2);
let mut buf = VecDynFloat::from(vec.clone()); buf.push_cloned(ValueRef::new(&[2.0_f64; 3]));
vec.push([2.0; 3]);
let nu_vec: Vec<[f64; 3]> = buf.clone_into_vec().unwrap(); assert_eq!(vec, nu_vec);
let mut vec = Vec::new();
let buf = VecDynFloat::from(vec.clone());
let mut buf2 = VecDynFloat::from(buf.clone());
buf2.push_cloned(ValueRef::new(&[2.0_f64; 3]));
vec.push([2.0; 3]);
let nu_vec: Vec<[f64; 3]> = buf2.clone_into_vec().unwrap(); assert_eq!(vec, nu_vec);
let mut vec = Vec::new();
let buf = VecDynFloat::from(vec.clone());
let mut buf2 = VecDynFloat::with_type_from(buf.as_slice());
buf2.push_cloned(ValueRef::new(&[2.0_f64; 3]));
vec.push([2.0; 3]);
let nu_vec: Vec<[f64; 3]> = buf2.clone_into_vec().unwrap(); assert_eq!(vec, nu_vec);
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
struct Foo {
a: u8,
b: i64,
}
#[test]
fn from_empty_vec_test() {
let vec: Vec<Rc<u32>> = Vec::new();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<u32>> = buf.into_vec().unwrap(); assert_eq!(vec, nu_vec);
let vec: Vec<Rc<String>> = Vec::new();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<String>> = buf.into_vec().unwrap(); assert_eq!(vec, nu_vec);
let vec: Vec<Rc<Foo>> = Vec::new();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<Foo>> = buf.into_vec().unwrap(); assert_eq!(vec, nu_vec);
}
#[test]
fn from_struct_test() {
let f1 = Foo { a: 3, b: -32 };
let f2 = Foo {
a: 33,
b: -3342432412,
};
let vec: Vec<Rc<Foo>> = vec![Rc::new(f1.clone()), Rc::new(f2.clone())];
let buf = VecDynAll::from(vec.clone()); assert_eq!(Rc::new(f1), buf.get_ref_as::<Rc<Foo>>(0).unwrap().clone());
assert_eq!(Rc::new(f2), buf.get_ref_as::<Rc<Foo>>(1).unwrap().clone());
let nu_vec: Vec<Rc<Foo>> = buf.into_vec().unwrap(); assert_eq!(vec, nu_vec);
}
#[test]
fn from_strings_test() {
let vec: Vec<Rc<String>> = vec![
String::from("hi"),
String::from("hello"),
String::from("goodbye"),
String::from("bye"),
String::from("supercalifragilisticexpialidocious"),
String::from("42"),
]
.into_iter()
.map(Rc::new)
.collect();
let buf = VecDynAll::from(vec.clone()); assert_eq!(
&Rc::new("hi".to_string()),
buf.get_ref_as::<Rc<String>>(0).unwrap()
);
assert_eq!(
&Rc::new("hello".to_string()),
buf.get_ref_as::<Rc<String>>(1).unwrap()
);
assert_eq!(
&Rc::new("goodbye".to_string()),
buf.get_ref_as::<Rc<String>>(2).unwrap()
);
let nu_vec: Vec<Rc<String>> = buf.into_vec().unwrap(); assert_eq!(vec, nu_vec);
}
#[test]
fn iter_test() {
let vec_u8: Vec<Rc<u8>> = vec![1u8, 3, 4, 1, 2, 4, 128, 32]
.into_iter()
.map(Rc::new)
.collect();
let buf = VecDynAll::from(vec_u8.clone()); for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
assert_eq!(val, &vec_u8[i]);
}
}
#[cfg_attr(miri, ignore)]
#[test]
fn large_sizes_clone() {
for i in 100000..100010 {
let vec: Vec<Rc<u8>> = vec![32u8; i].into_iter().map(Rc::new).collect();
let buf = VecDynAll::from(vec.clone()); let nu_vec: Vec<Rc<u8>> = buf.into_vec().unwrap(); assert_eq!(vec, nu_vec);
}
}
#[test]
fn wrong_type_test() {
let vec: Vec<Rc<u8>> = vec![1, 23, 2, 42, 11].into_iter().map(Rc::new).collect();
let mut buf = VecDynAll::from(vec.clone()); assert_eq!(vec, buf.clone_into_vec::<Rc<u8>>().unwrap());
assert!(buf.clone_into_vec::<Rc<f64>>().is_none());
assert!(buf.as_slice_as::<Rc<f64>>().is_none());
assert!(buf.as_mut_slice_as::<Rc<f64>>().is_none());
assert!(buf.iter_as::<Rc<[u8; 3]>>().is_none());
assert!(buf.get_ref_as::<Rc<i32>>(1).is_none());
assert!(buf.get_mut_as::<Rc<i32>>(2).is_none());
}
#[test]
fn push_test() {
let mut vec_u8: Vec<Rc<u8>> = vec![1u8, 23, 2].into_iter().map(Rc::new).collect();
let mut buf = VecDynAll::from(vec_u8.clone()); for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
assert_eq!(val, &vec_u8[i]);
}
vec_u8.push(Rc::new(42u8));
buf.push_as(Rc::new(42u8)).unwrap();
for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
assert_eq!(val, &vec_u8[i]);
}
vec_u8.push(Rc::new(11u8));
buf.push_as(Rc::new(11u8)).unwrap();
assert!(buf.push_as("other").is_none());
for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
assert_eq!(val, &vec_u8[i]);
}
}
#[test]
fn append_test() {
let mut buf = VecDynAll::with_type::<Rc<u8>>();
let data: Vec<Rc<u8>> = vec![1, 23, 2, 42, 11].into_iter().map(Rc::new).collect();
let mut other_buf = VecDynAll::from_vec(data.clone());
buf.append(&mut other_buf);
assert!(other_buf.is_empty());
for (i, val) in buf.iter_as::<Rc<u8>>().unwrap().enumerate() {
assert_eq!(val, &data[i]);
}
}
#[test]
fn dynamic_vtables_assignment() {
use crate::{from_dyn, into_dyn};
let buf = VecDynAll::with_type::<u8>();
let mut buf_dyn = into_dyn;
buf_dyn.push(BoxValue::<AllTraitVTable>::new(1u8));
buf_dyn.push(BoxValue::<AllTraitVTable>::new(100u8));
buf_dyn.push(BoxValue::<AllTraitVTable>::new(23u8));
assert!(buf_dyn
.push(BoxValue::<AllTraitVTable>::new(2u32))
.is_none());
let buf = from_dyn;
let vec: Vec<u8> = buf.into_vec().unwrap();
assert_eq!(vec, vec![1u8, 100, 23]);
}
#[test]
fn clone_test() {
let buf = VecDynAll::with_size::<Rc<u8>>(3, Rc::new(1u8));
assert_eq!(&buf, &buf.clone());
}
#[cfg(feature = "numeric")]
#[test]
fn convert_float_test() {
let vecf64 = vec![1f64, -3.0, 10.02, -23.1, 32e-1];
let buf: VecDrop = VecDyn::from(vecf64.clone()); let nu_vec: Vec<f32> = buf.cast_into_vec().unwrap(); let vecf32 = vec![1f32, -3.0, 10.02, -23.1, 32e-1];
assert_eq!(vecf32, nu_vec);
let buf: VecDrop = VecDyn::from(vecf32.clone()); let nu_vec: Vec<f64> = buf.cast_into_vec().unwrap(); for (&a, &b) in vecf64.iter().zip(nu_vec.iter()) {
assert!((a - b).abs() < 1e-6f64 * f64::max(a, b).abs());
}
let vecf64 = vec![1f64, -3.1, 100.2, -2.31, 3.2, 4e2, -1e23];
let buf: VecDrop = VecDyn::from(vecf64.clone()); let nu_vec: Vec<f32> = buf.cast_into_vec().unwrap(); let vecf32 = vec![1f32, -3.1, 100.2, -2.31, 3.2, 4e2, -1e23];
assert_eq!(vecf32, nu_vec);
let buf: VecDrop = VecDyn::from(vecf32.clone()); let nu_vec: Vec<f64> = buf.cast_into_vec().unwrap(); for (&a, &b) in vecf64.iter().zip(nu_vec.iter()) {
assert!((a - b).abs() < 1e-6 * f64::max(a, b).abs());
}
}
#[test]
fn print_debug() {
let v = VecDynAll::from(vec![1, 2, 3]);
assert_eq!("[1, 2, 3]", format!("{:?}", v));
}
#[test]
fn hash() {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let v = VecDynAll::from(vec![1, 2, 3]);
let mut hasher = DefaultHasher::new();
v.hash(&mut hasher);
let vhash = hasher.finish();
let v2 = v.clone();
let mut hasher = DefaultHasher::new();
v2.hash(&mut hasher);
let v2hash = hasher.finish();
assert_eq!(vhash, v2hash);
}
#[test]
fn fill() {
let mut v = VecDynAll::from(&[1u32, 2, 3][..]);
v.fill(4u32).unwrap();
let vec: Option<Vec<u32>> = v.into();
assert_eq!(vec.unwrap(), vec![4, 4, 4]);
}
#[test]
fn unsafe_api() {
let mut v = VecDynAll::from(vec![1u32, 2, 3]);
unsafe {
assert_eq!(*v.get_unchecked_ref::<u32>(1), 2);
assert_eq!(*v.get_unchecked_mut::<u32>(2), 3);
}
}
#[test]
fn as_slice() {
let mut vec = vec![1u32, 2, 3];
let mut v = VecDynAll::from(vec.clone());
let s = SliceAll::from_slice(vec.as_slice());
let s_from_v = v.as_slice();
assert_eq!(s, s_from_v);
let sm = SliceMutAll::from_slice(vec.as_mut_slice());
let s_from_v_mut = v.as_mut_slice();
assert_eq!(sm, s_from_v_mut);
assert_eq!(vec.as_slice(), v.as_slice_as::<u32>().unwrap());
assert_eq!(vec.as_mut_slice(), v.as_mut_slice_as::<u32>().unwrap());
}
#[test]
fn get() {
let vec = vec![1u32, 2, 3];
let mut v = VecDynAll::from(vec);
assert_eq!(v.get(0), ValueRef::new(&1u32));
assert_eq!(v.get_mut(1), ValueMut::new(&mut 2u32));
}
#[test]
fn push_cloned() {
let vec = vec![1u32, 2, 3];
let mut v = VecDynAll::from(vec);
v.push_cloned(ValueRef::new(&4u32));
assert!(v.push_cloned(ValueRef::new(&4u64)).is_none());
assert_eq!(v.into_vec::<u32>().unwrap(), vec![1u32, 2, 3, 4]);
}
#[test]
fn rotate() {
let vec = vec![1u32, 2, 3];
let mut v = VecDynAll::from(vec);
v.rotate_left(2);
assert_eq!(v.clone().into_vec::<u32>().unwrap(), vec![3, 1, 2]);
v.rotate_right(1);
assert_eq!(v.clone().into_vec::<u32>().unwrap(), vec![2, 3, 1]);
}
#[test]
fn element_size() {
let v = VecDynAll::from(vec![1u32, 2, 3]);
assert_eq!(v.element_size(), 4);
}
#[test]
fn check() {
let mut v = VecDynAll::from(vec![1u32, 2, 3]);
assert!(v.clone().check::<u32>().is_some());
assert!(v.clone().check::<i32>().is_none());
assert!(v.check_ref::<u32>().is_some());
assert!(v.check_ref::<i32>().is_none());
assert!(v.check_mut::<u32>().is_some());
assert!(v.check_mut::<i32>().is_none());
}
#[test]
fn clear() {
let mut v = VecDynAll::from(vec![1u32, 2, 3]);
assert_eq!(v.len(), 3);
v.clear();
assert_eq!(v.len(), 0);
}
#[test]
fn vtable() {
let v: VecDrop = VecDyn::from(vec![1u32, 2, 3]);
let vtable: DropVTable = VTable::<u32>::build_vtable();
assert_eq!(v.vtable().type_id(), vtable.type_id());
}
#[test]
fn upcast() {
let v_all = VecDynAll::from(vec![1u32, 2, 3]);
let _: VecDyn<DropVTable> = v_all.upcast();
}
}