#![stable]
use mem;
use clone::Clone;
use intrinsics;
use option::Option::{self, Some, None};
use marker::{Send, Sized, Sync};
use cmp::{PartialEq, Eq, Ord, PartialOrd};
use cmp::Ordering::{self, Less, Equal, Greater};
#[unstable]
pub use intrinsics::copy_nonoverlapping_memory;
#[unstable]
pub use intrinsics::copy_memory;
#[experimental = "uncertain about naming and semantics"]
pub use intrinsics::set_memory;
#[inline]
#[stable]
pub fn null<T>() -> *const T { 0 as *const T }
#[inline]
#[stable]
pub fn null_mut<T>() -> *mut T { 0 as *mut T }
#[inline]
#[unstable = "may play a larger role in std::ptr future extensions"]
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
set_memory(dst, 0, count);
}
#[inline]
#[stable]
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
let mut tmp: T = mem::uninitialized();
let t: *mut T = &mut tmp;
copy_nonoverlapping_memory(t, &*x, 1);
copy_memory(x, &*y, 1); copy_nonoverlapping_memory(y, &*t, 1);
mem::forget(tmp);
}
#[inline]
#[stable]
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
mem::swap(mem::transmute(dest), &mut src); src
}
#[inline(always)]
#[stable]
pub unsafe fn read<T>(src: *const T) -> T {
let mut tmp: T = mem::uninitialized();
copy_nonoverlapping_memory(&mut tmp, src, 1);
tmp
}
#[inline(always)]
#[unstable = "may play a larger role in std::ptr future extensions"]
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
let tmp = read(&*dest);
zero_memory(dest, 1);
tmp
}
#[inline]
#[stable]
pub unsafe fn write<T>(dst: *mut T, src: T) {
intrinsics::move_val_init(&mut *dst, src)
}
#[stable]
pub trait PtrExt: Sized {
type Target;
#[stable]
fn is_null(self) -> bool;
#[unstable = "Option is not clearly the right return type, and we may want \
to tie the return lifetime to a borrow of the raw pointer"]
unsafe fn as_ref<'a>(&self) -> Option<&'a Self::Target>;
#[stable]
unsafe fn offset(self, count: int) -> Self;
}
#[stable]
pub trait MutPtrExt {
type Target;
#[unstable = "Option is not clearly the right return type, and we may want \
to tie the return lifetime to a borrow of the raw pointer"]
unsafe fn as_mut<'a>(&self) -> Option<&'a mut Self::Target>;
}
#[stable]
impl<T> PtrExt for *const T {
type Target = T;
#[inline]
#[stable]
fn is_null(self) -> bool { self as uint == 0 }
#[inline]
#[stable]
unsafe fn offset(self, count: int) -> *const T {
intrinsics::offset(self, count)
}
#[inline]
#[unstable = "return value does not necessarily convey all possible \
information"]
unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
if self.is_null() {
None
} else {
Some(&**self)
}
}
}
#[stable]
impl<T> PtrExt for *mut T {
type Target = T;
#[inline]
#[stable]
fn is_null(self) -> bool { self as uint == 0 }
#[inline]
#[stable]
unsafe fn offset(self, count: int) -> *mut T {
intrinsics::offset(self as *const T, count) as *mut T
}
#[inline]
#[unstable = "return value does not necessarily convey all possible \
information"]
unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
if self.is_null() {
None
} else {
Some(&**self)
}
}
}
#[stable]
impl<T> MutPtrExt for *mut T {
type Target = T;
#[inline]
#[unstable = "return value does not necessarily convey all possible \
information"]
unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
if self.is_null() {
None
} else {
Some(&mut **self)
}
}
}
#[stable]
impl<T> PartialEq for *const T {
#[inline]
fn eq(&self, other: &*const T) -> bool {
*self == *other
}
#[inline]
fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
}
#[stable]
impl<T> Eq for *const T {}
#[stable]
impl<T> PartialEq for *mut T {
#[inline]
fn eq(&self, other: &*mut T) -> bool {
*self == *other
}
#[inline]
fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
}
#[stable]
impl<T> Eq for *mut T {}
#[stable]
impl<T> Clone for *const T {
#[inline]
fn clone(&self) -> *const T {
*self
}
}
#[stable]
impl<T> Clone for *mut T {
#[inline]
fn clone(&self) -> *mut T {
*self
}
}
mod externfnpointers {
use mem;
use cmp::PartialEq;
#[stable]
impl<_R> PartialEq for extern "C" fn() -> _R {
#[inline]
fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
let self_: *const () = unsafe { mem::transmute(*self) };
let other_: *const () = unsafe { mem::transmute(*other) };
self_ == other_
}
}
macro_rules! fnptreq {
($($p:ident),*) => {
#[stable]
impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R {
#[inline]
fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
let self_: *const () = unsafe { mem::transmute(*self) };
let other_: *const () = unsafe { mem::transmute(*other) };
self_ == other_
}
}
}
}
fnptreq! { A }
fnptreq! { A,B }
fnptreq! { A,B,C }
fnptreq! { A,B,C,D }
fnptreq! { A,B,C,D,E }
}
#[stable]
impl<T> Ord for *const T {
#[inline]
fn cmp(&self, other: &*const T) -> Ordering {
if self < other {
Less
} else if self == other {
Equal
} else {
Greater
}
}
}
#[stable]
impl<T> PartialOrd for *const T {
#[inline]
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
Some(self.cmp(other))
}
#[inline]
fn lt(&self, other: &*const T) -> bool { *self < *other }
#[inline]
fn le(&self, other: &*const T) -> bool { *self <= *other }
#[inline]
fn gt(&self, other: &*const T) -> bool { *self > *other }
#[inline]
fn ge(&self, other: &*const T) -> bool { *self >= *other }
}
#[stable]
impl<T> Ord for *mut T {
#[inline]
fn cmp(&self, other: &*mut T) -> Ordering {
if self < other {
Less
} else if self == other {
Equal
} else {
Greater
}
}
}
#[stable]
impl<T> PartialOrd for *mut T {
#[inline]
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
Some(self.cmp(other))
}
#[inline]
fn lt(&self, other: &*mut T) -> bool { *self < *other }
#[inline]
fn le(&self, other: &*mut T) -> bool { *self <= *other }
#[inline]
fn gt(&self, other: &*mut T) -> bool { *self > *other }
#[inline]
fn ge(&self, other: &*mut T) -> bool { *self >= *other }
}
#[unstable = "recently added to this module"]
pub struct Unique<T>(pub *mut T);
#[unstable = "recently added to this module"]
unsafe impl<T:Send> Send for Unique<T> { }
#[unstable = "recently added to this module"]
unsafe impl<T:Sync> Sync for Unique<T> { }
impl<T> Unique<T> {
#[unstable = "recently added to this module"]
pub fn null() -> Unique<T> {
Unique(null_mut())
}
#[unstable = "recently added to this module"]
pub unsafe fn offset(self, offset: int) -> *mut T {
self.0.offset(offset)
}
}