1use core::ops::{Deref, DerefMut};
4use core::pin::Pin;
5use core::ptr::NonNull;
6use core::{fmt, mem};
7
8pub use alloc::boxed::Box as UniqueBox;
9
10pub struct AliasableBox<T: ?Sized>(NonNull<T>);
13
14impl<T: ?Sized> AliasableBox<T> {
15 pub fn from_unique(ptr: UniqueBox<T>) -> Self {
17 let ptr = unsafe { NonNull::new_unchecked(UniqueBox::into_raw(ptr)) };
18 Self(ptr)
19 }
20
21 #[inline]
23 pub fn into_unique(mut ptr: AliasableBox<T>) -> UniqueBox<T> {
24 let unique = unsafe { ptr.reclaim_as_unique_box() };
28 mem::forget(ptr);
31 unique
33 }
34
35 pub fn into_unique_pin(pin: Pin<AliasableBox<T>>) -> Pin<UniqueBox<T>> {
38 unsafe {
40 let aliasable = Pin::into_inner_unchecked(pin);
41 Pin::new_unchecked(AliasableBox::into_unique(aliasable))
42 }
43 }
44
45 pub fn from_unique_pin(pin: Pin<UniqueBox<T>>) -> Pin<AliasableBox<T>> {
48 unsafe {
50 let unique = Pin::into_inner_unchecked(pin);
51 Pin::new_unchecked(AliasableBox::from(unique))
52 }
53 }
54
55 #[inline]
56 unsafe fn reclaim_as_unique_box(&mut self) -> UniqueBox<T> {
57 UniqueBox::from_raw(self.0.as_ptr())
58 }
59}
60
61impl<T: ?Sized> From<UniqueBox<T>> for AliasableBox<T> {
62 fn from(ptr: UniqueBox<T>) -> Self {
63 Self::from_unique(ptr)
64 }
65}
66
67impl<T: ?Sized> Drop for AliasableBox<T> {
68 fn drop(&mut self) {
69 let _ = unsafe { self.reclaim_as_unique_box() };
73 }
74}
75
76impl<T: ?Sized> Deref for AliasableBox<T> {
77 type Target = T;
78
79 #[inline]
80 fn deref(&self) -> &T {
81 unsafe { self.0.as_ref() }
83 }
84}
85
86impl<T: ?Sized> DerefMut for AliasableBox<T> {
87 #[inline]
88 fn deref_mut(&mut self) -> &mut T {
89 unsafe { self.0.as_mut() }
91 }
92}
93
94impl<T: ?Sized> AsRef<T> for AliasableBox<T> {
95 #[inline]
96 fn as_ref(&self) -> &T {
97 &*self
98 }
99}
100
101impl<T: ?Sized> AsMut<T> for AliasableBox<T> {
102 fn as_mut(&mut self) -> &mut T {
103 &mut *self
104 }
105}
106
107impl<T: ?Sized> fmt::Debug for AliasableBox<T>
108where
109 T: fmt::Debug,
110{
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 fmt::Debug::fmt(self.as_ref(), f)
113 }
114}
115
116unsafe impl<T: ?Sized> Send for AliasableBox<T> where T: Send {}
117unsafe impl<T: ?Sized> Sync for AliasableBox<T> where T: Sync {}
118
119#[cfg(feature = "traits")]
120unsafe impl<T: ?Sized> crate::StableDeref for AliasableBox<T> {}
121
122#[cfg(feature = "traits")]
123unsafe impl<T: ?Sized> crate::AliasableDeref for AliasableBox<T> {}
124
125#[cfg(test)]
126mod tests {
127 use super::{AliasableBox, UniqueBox};
128 use alloc::format;
129
130 #[test]
131 fn test_new() {
132 let aliasable = AliasableBox::from_unique(UniqueBox::new(10));
133 assert_eq!(*aliasable, 10);
134 let unique = AliasableBox::into_unique(aliasable);
135 assert_eq!(*unique, 10);
136 }
137
138 #[test]
139 fn test_new_pin() {
140 let aliasable = AliasableBox::from_unique_pin(UniqueBox::pin(10));
141 assert_eq!(*aliasable, 10);
142 let unique = AliasableBox::into_unique_pin(aliasable);
143 assert_eq!(*unique, 10);
144 }
145
146 #[test]
147 fn test_refs() {
148 let mut aliasable = AliasableBox::from_unique(UniqueBox::new(10));
149 let ptr: *const u8 = &*aliasable;
150 let as_mut_ptr: *const u8 = aliasable.as_mut();
151 let as_ref_ptr: *const u8 = aliasable.as_ref();
152 assert_eq!(ptr, as_mut_ptr);
153 assert_eq!(ptr, as_ref_ptr);
154 }
155
156 #[test]
157 fn test_debug() {
158 let aliasable = AliasableBox::from_unique(UniqueBox::new(10));
159 assert_eq!(format!("{:?}", aliasable), "10");
160 }
161}