8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- //! Unsafe pointer utility functions
11
+ //! Conveniences for working with unsafe pointers, the `*T`, and `*mut T` types.
12
+ //!
13
+ //! Working with unsafe pointers in Rust is fairly uncommon,
14
+ //! and often limited to some narrow use cases: holding
15
+ //! an unsafe pointer when safe pointers are unsuitable;
16
+ //! checking for null; and converting back to safe pointers.
17
+ //! As a result, there is not yet an abundance of library code
18
+ //! for working with unsafe poniters, and in particular,
19
+ //! since pointer math is fairly uncommon in Rust, it is not
20
+ //! all that convenient.
21
+ //!
22
+ //! Use the [`null` function](fn.null.html) to create null pointers,
23
+ //! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
24
+ //! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
25
+ //! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
26
+ //! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
27
+ //! work everywhere.
28
+ //!
29
+ //! # Common ways to create unsafe pointers
30
+ //!
31
+ //! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
32
+ //!
33
+ //! ```
34
+ //! let my_num: int = 10;
35
+ //! let my_num_ptr: *int = &my_num;
36
+ //! let mut my_speed: int = 88;
37
+ //! let my_speed_ptr: *mut int = &mut my_speed;
38
+ //! ```
39
+ //!
40
+ //! This does not take ownership of the original allocation
41
+ //! and requires no resource management later,
42
+ //! but you must not use the pointer after its lifetime.
43
+ //!
44
+ //! ## 2. Transmute an owned box (`~T`).
45
+ //!
46
+ //! The `transmute` function takes, by value, whatever it's given
47
+ //! and returns it as whatever type is requested, as long as the
48
+ //! types are the same size. Because `~T` and `*T` have the same
49
+ //! representation they can be trivially,
50
+ //! though unsafely, transformed from one type to the other.
51
+ //!
52
+ //! ```
53
+ //! use std::cast;
54
+ //!
55
+ //! unsafe {
56
+ //! let my_num: ~int = ~10;
57
+ //! let my_num: *int = cast::transmute(my_num);
58
+ //! let my_speed: ~int = ~88;
59
+ //! let my_speed: *mut int = cast::transmute(my_speed);
60
+ //!
61
+ //! // By taking ownership of the original `~T` though
62
+ //! // we are obligated to transmute it back later to be destroyed.
63
+ //! drop(cast::transmute::<_, ~int>(my_speed));
64
+ //! drop(cast::transmute::<_, ~int>(my_num));
65
+ //! }
66
+ //! ```
67
+ //!
68
+ //! Note that here the call to `drop` is for clarity - it indicates
69
+ //! that we are done with the given value and it should be destroyed.
70
+ //!
71
+ //! ## 3. Get it from C.
72
+ //!
73
+ //! ```
74
+ //! extern crate libc;
75
+ //!
76
+ //! use std::mem;
77
+ //!
78
+ //! fn main() {
79
+ //! unsafe {
80
+ //! let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
81
+ //! if my_num.is_null() {
82
+ //! fail!("failed to allocate memory");
83
+ //! }
84
+ //! libc::free(my_num as *mut libc::c_void);
85
+ //! }
86
+ //! }
87
+ //! ```
88
+ //!
89
+ //! Usually you wouldn't literally use `malloc` and `free` from Rust,
90
+ //! but C APIs hand out a lot of pointers generally, so are a common source
91
+ //! of unsafe pointers in Rust.
12
92
13
93
use cast;
14
94
use clone:: Clone ;
@@ -51,59 +131,119 @@ pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
51
131
}
52
132
}
53
133
54
- /// Create an unsafe null pointer
134
+ /// Create an null pointer.
135
+ ///
136
+ /// # Example
137
+ ///
138
+ /// ```
139
+ /// use std::ptr;
140
+ ///
141
+ /// let p: *int = ptr::null();
142
+ /// assert!(p.is_null());
143
+ /// ```
55
144
#[ inline]
56
145
pub fn null < T > ( ) -> * T { 0 as * T }
57
146
58
- /// Create an unsafe mutable null pointer
147
+ /// Create an unsafe mutable null pointer.
148
+ ///
149
+ /// # Example
150
+ ///
151
+ /// ```
152
+ /// use std::ptr;
153
+ ///
154
+ /// let p: *mut int = ptr::mut_null();
155
+ /// assert!(p.is_null());
156
+ /// ```
59
157
#[ inline]
60
158
pub fn mut_null < T > ( ) -> * mut T { 0 as * mut T }
61
159
62
- /**
63
- * Copies data from one location to another.
64
- *
65
- * Copies `count` elements (not bytes) from `src` to `dst`. The source
66
- * and destination may overlap.
67
- */
160
+ /// Copies data from one location to another.
161
+ ///
162
+ /// Copies `count` elements (not bytes) from `src` to `dst`. The source
163
+ /// and destination may overlap.
164
+ ///
165
+ /// `copy_memory` is semantically equivalent to C's `memmove`.
166
+ ///
167
+ /// # Example
168
+ ///
169
+ /// Efficiently create a Rust vector from an unsafe buffer:
170
+ ///
171
+ /// ```
172
+ /// use std::ptr;
173
+ /// use std::slice;
174
+ ///
175
+ /// unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
176
+ /// let mut dst = slice::with_capacity(elts);
177
+ /// dst.set_len(elts);
178
+ /// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
179
+ /// dst
180
+ /// }
181
+ /// ```
182
+ ///
68
183
#[ inline]
69
184
pub unsafe fn copy_memory < T > ( dst : * mut T , src : * T , count : uint ) {
70
185
intrinsics:: copy_memory ( dst, src, count)
71
186
}
72
187
73
- /**
74
- * Copies data from one location to another.
75
- *
76
- * Copies `count` elements (not bytes) from `src` to `dst`. The source
77
- * and destination may *not* overlap.
78
- */
188
+ /// Copies data from one location to another.
189
+ ///
190
+ /// Copies `count` elements (not bytes) from `src` to `dst`. The source
191
+ /// and destination may *not* overlap.
192
+ ///
193
+ /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
194
+ ///
195
+ /// # Example
196
+ ///
197
+ /// A safe swap function:
198
+ ///
199
+ /// ```
200
+ /// use std::cast;
201
+ /// use std::mem;
202
+ /// use std::ptr;
203
+ ///
204
+ /// fn swap<T>(x: &mut T, y: &mut T) {
205
+ /// unsafe {
206
+ /// // Give ourselves some scratch space to work with
207
+ /// let mut t: T = mem::uninit();
208
+ ///
209
+ /// // Perform the swap, `&mut` pointers never alias
210
+ /// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
211
+ /// ptr::copy_nonoverlapping_memory(x, &*y, 1);
212
+ /// ptr::copy_nonoverlapping_memory(y, &t, 1);
213
+ ///
214
+ /// // y and t now point to the same thing, but we need to completely forget `tmp`
215
+ /// // because it's no longer relevant.
216
+ /// cast::forget(t);
217
+ /// }
218
+ /// }
219
+ /// ```
220
+ ///
221
+ /// # Safety Note
222
+ ///
223
+ /// If the source and destination overlap then the behavior of this
224
+ /// function is undefined.
79
225
#[ inline]
80
226
pub unsafe fn copy_nonoverlapping_memory < T > ( dst : * mut T ,
81
227
src : * T ,
82
228
count : uint ) {
83
229
intrinsics:: copy_nonoverlapping_memory ( dst, src, count)
84
230
}
85
231
86
- /**
87
- * Invokes memset on the specified pointer, setting `count * size_of::<T>()`
88
- * bytes of memory starting at `dst` to `c`.
89
- */
232
+ /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
233
+ /// bytes of memory starting at `dst` to `c`.
90
234
#[ inline]
91
235
pub unsafe fn set_memory < T > ( dst : * mut T , c : u8 , count : uint ) {
92
236
intrinsics:: set_memory ( dst, c, count)
93
237
}
94
238
95
- /**
96
- * Zeroes out `count * size_of::<T>` bytes of memory at `dst`
97
- */
239
+ /// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
98
240
#[ inline]
99
241
pub unsafe fn zero_memory < T > ( dst : * mut T , count : uint ) {
100
242
set_memory ( dst, 0 , count) ;
101
243
}
102
244
103
- /**
104
- * Swap the values at two mutable locations of the same type, without
105
- * deinitialising either. They may overlap.
106
- */
245
+ /// Swap the values at two mutable locations of the same type, without
246
+ /// deinitialising either. They may overlap.
107
247
#[ inline]
108
248
pub unsafe fn swap < T > ( x : * mut T , y : * mut T ) {
109
249
// Give ourselves some scratch space to work with
@@ -120,30 +260,24 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
120
260
cast:: forget ( tmp) ;
121
261
}
122
262
123
- /**
124
- * Replace the value at a mutable location with a new one, returning the old
125
- * value, without deinitialising either.
126
- */
263
+ /// Replace the value at a mutable location with a new one, returning the old
264
+ /// value, without deinitialising either.
127
265
#[ inline]
128
266
pub unsafe fn replace < T > ( dest : * mut T , mut src : T ) -> T {
129
267
mem:: swap ( cast:: transmute ( dest) , & mut src) ; // cannot overlap
130
268
src
131
269
}
132
270
133
- /**
134
- * Reads the value from `*src` and returns it.
135
- */
271
+ /// Reads the value from `*src` and returns it.
136
272
#[ inline( always) ]
137
273
pub unsafe fn read < T > ( src : * T ) -> T {
138
274
let mut tmp: T = mem:: uninit ( ) ;
139
275
copy_nonoverlapping_memory ( & mut tmp, src, 1 ) ;
140
276
tmp
141
277
}
142
278
143
- /**
144
- * Reads the value from `*src` and nulls it out.
145
- * This currently prevents destructors from executing.
146
- */
279
+ /// Reads the value from `*src` and nulls it out.
280
+ /// This currently prevents destructors from executing.
147
281
#[ inline( always) ]
148
282
pub unsafe fn read_and_zero < T > ( dest : * mut T ) -> T {
149
283
// Copy the data out from `dest`:
@@ -155,13 +289,9 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
155
289
tmp
156
290
}
157
291
158
- /**
159
- Given a **T (pointer to an array of pointers),
160
- iterate through each *T, up to the provided `len`,
161
- passing to the provided callback function
162
-
163
- SAFETY NOTE: Pointer-arithmetic. Dragons be here.
164
- */
292
+ /// Given a **T (pointer to an array of pointers),
293
+ /// iterate through each *T, up to the provided `len`,
294
+ /// passing to the provided callback function
165
295
pub unsafe fn array_each_with_len < T > ( arr : * * T , len : uint , cb: |* T |) {
166
296
if arr. is_null ( ) {
167
297
fail ! ( "ptr::array_each_with_len failure: arr input is null pointer" ) ;
@@ -173,15 +303,14 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
173
303
}
174
304
}
175
305
176
- /**
177
- Given a null-pointer-terminated **T (pointer to
178
- an array of pointers), iterate through each *T,
179
- passing to the provided callback function
180
-
181
- SAFETY NOTE: This will only work with a null-terminated
182
- pointer array. Barely less-dodgy Pointer Arithmetic.
183
- Dragons be here.
184
- */
306
+ /// Given a null-pointer-terminated **T (pointer to
307
+ /// an array of pointers), iterate through each *T,
308
+ /// passing to the provided callback function
309
+ ///
310
+ /// # Safety Note
311
+ ///
312
+ /// This will only work with a null-terminated
313
+ /// pointer array.
185
314
pub unsafe fn array_each < T > ( arr : * * T , cb: |* T |) {
186
315
if arr. is_null ( ) {
187
316
fail ! ( "ptr::array_each_with_len failure: arr input is null pointer" ) ;
0 commit comments