#[doc(hidden)]
#[macro_export]
macro_rules! __internal_deep_clone_trait_object {
(begin < $($rest:tt)*) => {
$crate::__internal_deep_clone_trait_object!(generics () () $($rest)*);
};
(begin $first:tt $($rest:tt)*) => {
$crate::__internal_deep_clone_trait_object!(path () ($first) $($rest)*);
};
(generics ($($generics:tt)*) () > $($rest:tt)*) => {
$crate::__internal_deep_clone_trait_object!(path ($($generics)*) () $($rest)*);
};
(generics ($($generics:tt)*) ($($brackets:tt)*) < $($rest:tt)*) => {
$crate::__internal_deep_clone_trait_object!(generics ($($generics)* <) ($($brackets)* <) $($rest)*);
};
(generics ($($generics:tt)*) (< $($brackets:tt)*) > $($rest:tt)*) => {
$crate::__internal_deep_clone_trait_object!(generics ($($generics)* >) ($($brackets)*) $($rest)*);
};
(generics ($($generics:tt)*) ($($brackets:tt)*) $first:tt $($rest:tt)*) => {
$crate::__internal_deep_clone_trait_object!(generics ($($generics)* $first) ($($brackets)*) $($rest)*);
};
(path ($($generics:tt)*) ($($path:tt)*) where $($rest:tt)*) => {
$crate::__internal_deep_clone_trait_object!(impl ($($generics)*) ($($path)*) ($($rest)*));
};
(path ($($generics:tt)*) ($($path:tt)*)) => {
$crate::__internal_deep_clone_trait_object!(impl ($($generics)*) ($($path)*) ());
};
(path ($($generics:tt)*) ($($path:tt)*) $first:tt $($rest:tt)*) => {
$crate::__internal_deep_clone_trait_object!(path ($($generics)*) ($($path)* $first) $($rest)*);
};
(impl ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*)) => {
$crate::__internal_deep_clone_trait_object!(@one ($($generics)*) (dyn $($path)*) ($($bound)*));
$crate::__internal_deep_clone_trait_object!(@one ($($generics)*) (dyn $($path)* + $crate::__private::Send) ($($bound)*));
$crate::__internal_deep_clone_trait_object!(@one ($($generics)*) (dyn $($path)* + $crate::__private::Sync) ($($bound)*));
$crate::__internal_deep_clone_trait_object!(@one ($($generics)*) (dyn $($path)* + $crate::__private::Send + $crate::__private::Sync) ($($bound)*));
};
(@one ($($generics:tt)*) ($($object:tt)*) ($($bound:tt)*)) => {
#[allow(unknown_lints, non_local_definitions)]
impl<'clone, $($generics)*> $crate::DeepClone
for $crate::__private::Box<$($object)* + 'clone>
where
$($bound)*
{
fn deep_clone_in(&self, cloner: &mut $crate::Cloner) -> Self {
$crate::deep_clone_box(&**self, cloner)
}
}
};
}
#[macro_export]
macro_rules! deep_clone_trait_object {
($($path:tt)+) => {
$crate::__internal_deep_clone_trait_object!(begin $($path)+);
};
}
use std::ptr;
use crate::{
Cloner, DeepClone,
dyn_clone::sealed::{Private, Sealed},
};
pub trait DynDeepClone: Sealed {
#[doc(hidden)]
fn __deep_clone_box(&self, cloner: &mut Cloner, _: Private) -> *mut ();
}
pub fn deep_clone_box<T>(value: &T, cloner: &mut Cloner) -> Box<T>
where
T: ?Sized + DynDeepClone,
{
let mut fat_ptr = ptr::from_ref(value);
unsafe {
let data_ptr = ptr::addr_of_mut!(fat_ptr).cast::<*mut ()>();
assert_eq!(*data_ptr as *const (), ptr::from_ref(value).cast::<()>());
*data_ptr = T::__deep_clone_box(value, cloner, Private);
}
unsafe { Box::from_raw(fat_ptr as *mut T) }
}
impl<T: DeepClone> DynDeepClone for T {
fn __deep_clone_box(&self, cloner: &mut Cloner, _: Private) -> *mut () {
Box::<T>::into_raw(Box::new(self.deep_clone_in(cloner))).cast::<()>()
}
}
#[doc(hidden)]
pub mod __private {
pub use std::{
boxed::Box,
marker::{Send, Sync},
};
}
#[expect(unnameable_types, reason = "being unnameable is what seals the trait")]
mod sealed {
#[derive(Debug)]
pub struct Private;
pub trait Sealed {}
impl<T: crate::DeepClone> Sealed for T {}
}