diff --git a/src/doc/guide-unsafe.md b/src/doc/guide-unsafe.md index 4e1a96710be..e0a48682963 100644 --- a/src/doc/guide-unsafe.md +++ b/src/doc/guide-unsafe.md @@ -213,14 +213,14 @@ pub struct Unique { impl Unique { pub fn new(value: T) -> Unique { unsafe { - let ptr = malloc(std::mem::size_of::() as size_t) as *mut T; + let ptr = malloc(mem::size_of::() 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} } } diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 7acef128016..871f8197c9a 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -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::(), mem::min_align_of::()); 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 TypedArenaChunk { let mut chunk = unsafe { let chunk = allocate(size, mem::min_align_of::>()); let mut chunk: Box> = mem::transmute(chunk); - mem::overwrite(&mut chunk.next, next); + ptr::write(&mut chunk.next, next); chunk }; @@ -376,7 +376,7 @@ impl TypedArenaChunk { if intrinsics::needs_drop::() { 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::() as int) } } @@ -442,7 +442,7 @@ impl TypedArena { } 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 diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs index 3c1337a0382..d73c07ee17d 100644 --- a/src/libcollections/priority_queue.rs +++ b/src/libcollections/priority_queue.rs @@ -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 PriorityQueue { 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 PriorityQueue { 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); } } diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 157be76b8f1..8933c95350d 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -155,16 +155,16 @@ pub unsafe fn uninit() -> 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(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(dst: &mut T, src: T) { - overwrite(dst, src) + ptr::write(dst, src) } /// Convert an u16 to little endian from the target's endianness. diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index dacbba61856..b2776b78b1c 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -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(buf: **T) -> uint { - position(buf, |i| *i == null()) -} - -impl Clone for *T { - #[inline] - fn clone(&self) -> *T { - *self - } -} - -impl 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(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(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 { 0 as *T } /// Create an unsafe mutable null pointer. @@ -149,6 +120,7 @@ pub fn null() -> *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() -> *mut T { 0 as *mut T } /// Copies data from one location to another. @@ -174,6 +146,7 @@ pub fn mut_null() -> *mut T { 0 as *mut T } /// ``` /// #[inline] +#[unstable] pub unsafe fn copy_memory(dst: *mut T, src: *T, count: uint) { intrinsics::copy_memory(dst, src, count) } @@ -215,6 +188,7 @@ pub unsafe fn copy_memory(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(dst: *mut T, src: *T, count: uint) { @@ -224,12 +198,15 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, /// Invokes memset on the specified pointer, setting `count * size_of::()` /// bytes of memory starting at `dst` to `c`. #[inline] +#[experimental = "uncertain about naming and semantics"] pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { intrinsics::set_memory(dst, c, count) } /// Zeroes out `count * size_of::` bytes of memory at `dst` #[inline] +#[experimental = "uncertain about naming and semantics"] +#[allow(experimental)] pub unsafe fn zero_memory(dst: *mut T, count: uint) { set_memory(dst, 0, count); } @@ -237,6 +214,7 @@ pub unsafe fn zero_memory(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(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(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(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(dest: *mut T, mut src: T) -> T { /// Reads the value from `*src` and returns it. #[inline(always)] +#[unstable] pub unsafe fn read(src: *T) -> T { let mut tmp: T = mem::uninitialized(); copy_nonoverlapping_memory(&mut tmp, src, 1); @@ -271,6 +251,8 @@ pub unsafe fn read(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(dest: *mut T) -> T { // Copy the data out from `dest`: let tmp = read(&*dest); @@ -281,9 +263,22 @@ pub unsafe fn read_and_zero(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(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(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(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(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(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(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(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 { /// Returns the null pointer. @@ -426,6 +442,20 @@ impl Equiv<*T> for *mut T { } } +impl Clone for *T { + #[inline] + fn clone(&self) -> *T { + *self + } +} + +impl Clone for *mut T { + #[inline] + fn clone(&self) -> *mut T { + *self + } +} + // Equality for extern "C" fn pointers #[cfg(not(test))] mod externfnpointers { diff --git a/src/libcore/should_not_exist.rs b/src/libcore/should_not_exist.rs index 9a0e3ad7ca4..2c6f2978aa7 100644 --- a/src/libcore/should_not_exist.rs +++ b/src/libcore/should_not_exist.rs @@ -77,7 +77,7 @@ impl 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; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 5673d0c020d..6312d9115ef 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -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()) }; }