1use std::mem::{self, MaybeUninit};
2
3pub unsafe fn transmute_maybe_uninit<T>(ptr: &mut T) -> &mut MaybeUninit<T> {
9 mem::transmute(ptr)
10}
11
12#[macro_export]
14macro_rules! pin_new {
15 ($varn:ident: $vart:ty = $methodn:ident($($arg:expr),* $(,)?)) => {
16 let mut __uninit = std::mem::MaybeUninit::<$vart>::uninit();
17 let __uninit_ptr = std::pin::pin!(__uninit);
18 let $varn = <$vart>::init(__uninit_ptr, $($($arg),*)?);
19 };
20 (mut $varn:ident: $vart:ty = $methodn:ident($($arg:expr),* $(,)?)) => {
21 let mut __uninit = std::mem::MaybeUninit::<$vart>::uninit();
22 let __uninit_ptr = std::pin::pin!(__uninit);
23 let mut $varn = <$vart>::init(__uninit_ptr, $($($arg),*)?);
24 };
25}
26#[macro_export]
28macro_rules! pin_init {
29 ($v:vis fn $name:ident<$a:lifetime>($this:ident $(, $($argn:ident: $argt:ty),+)? $(,)?) $blk:block) => {
30 $v fn $name(
31 mut __uninit_ptr: std::pin::Pin<&$a mut std::mem::MaybeUninit<Self>>,
32 $($($argn: $argt)+)?
33 ) -> std::pin::Pin<&$a mut Self> {
34 let __init_ptr = unsafe { __uninit_ptr.as_mut().get_unchecked_mut().as_mut_ptr() };
35
36 macro_rules! pin_init_clone {
39 () => {
40 unsafe { std::pin::Pin::new_unchecked(&mut *__init_ptr) }
41 };
42 }
43 macro_rules! pin_init_field {
45 ($fieldn:ident: $fieldt:ty) => {
46 unsafe { std::pin::Pin::new_unchecked($crate::transmute_maybe_uninit(&mut (*__init_ptr).$fieldn)) }
47 };
48 }
49
50 let $this = unsafe { &mut *__init_ptr };
51 $blk;
52 unsafe { std::pin::Pin::new_unchecked($this) }
53 }
54 };
55}
56#[macro_export]
63macro_rules! pin_field_init {
64 ($fieldt:ty: $methodn:ident($this:ident.$fieldn:ident $(, $($arg:expr)+)? $(,)?)) => {
65 unsafe {
66 let __field_ptr = &mut $this.as_mut().get_unchecked_mut().$fieldn as *mut Option<$fieldt>;
67 *__field_ptr = Some(std::mem::MaybeUninit::uninit().assume_init());
68
69 match &mut *__field_ptr {
70 Some(__field) => {
71 let __pinned_field = std::pin::Pin::new_unchecked($crate::transmute_maybe_uninit(__field));
72 <$fieldt>::$methodn(__pinned_field, $($($arg)+)?);
73 },
74 None => unreachable!(),
75 }
76 }
77 };
78 ($this:ident: |$($srcfield:ident),+ => $dstfield:ident| $fieldv:expr) => {{
79 let __this_ptr = unsafe { $this.as_mut().get_unchecked_mut() as *mut Self };
80 $(let $srcfield = unsafe { &mut (*__this_ptr).$srcfield };)+
81 let __dst_ptr = unsafe { &mut (*__this_ptr).$dstfield };
82 __dst_ptr.replace($fieldv)
83 }};
84}
85#[macro_export]
88macro_rules! field_pin {
89 ($name:ident: $type:ty) => {
90 fn $name(self: std::pin::Pin<&mut Self>) -> std::pin::Pin<&mut $type> {
91 unsafe { self.map_unchecked_mut(|this| &mut this.$name) }
92 }
93 }
94}
95#[macro_export]
97macro_rules! field_unpin {
98 ($name:ident: $type:ty) => {
99 fn $name(self: std::pin::Pin<&mut Self>) -> &mut $type {
100 unsafe { self.map_unchecked_mut(|this| &mut this.$name).get_mut() }
101 }
102 };
103}