use ::core::{
cmp::*,
fmt::{self, Debug},
hash::{self, Hash},
mem::MaybeUninit as MU,
ops::{Deref, DerefMut},
};
#[derive(Copy)]
#[repr(transparent)]
pub struct ManuallyDrop<T> {
value: MU<T>,
}
#[allow(unsafe_code)]
impl<T> ManuallyDrop<T> {
#[inline]
pub const fn new(value: T) -> ManuallyDrop<T> {
Self {
value: MU::new(value),
}
}
#[inline]
pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
unsafe { MU::assume_init(slot.value) }
}
#[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
#[inline]
pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
unsafe {
slot.value.as_ptr().read()
}
}
#[inline]
pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
unsafe {
slot.value.as_mut_ptr().drop_in_place()
}
}
}
#[allow(unsafe_code)]
impl<T> DerefMut for ManuallyDrop<T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
impl<T> Deref for ManuallyDrop<T> {
type Target = T;
#[inline]
fn deref(self: &Self) -> &T {
unsafe {
self.value.assume_init_ref()
}
}
}
unsafe {
self.value.assume_init_mut()
}
}
}
impl<T: Default> Default for ManuallyDrop<T> {
#[inline]
fn default() -> Self {
Self::new(T::default())
}
}
impl<T: Clone> Clone for ManuallyDrop<T> {
fn clone(self: &Self) -> Self {
Self::new(T::clone(self))
}
JustDerefTM! {
fn clone_from(self: &mut Self, source: &Self);
}
}
JustDerefTM! {
impl<T: Debug> Debug for ManuallyDrop<T> {
fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
}
impl<T: Hash> Hash for ManuallyDrop<T> {
fn hash<__H: hash::Hasher>(self: &Self, state: &mut __H);
}
impl<T: Ord> Ord for ManuallyDrop<T> {
fn cmp(self: &Self, other: &Self) -> Ordering;
}
impl<T: PartialOrd> PartialOrd for ManuallyDrop<T> {
fn partial_cmp(self: &Self, other: &Self) -> Option<Ordering>;
}
impl<T: PartialEq> PartialEq for ManuallyDrop<T> {
fn eq(self: &Self, other: &Self) -> bool;
}
impl<T: Eq> Eq for ManuallyDrop<T> {}
}
macro_rules! JustDerefTM {
(
$(
$(#$attr:tt)*
$($(@$if_unsafe:tt)?
unsafe
)?
impl<T $(: $Bound:path)?>
$($($Trait:ident)::+ for)?
ManuallyDrop<T>
{
$($inner:tt)*
}
)*
) => (
$(
$(#$attr)*
$($($if_unsafe)?
unsafe
)?
impl<T $(: $Bound)?>
$($($Trait)::+ for)?
ManuallyDrop<T>
{
JustDerefTM! {
$($inner)*
}
}
)*
$(
$(#$attr)*
$($($if_unsafe)?
unsafe
)?
impl<T $(: $Bound)?>
$($($Trait)::+ for)?
crate::MaybeDangling<T>
{
JustDerefTM! {
$($inner)*
}
}
)*
);
(
$(
$(#$attr:tt)*
$pub:vis
fn $fname:ident
$(<$H:ident $(: $Bound:path)?>)?
(
$(
$arg_name:ident : $ArgTy:ty
),* $(,)?
) $(-> $Ret:ty)? ;
)*
) => (
$(
#[inline]
$(#$attr)*
#[doc = concat!(
"\nSee [`::core::mem::ManuallyDrop::", stringify!($fname), "()`] for more info."
)]
$pub
fn $fname
$(<$H $(: $Bound)?>)?
(
$(
$arg_name : $ArgTy
),*
) $(-> $Ret)?
{
T::$fname($($arg_name),*)
}
)*
);
}
use JustDerefTM;