llvm_quick/
owning.rs

1use std::fmt::{Debug, Formatter};
2use std::mem::forget;
3use std::ops::Deref;
4use std::ptr::NonNull;
5
6use crate::Opaque;
7
8pub trait OpaqueDrop {
9    unsafe fn drop_raw(ptr: *mut Self);
10}
11
12pub trait OpaqueClone {
13    unsafe fn clone_raw(ptr: *mut Self) -> *mut Self;
14}
15
16pub struct Owning<T: Opaque<Inner: OpaqueDrop>> {
17    ptr: NonNull<T>,
18}
19
20impl<T: Opaque<Inner: OpaqueDrop + OpaqueClone>> Clone for Owning<T> {
21    fn clone(&self) -> Self {
22        unsafe { Self::from_raw(T::Inner::clone_raw(self.as_raw())) }
23    }
24}
25
26impl<T: Opaque<Inner: OpaqueDrop>> Drop for Owning<T> {
27    fn drop(&mut self) {
28        unsafe { T::Inner::drop_raw(self.as_raw()) }
29    }
30}
31
32impl<T: Opaque<Inner: OpaqueDrop>> Deref for Owning<T> {
33    type Target = T;
34
35    fn deref(&self) -> &Self::Target {
36        unsafe { self.ptr.as_ref() }
37    }
38}
39
40impl<T: Opaque<Inner: OpaqueDrop> + Debug> Debug for Owning<T> {
41    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42        Debug::fmt(self.deref(), f)
43    }
44}
45
46impl<T: Opaque<Inner: OpaqueDrop>> Owning<T> {
47    pub unsafe fn from_ptr(ptr: *mut T::Inner) -> Option<Self> {
48        if ptr.is_null() {
49            None
50        } else {
51            unsafe { Some(Self::from_raw(ptr)) }
52        }
53    }
54
55    pub unsafe fn from_raw(ptr: *mut T::Inner) -> Self {
56        unsafe {
57            Self {
58                ptr: T::from_raw(ptr).into(),
59            }
60        }
61    }
62
63    pub fn into_raw(self) -> *mut T::Inner {
64        let ptr = self.as_raw();
65        forget(self);
66        ptr
67    }
68}