safer_ffi/
ptr.rs

1#![cfg_attr(rustfmt, rustfmt::skip)]
2//! Wrappers around `NonNull` to better express the semantics of such pointer.
3//!
4//! Useful when manually defining custom low-level `ReprC` types.
5
6use_prelude!();
7
8#[doc(no_inline)]
9pub use ::core::ptr::*;
10
11#[cfg_attr(feature = "stabby", stabby::stabby)]
12#[repr(transparent)]
13pub
14struct NonNullRef<T> (
15    pub
16    ptr::NonNull<T>, // Variance OK because immutable
17);
18
19#[cfg_attr(feature = "stabby", stabby::stabby)]
20#[repr(transparent)]
21pub
22struct NonNullMut<T> (
23    pub
24    ptr::NonNull<T>,
25
26    pub
27    PhantomInvariant<T>, // Must be invariant because non-owning mutable.
28);
29
30#[cfg_attr(feature = "stabby", stabby::stabby)]
31#[repr(transparent)]
32pub
33struct NonNullOwned<T> (
34    pub
35    ptr::NonNull<T>, // Variance OK because ownership
36
37    pub
38    PhantomData<T>, // Express ownership to dropck
39);
40
41macro_rules! impl_for_each {(
42    [$($T:ident),* $(,)?]
43        .impl_for_each!(|$dol:tt $NonNull:ident| {
44            $($expansion:tt)*
45        })
46    ;
47) => (
48    // const _: () = {
49        macro_rules! helper {(
50            $dol $NonNull : ident
51        ) => (
52            $($expansion)*
53        )}
54        $(
55            helper! { $T }
56        )*
57    // };
58)}
59
60impl_for_each! {
61    [NonNullRef, NonNullMut, NonNullOwned].impl_for_each!(|$NonNull| {
62        impl<T> From<NonNull<T>>
63            for $NonNull<T>
64        {
65            #[inline]
66            fn from (it: NonNull<T>)
67              -> Self
68            {
69                unsafe { ::core::mem::transmute(it) }
70            }
71        }
72
73        impl<T> ::core::ops::Deref
74            for $NonNull<T>
75        {
76            type Target = ptr::NonNull<T>;
77
78            #[inline]
79            fn deref (self: &'_ $NonNull<T>)
80            -> &'_ ptr::NonNull<T>
81            {
82                &self.0
83            }
84        }
85
86        impl<T> fmt::Debug
87            for $NonNull<T>
88        {
89            fn fmt (self: &'_ $NonNull<T>, fmt: &'_ mut fmt::Formatter<'_>)
90              -> fmt::Result
91            {
92                fmt .debug_tuple(stringify!($NonNull))
93                    .field(&self.0)
94                    .finish()
95            }
96        }
97
98        impl<T> $NonNull<T> {
99            #[inline]
100            pub
101            fn as_ptr (self: &'_ Self)
102              -> *const T
103            {
104                self.0.as_ptr()
105            }
106
107            #[inline]
108            pub
109            fn cast<U> (self: $NonNull<T>)
110              -> $NonNull<U>
111            {
112                unsafe { ::core::mem::transmute(self) }
113            }
114        }
115    });
116}
117
118impl_for_each! {
119    [NonNullMut, NonNullOwned].impl_for_each!(|$NonNull| {
120        impl<T> ::core::ops::DerefMut
121            for $NonNull<T>
122        {
123            #[inline]
124            fn deref_mut (self: &'_ mut $NonNull<T>)
125              -> &'_ mut ptr::NonNull<T>
126            {
127                &mut self.0
128            }
129        }
130
131        impl<T> $NonNull<T> {
132            #[inline]
133            pub
134            fn as_mut_ptr (self: &'_ mut Self)
135              -> *mut T
136            {
137                self.0.as_ptr()
138            }
139
140            #[inline]
141            pub
142            fn copy (self: &'_ mut $NonNull<T>)
143              -> $NonNull<T>
144            {
145                $NonNull::<T> { .. *self }
146            }
147        }
148    });
149}
150impl_for_each! {
151    [NonNullMut, NonNullRef].impl_for_each!(|$NonNull| {
152        impl<'lt, T : 'lt> From<&'lt mut T>
153            for $NonNull<T>
154        {
155            #[inline]
156            fn from (it: &'lt mut T)
157              -> $NonNull<T>
158            {
159                $NonNull::from(NonNull::from(it))
160            }
161        }
162    });
163}
164impl<'lt, T : 'lt> From<&'lt T>
165    for NonNullRef<T>
166{
167    #[inline]
168    fn from (it: &'lt T)
169      -> NonNullRef<T>
170    {
171        NonNullRef::from(NonNull::from(it))
172    }
173}
174
175impl<__> NonNullOwned<__> {
176    cfg_alloc! {
177        #[inline]
178        pub
179        unsafe
180        fn dealloc<T> (self)
181        {
182            if ::core::mem::size_of::<T>() == 0 {
183                return;
184            }
185            ::alloc::alloc::dealloc(
186                self.0.as_ptr().cast(),
187                ::alloc::alloc::Layout::new::<T>(),
188            );
189        }
190
191        #[inline]
192        pub
193        unsafe
194        fn drop_in_place_and_dealloc<T> (mut self)
195        {
196            drop_in_place::<T>(self.copy().cast().as_mut());
197            self.dealloc::<T>();
198        }
199    }
200
201    #[inline]
202    pub
203    unsafe
204    fn drop_in_place<T> (self)
205    {
206        drop_in_place::<T>(self.0.cast().as_mut());
207    }
208}
209
210impl<__> Copy
211    for NonNullRef<__>
212{}
213impl<__> Clone
214    for NonNullRef<__>
215{
216    #[inline]
217    fn clone (self: &'_ Self)
218      -> Self
219    {
220        *self
221    }
222}