owned_drop/
lib.rs

1use core::ops::{Deref, DerefMut};
2use std::mem::ManuallyDrop;
3
4/// Creates a new instance of `DropOwned` containing
5/// the passed `val`.
6#[inline]
7pub fn drop_owned<T: OwnedDroppable>(val: T) -> DropOwned<T> {
8    DropOwned::new(val)
9}
10
11/// This trait has to be implemented for types that
12/// can be dropped ownedly.
13pub trait OwnedDroppable: Sized {
14    /// This method is called once the `OwnedDrop`
15    /// got dropped and provides the dropped instance to
16    /// the implementor.
17    fn drop_owned(self);
18}
19
20/// Once this type gets dropped, the contained value
21/// is passed to the `drop_owned` function it has to implement.
22pub struct DropOwned<T: OwnedDroppable>(ManuallyDrop<T>);
23
24impl<T: OwnedDroppable> DropOwned<T> {
25    /// Creates a new instance of `DropOwned` containing
26    /// the passed `val`.
27    #[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        // SAFETY: This is safe because we only ever read this instance once and
60        // that is here and we know that the location is valid for reads,
61        // initialized and aligned.
62        let owned = unsafe { ((&mut self.0) as *mut ManuallyDrop<T>).read() };
63        ManuallyDrop::into_inner(owned).drop_owned();
64    }
65}