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
68
69
70
71
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) {
unsafe { Clone::clone_from(&mut *(dst as *mut Self), self) }
}
unsafe fn raw_move_to(&mut self, dst: *mut u8) {
unsafe {
*(dst as *mut T) = take(self);
}
}
unsafe fn raw_clone_from(&mut self, src: *const u8) {
unsafe {
*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 {}