mod bytes;
pub mod macros;
#[macro_use]
mod elem;
#[macro_use]
mod copy_value;
mod vtable;
mod meta;
#[cfg(feature = "traits")]
pub mod traits;
#[cfg(feature = "traits")]
#[macro_use]
mod value;
pub mod index_slice;
mod vec_void;
mod slice_copy;
mod vec_copy;
#[cfg(feature = "traits")]
mod slice;
#[cfg(feature = "traits")]
mod vec_dyn;
#[cfg(feature = "traits")]
pub use crate::meta::*;
pub use copy_value::*;
#[cfg(feature = "traits")]
pub use downcast_rs as downcast;
#[cfg(feature = "traits")]
pub use dync_derive::dync_mod;
#[cfg(feature = "traits")]
pub use dync_derive::dync_trait;
pub use elem::CopyElem;
pub use index_slice::*;
#[cfg(feature = "traits")]
pub use slice::*;
pub use slice_copy::*;
#[cfg(feature = "traits")]
pub use value::*;
pub use vec_copy::VecCopy;
#[cfg(feature = "traits")]
pub use vec_dyn::*;
pub use vtable::*;
#[cfg(feature = "traits")]
#[macro_export]
macro_rules! from_dyn {
(Slice < dyn $trait:path as $vtable:path >) => {{
from_dyn![@slice Slice < dyn $trait as $vtable >]
}};
(SliceMut < dyn $trait:path as $vtable:path >) => {{
from_dyn![@slice SliceMut < dyn $trait as $vtable >]
}};
(VecDyn < dyn $trait:path as $vtable:path >) => {{
from_dyn![@owned VecDyn < dyn $trait as $vtable >]
}};
(SliceCopy < dyn $trait:path as $vtable:path >) => {{
from_dyn![@slice SliceCopy < dyn $trait as $vtable >]
}};
(SliceCopyMut < dyn $trait:path as $vtable:path >) => {{
from_dyn![@slice SliceCopyMut < dyn $trait as $vtable >]
}};
(VecCopy < dyn $trait:path as $vtable:path >) => {{
from_dyn![@owned VecCopy < dyn $trait as $vtable >]
}};
(@owned $vec:ident < dyn $trait:path as $vtable:path>) => {{
fn from_dyn<V: $trait>(vec: $crate::$vec<dyn $trait>) -> $crate::$vec<V> {
unsafe {
let (data, vtable) = vec.into_raw_parts();
let updated_vtable: Box<V> = vtable.downcast().ok().unwrap();
$vec::from_raw_parts(data, updated_vtable)
}
}
from_dyn::<$vtable>
}};
(@slice $slice:ident < dyn $trait:path >) => {{
fn from_dyn<'a, V: ?Sized + HasDrop + std::any::Any>(slice: $crate::$slice<'a, V>) -> $crate::$slice<'a, $vtable> {
unsafe {
let (data, elem, vtable) = slice.into_raw_parts();
match vtable {
$crate::VTableRef::Ref(v) => {
let updated_vtable: &$vtable = v.downcast_ref().unwrap();
$slice::from_raw_parts(data, elem, updated_vtable)
}
$crate::VTableRef::Box(v) => {
let updated_vtable: Box<$vtable> = v.downcast().unwrap();
$slice::from_raw_parts(data, elem, updated_vtable)
}
#[cfg(feature = "shared-vtables")]
$crate::VTableRef::Rc(v) => {
let updated_vtable: std::rc::Rc<$vtable> = v.downcast().unwrap();
$slice::from_raw_parts(data, elem, updated_vtable)
}
}
}
}
from_dyn
}};
}
#[cfg(feature = "traits")]
#[macro_export]
macro_rules! into_dyn {
(Slice < dyn $trait:path >) => {{
into_dyn![@slice Slice < dyn $trait >]
}};
(SliceMut < dyn $trait:ident >) => {{
into_dyn![@slice SliceMut < dyn $trait >]
}};
(VecDyn < dyn $trait:ident >) => {{
into_dyn![@owned VecDyn < dyn $trait >]
}};
(SliceCopy < dyn $trait:ident >) => {{
into_dyn![@slice SliceCopy < dyn $trait >]
}};
(SliceCopyMut < dyn $trait:ident >) => {{
into_dyn![@slice SliceCopyMut < dyn $trait >]
}};
(VecCopy < dyn $trait:ident >) => {{
into_dyn![@owned VecCopy < dyn $trait >]
}};
(@owned $vec:ident < dyn $trait:ident >) => {{
fn into_dyn<V: 'static + $trait>(vec: $crate::$vec<V>) -> $crate::$vec<dyn $trait> {
unsafe {
let (data, vtable) = vec.into_raw_parts();
let updated_vtable: Box<dyn $trait> = vtable;
$vec::from_raw_parts(data, updated_vtable)
}
}
into_dyn
}};
(@slice $slice:ident < dyn $trait:path >) => {{
fn into_dyn<'a, V: 'static + $trait>(slice: $crate::$slice<'a, V>) -> $crate::$slice<'a, dyn $trait> {
unsafe {
let (data, elem, vtable) = slice.into_raw_parts();
match vtable {
$crate::VTableRef::Ref(v) => {
let updated_vtable: &dyn $trait = v;
$slice::from_raw_parts(data, elem, updated_vtable)
}
$crate::VTableRef::Box(v) => {
let updated_vtable: Box<dyn $trait> = v;
$slice::from_raw_parts(data, elem, updated_vtable)
}
#[cfg(feature = "shared-vtables")]
$crate::VTableRef::Rc(v) => {
let updated_vtable: std::rc::Rc<dyn $trait> = v;
$slice::from_raw_parts(data, elem, updated_vtable)
}
}
}
}
into_dyn
}};
}
pub(crate) trait ElementBytes {
fn bytes(&self) -> &[std::mem::MaybeUninit<u8>];
fn element_size(&self) -> usize;
#[inline]
fn index_byte_range(&self, i: usize) -> std::ops::Range<usize> {
i * self.element_size()..(i + 1) * self.element_size()
}
#[inline]
fn index_byte_slice(&self, i: usize) -> &[std::mem::MaybeUninit<u8>] {
&self.bytes()[self.index_byte_range(i)]
}
}
pub(crate) trait ElementBytesMut: ElementBytes {
unsafe fn bytes_mut(&mut self) -> &mut [std::mem::MaybeUninit<u8>];
#[inline]
unsafe fn index_byte_slice_mut(&mut self, i: usize) -> &mut [std::mem::MaybeUninit<u8>] {
let rng = self.index_byte_range(i);
&mut self.bytes_mut()[rng]
}
#[inline]
fn swap(&mut self, i: usize, j: usize) {
if i == j {
return;
}
let element_size = self.element_size();
let r_rng = self.index_byte_range(0);
if i < j {
let l_rng = self.index_byte_range(i);
unsafe {
let (l, r) = self.bytes_mut().split_at_mut(element_size * j);
l[l_rng].swap_with_slice(&mut r[r_rng])
}
} else {
let l_rng = self.index_byte_range(j);
unsafe {
let (l, r) = self.bytes_mut().split_at_mut(element_size * i);
l[l_rng].swap_with_slice(&mut r[r_rng])
}
}
}
}