1use core::ops::{Deref, DerefMut};
2use std::mem::ManuallyDrop;
3
4#[inline]
7pub fn drop_owned<T: OwnedDroppable>(val: T) -> DropOwned<T> {
8 DropOwned::new(val)
9}
10
11pub trait OwnedDroppable: Sized {
14 fn drop_owned(self);
18}
19
20pub struct DropOwned<T: OwnedDroppable>(ManuallyDrop<T>);
23
24impl<T: OwnedDroppable> DropOwned<T> {
25 #[inline]
28 pub fn new(val: T) -> Self {
29 Self(ManuallyDrop::new(val))
30 }
31}
32
33impl<T: OwnedDroppable> From<T> for DropOwned<T> {
34 #[inline]
35 fn from(val: T) -> Self {
36 DropOwned::new(val)
37 }
38}
39
40impl<T: OwnedDroppable> Deref for DropOwned<T> {
41 type Target = T;
42
43 #[inline]
44 fn deref(&self) -> &Self::Target {
45 self.0.deref()
46 }
47}
48
49impl<T: OwnedDroppable> DerefMut for DropOwned<T> {
50 #[inline]
51 fn deref_mut(&mut self) -> &mut Self::Target {
52 self.0.deref_mut()
53 }
54}
55
56impl<T: OwnedDroppable> Drop for DropOwned<T> {
57 #[inline]
58 fn drop(&mut self) {
59 let owned = unsafe { ((&mut self.0) as *mut ManuallyDrop<T>).read() };
63 ManuallyDrop::into_inner(owned).drop_owned();
64 }
65}