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