• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 Amanieu d'Antras
2 //
3 // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4 // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5 // http://opensource.org/licenses/MIT>, at your option. This file may not be
6 // copied, modified, or distributed except according to those terms.
7 
8 #[cfg(feature = "alloc")]
9 use crate::alloc::boxed::Box;
10 use core::borrow::Borrow;
11 use core::fmt;
12 use core::ops::Deref;
13 use core::ptr::NonNull;
14 
15 /// Unchecked shared pointer
16 ///
17 /// This type acts like a `Rc` or `Arc` except that no reference count is
18 /// maintained. Instead, the user is responsible for freeing the managed object
19 /// once it is no longer in use.
20 ///
21 /// You must guarantee that an object managed by an `UnsafeRef` is not
22 /// moved, dropped or accessed through a mutable reference as long as at least
23 /// one `UnsafeRef` is pointing to it.
24 pub struct UnsafeRef<T: ?Sized> {
25     ptr: NonNull<T>,
26 }
27 
28 impl<T: ?Sized> UnsafeRef<T> {
29     /// Creates an `UnsafeRef` from a raw pointer
30     ///
31     /// # Safety
32     ///
33     /// You must ensure that the `UnsafeRef` guarantees are upheld.
34     #[inline]
from_raw(val: *const T) -> UnsafeRef<T>35     pub unsafe fn from_raw(val: *const T) -> UnsafeRef<T> {
36         UnsafeRef {
37             ptr: NonNull::new_unchecked(val as *mut _),
38         }
39     }
40 
41     /// Converts an `UnsafeRef` into a raw pointer
42     #[inline]
into_raw(ptr: Self) -> *mut T43     pub fn into_raw(ptr: Self) -> *mut T {
44         ptr.ptr.as_ptr()
45     }
46 }
47 
48 #[cfg(feature = "alloc")]
49 impl<T: ?Sized> UnsafeRef<T> {
50     /// Creates an `UnsafeRef` from a `Box`
51     #[inline]
from_box(val: Box<T>) -> UnsafeRef<T>52     pub fn from_box(val: Box<T>) -> UnsafeRef<T> {
53         unsafe { UnsafeRef::from_raw(Box::into_raw(val)) }
54     }
55 
56     /// Converts an `UnsafeRef` into a `Box`
57     ///
58     /// # Safety
59     ///
60     /// You must ensure that this is the only `UnsafeRef` managing this
61     /// object and that it is not currently a member of any intrusive
62     /// collections. This operation is only valid if the `UnsafeRef` was
63     /// created using `UnsafeRef::from_box`.
64     #[inline]
into_box(ptr: Self) -> Box<T>65     pub unsafe fn into_box(ptr: Self) -> Box<T> {
66         Box::from_raw(UnsafeRef::into_raw(ptr))
67     }
68 }
69 
70 impl<T: ?Sized> Clone for UnsafeRef<T> {
71     #[inline]
clone(&self) -> UnsafeRef<T>72     fn clone(&self) -> UnsafeRef<T> {
73         UnsafeRef { ptr: self.ptr }
74     }
75 }
76 
77 impl<T: ?Sized> Deref for UnsafeRef<T> {
78     type Target = T;
79 
80     #[inline]
deref(&self) -> &T81     fn deref(&self) -> &T {
82         self.as_ref()
83     }
84 }
85 
86 impl<T: ?Sized> AsRef<T> for UnsafeRef<T> {
87     #[inline]
as_ref(&self) -> &T88     fn as_ref(&self) -> &T {
89         unsafe { self.ptr.as_ref() }
90     }
91 }
92 
93 impl<T: ?Sized> Borrow<T> for UnsafeRef<T> {
94     #[inline]
borrow(&self) -> &T95     fn borrow(&self) -> &T {
96         self.as_ref()
97     }
98 }
99 
100 impl<T: fmt::Debug + ?Sized> fmt::Debug for UnsafeRef<T> {
101     #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result102     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103         fmt::Debug::fmt(self.as_ref(), f)
104     }
105 }
106 
107 unsafe impl<T: ?Sized + Send> Send for UnsafeRef<T> {}
108 
109 unsafe impl<T: ?Sized + Sync> Sync for UnsafeRef<T> {}
110