basedrop/
owned.rs

1use crate::{Handle, Node};
2
3use core::marker::PhantomData;
4use core::ops::{Deref, DerefMut};
5use core::ptr::NonNull;
6
7/// An owned smart pointer with deferred collection, analogous to `Box`.
8///
9/// When an `Owned<T>` is dropped, its contents are added to the drop queue
10/// of the [`Collector`] whose [`Handle`] it was originally allocated with.
11/// As the collector may be on another thread, contents are required to be
12/// `Send + 'static`.
13///
14/// [`Collector`]: crate::Collector
15/// [`Handle`]: crate::Handle
16pub struct Owned<T> {
17    node: NonNull<Node<T>>,
18    phantom: PhantomData<T>,
19}
20
21unsafe impl<T: Send> Send for Owned<T> {}
22unsafe impl<T: Sync> Sync for Owned<T> {}
23
24impl<T: Send + 'static> Owned<T> {
25    /// Constructs a new `Owned<T>`.
26    ///
27    /// # Examples
28    /// ```
29    /// use basedrop::{Collector, Owned};
30    ///
31    /// let collector = Collector::new();
32    /// let three = Owned::new(&collector.handle(), 3);
33    /// ```
34    pub fn new(handle: &Handle, data: T) -> Owned<T> {
35        Owned {
36            node: unsafe { NonNull::new_unchecked(Node::alloc(handle, data)) },
37            phantom: PhantomData,
38        }
39    }
40}
41
42impl<T: Clone + Send + 'static> Clone for Owned<T> {
43    fn clone(&self) -> Self {
44        let handle = unsafe { Node::handle(self.node.as_ptr()) };
45        Owned::new(&handle, self.deref().clone())
46    }
47}
48
49impl<T> Deref for Owned<T> {
50    type Target = T;
51
52    fn deref(&self) -> &Self::Target {
53        unsafe { &self.node.as_ref().data }
54    }
55}
56
57impl<T> DerefMut for Owned<T> {
58    fn deref_mut(&mut self) -> &mut Self::Target {
59        unsafe { &mut self.node.as_mut().data }
60    }
61}
62
63impl<T> Drop for Owned<T> {
64    fn drop(&mut self) {
65        unsafe {
66            Node::queue_drop(self.node.as_ptr());
67        }
68    }
69}