evmap/
shallow_copy.rs

1//! Types that can be cheaply aliased.
2
3use std::mem::ManuallyDrop;
4use std::ops::{Deref, DerefMut};
5
6/// Types that implement this trait can be cheaply copied by (potentially) aliasing the data they
7/// contain. Only the _last_ shallow copy will be dropped -- all others will be silently leaked
8/// (with `mem::forget`).
9///
10/// To implement this trait for your own `Copy` type, write:
11///
12/// ```rust
13/// # use evmap::ShallowCopy;
14/// use std::mem::ManuallyDrop;
15///
16/// #[derive(Copy, Clone)]
17/// struct T;
18///
19/// impl ShallowCopy for T {
20///     unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
21///         ManuallyDrop::new(*self)
22///     }
23/// }
24/// ```
25///
26/// If you have a non-`Copy` type, the value returned by `shallow_copy` should point to the same
27/// data as the `&mut self`, and it should be safe to `mem::forget` either of the copies as long as
28/// the other is dropped normally afterwards.
29///
30/// For complex, non-`Copy` types, you can place the type behind a wrapper that implements
31/// `ShallowCopy` such as `Box` or `Arc`.
32/// Alternatively, if your type is made up of types that all implement `ShallowCopy`, consider
33/// using the `evmap-derive` crate, which contains a derive macro for `ShallowCopy`.
34/// See that crate's documentation for details.
35pub trait ShallowCopy {
36    /// Perform an aliasing copy of this value.
37    ///
38    /// # Safety
39    ///
40    /// The use of this method is *only* safe if the values involved are never mutated, and only
41    /// one of the copies is dropped; the remaining copies must be forgotten with `mem::forget`.
42    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self>;
43}
44
45use std::sync::Arc;
46impl<T> ShallowCopy for Arc<T>
47where
48    T: ?Sized,
49{
50    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
51        ManuallyDrop::new(Arc::from_raw(&**self as *const _))
52    }
53}
54
55use std::rc::Rc;
56impl<T> ShallowCopy for Rc<T>
57where
58    T: ?Sized,
59{
60    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
61        ManuallyDrop::new(Rc::from_raw(&**self as *const _))
62    }
63}
64
65impl<T> ShallowCopy for Box<T>
66where
67    T: ?Sized,
68{
69    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
70        ManuallyDrop::new(Box::from_raw(&**self as *const _ as *mut _))
71    }
72}
73
74impl<T> ShallowCopy for Option<T>
75where
76    T: ShallowCopy,
77{
78    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
79        ManuallyDrop::new(if let Some(value) = self {
80            Some(ManuallyDrop::into_inner(value.shallow_copy()))
81        } else {
82            None
83        })
84    }
85}
86
87impl ShallowCopy for String {
88    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
89        let buf = self.as_bytes().as_ptr();
90        let len = self.len();
91        let cap = self.capacity();
92        ManuallyDrop::new(String::from_raw_parts(buf as *mut _, len, cap))
93    }
94}
95
96impl<T> ShallowCopy for Vec<T> {
97    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
98        let ptr = self.as_ptr() as *mut _;
99        let len = self.len();
100        let cap = self.capacity();
101        ManuallyDrop::new(Vec::from_raw_parts(ptr, len, cap))
102    }
103}
104
105#[cfg(feature = "bytes")]
106impl ShallowCopy for bytes::Bytes {
107    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
108        let len = self.len();
109        let buf: &'static [u8] = std::slice::from_raw_parts(self.as_ptr(), len);
110        ManuallyDrop::new(bytes::Bytes::from_static(buf))
111    }
112}
113
114impl<'a, T> ShallowCopy for &'a T
115where
116    T: ?Sized,
117{
118    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
119        ManuallyDrop::new(&*self)
120    }
121}
122
123/// If you are willing to have your values be copied between the two views of the `evmap`,
124/// wrap them in this type.
125///
126/// This is effectively a way to bypass the `ShallowCopy` optimization.
127/// Note that you do not need this wrapper for most `Copy` primitives.
128#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Default)]
129#[repr(transparent)]
130pub struct CopyValue<T>(T);
131
132impl<T: Copy> From<T> for CopyValue<T> {
133    fn from(t: T) -> Self {
134        CopyValue(t)
135    }
136}
137
138impl<T> ShallowCopy for CopyValue<T>
139where
140    T: Copy,
141{
142    unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
143        ManuallyDrop::new(CopyValue(self.0))
144    }
145}
146
147impl<T> Deref for CopyValue<T> {
148    type Target = T;
149    fn deref(&self) -> &Self::Target {
150        &self.0
151    }
152}
153
154impl<T> DerefMut for CopyValue<T> {
155    fn deref_mut(&mut self) -> &mut Self::Target {
156        &mut self.0
157    }
158}
159
160macro_rules! impl_shallow_copy_for_copy_primitives {
161    ($($t:ty)*) => ($(
162        impl ShallowCopy for $t {
163            unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
164                ManuallyDrop::new(*self)
165            }
166        }
167    )*)
168}
169
170impl_shallow_copy_for_copy_primitives!(() bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64);
171
172macro_rules! tuple_impls {
173    ($(
174        $Tuple:ident {
175            $(($idx:tt) -> $T:ident)+
176        }
177    )+) => {
178        $(
179            impl<$($T:ShallowCopy),+> ShallowCopy for ($($T,)+) {
180                unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
181                    ManuallyDrop::new(($(ManuallyDrop::into_inner(self.$idx.shallow_copy()),)+))
182                }
183            }
184        )+
185    }
186}
187
188tuple_impls! {
189    Tuple1 {
190        (0) -> A
191    }
192    Tuple2 {
193        (0) -> A
194        (1) -> B
195    }
196    Tuple3 {
197        (0) -> A
198        (1) -> B
199        (2) -> C
200    }
201    Tuple4 {
202        (0) -> A
203        (1) -> B
204        (2) -> C
205        (3) -> D
206    }
207    Tuple5 {
208        (0) -> A
209        (1) -> B
210        (2) -> C
211        (3) -> D
212        (4) -> E
213    }
214    Tuple6 {
215        (0) -> A
216        (1) -> B
217        (2) -> C
218        (3) -> D
219        (4) -> E
220        (5) -> F
221    }
222    Tuple7 {
223        (0) -> A
224        (1) -> B
225        (2) -> C
226        (3) -> D
227        (4) -> E
228        (5) -> F
229        (6) -> G
230    }
231    Tuple8 {
232        (0) -> A
233        (1) -> B
234        (2) -> C
235        (3) -> D
236        (4) -> E
237        (5) -> F
238        (6) -> G
239        (7) -> H
240    }
241    Tuple9 {
242        (0) -> A
243        (1) -> B
244        (2) -> C
245        (3) -> D
246        (4) -> E
247        (5) -> F
248        (6) -> G
249        (7) -> H
250        (8) -> I
251    }
252    Tuple10 {
253        (0) -> A
254        (1) -> B
255        (2) -> C
256        (3) -> D
257        (4) -> E
258        (5) -> F
259        (6) -> G
260        (7) -> H
261        (8) -> I
262        (9) -> J
263    }
264    Tuple11 {
265        (0) -> A
266        (1) -> B
267        (2) -> C
268        (3) -> D
269        (4) -> E
270        (5) -> F
271        (6) -> G
272        (7) -> H
273        (8) -> I
274        (9) -> J
275        (10) -> K
276    }
277    Tuple12 {
278        (0) -> A
279        (1) -> B
280        (2) -> C
281        (3) -> D
282        (4) -> E
283        (5) -> F
284        (6) -> G
285        (7) -> H
286        (8) -> I
287        (9) -> J
288        (10) -> K
289        (11) -> L
290    }
291}