use iter::{range, Iterator};
use mem;
use option::{Option, Some, None};
-use unstable::intrinsics;
-use util::swap;
+use intrinsics;
-#[cfg(not(test))] use cmp::{Eq, Ord};
-
-/// Calculate the offset from a pointer.
-/// The `count` argument is in units of T; e.g. a `count` of 3
-/// represents a pointer offset of `3 * sizeof::<T>()` bytes.
-#[inline]
-pub unsafe fn offset<T>(ptr: *T, count: int) -> *T {
- intrinsics::offset(ptr, count)
-}
-
-/// Calculate the offset from a mut pointer. The count *must* be in bounds or
-/// otherwise the loads of this address are undefined.
-/// The `count` argument is in units of T; e.g. a `count` of 3
-/// represents a pointer offset of `3 * sizeof::<T>()` bytes.
-#[inline]
-pub unsafe fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
- intrinsics::offset(ptr as *T, count) as *mut T
-}
+#[cfg(not(test))] use cmp::{Eq, TotalEq, Ord};
/// Return the offset of the first null pointer in `buf`.
#[inline]
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
let mut i = 0;
loop {
- if f(&(*offset(buf, i as int))) { return i; }
+ if f(&(*buf.offset(i as int))) { return i; }
else { i += 1; }
}
}
#[inline]
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
-/// Returns true if the pointer is equal to the null pointer.
-#[inline]
-pub fn is_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_null() }
-
-/// Returns true if the pointer is not equal to the null pointer.
-#[inline]
-pub fn is_not_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_not_null() }
-
/**
* Copies data from one location to another.
*
* and destination may overlap.
*/
#[inline]
-pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
- intrinsics::copy_memory(dst, cast::transmute_immut_unsafe(src), count)
+pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
+ intrinsics::copy_memory(dst, src, count)
}
/**
* and destination may *not* overlap.
*/
#[inline]
-pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
- src: P,
- count: uint) {
- intrinsics::copy_nonoverlapping_memory(dst, cast::transmute_immut_unsafe(src), count)
+pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
+ src: *T,
+ count: uint) {
+ intrinsics::copy_nonoverlapping_memory(dst, src, count)
}
/**
/**
* Swap the values at two mutable locations of the same type, without
- * deinitialising or copying either one.
+ * deinitialising either. They may overlap.
*/
#[inline]
-pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {
+pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
// Give ourselves some scratch space to work with
let mut tmp: T = mem::uninit();
let t: *mut T = &mut tmp;
// Perform the swap
- copy_nonoverlapping_memory(t, x, 1);
- copy_memory(x, y, 1); // `x` and `y` may overlap
- copy_nonoverlapping_memory(y, t, 1);
+ copy_nonoverlapping_memory(t, &*x, 1);
+ copy_memory(x, &*y, 1); // `x` and `y` may overlap
+ copy_nonoverlapping_memory(y, &*t, 1);
// y and t now point to the same thing, but we need to completely forget `tmp`
// because it's no longer relevant.
/**
* Replace the value at a mutable location with a new one, returning the old
- * value, without deinitialising or copying either one.
+ * value, without deinitialising either.
*/
#[inline]
-pub unsafe fn replace_ptr<T>(dest: *mut T, mut src: T) -> T {
- swap(cast::transmute(dest), &mut src); // cannot overlap
+pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
+ mem::swap(cast::transmute(dest), &mut src); // cannot overlap
src
}
/**
- * Reads the value from `*src` and returns it. Does not copy `*src`.
+ * Reads the value from `*src` and returns it.
*/
#[inline(always)]
-pub unsafe fn read_ptr<T>(src: *T) -> T {
+pub unsafe fn read<T>(src: *T) -> T {
let mut tmp: T = mem::uninit();
copy_nonoverlapping_memory(&mut tmp, src, 1);
tmp
* This currently prevents destructors from executing.
*/
#[inline(always)]
-pub unsafe fn read_and_zero_ptr<T>(dest: *mut T) -> T {
+pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
// Copy the data out from `dest`:
- let tmp = read_ptr(&*dest);
+ let tmp = read(&*dest);
// Now zero out `dest`:
zero_memory(dest, 1);
tmp
}
-/// Transform a region pointer - &T - to an unsafe pointer - *T.
-#[inline]
-pub fn to_unsafe_ptr<T>(thing: &T) -> *T {
- thing as *T
-}
-
-/// Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T.
-#[inline]
-pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
- thing as *mut T
-}
-
/**
Given a **T (pointer to an array of pointers),
iterate through each *T, up to the provided `len`,
SAFETY NOTE: Pointer-arithmetic. Dragons be here.
*/
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
- debug!("array_each_with_len: before iterate");
- if arr as uint == 0 {
+ if arr.is_null() {
fail!("ptr::array_each_with_len failure: arr input is null pointer");
}
//let start_ptr = *arr;
for e in range(0, len) {
- let n = offset(arr, e as int);
+ let n = arr.offset(e as int);
cb(*n);
}
- debug!("array_each_with_len: after iterate");
}
/**
Dragons be here.
*/
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
- if arr as uint == 0 {
+ if arr.is_null() {
fail!("ptr::array_each_with_len failure: arr input is null pointer");
}
let len = buf_len(arr);
- debug!("array_each inferred len: {}", len);
array_each_with_len(arr, len, cb);
}
-#[allow(missing_doc)]
+/// Extension methods for raw pointers.
pub trait RawPtr<T> {
+ /// Returns the null pointer.
fn null() -> Self;
+ /// Returns true if the pointer is equal to the null pointer.
fn is_null(&self) -> bool;
- fn is_not_null(&self) -> bool;
+ /// Returns true if the pointer is not equal to the null pointer.
+ fn is_not_null(&self) -> bool { !self.is_null() }
+ /// Returns the value of this pointer (ie, the address it points to)
fn to_uint(&self) -> uint;
+ /// Returns `None` if the pointer is null, or else returns the value wrapped
+ /// in `Some`.
+ ///
+ /// # Safety Notes
+ ///
+ /// While this method is useful for null-safety, it is important to note
+ /// that this is still an unsafe operation because the returned value could
+ /// be pointing to invalid memory.
unsafe fn to_option(&self) -> Option<&T>;
+ /// Calculates the offset from a pointer. The offset *must* be in-bounds of
+ /// the object, or one-byte-past-the-end. `count` is in units of T; e.g. a
+ /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
unsafe fn offset(self, count: int) -> Self;
}
-/// Extension methods for immutable pointers
impl<T> RawPtr<T> for *T {
- /// Returns the null pointer.
#[inline]
fn null() -> *T { null() }
- /// Returns true if the pointer is equal to the null pointer.
#[inline]
fn is_null(&self) -> bool { *self == RawPtr::null() }
- /// Returns true if the pointer is not equal to the null pointer.
#[inline]
- fn is_not_null(&self) -> bool { *self != RawPtr::null() }
+ fn to_uint(&self) -> uint { *self as uint }
- /// Returns the address of this pointer.
#[inline]
- fn to_uint(&self) -> uint { *self as uint }
+ unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) }
- ///
- /// Returns `None` if the pointer is null, or else returns the value wrapped
- /// in `Some`.
- ///
- /// # Safety Notes
- ///
- /// While this method is useful for null-safety, it is important to note
- /// that this is still an unsafe operation because the returned value could
- /// be pointing to invalid memory.
- ///
#[inline]
unsafe fn to_option(&self) -> Option<&T> {
- if self.is_null() { None } else {
+ if self.is_null() {
+ None
+ } else {
Some(cast::transmute(*self))
}
}
-
- /// Calculates the offset from a pointer. The offset *must* be in-bounds of
- /// the object, or one-byte-past-the-end.
- #[inline]
- unsafe fn offset(self, count: int) -> *T { offset(self, count) }
}
-/// Extension methods for mutable pointers
impl<T> RawPtr<T> for *mut T {
- /// Returns the null pointer.
#[inline]
fn null() -> *mut T { mut_null() }
- /// Returns true if the pointer is equal to the null pointer.
#[inline]
fn is_null(&self) -> bool { *self == RawPtr::null() }
- /// Returns true if the pointer is not equal to the null pointer.
#[inline]
- fn is_not_null(&self) -> bool { *self != RawPtr::null() }
+ fn to_uint(&self) -> uint { *self as uint }
- /// Returns the address of this pointer.
#[inline]
- fn to_uint(&self) -> uint { *self as uint }
+ unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *T, count) as *mut T }
- ///
- /// Returns `None` if the pointer is null, or else returns the value wrapped
- /// in `Some`.
- ///
- /// # Safety Notes
- ///
- /// While this method is useful for null-safety, it is important to note
- /// that this is still an unsafe operation because the returned value could
- /// be pointing to invalid memory.
- ///
#[inline]
unsafe fn to_option(&self) -> Option<&T> {
- if self.is_null() { None } else {
+ if self.is_null() {
+ None
+ } else {
Some(cast::transmute(*self))
}
}
-
- /// Calculates the offset from a pointer. The offset *must* be in-bounds of
- /// the object, or one-byte-past-the-end. An arithmetic overflow is also
- /// undefined behaviour.
- ///
- /// This method should be preferred over `offset` when the guarantee can be
- /// satisfied, to enable better optimization.
- #[inline]
- unsafe fn offset(self, count: int) -> *mut T { mut_offset(self, count) }
}
// Equality for pointers
fn ne(&self, other: &*T) -> bool { !self.eq(other) }
}
+#[cfg(not(test))]
+impl<T> TotalEq for *T {}
+
#[cfg(not(test))]
impl<T> Eq for *mut T {
#[inline]
fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
}
+#[cfg(not(test))]
+impl<T> TotalEq for *mut T {}
+
// Equivalence for pointers
#[cfg(not(test))]
impl<T> Equiv<*mut T> for *T {
use cast;
use libc;
use str;
- use vec::{ImmutableVector, MutableVector};
+ use slice::{ImmutableVector, MutableVector};
#[test]
fn test() {
let v0 = ~[32000u16, 32001u16, 32002u16];
let mut v1 = ~[0u16, 0u16, 0u16];
- copy_memory(mut_offset(v1.as_mut_ptr(), 1),
- offset(v0.as_ptr(), 1), 1);
+ copy_memory(v1.as_mut_ptr().offset(1),
+ v0.as_ptr().offset(1), 1);
assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
copy_memory(v1.as_mut_ptr(),
- offset(v0.as_ptr(), 2), 1);
+ v0.as_ptr().offset(2), 1);
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
v1[2] == 0u16));
- copy_memory(mut_offset(v1.as_mut_ptr(), 2),
+ copy_memory(v1.as_mut_ptr().offset(2),
v0.as_ptr(), 1u);
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
v1[2] == 32000u16));
assert!(p.is_null());
assert!(!p.is_not_null());
- let q = unsafe { offset(p, 1) };
+ let q = unsafe { p.offset(1) };
assert!(!q.is_null());
assert!(q.is_not_null());
let mut xs = [0u8, ..20];
let ptr = xs.as_mut_ptr();
unsafe { set_memory(ptr, 5u8, xs.len()); }
- assert_eq!(xs, [5u8, ..20]);
+ assert!(xs == [5u8, ..20]);
}
}