core: Apply stability attributes to ptr mod
* null and mut_null are unstable. Their names may change if the unsafe pointer types change. * copy_memory and copy_overlapping_memory are unstable. We think they aren't going to change. * set_memory and zero_memory are experimental. Both the names and the semantics are under question. * swap and replace are unstable and probably won't change. * read is unstable, probably won't change * read_and_zero is experimental. It's necessity is in doubt. * mem::overwrite is now called ptr::write to match read and is unstable. mem::overwrite is now deprecated * array_each, array_each_with_len, buf_len, and position are all deprecated because they use old style iteration and their utility is generally under question.
This commit is contained in:
parent
aa09561bb6
commit
9b228f8424
@ -213,14 +213,14 @@ pub struct Unique<T> {
|
||||
impl<T: Send> Unique<T> {
|
||||
pub fn new(value: T) -> Unique<T> {
|
||||
unsafe {
|
||||
let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
|
||||
let ptr = malloc(mem::size_of::<T>() as size_t) as *mut T;
|
||||
// we *need* valid pointer.
|
||||
assert!(!ptr.is_null());
|
||||
// `*ptr` is uninitialized, and `*ptr = value` would
|
||||
// attempt to destroy it `overwrite` moves a value into
|
||||
// this memory without attempting to drop the original
|
||||
// value.
|
||||
mem::overwrite(&mut *ptr, value);
|
||||
ptr::write(&mut *ptr, value);
|
||||
Unique{ptr: ptr}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ use std::intrinsics::{TyDesc, get_tydesc};
|
||||
use std::intrinsics;
|
||||
use std::mem;
|
||||
use std::num;
|
||||
use std::ptr::read;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use std::rt::heap::allocate;
|
||||
|
||||
@ -209,7 +209,7 @@ impl Arena {
|
||||
let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
|
||||
mem::min_align_of::<T>());
|
||||
let ptr = ptr as *mut T;
|
||||
mem::overwrite(&mut (*ptr), op());
|
||||
ptr::write(&mut (*ptr), op());
|
||||
return &*ptr;
|
||||
}
|
||||
}
|
||||
@ -262,7 +262,7 @@ impl Arena {
|
||||
// has *not* been initialized yet.
|
||||
*ty_ptr = mem::transmute(tydesc);
|
||||
// Actually initialize it
|
||||
mem::overwrite(&mut(*ptr), op());
|
||||
ptr::write(&mut(*ptr), op());
|
||||
// Now that we are done, update the tydesc to indicate that
|
||||
// the object is there.
|
||||
*ty_ptr = bitpack_tydesc_ptr(tydesc, true);
|
||||
@ -360,7 +360,7 @@ impl<T> TypedArenaChunk<T> {
|
||||
let mut chunk = unsafe {
|
||||
let chunk = allocate(size, mem::min_align_of::<TypedArenaChunk<T>>());
|
||||
let mut chunk: Box<TypedArenaChunk<T>> = mem::transmute(chunk);
|
||||
mem::overwrite(&mut chunk.next, next);
|
||||
ptr::write(&mut chunk.next, next);
|
||||
chunk
|
||||
};
|
||||
|
||||
@ -376,7 +376,7 @@ impl<T> TypedArenaChunk<T> {
|
||||
if intrinsics::needs_drop::<T>() {
|
||||
let mut start = self.start();
|
||||
for _ in range(0, len) {
|
||||
read(start as *T); // run the destructor on the pointer
|
||||
ptr::read(start as *T); // run the destructor on the pointer
|
||||
start = start.offset(mem::size_of::<T>() as int)
|
||||
}
|
||||
}
|
||||
@ -442,7 +442,7 @@ impl<T> TypedArena<T> {
|
||||
}
|
||||
|
||||
let ptr: &'a mut T = mem::transmute(this.ptr);
|
||||
mem::overwrite(ptr, object);
|
||||
ptr::write(ptr, object);
|
||||
this.ptr = this.ptr.offset(1);
|
||||
let ptr: &'a T = ptr;
|
||||
ptr
|
||||
|
@ -13,7 +13,8 @@
|
||||
#![allow(missing_doc)]
|
||||
|
||||
use std::clone::Clone;
|
||||
use std::mem::{overwrite, zeroed, replace, swap};
|
||||
use std::mem::{zeroed, replace, swap};
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
|
||||
/// A priority queue implemented with a binary heap
|
||||
@ -163,13 +164,13 @@ impl<T: Ord> PriorityQueue<T> {
|
||||
let parent = (pos - 1) >> 1;
|
||||
if new > *self.data.get(parent) {
|
||||
let x = replace(self.data.get_mut(parent), zeroed());
|
||||
overwrite(self.data.get_mut(pos), x);
|
||||
ptr::write(self.data.get_mut(pos), x);
|
||||
pos = parent;
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
overwrite(self.data.get_mut(pos), new);
|
||||
ptr::write(self.data.get_mut(pos), new);
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,12 +186,12 @@ impl<T: Ord> PriorityQueue<T> {
|
||||
child = right;
|
||||
}
|
||||
let x = replace(self.data.get_mut(child), zeroed());
|
||||
overwrite(self.data.get_mut(pos), x);
|
||||
ptr::write(self.data.get_mut(pos), x);
|
||||
pos = child;
|
||||
child = 2 * pos + 1;
|
||||
}
|
||||
|
||||
overwrite(self.data.get_mut(pos), new);
|
||||
ptr::write(self.data.get_mut(pos), new);
|
||||
self.siftup(start, pos);
|
||||
}
|
||||
}
|
||||
|
@ -155,16 +155,16 @@ pub unsafe fn uninit<T>() -> T {
|
||||
/// contained at the location `dst`. This could leak allocations or resources,
|
||||
/// so care must be taken to previously deallocate the value at `dst`.
|
||||
#[inline]
|
||||
#[stable]
|
||||
#[deprecated = "use ptr::write"]
|
||||
pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
|
||||
intrinsics::move_val_init(&mut *dst, src)
|
||||
}
|
||||
|
||||
/// Deprecated, use `overwrite` instead
|
||||
#[inline]
|
||||
#[deprecated = "this function has been renamed to `overwrite`"]
|
||||
#[deprecated = "use ptr::write"]
|
||||
pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
|
||||
overwrite(dst, src)
|
||||
ptr::write(dst, src)
|
||||
}
|
||||
|
||||
/// Convert an u16 to little endian from the target's endianness.
|
||||
|
@ -95,36 +95,6 @@ use option::{Some, None, Option};
|
||||
|
||||
#[cfg(not(test))] use cmp::{PartialEq, Eq, PartialOrd, Equiv};
|
||||
|
||||
/// Return the offset of the first null pointer in `buf`.
|
||||
#[inline]
|
||||
pub unsafe fn buf_len<T>(buf: **T) -> uint {
|
||||
position(buf, |i| *i == null())
|
||||
}
|
||||
|
||||
impl<T> Clone for *T {
|
||||
#[inline]
|
||||
fn clone(&self) -> *T {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for *mut T {
|
||||
#[inline]
|
||||
fn clone(&self) -> *mut T {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the first offset `i` such that `f(buf[i]) == true`.
|
||||
#[inline]
|
||||
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
|
||||
let mut i = 0;
|
||||
loop {
|
||||
if f(&(*buf.offset(i as int))) { return i; }
|
||||
else { i += 1; }
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a null pointer.
|
||||
///
|
||||
/// # Example
|
||||
@ -136,6 +106,7 @@ pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
|
||||
/// assert!(p.is_null());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "may need a different name after pending changes to pointer types"]
|
||||
pub fn null<T>() -> *T { 0 as *T }
|
||||
|
||||
/// Create an unsafe mutable null pointer.
|
||||
@ -149,6 +120,7 @@ pub fn null<T>() -> *T { 0 as *T }
|
||||
/// assert!(p.is_null());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "may need a different name after pending changes to pointer types"]
|
||||
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
|
||||
|
||||
/// Copies data from one location to another.
|
||||
@ -174,6 +146,7 @@ pub fn mut_null<T>() -> *mut T { 0 as *mut T }
|
||||
/// ```
|
||||
///
|
||||
#[inline]
|
||||
#[unstable]
|
||||
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
|
||||
intrinsics::copy_memory(dst, src, count)
|
||||
}
|
||||
@ -215,6 +188,7 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
|
||||
/// If the source and destination overlap then the behavior of this
|
||||
/// function is undefined.
|
||||
#[inline]
|
||||
#[unstable]
|
||||
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
|
||||
src: *T,
|
||||
count: uint) {
|
||||
@ -224,12 +198,15 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
|
||||
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
|
||||
/// bytes of memory starting at `dst` to `c`.
|
||||
#[inline]
|
||||
#[experimental = "uncertain about naming and semantics"]
|
||||
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
|
||||
intrinsics::set_memory(dst, c, count)
|
||||
}
|
||||
|
||||
/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
|
||||
#[inline]
|
||||
#[experimental = "uncertain about naming and semantics"]
|
||||
#[allow(experimental)]
|
||||
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
|
||||
set_memory(dst, 0, count);
|
||||
}
|
||||
@ -237,6 +214,7 @@ pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
|
||||
/// Swap the values at two mutable locations of the same type, without
|
||||
/// deinitialising either. They may overlap.
|
||||
#[inline]
|
||||
#[unstable]
|
||||
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
|
||||
// Give ourselves some scratch space to work with
|
||||
let mut tmp: T = mem::uninitialized();
|
||||
@ -255,6 +233,7 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
|
||||
/// Replace the value at a mutable location with a new one, returning the old
|
||||
/// value, without deinitialising either.
|
||||
#[inline]
|
||||
#[unstable]
|
||||
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
||||
mem::swap(mem::transmute(dest), &mut src); // cannot overlap
|
||||
src
|
||||
@ -262,6 +241,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
||||
|
||||
/// Reads the value from `*src` and returns it.
|
||||
#[inline(always)]
|
||||
#[unstable]
|
||||
pub unsafe fn read<T>(src: *T) -> T {
|
||||
let mut tmp: T = mem::uninitialized();
|
||||
copy_nonoverlapping_memory(&mut tmp, src, 1);
|
||||
@ -271,6 +251,8 @@ pub unsafe fn read<T>(src: *T) -> T {
|
||||
/// Reads the value from `*src` and nulls it out.
|
||||
/// This currently prevents destructors from executing.
|
||||
#[inline(always)]
|
||||
#[experimental]
|
||||
#[allow(experimental)]
|
||||
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
||||
// Copy the data out from `dest`:
|
||||
let tmp = read(&*dest);
|
||||
@ -281,9 +263,22 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
||||
tmp
|
||||
}
|
||||
|
||||
/// Unsafely overwrite a memory location with the given value without destroying
|
||||
/// the old value.
|
||||
///
|
||||
/// This operation is unsafe because it does not destroy the previous value
|
||||
/// contained at the location `dst`. This could leak allocations or resources,
|
||||
/// so care must be taken to previously deallocate the value at `dst`.
|
||||
#[inline]
|
||||
#[unstable]
|
||||
pub unsafe fn write<T>(dst: *mut T, src: T) {
|
||||
intrinsics::move_val_init(&mut *dst, src)
|
||||
}
|
||||
|
||||
/// Given a **T (pointer to an array of pointers),
|
||||
/// iterate through each *T, up to the provided `len`,
|
||||
/// passing to the provided callback function
|
||||
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
|
||||
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
|
||||
if arr.is_null() {
|
||||
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
||||
@ -303,6 +298,8 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
|
||||
///
|
||||
/// This will only work with a null-terminated
|
||||
/// pointer array.
|
||||
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
|
||||
#[allow(deprecated)]
|
||||
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
|
||||
if arr.is_null() {
|
||||
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
||||
@ -311,6 +308,25 @@ pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
|
||||
array_each_with_len(arr, len, cb);
|
||||
}
|
||||
|
||||
/// Return the offset of the first null pointer in `buf`.
|
||||
#[inline]
|
||||
#[deprecated = "use a loop and RawPtr::offset"]
|
||||
#[allow(deprecated)]
|
||||
pub unsafe fn buf_len<T>(buf: **T) -> uint {
|
||||
position(buf, |i| *i == null())
|
||||
}
|
||||
|
||||
/// Return the first offset `i` such that `f(buf[i]) == true`.
|
||||
#[inline]
|
||||
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
|
||||
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
|
||||
let mut i = 0;
|
||||
loop {
|
||||
if f(&(*buf.offset(i as int))) { return i; }
|
||||
else { i += 1; }
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods on raw pointers
|
||||
pub trait RawPtr<T> {
|
||||
/// Returns the null pointer.
|
||||
@ -426,6 +442,20 @@ impl<T> Equiv<*T> for *mut T {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for *T {
|
||||
#[inline]
|
||||
fn clone(&self) -> *T {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for *mut T {
|
||||
#[inline]
|
||||
fn clone(&self) -> *mut T {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
// Equality for extern "C" fn pointers
|
||||
#[cfg(not(test))]
|
||||
mod externfnpointers {
|
||||
|
@ -77,7 +77,7 @@ impl<A: Clone> Clone for ~[A] {
|
||||
try_finally(
|
||||
&mut i, (),
|
||||
|i, ()| while *i < len {
|
||||
mem::overwrite(
|
||||
ptr::write(
|
||||
&mut(*p.offset(*i as int)),
|
||||
self.unsafe_ref(*i).clone());
|
||||
*i += 1;
|
||||
|
@ -1093,7 +1093,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
|
||||
|
||||
#[inline]
|
||||
unsafe fn init_elem(self, i: uint, val: T) {
|
||||
mem::overwrite(&mut (*self.as_mut_ptr().offset(i as int)), val);
|
||||
ptr::write(&mut (*self.as_mut_ptr().offset(i as int)), val);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -1218,6 +1218,7 @@ pub mod bytes {
|
||||
|
||||
impl<'a> MutableByteVector for &'a mut [u8] {
|
||||
#[inline]
|
||||
#[allow(experimental)]
|
||||
fn set_memory(self, value: u8) {
|
||||
unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user