|
|
|
|
@@ -101,16 +101,28 @@ use cmp::Ordering::{self, Less, Equal, Greater};
|
|
|
|
|
|
|
|
|
|
// FIXME #19649: intrinsic docs don't render, so these have no docs :(
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
pub use intrinsics::copy_nonoverlapping_memory;
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub use intrinsics::copy_nonoverlapping_memory as copy_nonoverlapping;
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
pub use intrinsics::copy_memory;
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub use intrinsics::copy_memory as copy;
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "uncertain about naming and semantics")]
|
|
|
|
|
pub use intrinsics::set_memory;
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub use intrinsics::set_memory as write_bytes;
|
|
|
|
|
|
|
|
|
|
extern "rust-intrinsic" {
|
|
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0", reason = "renamed to `copy_nonoverlapping`")]
|
|
|
|
|
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
|
|
|
|
|
#[unstable(feature = "core")]
|
|
|
|
|
#[deprecated(since = "1.0.0", reason = "renamed to `copy`")]
|
|
|
|
|
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize);
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "uncertain about naming and semantics")]
|
|
|
|
|
#[deprecated(since = "1.0.0", reason = "renamed to `write_bytes`")]
|
|
|
|
|
pub fn set_memory<T>(dst: *mut T, val: u8, count: usize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a null raw pointer.
|
|
|
|
|
///
|
|
|
|
|
@@ -150,8 +162,9 @@ pub fn null_mut<T>() -> *mut T { 0 as *mut T }
|
|
|
|
|
#[inline]
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "may play a larger role in std::ptr future extensions")]
|
|
|
|
|
#[deprecated(since = "1.0.0", reason = "use `write_bytes` instead")]
|
|
|
|
|
pub unsafe fn zero_memory<T>(dst: *mut T, count: usize) {
|
|
|
|
|
set_memory(dst, 0, count);
|
|
|
|
|
write_bytes(dst, 0, count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Swaps the values at two mutable locations of the same type, without
|
|
|
|
|
@@ -169,9 +182,9 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
|
|
|
|
|
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(t, &*x, 1);
|
|
|
|
|
copy(x, &*y, 1); // `x` and `y` may overlap
|
|
|
|
|
copy_nonoverlapping(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.
|
|
|
|
|
@@ -207,7 +220,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub unsafe fn read<T>(src: *const T) -> T {
|
|
|
|
|
let mut tmp: T = mem::uninitialized();
|
|
|
|
|
copy_nonoverlapping_memory(&mut tmp, src, 1);
|
|
|
|
|
copy_nonoverlapping(&mut tmp, src, 1);
|
|
|
|
|
tmp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -224,7 +237,7 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
|
|
|
|
let tmp = read(&*dest);
|
|
|
|
|
|
|
|
|
|
// Now zero out `dest`:
|
|
|
|
|
zero_memory(dest, 1);
|
|
|
|
|
write_bytes(dest, 0, 1);
|
|
|
|
|
|
|
|
|
|
tmp
|
|
|
|
|
}
|
|
|
|
|
@@ -248,9 +261,9 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
|
|
|
|
|
|
|
|
|
|
/// Methods on raw pointers
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub trait PtrExt: Sized {
|
|
|
|
|
pub trait PtrExt {
|
|
|
|
|
/// The type which is being pointed at
|
|
|
|
|
type Target;
|
|
|
|
|
type Target: ?Sized;
|
|
|
|
|
|
|
|
|
|
/// Returns true if the pointer is null.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
@@ -279,14 +292,14 @@ pub trait PtrExt: Sized {
|
|
|
|
|
/// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
|
|
|
|
|
/// the pointer is used.
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
unsafe fn offset(self, count: isize) -> Self;
|
|
|
|
|
unsafe fn offset(self, count: isize) -> Self where Self::Target: Sized;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Methods on mutable raw pointers
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
pub trait MutPtrExt {
|
|
|
|
|
/// The type which is being pointed at
|
|
|
|
|
type Target;
|
|
|
|
|
type Target: ?Sized;
|
|
|
|
|
|
|
|
|
|
/// Returns `None` if the pointer is null, or else returns a mutable
|
|
|
|
|
/// reference to the value wrapped in `Some`.
|
|
|
|
|
@@ -302,7 +315,7 @@ pub trait MutPtrExt {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> PtrExt for *const T {
|
|
|
|
|
impl<T: ?Sized> PtrExt for *const T {
|
|
|
|
|
type Target = T;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
@@ -311,7 +324,7 @@ impl<T> PtrExt for *const T {
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
unsafe fn offset(self, count: isize) -> *const T {
|
|
|
|
|
unsafe fn offset(self, count: isize) -> *const T where T: Sized {
|
|
|
|
|
intrinsics::offset(self, count)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -329,7 +342,7 @@ impl<T> PtrExt for *const T {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> PtrExt for *mut T {
|
|
|
|
|
impl<T: ?Sized> PtrExt for *mut T {
|
|
|
|
|
type Target = T;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
@@ -338,7 +351,7 @@ impl<T> PtrExt for *mut T {
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
unsafe fn offset(self, count: isize) -> *mut T {
|
|
|
|
|
unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
|
|
|
|
|
intrinsics::offset(self, count) as *mut T
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -356,7 +369,7 @@ impl<T> PtrExt for *mut T {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> MutPtrExt for *mut T {
|
|
|
|
|
impl<T: ?Sized> MutPtrExt for *mut T {
|
|
|
|
|
type Target = T;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
@@ -374,33 +387,25 @@ impl<T> MutPtrExt for *mut T {
|
|
|
|
|
|
|
|
|
|
// Equality for pointers
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> PartialEq for *const T {
|
|
|
|
|
impl<T: ?Sized> 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) }
|
|
|
|
|
fn eq(&self, other: &*const T) -> bool { *self == *other }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> Eq for *const T {}
|
|
|
|
|
impl<T: ?Sized> Eq for *const T {}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> PartialEq for *mut T {
|
|
|
|
|
impl<T: ?Sized> 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) }
|
|
|
|
|
fn eq(&self, other: &*mut T) -> bool { *self == *other }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> Eq for *mut T {}
|
|
|
|
|
impl<T: ?Sized> Eq for *mut T {}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> Clone for *const T {
|
|
|
|
|
impl<T: ?Sized> Clone for *const T {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn clone(&self) -> *const T {
|
|
|
|
|
*self
|
|
|
|
|
@@ -408,7 +413,7 @@ impl<T> Clone for *const T {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> Clone for *mut T {
|
|
|
|
|
impl<T: ?Sized> Clone for *mut T {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn clone(&self) -> *mut T {
|
|
|
|
|
*self
|
|
|
|
|
@@ -452,7 +457,7 @@ mod externfnpointers {
|
|
|
|
|
|
|
|
|
|
// Comparison for pointers
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> Ord for *const T {
|
|
|
|
|
impl<T: ?Sized> Ord for *const T {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn cmp(&self, other: &*const T) -> Ordering {
|
|
|
|
|
if self < other {
|
|
|
|
|
@@ -466,7 +471,7 @@ impl<T> Ord for *const T {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> PartialOrd for *const T {
|
|
|
|
|
impl<T: ?Sized> PartialOrd for *const T {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
|
|
|
|
|
Some(self.cmp(other))
|
|
|
|
|
@@ -486,7 +491,7 @@ impl<T> PartialOrd for *const T {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> Ord for *mut T {
|
|
|
|
|
impl<T: ?Sized> Ord for *mut T {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn cmp(&self, other: &*mut T) -> Ordering {
|
|
|
|
|
if self < other {
|
|
|
|
|
@@ -500,7 +505,7 @@ impl<T> Ord for *mut T {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<T> PartialOrd for *mut T {
|
|
|
|
|
impl<T: ?Sized> PartialOrd for *mut T {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
|
|
|
|
|
Some(self.cmp(other))
|
|
|
|
|
@@ -527,8 +532,8 @@ impl<T> PartialOrd for *mut T {
|
|
|
|
|
/// modified without a unique path to the `Unique` reference. Useful
|
|
|
|
|
/// for building abstractions like `Vec<T>` or `Box<T>`, which
|
|
|
|
|
/// internally use raw pointers to manage the memory that they own.
|
|
|
|
|
#[unstable(feature = "core", reason = "recently added to this module")]
|
|
|
|
|
pub struct Unique<T:?Sized> {
|
|
|
|
|
#[unstable(feature = "unique")]
|
|
|
|
|
pub struct Unique<T: ?Sized> {
|
|
|
|
|
pointer: NonZero<*const T>,
|
|
|
|
|
_marker: PhantomData<T>,
|
|
|
|
|
}
|
|
|
|
|
@@ -537,39 +542,37 @@ pub struct Unique<T:?Sized> {
|
|
|
|
|
/// reference is unaliased. Note that this aliasing invariant is
|
|
|
|
|
/// unenforced by the type system; the abstraction using the
|
|
|
|
|
/// `Unique` must enforce it.
|
|
|
|
|
#[unstable(feature = "core", reason = "recently added to this module")]
|
|
|
|
|
#[unstable(feature = "unique")]
|
|
|
|
|
unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
|
|
|
|
|
|
|
|
|
|
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
|
|
|
|
|
/// reference is unaliased. Note that this aliasing invariant is
|
|
|
|
|
/// unenforced by the type system; the abstraction using the
|
|
|
|
|
/// `Unique` must enforce it.
|
|
|
|
|
#[unstable(feature = "core", reason = "recently added to this module")]
|
|
|
|
|
#[unstable(feature = "unique")]
|
|
|
|
|
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
|
|
|
|
|
|
|
|
|
|
impl<T:?Sized> Unique<T> {
|
|
|
|
|
impl<T: ?Sized> Unique<T> {
|
|
|
|
|
/// Create a new `Unique`.
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "recently added to this module")]
|
|
|
|
|
#[unstable(feature = "unique")]
|
|
|
|
|
pub unsafe fn new(ptr: *mut T) -> Unique<T> {
|
|
|
|
|
Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Dereference the content.
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "recently added to this module")]
|
|
|
|
|
#[unstable(feature = "unique")]
|
|
|
|
|
pub unsafe fn get(&self) -> &T {
|
|
|
|
|
&**self.pointer
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Mutably dereference the content.
|
|
|
|
|
#[unstable(feature = "core",
|
|
|
|
|
reason = "recently added to this module")]
|
|
|
|
|
#[unstable(feature = "unique")]
|
|
|
|
|
pub unsafe fn get_mut(&mut self) -> &mut T {
|
|
|
|
|
&mut ***self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[unstable(feature = "unique")]
|
|
|
|
|
impl<T:?Sized> Deref for Unique<T> {
|
|
|
|
|
type Target = *mut T;
|
|
|
|
|
|
|
|
|
|
|