1#![allow(clippy::transmute_ptr_to_ptr)]
8
9use crate::Yokeable;
10use core::{
11 mem::{self, ManuallyDrop},
12 ptr,
13};
14
15macro_rules! copy_yoke_impl {
16 () => {
17 #[inline]
18 fn transform(&self) -> &Self::Output {
19 self
20 }
21 #[inline]
22 fn transform_owned(self) -> Self::Output {
23 self
24 }
25 #[inline]
26 unsafe fn make(this: Self::Output) -> Self {
27 this
28 }
29 #[inline]
30 fn transform_mut<F>(&'a mut self, f: F)
31 where
32 F: 'static + for<'b> FnOnce(&'b mut Self::Output),
33 {
34 f(self)
35 }
36 };
37}
38macro_rules! impl_copy_type {
39 ($ty:ty) => {
40 unsafe impl<'a> Yokeable<'a> for $ty {
43 type Output = Self;
44 copy_yoke_impl!();
45 }
46 };
47}
48
49impl_copy_type!(());
50impl_copy_type!(u8);
51impl_copy_type!(u16);
52impl_copy_type!(u32);
53impl_copy_type!(u64);
54impl_copy_type!(u128);
55impl_copy_type!(usize);
56impl_copy_type!(i8);
57impl_copy_type!(i16);
58impl_copy_type!(i32);
59impl_copy_type!(i64);
60impl_copy_type!(i128);
61impl_copy_type!(isize);
62impl_copy_type!(char);
63impl_copy_type!(bool);
64
65macro_rules! unsafe_complex_yoke_impl {
70 () => {
71 fn transform(&'a self) -> &'a Self::Output {
72 unsafe { mem::transmute(self) }
74 }
75
76 fn transform_owned(self) -> Self::Output {
77 debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
78 unsafe {
80 let ptr: *const Self::Output = (&self as *const Self).cast();
81 let _ = ManuallyDrop::new(self);
82 ptr::read(ptr)
83 }
84 }
85
86 unsafe fn make(from: Self::Output) -> Self {
87 debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>());
88 let ptr: *const Self = (&from as *const Self::Output).cast();
89 let _ = ManuallyDrop::new(from);
90 unsafe { ptr::read(ptr) }
93 }
94
95 fn transform_mut<F>(&'a mut self, f: F)
96 where
97 F: 'static + for<'b> FnOnce(&'b mut Self::Output),
98 {
99 unsafe { f(mem::transmute::<&'a mut Self, &'a mut Self::Output>(self)) }
103 }
104 };
105}
106
107unsafe impl<'a, T: 'static + for<'b> Yokeable<'b>> Yokeable<'a> for Option<T> {
110 type Output = Option<<T as Yokeable<'a>>::Output>;
111 unsafe_complex_yoke_impl!();
112}
113
114unsafe impl<'a, T1: 'static + for<'b> Yokeable<'b>, T2: 'static + for<'b> Yokeable<'b>> Yokeable<'a>
117 for (T1, T2)
118{
119 type Output = (<T1 as Yokeable<'a>>::Output, <T2 as Yokeable<'a>>::Output);
120 unsafe_complex_yoke_impl!();
121}
122
123unsafe impl<'a, T: 'static + for<'b> Yokeable<'b>, const N: usize> Yokeable<'a> for [T; N] {
126 type Output = [<T as Yokeable<'a>>::Output; N];
127 unsafe_complex_yoke_impl!();
128}