dbsp/dynamic/clonable.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
use crate::dynamic::DowncastTrait;
use dyn_clone::DynClone;
use std::mem::take;
pub trait Clonable: DynClone {
/// Clone `self` into `dst`.
///
/// # Safety
///
/// `dst` must be a valid mutable reference to a value of type `Self`.
unsafe fn raw_clone_to(&self, dst: *mut u8);
/// Move the contents of `self` into `dst`, replacing the contents of
/// `self` with `Self::default()`.
///
/// # Safety
///
/// `dst` must be a valid mutable reference to a value of type `Self`.
unsafe fn raw_move_to(&mut self, dst: *mut u8);
/// Clone `src` into `self`.
///
/// # Safety
///
/// `src` must be a valid reference to a value of type `Self`.
unsafe fn raw_clone_from(&mut self, src: *const u8);
}
impl<T: Clone + Default> Clonable for T {
unsafe fn raw_clone_to(&self, dst: *mut u8) {
Clone::clone_from(&mut *(dst as *mut Self), self)
}
unsafe fn raw_move_to(&mut self, dst: *mut u8) {
*(dst as *mut T) = take(self);
}
unsafe fn raw_clone_from(&mut self, src: *const u8) {
*self = (*(src as *const Self)).clone();
}
}
/// Trait for trait objects whose concrete type can be cloned and moved.
// FIXME: this should be unsafe, similar to other traits in this crate.
pub trait ClonableTrait: Clonable + DowncastTrait {
/// Clone `self` into `dst`.
#[inline]
fn clone_to(&self, dst: &mut Self) {
debug_assert_eq!(self.as_any().type_id(), (dst as &Self).as_any().type_id());
unsafe { Clonable::raw_clone_to(self, dst as *mut Self as *mut u8) }
}
/// Move the contents of `self` into `dst`, replacing the contents of
/// `self` with `Self::default()`.
#[inline]
fn move_to(&mut self, dst: &mut Self) {
debug_assert_eq!(
(self as &Self).as_any().type_id(),
(dst as &Self).as_any().type_id()
);
unsafe { Clonable::raw_move_to(self, dst as *mut Self as *mut u8) }
}
}
impl<Trait> ClonableTrait for Trait where Trait: Clonable + DowncastTrait + ?Sized {}