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