use super::*;
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DropMoveWrapper<T: DropMove>(ManuallyDrop<T>);
impl<T: DropMove> DropMoveWrapper<T> {
unsafe fn take(self_: &mut Self) -> T {
ManuallyDrop::take(&mut self_.0)
}
pub fn new(x: T) -> Self {
DropMoveWrapper(ManuallyDrop::new(x))
}
pub fn into_inner(mut self_: Self) -> T {
let inner = unsafe { Self::take(&mut self_) };
mem::forget(self_);
inner
}
}
impl<T: DropMove> Deref for DropMoveWrapper<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.deref()
}
}
impl<T: DropMove> DerefMut for DropMoveWrapper<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0.deref_mut()
}
}
impl<T: DropMove> Drop for DropMoveWrapper<T> {
fn drop(&mut self) {
let drop_ref: DropHandle<T> = From::from(unsafe { Self::take(self) });
DropMove::drop_move(drop_ref);
}
}
#[macro_export]
macro_rules! drop_move_wrap {
{$($def:tt)+} => {
$crate::drop_move_wrap_match!{$($def)+}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! drop_move_wrap_match {
{
$(#[$attrs:meta])*
$({$(#[$outer_only_attrs:meta])+})?
$vis:vis struct $name:ident $(<
$($lifetimes:lifetime $(: $lifetime_bounds1:lifetime $(+ $lifetime_bounds2:lifetime)*)?),*
$(,)?
$($types:ident $(:
$($lifetime_ty_bounds1:lifetime)? $($type_bounds1:path)?
$(: $($lifetime_ty_bounds2:lifetime)? $($type_bounds2:path)?)*
)?),*
$(,)?
>)?(
$(#[$inner_only_attrs:meta])*
$inner_vis:vis $inner_name:ident {$($members:tt)*}
) $(where
$(
$($lifetime_wheres:lifetime)?
$($(for<($for_lt:lifetime),*>)? $type_wheres:ty)?
:
$($lifetime_ty_bounds3:lifetime)? $($type_bounds3:path)?
$(: $($lifetime_ty_bounds4:lifetime)? $($type_bounds4:path)?)*
),*
$(,)?
)?;
} => {
$crate::drop_move_wrap_transcribe!{
{ $(#[$attrs])* $($(#[$outer_only_attrs])+)? },
{ $(#[$attrs])* $(#[$inner_only_attrs])* },
$vis, $inner_vis,
struct,
$name, $inner_name,
{ $(<$($lifetimes, )*$($types, )*>)? },
{ $(<
$($lifetimes $(: $lifetime_bounds1 $(+ $lifetime_bounds2)*)?, )*
$($types $(:
$($type_bounds1)? $($lifetime_ty_bounds1)?
$(+ $($type_bounds2)? $($lifetime_ty_bounds2)?)*
)?, )*
>)? },
{ $(where
$(
$($lifetime_wheres)?
$($(for<($for_lt),*>)? $type_wheres)?
:
$($type_bounds3)? $($lifetime_ty_bounds3)?
$(+ $($type_bounds4)? $($lifetime_ty_bounds4)?)*
,)*
)? },
{ $($members)* },
}
};
{
$(#[$attrs:meta])*
$({$(#[$outer_only_attrs:meta])+})?
$vis:vis struct $name:ident $(<
$($lifetimes:lifetime $(: $lifetime_bounds1:lifetime $(+ $lifetime_bounds2:lifetime)*)?),*
$(,)?
$($types:ident $(:
$($lifetime_ty_bounds1:lifetime)? $($type_bounds1:path)?
$(: $($lifetime_ty_bounds2:lifetime)? $($type_bounds2:path)?)*
)?),*
$(,)?
>)?(
$(#[$inner_only_attrs:meta])*
$inner_vis:vis $inner_name:ident ($($members:tt)*)
) $(where
$(
$($lifetime_wheres:lifetime)?
$($(for<($for_lt:lifetime),*>)? $type_wheres:ty)?
:
$($lifetime_ty_bounds3:lifetime)? $($type_bounds3:path)?
$(: $($lifetime_ty_bounds4:lifetime)? $($type_bounds4:path)?)*
),*
$(,)?
)?;
} => {
$crate::drop_move_wrap_transcribe!{
{ $(#[$attrs])* $($(#[$outer_only_attrs])+)? },
{ $(#[$attrs])* $(#[$inner_only_attrs])* },
$vis, $inner_vis,
tuple,
$name, $inner_name,
{ $(<$($lifetimes, )*$($types, )*>)? },
{ $(<
$($lifetimes $(: $lifetime_bounds1 $(+ $lifetime_bounds2)*)?, )*
$($types $(:
$($type_bounds1)? $($lifetime_ty_bounds1)?
$(+ $($type_bounds2)? $($lifetime_ty_bounds2)?)*
)?, )*
>)? },
{ $(where
$(
$($lifetime_wheres)?
$($(for<($for_lt),*>)? $type_wheres)?
:
$($type_bounds3)? $($lifetime_ty_bounds3)?
$(+ $($type_bounds4)? $($lifetime_ty_bounds4)?)*
,)*
)? },
{ $($members)* },
}
};
{
$(#[$attrs:meta])*
$({$(#[$outer_only_attrs:meta])+})?
$vis:vis enum $name:ident $(<
$($lifetimes:lifetime $(: $lifetime_bounds1:lifetime $(+ $lifetime_bounds2:lifetime)*)?),*
$(,)?
$($types:ident $(:
$($lifetime_ty_bounds1:lifetime)? $($type_bounds1:path)?
$(: $($lifetime_ty_bounds2:lifetime)? $($type_bounds2:path)?)*
)?),*
$(,)?
>)?(
$(#[$inner_only_attrs:meta])*
$inner_vis:vis $inner_name:ident {$($members:tt)*}
) $(where
$(
$($lifetime_wheres:lifetime)?
$($(for<($for_lt:lifetime),*>)? $type_wheres:ty)?
:
$($lifetime_ty_bounds3:lifetime)? $($type_bounds3:path)?
$(: $($lifetime_ty_bounds4:lifetime)? $($type_bounds4:path)?)*
),*
$(,)?
)?;
} => {
$crate::drop_move_wrap_transcribe!{
{ $(#[$attrs])* $($(#[$outer_only_attrs])+)? },
{ $(#[$attrs])* $(#[$inner_only_attrs])* },
$vis, $inner_vis,
enum,
$name, $inner_name,
{ $(<$($lifetimes, )*$($types, )*>)? },
{ $(<
$($lifetimes $(: $lifetime_bounds1 $(+ $lifetime_bounds2)*)?, )*
$($types $(:
$($type_bounds1)? $($lifetime_ty_bounds1)?
$(+ $($type_bounds2)? $($lifetime_ty_bounds2)?)*
)?, )*
>)? },
{ $(where
$(
$($lifetime_wheres)?
$($(for<($for_lt),*>)? $type_wheres)?
:
$($type_bounds3)? $($lifetime_ty_bounds3)?
$(+ $($type_bounds4)? $($lifetime_ty_bounds4)?)*
,)*
)? },
{ $($members)* },
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! drop_move_wrap_transcribe {
{
{ $($attrs:tt)* },
{ $($inner_attrs:tt)* },
$vis:vis, $inner_vis:vis,
$decl_kind:ident,
$name:ident, $inner_name:ident,
{ $($generic_params:tt)* },
{ $($generic_bounds:tt)* },
{ $($where_clause:tt)* },
{ $($members:tt)* }$(,)?
} => {
$($attrs)*
$vis struct $name$($generic_bounds)*(
$inner_vis $crate::DropMoveWrapper<$inner_name$($generic_params)*>
) $($where_clause)*;
$crate::drop_move_wrap_inner_decl!{
{ $($inner_attrs)* },
$inner_vis, $decl_kind,
{ $inner_name$($generic_bounds)* },
{ $($where_clause)* },
{ $($members)* },
}
impl$($generic_bounds)* From<$name$($generic_params)*> for $inner_name$($generic_params)*
$($where_clause)* {
fn from(x: $name$($generic_params)*) -> Self {
$crate::DropMoveWrapper::into_inner(x.0)
}
}
impl$($generic_bounds)* From<$inner_name$($generic_params)*> for $name$($generic_params)*
$($where_clause)* {
fn from(x: $inner_name$($generic_params)*) -> Self {
Self($crate::DropMoveWrapper::new(x))
}
}
impl$($generic_bounds)* $crate::DropMoveTypes for $inner_name$($generic_params)*
$($where_clause)* {
type Outer = $name$($generic_params)*;
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! drop_move_wrap_inner_decl {
{
{ $($inner_attrs:tt)* },
$inner_vis:vis, struct,
{ $($inner_type:tt)* },
{ $($where_clause:tt)* },
{ $($members:tt)* },
} => {
$($inner_attrs)*
$inner_vis struct $($inner_type)* $($where_clause)* { $($members)* }
};
{
{ $($inner_attrs:tt)* },
$inner_vis:vis, tuple,
{ $($inner_type:tt)* },
{ $($where_clause:tt)* },
{ $($members:tt)* },
} => {
$($inner_attrs)*
$inner_vis struct $($inner_type)* ( $($members)* ) $($where_clause)*;
};
{
{ $($inner_attrs:tt)* },
$inner_vis:vis, enum,
{ $($inner_type:tt)* },
{ $($where_clause:tt)* },
{ $($members:tt)* },
} => {
$($inner_attrs)*
$inner_vis enum $($inner_type)* $($where_clause)* { $($members)* }
};
}