auto merge of #14529 : brson/rust/ptr, r=brson
This time we're not promoting anything directly to 'stable', but instead promoting functions we're happy with to 'unstable'. They'll become stable in another pass later. * 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. Note that `mem::overwrite`, which was just declared stable last week, is deprecated now in favor of `ptr::write`. Woo!
This commit is contained in:
commit
193574ae1e
|
@ -213,14 +213,14 @@ pub struct Unique<T> {
|
||||||
impl<T: Send> Unique<T> {
|
impl<T: Send> Unique<T> {
|
||||||
pub fn new(value: T) -> Unique<T> {
|
pub fn new(value: T) -> Unique<T> {
|
||||||
unsafe {
|
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.
|
// we *need* valid pointer.
|
||||||
assert!(!ptr.is_null());
|
assert!(!ptr.is_null());
|
||||||
// `*ptr` is uninitialized, and `*ptr = value` would
|
// `*ptr` is uninitialized, and `*ptr = value` would
|
||||||
// attempt to destroy it `overwrite` moves a value into
|
// attempt to destroy it `overwrite` moves a value into
|
||||||
// this memory without attempting to drop the original
|
// this memory without attempting to drop the original
|
||||||
// value.
|
// value.
|
||||||
mem::overwrite(&mut *ptr, value);
|
ptr::write(&mut *ptr, value);
|
||||||
Unique{ptr: ptr}
|
Unique{ptr: ptr}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ use std::intrinsics::{TyDesc, get_tydesc};
|
||||||
use std::intrinsics;
|
use std::intrinsics;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::num;
|
use std::num;
|
||||||
use std::ptr::read;
|
use std::ptr;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::rt::heap::allocate;
|
use std::rt::heap::allocate;
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ impl Arena {
|
||||||
let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
|
let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
|
||||||
mem::min_align_of::<T>());
|
mem::min_align_of::<T>());
|
||||||
let ptr = ptr as *mut T;
|
let ptr = ptr as *mut T;
|
||||||
mem::overwrite(&mut (*ptr), op());
|
ptr::write(&mut (*ptr), op());
|
||||||
return &*ptr;
|
return &*ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ impl Arena {
|
||||||
// has *not* been initialized yet.
|
// has *not* been initialized yet.
|
||||||
*ty_ptr = mem::transmute(tydesc);
|
*ty_ptr = mem::transmute(tydesc);
|
||||||
// Actually initialize it
|
// Actually initialize it
|
||||||
mem::overwrite(&mut(*ptr), op());
|
ptr::write(&mut(*ptr), op());
|
||||||
// Now that we are done, update the tydesc to indicate that
|
// Now that we are done, update the tydesc to indicate that
|
||||||
// the object is there.
|
// the object is there.
|
||||||
*ty_ptr = bitpack_tydesc_ptr(tydesc, true);
|
*ty_ptr = bitpack_tydesc_ptr(tydesc, true);
|
||||||
|
@ -360,7 +360,7 @@ impl<T> TypedArenaChunk<T> {
|
||||||
let mut chunk = unsafe {
|
let mut chunk = unsafe {
|
||||||
let chunk = allocate(size, mem::min_align_of::<TypedArenaChunk<T>>());
|
let chunk = allocate(size, mem::min_align_of::<TypedArenaChunk<T>>());
|
||||||
let mut chunk: Box<TypedArenaChunk<T>> = mem::transmute(chunk);
|
let mut chunk: Box<TypedArenaChunk<T>> = mem::transmute(chunk);
|
||||||
mem::overwrite(&mut chunk.next, next);
|
ptr::write(&mut chunk.next, next);
|
||||||
chunk
|
chunk
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ impl<T> TypedArenaChunk<T> {
|
||||||
if intrinsics::needs_drop::<T>() {
|
if intrinsics::needs_drop::<T>() {
|
||||||
let mut start = self.start();
|
let mut start = self.start();
|
||||||
for _ in range(0, len) {
|
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)
|
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);
|
let ptr: &'a mut T = mem::transmute(this.ptr);
|
||||||
mem::overwrite(ptr, object);
|
ptr::write(ptr, object);
|
||||||
this.ptr = this.ptr.offset(1);
|
this.ptr = this.ptr.offset(1);
|
||||||
let ptr: &'a T = ptr;
|
let ptr: &'a T = ptr;
|
||||||
ptr
|
ptr
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
#![allow(missing_doc)]
|
#![allow(missing_doc)]
|
||||||
|
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::mem::{overwrite, zeroed, replace, swap};
|
use std::mem::{zeroed, replace, swap};
|
||||||
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
/// A priority queue implemented with a binary heap
|
/// A priority queue implemented with a binary heap
|
||||||
|
@ -163,13 +164,13 @@ impl<T: Ord> PriorityQueue<T> {
|
||||||
let parent = (pos - 1) >> 1;
|
let parent = (pos - 1) >> 1;
|
||||||
if new > *self.data.get(parent) {
|
if new > *self.data.get(parent) {
|
||||||
let x = replace(self.data.get_mut(parent), zeroed());
|
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;
|
pos = parent;
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
break
|
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;
|
child = right;
|
||||||
}
|
}
|
||||||
let x = replace(self.data.get_mut(child), zeroed());
|
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;
|
pos = child;
|
||||||
child = 2 * pos + 1;
|
child = 2 * pos + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
overwrite(self.data.get_mut(pos), new);
|
ptr::write(self.data.get_mut(pos), new);
|
||||||
self.siftup(start, pos);
|
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,
|
/// contained at the location `dst`. This could leak allocations or resources,
|
||||||
/// so care must be taken to previously deallocate the value at `dst`.
|
/// so care must be taken to previously deallocate the value at `dst`.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable]
|
#[deprecated = "use ptr::write"]
|
||||||
pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
|
pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
|
||||||
intrinsics::move_val_init(&mut *dst, src)
|
intrinsics::move_val_init(&mut *dst, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deprecated, use `overwrite` instead
|
/// Deprecated, use `overwrite` instead
|
||||||
#[inline]
|
#[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) {
|
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.
|
/// 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};
|
#[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.
|
/// Create a null pointer.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
@ -136,6 +106,7 @@ pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
|
||||||
/// assert!(p.is_null());
|
/// assert!(p.is_null());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[unstable = "may need a different name after pending changes to pointer types"]
|
||||||
pub fn null<T>() -> *T { 0 as *T }
|
pub fn null<T>() -> *T { 0 as *T }
|
||||||
|
|
||||||
/// Create an unsafe mutable null pointer.
|
/// Create an unsafe mutable null pointer.
|
||||||
|
@ -149,6 +120,7 @@ pub fn null<T>() -> *T { 0 as *T }
|
||||||
/// assert!(p.is_null());
|
/// assert!(p.is_null());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[unstable = "may need a different name after pending changes to pointer types"]
|
||||||
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
|
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
|
||||||
|
|
||||||
/// Copies data from one location to another.
|
/// Copies data from one location to another.
|
||||||
|
@ -174,6 +146,7 @@ pub fn mut_null<T>() -> *mut T { 0 as *mut T }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[unstable]
|
||||||
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
|
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
|
||||||
intrinsics::copy_memory(dst, src, count)
|
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
|
/// If the source and destination overlap then the behavior of this
|
||||||
/// function is undefined.
|
/// function is undefined.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[unstable]
|
||||||
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
|
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
|
||||||
src: *T,
|
src: *T,
|
||||||
count: uint) {
|
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>()`
|
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
|
||||||
/// bytes of memory starting at `dst` to `c`.
|
/// bytes of memory starting at `dst` to `c`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[experimental = "uncertain about naming and semantics"]
|
||||||
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
|
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
|
||||||
intrinsics::set_memory(dst, c, count)
|
intrinsics::set_memory(dst, c, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
|
/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[experimental = "uncertain about naming and semantics"]
|
||||||
|
#[allow(experimental)]
|
||||||
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
|
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
|
||||||
set_memory(dst, 0, count);
|
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
|
/// Swap the values at two mutable locations of the same type, without
|
||||||
/// deinitialising either. They may overlap.
|
/// deinitialising either. They may overlap.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[unstable]
|
||||||
pub unsafe fn swap<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
|
// Give ourselves some scratch space to work with
|
||||||
let mut tmp: T = mem::uninitialized();
|
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
|
/// Replace the value at a mutable location with a new one, returning the old
|
||||||
/// value, without deinitialising either.
|
/// value, without deinitialising either.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[unstable]
|
||||||
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
||||||
mem::swap(mem::transmute(dest), &mut src); // cannot overlap
|
mem::swap(mem::transmute(dest), &mut src); // cannot overlap
|
||||||
src
|
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.
|
/// Reads the value from `*src` and returns it.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#[unstable]
|
||||||
pub unsafe fn read<T>(src: *T) -> T {
|
pub unsafe fn read<T>(src: *T) -> T {
|
||||||
let mut tmp: T = mem::uninitialized();
|
let mut tmp: T = mem::uninitialized();
|
||||||
copy_nonoverlapping_memory(&mut tmp, src, 1);
|
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.
|
/// Reads the value from `*src` and nulls it out.
|
||||||
/// This currently prevents destructors from executing.
|
/// This currently prevents destructors from executing.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#[experimental]
|
||||||
|
#[allow(experimental)]
|
||||||
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
||||||
// Copy the data out from `dest`:
|
// Copy the data out from `dest`:
|
||||||
let tmp = read(&*dest);
|
let tmp = read(&*dest);
|
||||||
|
@ -281,9 +263,22 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
||||||
tmp
|
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),
|
/// Given a **T (pointer to an array of pointers),
|
||||||
/// iterate through each *T, up to the provided `len`,
|
/// iterate through each *T, up to the provided `len`,
|
||||||
/// passing to the provided callback function
|
/// 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|) {
|
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
|
||||||
if arr.is_null() {
|
if arr.is_null() {
|
||||||
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
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
|
/// This will only work with a null-terminated
|
||||||
/// pointer array.
|
/// pointer array.
|
||||||
|
#[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
|
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
|
||||||
if arr.is_null() {
|
if arr.is_null() {
|
||||||
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
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);
|
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
|
/// Methods on raw pointers
|
||||||
pub trait RawPtr<T> {
|
pub trait RawPtr<T> {
|
||||||
/// Returns the null pointer.
|
/// 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
|
// Equality for extern "C" fn pointers
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
mod externfnpointers {
|
mod externfnpointers {
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl<A: Clone> Clone for ~[A] {
|
||||||
try_finally(
|
try_finally(
|
||||||
&mut i, (),
|
&mut i, (),
|
||||||
|i, ()| while *i < len {
|
|i, ()| while *i < len {
|
||||||
mem::overwrite(
|
ptr::write(
|
||||||
&mut(*p.offset(*i as int)),
|
&mut(*p.offset(*i as int)),
|
||||||
self.unsafe_ref(*i).clone());
|
self.unsafe_ref(*i).clone());
|
||||||
*i += 1;
|
*i += 1;
|
||||||
|
|
|
@ -1093,7 +1093,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn init_elem(self, i: uint, val: T) {
|
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]
|
#[inline]
|
||||||
|
@ -1218,6 +1218,7 @@ pub mod bytes {
|
||||||
|
|
||||||
impl<'a> MutableByteVector for &'a mut [u8] {
|
impl<'a> MutableByteVector for &'a mut [u8] {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[allow(experimental)]
|
||||||
fn set_memory(self, value: u8) {
|
fn set_memory(self, value: u8) {
|
||||||
unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
|
unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue