1 //! Pointer wrappers. 2 3 use core::ptr::NonNull; 4 use core::marker; 5 6 /// A pointer wrapper type. 7 /// 8 /// A wrapper around a raw non-null `*mut T` that indicates that the possessor of this wrapper owns 9 /// the referent. 10 #[derive(PartialEq, Eq, Debug, Clone)] 11 pub struct Pointer<T> { 12 /// The internal pointer. 13 ptr: NonNull<T>, 14 /// Associated phantom data. 15 /// 16 /// This indicates that we _own_ T. 17 _phantom: marker::PhantomData<T>, 18 } 19 20 impl<T> Pointer<T> { 21 /// Create a new `Pointer` from a raw pointer. 22 /// 23 /// # Safety 24 /// 25 /// This function is unsafe since a null pointer can cause UB, due to `Pointer` being 26 /// non-nullable. 27 #[inline] 28 pub unsafe fn new(ptr: *mut T) -> Pointer<T> { 29 // For the sake of nice debugging, make some assertions. 30 debug_assert!(!ptr.is_null(), "Null pointer!"); 31 32 Pointer { 33 ptr: NonNull::new_unchecked(ptr), 34 _phantom: marker::PhantomData, 35 } 36 } 37 38 /// Create an "empty" `Pointer`. 39 /// 40 /// This acts as a null pointer, although it is represented by 0x1 instead of 0x0. 41 #[inline] 42 pub const fn empty() -> Pointer<T> { 43 Pointer { 44 ptr: unsafe { 45 // LAST AUDIT: 2016-08-21 (Ticki). 46 47 // 0x1 is non-zero. 48 NonNull::new_unchecked(0x1 as *mut T) 49 }, 50 _phantom: marker::PhantomData, 51 } 52 } 53 54 /// Cast this pointer into a pointer to another type. 55 /// 56 /// This will simply transmute the pointer, leaving the actual data unmodified. 57 #[inline] 58 pub fn cast<U>(self) -> Pointer<U> { 59 Pointer { 60 ptr: unsafe { 61 // LAST AUDIT: 2016-08-21 (Ticki). 62 63 // Casting the pointer will preserve its nullable state. 64 NonNull::new_unchecked(self.get() as *mut U) 65 }, 66 _phantom: marker::PhantomData, 67 } 68 } 69 70 /// Offset this pointer. 71 /// 72 /// This will add some value multiplied by the size of T to the pointer. 73 /// 74 /// # Safety 75 /// 76 /// This is unsafe, due to OOB offsets being undefined behavior. 77 #[inline] 78 pub unsafe fn offset(self, diff: isize) -> Pointer<T> { 79 Pointer::new(self.ptr.as_ptr().offset(diff)) 80 } 81 82 pub fn get(&self) -> *mut T { 83 self.ptr.as_ptr() 84 } 85 } 86 87 impl<T> Default for Pointer<T> { 88 fn default() -> Pointer<T> { 89 Pointer::empty() 90 } 91 } 92 93 unsafe impl<T: Send> Send for Pointer<T> {} 94 unsafe impl<T: Sync> Sync for Pointer<T> {} 95 96 #[cfg(test)] 97 mod test { 98 use super::*; 99 100 #[test] 101 fn test_pointer() { 102 let mut x = [b'a', b'b']; 103 104 unsafe { 105 let ptr = Pointer::new(&mut x[0] as *mut u8); 106 assert_eq!(*ptr.get(), b'a'); 107 assert_eq!(*ptr.clone().cast::<[u8; 1]>().get(), [b'a']); 108 assert_eq!(*ptr.offset(1).get(), b'b'); 109 } 110 111 let mut y = ['a', 'b']; 112 113 unsafe { 114 let ptr = Pointer::new(&mut y[0] as *mut char); 115 assert_eq!(*ptr.clone().cast::<[char; 1]>().get(), ['a']); 116 assert_eq!(*ptr.offset(1).get(), 'b'); 117 } 118 } 119 120 #[test] 121 fn test_empty() { 122 assert_eq!(Pointer::<u8>::empty().get() as usize, 1); 123 } 124 } 125