(index<- ) ./libstd/ptr.rs
git branch: * master c7553ea auto merge of #13609 : richo/rust/str-type-vim, r=alexcrichton
modified: Sat Apr 19 11:22:39 2014
1 // Copyright 2012-2013 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 //! 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.
92
93 use cast;
94 use clone::Clone;
95 #[cfg(not(test))]
96 use cmp::Equiv;
97 use iter::{range, Iterator};
98 use mem;
99 use option::{Option, Some, None};
100 use intrinsics;
101
102 #[cfg(not(test))] use cmp::{Eq, TotalEq, Ord};
103
104 /// Return the offset of the first null pointer in `buf`.
105 #[inline]
106 pub unsafe fn buf_len<T>(buf: **T) -> uint {
107 position(buf, |i| *i == null())
108 }
109
110 impl<T> Clone for *T {
111 #[inline]
112 fn clone(&self) -> *T {
113 *self
114 }
115 }
116
117 impl<T> Clone for *mut T {
118 #[inline]
119 fn clone(&self) -> *mut T {
120 *self
121 }
122 }
123
124 /// Return the first offset `i` such that `f(buf[i]) == true`.
125 #[inline]
126 pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
127 let mut i = 0;
128 loop {
129 if f(&(*buf.offset(i as int))) { return i; }
130 else { i += 1; }
131 }
132 }
133
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 /// ```
144 #[inline]
145 pub fn null<T>() -> *T { 0 as *T }
146
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 /// ```
157 #[inline]
158 pub fn mut_null<T>() -> *mut T { 0 as *mut T }
159
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 ///
174 /// unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> Vec<T> {
175 /// let mut dst = Vec::with_capacity(elts);
176 /// dst.set_len(elts);
177 /// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
178 /// dst
179 /// }
180 /// ```
181 ///
182 #[inline]
183 pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
184 intrinsics::copy_memory(dst, src, count)
185 }
186
187 /// Copies data from one location to another.
188 ///
189 /// Copies `count` elements (not bytes) from `src` to `dst`. The source
190 /// and destination may *not* overlap.
191 ///
192 /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
193 ///
194 /// # Example
195 ///
196 /// A safe swap function:
197 ///
198 /// ```
199 /// use std::cast;
200 /// use std::mem;
201 /// use std::ptr;
202 ///
203 /// fn swap<T>(x: &mut T, y: &mut T) {
204 /// unsafe {
205 /// // Give ourselves some scratch space to work with
206 /// let mut t: T = mem::uninit();
207 ///
208 /// // Perform the swap, `&mut` pointers never alias
209 /// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
210 /// ptr::copy_nonoverlapping_memory(x, &*y, 1);
211 /// ptr::copy_nonoverlapping_memory(y, &t, 1);
212 ///
213 /// // y and t now point to the same thing, but we need to completely forget `tmp`
214 /// // because it's no longer relevant.
215 /// cast::forget(t);
216 /// }
217 /// }
218 /// ```
219 ///
220 /// # Safety Note
221 ///
222 /// If the source and destination overlap then the behavior of this
223 /// function is undefined.
224 #[inline]
225 pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
226 src: *T,
227 count: uint) {
228 intrinsics::copy_nonoverlapping_memory(dst, src, count)
229 }
230
231 /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
232 /// bytes of memory starting at `dst` to `c`.
233 #[inline]
234 pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
235 intrinsics::set_memory(dst, c, count)
236 }
237
238 /// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
239 #[inline]
240 pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
241 set_memory(dst, 0, count);
242 }
243
244 /// Swap the values at two mutable locations of the same type, without
245 /// deinitialising either. They may overlap.
246 #[inline]
247 pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
248 // Give ourselves some scratch space to work with
249 let mut tmp: T = mem::uninit();
250 let t: *mut T = &mut tmp;
251
252 // Perform the swap
253 copy_nonoverlapping_memory(t, &*x, 1);
254 copy_memory(x, &*y, 1); // `x` and `y` may overlap
255 copy_nonoverlapping_memory(y, &*t, 1);
256
257 // y and t now point to the same thing, but we need to completely forget `tmp`
258 // because it's no longer relevant.
259 cast::forget(tmp);
260 }
261
262 /// Replace the value at a mutable location with a new one, returning the old
263 /// value, without deinitialising either.
264 #[inline]
265 pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
266 mem::swap(cast::transmute(dest), &mut src); // cannot overlap
267 src
268 }
269
270 /// Reads the value from `*src` and returns it.
271 #[inline(always)]
272 pub unsafe fn read<T>(src: *T) -> T {
273 let mut tmp: T = mem::uninit();
274 copy_nonoverlapping_memory(&mut tmp, src, 1);
275 tmp
276 }
277
278 /// Reads the value from `*src` and nulls it out.
279 /// This currently prevents destructors from executing.
280 #[inline(always)]
281 pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
282 // Copy the data out from `dest`:
283 let tmp = read(&*dest);
284
285 // Now zero out `dest`:
286 zero_memory(dest, 1);
287
288 tmp
289 }
290
291 /// Given a **T (pointer to an array of pointers),
292 /// iterate through each *T, up to the provided `len`,
293 /// passing to the provided callback function
294 pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
295 if arr.is_null() {
296 fail!("ptr::array_each_with_len failure: arr input is null pointer");
297 }
298 //let start_ptr = *arr;
299 for e in range(0, len) {
300 let n = arr.offset(e as int);
301 cb(*n);
302 }
303 }
304
305 /// Given a null-pointer-terminated **T (pointer to
306 /// an array of pointers), iterate through each *T,
307 /// passing to the provided callback function
308 ///
309 /// # Safety Note
310 ///
311 /// This will only work with a null-terminated
312 /// pointer array.
313 pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
314 if arr.is_null() {
315 fail!("ptr::array_each_with_len failure: arr input is null pointer");
316 }
317 let len = buf_len(arr);
318 array_each_with_len(arr, len, cb);
319 }
320
321 /// Extension methods for raw pointers.
322 pub trait RawPtr<T> {
323 /// Returns the null pointer.
324 fn null() -> Self;
325 /// Returns true if the pointer is equal to the null pointer.
326 fn is_null(&self) -> bool;
327 /// Returns true if the pointer is not equal to the null pointer.
328 fn is_not_null(&self) -> bool { !self.is_null() }
329 /// Returns the value of this pointer (ie, the address it points to)
330 fn to_uint(&self) -> uint;
331 /// Returns `None` if the pointer is null, or else returns the value wrapped
332 /// in `Some`.
333 ///
334 /// # Safety Notes
335 ///
336 /// While this method is useful for null-safety, it is important to note
337 /// that this is still an unsafe operation because the returned value could
338 /// be pointing to invalid memory.
339 unsafe fn to_option(&self) -> Option<&T>;
340 /// Calculates the offset from a pointer. The offset *must* be in-bounds of
341 /// the object, or one-byte-past-the-end. `count` is in units of T; e.g. a
342 /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
343 unsafe fn offset(self, count: int) -> Self;
344 }
345
346 impl<T> RawPtr<T> for *T {
347 #[inline]
348 fn null() -> *T { null() }
349
350 #[inline]
351 fn is_null(&self) -> bool { *self == RawPtr::null() }
352
353 #[inline]
354 fn to_uint(&self) -> uint { *self as uint }
355
356 #[inline]
357 unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) }
358
359 #[inline]
360 unsafe fn to_option(&self) -> Option<&T> {
361 if self.is_null() {
362 None
363 } else {
364 Some(cast::transmute(*self))
365 }
366 }
367 }
368
369 impl<T> RawPtr<T> for *mut T {
370 #[inline]
371 fn null() -> *mut T { mut_null() }
372
373 #[inline]
374 fn is_null(&self) -> bool { *self == RawPtr::null() }
375
376 #[inline]
377 fn to_uint(&self) -> uint { *self as uint }
378
379 #[inline]
380 unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *T, count) as *mut T }
381
382 #[inline]
383 unsafe fn to_option(&self) -> Option<&T> {
384 if self.is_null() {
385 None
386 } else {
387 Some(cast::transmute(*self))
388 }
389 }
390 }
391
392 // Equality for pointers
393 #[cfg(not(test))]
394 impl<T> Eq for *T {
395 #[inline]
396 fn eq(&self, other: &*T) -> bool {
397 *self == *other
398 }
399 #[inline]
400 fn ne(&self, other: &*T) -> bool { !self.eq(other) }
401 }
402
403 #[cfg(not(test))]
404 impl<T> TotalEq for *T {}
405
406 #[cfg(not(test))]
407 impl<T> Eq for *mut T {
408 #[inline]
409 fn eq(&self, other: &*mut T) -> bool {
410 *self == *other
411 }
412 #[inline]
413 fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
414 }
415
416 #[cfg(not(test))]
417 impl<T> TotalEq for *mut T {}
418
419 // Equivalence for pointers
420 #[cfg(not(test))]
421 impl<T> Equiv<*mut T> for *T {
422 fn equiv(&self, other: &*mut T) -> bool {
423 self.to_uint() == other.to_uint()
424 }
425 }
426
427 #[cfg(not(test))]
428 impl<T> Equiv<*T> for *mut T {
429 fn equiv(&self, other: &*T) -> bool {
430 self.to_uint() == other.to_uint()
431 }
432 }
433
434 // Equality for extern "C" fn pointers
435 #[cfg(not(test))]
436 mod externfnpointers {
437 use cast;
438 use cmp::Eq;
439
440 impl<_R> Eq for extern "C" fn() -> _R {
441 #[inline]
442 fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
443 let self_: *() = unsafe { cast::transmute(*self) };
444 let other_: *() = unsafe { cast::transmute(*other) };
445 self_ == other_
446 }
447 #[inline]
448 fn ne(&self, other: &extern "C" fn() -> _R) -> bool {
449 !self.eq(other)
450 }
451 }
452 macro_rules! fnptreq(
453 ($($p:ident),*) => {
454 impl<_R,$($p),*> Eq for extern "C" fn($($p),*) -> _R {
455 #[inline]
456 fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
457 let self_: *() = unsafe { cast::transmute(*self) };
458 let other_: *() = unsafe { cast::transmute(*other) };
459 self_ == other_
460 }
461 #[inline]
462 fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
463 !self.eq(other)
464 }
465 }
466 }
467 )
468 fnptreq!(A)
469 fnptreq!(A,B)
470 fnptreq!(A,B,C)
471 fnptreq!(A,B,C,D)
472 fnptreq!(A,B,C,D,E)
473 }
474
475 // Comparison for pointers
476 #[cfg(not(test))]
477 impl<T> Ord for *T {
478 #[inline]
479 fn lt(&self, other: &*T) -> bool {
480 *self < *other
481 }
482 #[inline]
483 fn le(&self, other: &*T) -> bool {
484 *self <= *other
485 }
486 #[inline]
487 fn ge(&self, other: &*T) -> bool {
488 *self >= *other
489 }
490 #[inline]
491 fn gt(&self, other: &*T) -> bool {
492 *self > *other
493 }
494 }
495
496 #[cfg(not(test))]
497 impl<T> Ord for *mut T {
498 #[inline]
499 fn lt(&self, other: &*mut T) -> bool {
500 *self < *other
501 }
502 #[inline]
503 fn le(&self, other: &*mut T) -> bool {
504 *self <= *other
505 }
506 #[inline]
507 fn ge(&self, other: &*mut T) -> bool {
508 *self >= *other
509 }
510 #[inline]
511 fn gt(&self, other: &*mut T) -> bool {
512 *self > *other
513 }
514 }
515
516 #[cfg(test)]
517 pub mod ptr_tests {
518 use super::*;
519 use prelude::*;
520
521 use c_str::ToCStr;
522 use cast;
523 use libc;
524 use str;
525 use slice::{ImmutableVector, MutableVector};
526
527 #[test]
528 fn test() {
529 unsafe {
530 struct Pair {
531 fst: int,
532 snd: int
533 };
534 let mut p = Pair {fst: 10, snd: 20};
535 let pptr: *mut Pair = &mut p;
536 let iptr: *mut int = cast::transmute(pptr);
537 assert_eq!(*iptr, 10);
538 *iptr = 30;
539 assert_eq!(*iptr, 30);
540 assert_eq!(p.fst, 30);
541
542 *pptr = Pair {fst: 50, snd: 60};
543 assert_eq!(*iptr, 50);
544 assert_eq!(p.fst, 50);
545 assert_eq!(p.snd, 60);
546
547 let v0 = ~[32000u16, 32001u16, 32002u16];
548 let mut v1 = ~[0u16, 0u16, 0u16];
549
550 copy_memory(v1.as_mut_ptr().offset(1),
551 v0.as_ptr().offset(1), 1);
552 assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
553 copy_memory(v1.as_mut_ptr(),
554 v0.as_ptr().offset(2), 1);
555 assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
556 v1[2] == 0u16));
557 copy_memory(v1.as_mut_ptr().offset(2),
558 v0.as_ptr(), 1u);
559 assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
560 v1[2] == 32000u16));
561 }
562 }
563
564 #[test]
565 fn test_position() {
566 use libc::c_char;
567
568 "hello".with_c_str(|p| {
569 unsafe {
570 assert!(2u == position(p, |c| *c == 'l' as c_char));
571 assert!(4u == position(p, |c| *c == 'o' as c_char));
572 assert!(5u == position(p, |c| *c == 0 as c_char));
573 }
574 })
575 }
576
577 #[test]
578 fn test_buf_len() {
579 "hello".with_c_str(|p0| {
580 "there".with_c_str(|p1| {
581 "thing".with_c_str(|p2| {
582 let v = ~[p0, p1, p2, null()];
583 unsafe {
584 assert_eq!(buf_len(v.as_ptr()), 3u);
585 }
586 })
587 })
588 })
589 }
590
591 #[test]
592 fn test_is_null() {
593 let p: *int = null();
594 assert!(p.is_null());
595 assert!(!p.is_not_null());
596
597 let q = unsafe { p.offset(1) };
598 assert!(!q.is_null());
599 assert!(q.is_not_null());
600
601 let mp: *mut int = mut_null();
602 assert!(mp.is_null());
603 assert!(!mp.is_not_null());
604
605 let mq = unsafe { mp.offset(1) };
606 assert!(!mq.is_null());
607 assert!(mq.is_not_null());
608 }
609
610 #[test]
611 fn test_to_option() {
612 unsafe {
613 let p: *int = null();
614 assert_eq!(p.to_option(), None);
615
616 let q: *int = &2;
617 assert_eq!(q.to_option().unwrap(), &2);
618
619 let p: *mut int = mut_null();
620 assert_eq!(p.to_option(), None);
621
622 let q: *mut int = &mut 2;
623 assert_eq!(q.to_option().unwrap(), &2);
624 }
625 }
626
627 #[test]
628 fn test_ptr_addition() {
629 unsafe {
630 let xs = ~[5, ..16];
631 let mut ptr = xs.as_ptr();
632 let end = ptr.offset(16);
633
634 while ptr < end {
635 assert_eq!(*ptr, 5);
636 ptr = ptr.offset(1);
637 }
638
639 let mut xs_mut = xs.clone();
640 let mut m_ptr = xs_mut.as_mut_ptr();
641 let m_end = m_ptr.offset(16);
642
643 while m_ptr < m_end {
644 *m_ptr += 5;
645 m_ptr = m_ptr.offset(1);
646 }
647
648 assert_eq!(xs_mut, ~[10, ..16]);
649 }
650 }
651
652 #[test]
653 fn test_ptr_subtraction() {
654 unsafe {
655 let xs = ~[0,1,2,3,4,5,6,7,8,9];
656 let mut idx = 9i8;
657 let ptr = xs.as_ptr();
658
659 while idx >= 0i8 {
660 assert_eq!(*(ptr.offset(idx as int)), idx as int);
661 idx = idx - 1i8;
662 }
663
664 let mut xs_mut = xs.clone();
665 let m_start = xs_mut.as_mut_ptr();
666 let mut m_ptr = m_start.offset(9);
667
668 while m_ptr >= m_start {
669 *m_ptr += *m_ptr;
670 m_ptr = m_ptr.offset(-1);
671 }
672
673 assert_eq!(xs_mut, ~[0,2,4,6,8,10,12,14,16,18]);
674 }
675 }
676
677 #[test]
678 fn test_ptr_array_each_with_len() {
679 unsafe {
680 let one = "oneOne".to_c_str();
681 let two = "twoTwo".to_c_str();
682 let three = "threeThree".to_c_str();
683 let arr = ~[
684 one.with_ref(|buf| buf),
685 two.with_ref(|buf| buf),
686 three.with_ref(|buf| buf),
687 ];
688 let expected_arr = [
689 one, two, three
690 ];
691
692 let mut ctr = 0;
693 let mut iteration_count = 0;
694 array_each_with_len(arr.as_ptr(), arr.len(), |e| {
695 let actual = str::raw::from_c_str(e);
696 let expected = expected_arr[ctr].with_ref(|buf| {
697 str::raw::from_c_str(buf)
698 });
699 debug!(
700 "test_ptr_array_each_with_len e: {}, a: {}",
701 expected, actual);
702 assert_eq!(actual, expected);
703 ctr += 1;
704 iteration_count += 1;
705 });
706 assert_eq!(iteration_count, 3u);
707 }
708 }
709
710 #[test]
711 fn test_ptr_array_each() {
712 unsafe {
713 let one = "oneOne".to_c_str();
714 let two = "twoTwo".to_c_str();
715 let three = "threeThree".to_c_str();
716 let arr = ~[
717 one.with_ref(|buf| buf),
718 two.with_ref(|buf| buf),
719 three.with_ref(|buf| buf),
720 // fake a null terminator
721 null(),
722 ];
723 let expected_arr = [
724 one, two, three
725 ];
726
727 let arr_ptr = arr.as_ptr();
728 let mut ctr = 0;
729 let mut iteration_count = 0;
730 array_each(arr_ptr, |e| {
731 let actual = str::raw::from_c_str(e);
732 let expected = expected_arr[ctr].with_ref(|buf| {
733 str::raw::from_c_str(buf)
734 });
735 debug!(
736 "test_ptr_array_each e: {}, a: {}",
737 expected, actual);
738 assert_eq!(actual, expected);
739 ctr += 1;
740 iteration_count += 1;
741 });
742 assert_eq!(iteration_count, 3);
743 }
744 }
745
746 #[test]
747 #[should_fail]
748 fn test_ptr_array_each_with_len_null_ptr() {
749 unsafe {
750 array_each_with_len(0 as **libc::c_char, 1, |e| {
751 str::raw::from_c_str(e);
752 });
753 }
754 }
755 #[test]
756 #[should_fail]
757 fn test_ptr_array_each_null_ptr() {
758 unsafe {
759 array_each(0 as **libc::c_char, |e| {
760 str::raw::from_c_str(e);
761 });
762 }
763 }
764
765 #[test]
766 fn test_set_memory() {
767 let mut xs = [0u8, ..20];
768 let ptr = xs.as_mut_ptr();
769 unsafe { set_memory(ptr, 5u8, xs.len()); }
770 assert!(xs == [5u8, ..20]);
771 }
772 }
libstd/ptr.rs:224:10-224:10 -fn- definition:
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
src: *T,
count: uint) {
references:- 18273: let mut tmp: T = mem::uninit();
274: copy_nonoverlapping_memory(&mut tmp, src, 1);
275: tmp
libstd/sync/deque.rs:
373: let ptr = self.storage.offset(i & self.mask());
374: ptr::copy_nonoverlapping_memory(ptr as *mut T, &t as *T, 1);
375: cast::forget(t);
libstd/io/extensions.rs:
167: let out = buf.as_mut_ptr();
168: copy_nonoverlapping_memory(out.offset((8 - size) as int), ptr, size);
169: from_be64(*(out as *u64))
libstd/cast.rs:
22: let src_ptr: *u8 = transmute(src);
23: copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::<U>());
24: dest
libstd/mem.rs:
236: // Perform the swap, `&mut` pointers never alias
237: ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
238: ptr::copy_nonoverlapping_memory(x, &*y, 1);
239: ptr::copy_nonoverlapping_memory(y, &t, 1);
libstd/slice.rs:
1787: assert!(self.len() >= len_src);
1788: ptr::copy_nonoverlapping_memory(self.as_mut_ptr(), src.as_ptr(), len_src)
1789: }
--
2305: (*ret).alloc = len * mem::nonzero_size_of::<A>();
2306: ptr::copy_nonoverlapping_memory(&mut (*ret).data as *mut _ as *mut u8,
2307: data as *u8,
libstd/c_str.rs:
105: let buf = unsafe { malloc_raw(len) } as *mut libc::c_char;
106: unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); }
107: CString { buf: buf as *libc::c_char, owns_buffer_: true }
libstd/ptr.rs:182:10-182:10 -fn- definition:
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
intrinsics::copy_memory(dst, src, count)
}
references:- 9253: copy_nonoverlapping_memory(t, &*x, 1);
254: copy_memory(x, &*y, 1); // `x` and `y` may overlap
255: copy_nonoverlapping_memory(y, &*t, 1);
libstd/c_str.rs:
332: ptr::copy_memory(buf, self.as_ptr(), self_len);
333: *buf.offset(self_len as int) = 0;
libstd/slice.rs:
1915: dst.set_len(elts);
1916: ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
1917: dst.move_iter().collect()
libstd/vec.rs:
955: // Shift everything down to fill in that spot.
956: ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
957: }
libstd/str.rs:
2540: ptr::copy_memory(v.as_mut_ptr(), self.as_ptr(), len);
2541: v.set_len(len);
libstd/slice.rs:
1224: let tmp = ptr::read(read_ptr);
1225: ptr::copy_memory(buf_v.offset(j + 1),
1226: &*buf_v.offset(j),
libstd/ptr.rs:321:40-321:40 -trait- definition:
/// Extension methods for raw pointers.
pub trait RawPtr<T> {
/// Returns the null pointer.
references:- 4369: impl<T> RawPtr<T> for *mut T {
370: #[inline]
libstd/ptr.rs:157:10-157:10 -fn- definition:
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
/// Copies data from one location to another.
///
references:- 11370: #[inline]
371: fn null() -> *mut T { mut_null() }
libstd/c_vec.rs:
72: pub unsafe fn new(base: *mut T, len: uint) -> CVec<T> {
73: assert!(base != ptr::mut_null());
74: CVec {
--
93: dtor: proc():Send) -> CVec<T> {
94: assert!(base != ptr::mut_null());
95: CVec {
libstd/cleanup.rs:
31: let mut alloc = local_heap::live_allocs();
32: while alloc != ptr::mut_null() {
33: let next_before = (*alloc).next;
libstd/rt/global_heap.rs:
37: if size == 0 {
38: mut_null()
39: } else {
--
55: free(ptr as *mut c_void);
56: mut_null()
57: } else {
libstd/rt/local_heap.rs:
54: memory_region: region,
55: live_allocs: ptr::mut_null(),
56: }
libstd/rt/local_ptr.rs:
298: let ptr: ~T = cast::transmute(void_ptr);
299: tls::set(key, ptr::mut_null());
300: Some(ptr)
libstd/rt/backtrace.rs:
442: STATE = backtrace_create_state(filename, 0, error_cb,
443: ptr::mut_null());
444: return STATE
libstd/rt/local_heap.rs:
69: mybox.ref_count = 1;
70: mybox.prev = ptr::mut_null();
71: mybox.next = self.live_allocs;
libstd/ptr.rs:271:18-271:18 -fn- definition:
pub unsafe fn read<T>(src: *T) -> T {
let mut tmp: T = mem::uninit();
copy_nonoverlapping_memory(&mut tmp, src, 1);
references:- 12282: // Copy the data out from `dest`:
283: let tmp = read(&*dest);
libstd/rc.rs:
99: if self.strong() == 0 {
100: ptr::read(self.deref()); // destroy the contained object
libstd/sync/deque.rs:
366: unsafe fn get(&self, i: int) -> T {
367: ptr::read(self.storage.offset(i & self.mask()))
368: }
libstd/slice.rs:
2260: unsafe {
2261: self.iter.next_back().map(|x| ptr::read(x))
2262: }
libstd/vec.rs:
1378: for x in self.as_mut_slice().iter() {
1379: ptr::read(x);
1380: }
--
1407: unsafe {
1408: self.iter.next().map(|x| ptr::read(x))
1409: }
--
1421: unsafe {
1422: self.iter.next_back().map(|x| ptr::read(x))
1423: }
libstd/ptr.rs:233:10-233:10 -fn- definition:
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
intrinsics::set_memory(dst, c, count)
}
references:- 2240: pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
241: set_memory(dst, 0, count);
242: }
libstd/slice.rs:
1960: fn set_memory(self, value: u8) {
1961: unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
1962: }
libstd/ptr.rs:125:10-125:10 -fn- definition:
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
let mut i = 0;
loop {
references:- 2106: pub unsafe fn buf_len<T>(buf: **T) -> uint {
107: position(buf, |i| *i == null())
108: }
libstd/c_str.rs:
248: unsafe {
249: ptr::position(self.buf, |c| *c == 0)
250: }
libstd/ptr.rs:144:10-144:10 -fn- definition:
pub fn null<T>() -> *T { 0 as *T }
/// Create an unsafe mutable null pointer.
///
references:- 10106: pub unsafe fn buf_len<T>(buf: **T) -> uint {
107: position(buf, |i| *i == null())
108: }
--
347: #[inline]
348: fn null() -> *T { null() }
libstd/os.rs:
1075: }
1076: let mut addr: *u8 = ptr::null();
1077: let mut prot = 0;
--
1122: } else {
1123: MapFile(ptr::null())
1124: }
libstd/unstable/dynamic_lib.rs:
163: let last_error = dlerror();
164: let ret = if ptr::null() == last_error {
165: Ok(result)
libstd/rt/thread_local_storage.rs:
24: pub unsafe fn create(key: &mut Key) {
25: assert_eq!(0, pthread_key_create(key, null()));
26: }
libstd/rt/backtrace.rs:
439: }
440: None => ptr::null(),
441: };
libstd/rt/thread.rs:
265: pub unsafe fn join(native: rust_thread) {
266: assert_eq!(pthread_join(native, ptr::null()), 0);
267: }