// Copyright 2016 Amanieu d'Antras // // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. #[cfg(feature = "alloc")] use crate::alloc::boxed::Box; use core::borrow::Borrow; use core::fmt; use core::ops::Deref; use core::ptr::NonNull; /// Unchecked shared pointer /// /// This type acts like a `Rc` or `Arc` except that no reference count is /// maintained. Instead, the user is responsible for freeing the managed object /// once it is no longer in use. /// /// You must guarantee that an object managed by an `UnsafeRef` is not /// moved, dropped or accessed through a mutable reference as long as at least /// one `UnsafeRef` is pointing to it. pub struct UnsafeRef { ptr: NonNull, } impl UnsafeRef { /// Creates an `UnsafeRef` from a raw pointer /// /// # Safety /// /// You must ensure that the `UnsafeRef` guarantees are upheld. #[inline] pub unsafe fn from_raw(val: *const T) -> UnsafeRef { UnsafeRef { ptr: NonNull::new_unchecked(val as *mut _), } } /// Converts an `UnsafeRef` into a raw pointer #[inline] pub fn into_raw(ptr: Self) -> *mut T { ptr.ptr.as_ptr() } } #[cfg(feature = "alloc")] impl UnsafeRef { /// Creates an `UnsafeRef` from a `Box` #[inline] pub fn from_box(val: Box) -> UnsafeRef { unsafe { UnsafeRef::from_raw(Box::into_raw(val)) } } /// Converts an `UnsafeRef` into a `Box` /// /// # Safety /// /// You must ensure that this is the only `UnsafeRef` managing this /// object and that it is not currently a member of any intrusive /// collections. This operation is only valid if the `UnsafeRef` was /// created using `UnsafeRef::from_box`. #[inline] pub unsafe fn into_box(ptr: Self) -> Box { Box::from_raw(UnsafeRef::into_raw(ptr)) } } impl Clone for UnsafeRef { #[inline] fn clone(&self) -> UnsafeRef { UnsafeRef { ptr: self.ptr } } } impl Deref for UnsafeRef { type Target = T; #[inline] fn deref(&self) -> &T { self.as_ref() } } impl AsRef for UnsafeRef { #[inline] fn as_ref(&self) -> &T { unsafe { self.ptr.as_ref() } } } impl Borrow for UnsafeRef { #[inline] fn borrow(&self) -> &T { self.as_ref() } } impl fmt::Debug for UnsafeRef { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(self.as_ref(), f) } } unsafe impl Send for UnsafeRef {} unsafe impl Sync for UnsafeRef {}