]> git.lizzy.rs Git - rust.git/blob - src/libcore/ptr.rs
Doc says to avoid mixing allocator instead of forbiding it
[rust.git] / src / libcore / ptr.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory
12
13 //! Operations on unsafe pointers, `*const T`, and `*mut T`.
14 //!
15 //! Working with unsafe pointers in Rust is uncommon,
16 //! typically limited to a few patterns.
17 //!
18 //! Use the [`null` function](fn.null.html) to create null pointers,
19 //! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
20 //! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
21 //! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
22 //! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
23 //! work everywhere. The `RawPtr` also defines the `offset` method,
24 //! for pointer math.
25 //!
26 //! # Common ways to create unsafe pointers
27 //!
28 //! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
29 //!
30 //! ```
31 //! let my_num: int = 10;
32 //! let my_num_ptr: *const int = &my_num;
33 //! let mut my_speed: int = 88;
34 //! let my_speed_ptr: *mut int = &mut my_speed;
35 //! ```
36 //!
37 //! This does not take ownership of the original allocation
38 //! and requires no resource management later,
39 //! but you must not use the pointer after its lifetime.
40 //!
41 //! ## 2. Transmute an owned box (`Box<T>`).
42 //!
43 //! The `transmute` function takes, by value, whatever it's given
44 //! and returns it as whatever type is requested, as long as the
45 //! types are the same size. Because `Box<T>` and `*mut T` have the same
46 //! representation they can be trivially,
47 //! though unsafely, transformed from one type to the other.
48 //!
49 //! ```
50 //! use std::mem;
51 //!
52 //! unsafe {
53 //!     let my_num: Box<int> = box 10;
54 //!     let my_num: *const int = mem::transmute(my_num);
55 //!     let my_speed: Box<int> = box 88;
56 //!     let my_speed: *mut int = mem::transmute(my_speed);
57 //!
58 //!     // By taking ownership of the original `Box<T>` though
59 //!     // we are obligated to transmute it back later to be destroyed.
60 //!     drop(mem::transmute::<_, Box<int>>(my_speed));
61 //!     drop(mem::transmute::<_, Box<int>>(my_num));
62 //! }
63 //! ```
64 //!
65 //! Note that here the call to `drop` is for clarity - it indicates
66 //! that we are done with the given value and it should be destroyed.
67 //!
68 //! ## 3. Get it from C.
69 //!
70 //! ```
71 //! extern crate libc;
72 //!
73 //! use std::mem;
74 //!
75 //! fn main() {
76 //!     unsafe {
77 //!         let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
78 //!         if my_num.is_null() {
79 //!             fail!("failed to allocate memory");
80 //!         }
81 //!         libc::free(my_num as *mut libc::c_void);
82 //!     }
83 //! }
84 //! ```
85 //!
86 //! Usually you wouldn't literally use `malloc` and `free` from Rust,
87 //! but C APIs hand out a lot of pointers generally, so are a common source
88 //! of unsafe pointers in Rust.
89
90 use mem;
91 use clone::Clone;
92 use intrinsics;
93 use iter::range;
94 use option::{Some, None, Option};
95
96 use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
97
98 pub use intrinsics::copy_memory;
99 pub use intrinsics::copy_nonoverlapping_memory;
100 pub use intrinsics::set_memory;
101
102 /// Create a null pointer.
103 ///
104 /// # Example
105 ///
106 /// ```
107 /// use std::ptr;
108 ///
109 /// let p: *const int = ptr::null();
110 /// assert!(p.is_null());
111 /// ```
112 #[inline]
113 #[unstable = "may need a different name after pending changes to pointer types"]
114 pub fn null<T>() -> *const T { 0 as *const T }
115
116 /// Create an unsafe mutable null pointer.
117 ///
118 /// # Example
119 ///
120 /// ```
121 /// use std::ptr;
122 ///
123 /// let p: *mut int = ptr::mut_null();
124 /// assert!(p.is_null());
125 /// ```
126 #[inline]
127 #[unstable = "may need a different name after pending changes to pointer types"]
128 pub fn mut_null<T>() -> *mut T { 0 as *mut T }
129
130 /// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
131 #[inline]
132 #[experimental = "uncertain about naming and semantics"]
133 #[allow(experimental)]
134 pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
135     set_memory(dst, 0, count);
136 }
137
138 /// Swap the values at two mutable locations of the same type, without
139 /// deinitialising either. They may overlap.
140 #[inline]
141 #[unstable]
142 pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
143     // Give ourselves some scratch space to work with
144     let mut tmp: T = mem::uninitialized();
145     let t: *mut T = &mut tmp;
146
147     // Perform the swap
148     copy_nonoverlapping_memory(t, &*x, 1);
149     copy_memory(x, &*y, 1); // `x` and `y` may overlap
150     copy_nonoverlapping_memory(y, &*t, 1);
151
152     // y and t now point to the same thing, but we need to completely forget `tmp`
153     // because it's no longer relevant.
154     mem::forget(tmp);
155 }
156
157 /// Replace the value at a mutable location with a new one, returning the old
158 /// value, without deinitialising either.
159 #[inline]
160 #[unstable]
161 pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
162     mem::swap(mem::transmute(dest), &mut src); // cannot overlap
163     src
164 }
165
166 /// Reads the value from `*src` and returns it.
167 #[inline(always)]
168 #[unstable]
169 pub unsafe fn read<T>(src: *const T) -> T {
170     let mut tmp: T = mem::uninitialized();
171     copy_nonoverlapping_memory(&mut tmp, src, 1);
172     tmp
173 }
174
175 /// Reads the value from `*src` and nulls it out.
176 /// This currently prevents destructors from executing.
177 #[inline(always)]
178 #[experimental]
179 #[allow(experimental)]
180 pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
181     // Copy the data out from `dest`:
182     let tmp = read(&*dest);
183
184     // Now zero out `dest`:
185     zero_memory(dest, 1);
186
187     tmp
188 }
189
190 /// Unsafely overwrite a memory location with the given value without destroying
191 /// the old value.
192 ///
193 /// This operation is unsafe because it does not destroy the previous value
194 /// contained at the location `dst`. This could leak allocations or resources,
195 /// so care must be taken to previously deallocate the value at `dst`.
196 #[inline]
197 #[unstable]
198 pub unsafe fn write<T>(dst: *mut T, src: T) {
199     intrinsics::move_val_init(&mut *dst, src)
200 }
201
202 /// Given a *const *const T (pointer to an array of pointers),
203 /// iterate through each *const T, up to the provided `len`,
204 /// passing to the provided callback function
205 #[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
206 pub unsafe fn array_each_with_len<T>(arr: *const *const T, len: uint,
207                                      cb: |*const T|) {
208     if arr.is_null() {
209         fail!("ptr::array_each_with_len failure: arr input is null pointer");
210     }
211     //let start_ptr = *arr;
212     for e in range(0, len) {
213         let n = arr.offset(e as int);
214         cb(*n);
215     }
216 }
217
218 /// Given a null-pointer-terminated *const *const T (pointer to
219 /// an array of pointers), iterate through each *const T,
220 /// passing to the provided callback function
221 ///
222 /// # Safety Note
223 ///
224 /// This will only work with a null-terminated
225 /// pointer array.
226 #[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
227 #[allow(deprecated)]
228 pub unsafe fn array_each<T>(arr: *const  *const T, cb: |*const T|) {
229     if arr.is_null()  {
230         fail!("ptr::array_each_with_len failure: arr input is null pointer");
231     }
232     let len = buf_len(arr);
233     array_each_with_len(arr, len, cb);
234 }
235
236 /// Return the offset of the first null pointer in `buf`.
237 #[inline]
238 #[deprecated = "use a loop and RawPtr::offset"]
239 #[allow(deprecated)]
240 pub unsafe fn buf_len<T>(buf: *const *const T) -> uint {
241     position(buf, |i| *i == null())
242 }
243
244 /// Return the first offset `i` such that `f(buf[i]) == true`.
245 #[inline]
246 #[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
247 pub unsafe fn position<T>(buf: *const T, f: |&T| -> bool) -> uint {
248     let mut i = 0;
249     loop {
250         if f(&(*buf.offset(i as int))) { return i; }
251         else { i += 1; }
252     }
253 }
254
255 /// Methods on raw pointers
256 pub trait RawPtr<T> {
257     /// Returns the null pointer.
258     fn null() -> Self;
259
260     /// Returns true if the pointer is equal to the null pointer.
261     fn is_null(&self) -> bool;
262
263     /// Returns true if the pointer is not equal to the null pointer.
264     fn is_not_null(&self) -> bool { !self.is_null() }
265
266     /// Returns the value of this pointer (ie, the address it points to)
267     fn to_uint(&self) -> uint;
268
269     /// Returns `None` if the pointer is null, or else returns a reference to the
270     /// value wrapped in `Some`.
271     ///
272     /// # Safety Notes
273     ///
274     /// While this method and its mutable counterpart are useful for null-safety,
275     /// it is important to note that this is still an unsafe operation because
276     /// the returned value could be pointing to invalid memory.
277     unsafe fn as_ref<'a>(&self) -> Option<&'a T>;
278
279     /// A synonym for `as_ref`, except with incorrect lifetime semantics
280     #[deprecated="Use `as_ref` instead"]
281     unsafe fn to_option<'a>(&'a self) -> Option<&'a T> {
282         mem::transmute(self.as_ref())
283     }
284
285     /// Calculates the offset from a pointer. The offset *must* be in-bounds of
286     /// the object, or one-byte-past-the-end.  `count` is in units of T; e.g. a
287     /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
288     unsafe fn offset(self, count: int) -> Self;
289 }
290
291 /// Methods on mutable raw pointers
292 pub trait RawMutPtr<T>{
293     /// Returns `None` if the pointer is null, or else returns a mutable reference
294     /// to the value wrapped in `Some`. As with `as_ref`, this is unsafe because
295     /// it cannot verify the validity of the returned pointer.
296     unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>;
297 }
298
299 impl<T> RawPtr<T> for *const T {
300     #[inline]
301     fn null() -> *const T { null() }
302
303     #[inline]
304     fn is_null(&self) -> bool { *self == RawPtr::null() }
305
306     #[inline]
307     fn to_uint(&self) -> uint { *self as uint }
308
309     #[inline]
310     unsafe fn offset(self, count: int) -> *const T {
311         intrinsics::offset(self, count)
312     }
313
314     #[inline]
315     unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
316         if self.is_null() {
317             None
318         } else {
319             Some(&**self)
320         }
321     }
322 }
323
324 impl<T> RawPtr<T> for *mut T {
325     #[inline]
326     fn null() -> *mut T { mut_null() }
327
328     #[inline]
329     fn is_null(&self) -> bool { *self == RawPtr::null() }
330
331     #[inline]
332     fn to_uint(&self) -> uint { *self as uint }
333
334     #[inline]
335     unsafe fn offset(self, count: int) -> *mut T {
336         intrinsics::offset(self as *const T, count) as *mut T
337     }
338
339     #[inline]
340     unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
341         if self.is_null() {
342             None
343         } else {
344             Some(&**self)
345         }
346     }
347 }
348
349 impl<T> RawMutPtr<T> for *mut T {
350     #[inline]
351     unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
352         if self.is_null() {
353             None
354         } else {
355             Some(&mut **self)
356         }
357     }
358 }
359
360 // Equality for pointers
361 impl<T> PartialEq for *const T {
362     #[inline]
363     fn eq(&self, other: &*const T) -> bool {
364         *self == *other
365     }
366     #[inline]
367     fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
368 }
369
370 impl<T> Eq for *const T {}
371
372 impl<T> PartialEq for *mut T {
373     #[inline]
374     fn eq(&self, other: &*mut T) -> bool {
375         *self == *other
376     }
377     #[inline]
378     fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
379 }
380
381 impl<T> Eq for *mut T {}
382
383 // Equivalence for pointers
384 impl<T> Equiv<*mut T> for *const T {
385     fn equiv(&self, other: &*mut T) -> bool {
386         self.to_uint() == other.to_uint()
387     }
388 }
389
390 impl<T> Equiv<*const T> for *mut T {
391     fn equiv(&self, other: &*const T) -> bool {
392         self.to_uint() == other.to_uint()
393     }
394 }
395
396 impl<T> Clone for *const T {
397     #[inline]
398     fn clone(&self) -> *const T {
399         *self
400     }
401 }
402
403 impl<T> Clone for *mut T {
404     #[inline]
405     fn clone(&self) -> *mut T {
406         *self
407     }
408 }
409
410 // Equality for extern "C" fn pointers
411 mod externfnpointers {
412     use mem;
413     use cmp::PartialEq;
414
415     impl<_R> PartialEq for extern "C" fn() -> _R {
416         #[inline]
417         fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
418             let self_: *const () = unsafe { mem::transmute(*self) };
419             let other_: *const () = unsafe { mem::transmute(*other) };
420             self_ == other_
421         }
422     }
423     macro_rules! fnptreq(
424         ($($p:ident),*) => {
425             impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R {
426                 #[inline]
427                 fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
428                     let self_: *const () = unsafe { mem::transmute(*self) };
429
430                     let other_: *const () = unsafe { mem::transmute(*other) };
431                     self_ == other_
432                 }
433             }
434         }
435     )
436     fnptreq!(A)
437     fnptreq!(A,B)
438     fnptreq!(A,B,C)
439     fnptreq!(A,B,C,D)
440     fnptreq!(A,B,C,D,E)
441 }
442
443 // Comparison for pointers
444 impl<T> PartialOrd for *const T {
445     #[inline]
446     fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
447         if self < other {
448             Some(Less)
449         } else if self == other {
450             Some(Equal)
451         } else {
452             Some(Greater)
453         }
454     }
455
456     #[inline]
457     fn lt(&self, other: &*const T) -> bool { *self < *other }
458
459     #[inline]
460     fn le(&self, other: &*const T) -> bool { *self <= *other }
461
462     #[inline]
463     fn gt(&self, other: &*const T) -> bool { *self > *other }
464
465     #[inline]
466     fn ge(&self, other: &*const T) -> bool { *self >= *other }
467 }
468
469 impl<T> PartialOrd for *mut T {
470     #[inline]
471     fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
472         if self < other {
473             Some(Less)
474         } else if self == other {
475             Some(Equal)
476         } else {
477             Some(Greater)
478         }
479     }
480
481     #[inline]
482     fn lt(&self, other: &*mut T) -> bool { *self < *other }
483
484     #[inline]
485     fn le(&self, other: &*mut T) -> bool { *self <= *other }
486
487     #[inline]
488     fn gt(&self, other: &*mut T) -> bool { *self > *other }
489
490     #[inline]
491     fn ge(&self, other: &*mut T) -> bool { *self >= *other }
492 }