提交 f3a87a7f 编写于 作者: B bors

auto merge of #12143 : brson/rust/swap, r=alexcrichton

Thinking about swap as an example of unsafe programming. This cleans it up a bit. It also removes type parametrization over `RawPtr` from the memcpy functions to make this compile.
......@@ -10,7 +10,6 @@
//! Unsafe casting functions
use ptr::RawPtr;
use mem;
use unstable::intrinsics;
use ptr::copy_nonoverlapping_memory;
......@@ -72,13 +71,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {
/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_mut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *mut T {
pub unsafe fn transmute_mut_unsafe<T>(ptr: *T) -> *mut T {
transmute(ptr)
}
/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_immut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *T {
pub unsafe fn transmute_immut_unsafe<T>(ptr: *mut T) -> *T {
transmute(ptr)
}
......
......@@ -92,8 +92,8 @@ pub fn is_not_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_not_null() }
* and destination may overlap.
*/
#[inline]
pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
intrinsics::copy_memory(dst, cast::transmute_immut_unsafe(src), count)
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
intrinsics::copy_memory(dst, src, count)
}
/**
......@@ -103,10 +103,10 @@ pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
* and destination may *not* overlap.
*/
#[inline]
pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
src: P,
count: uint) {
intrinsics::copy_nonoverlapping_memory(dst, cast::transmute_immut_unsafe(src), count)
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
src: *T,
count: uint) {
intrinsics::copy_nonoverlapping_memory(dst, src, count)
}
/**
......@@ -137,9 +137,9 @@ pub unsafe fn swap_ptr<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_memory(t, &*x, 1);
copy_memory(x, &*y, 1); // `x` and `y` may overlap
copy_nonoverlapping_memory(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.
......
......@@ -26,19 +26,16 @@ pub fn id<T>(x: T) -> T { x }
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
// Give ourselves some scratch space to work with
let mut tmp: T = mem::uninit();
let t: *mut T = &mut tmp;
let mut t: T = mem::uninit();
// Perform the swap, `&mut` pointers never alias
let x_raw: *mut T = x;
let y_raw: *mut T = y;
ptr::copy_nonoverlapping_memory(t, x_raw, 1);
ptr::copy_nonoverlapping_memory(x, y_raw, 1);
ptr::copy_nonoverlapping_memory(y, t, 1);
ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
ptr::copy_nonoverlapping_memory(x, &*y, 1);
ptr::copy_nonoverlapping_memory(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.
cast::forget(tmp);
cast::forget(t);
}
}
......
......@@ -1548,7 +1548,7 @@ fn insert(&mut self, i: uint, x: T) {
let p = self.as_mut_ptr().offset(i as int);
// Shift everything over to make space. (Duplicating the
// `i`th element into two consecutive places.)
ptr::copy_memory(p.offset(1), p, len - i);
ptr::copy_memory(p.offset(1), &*p, len - i);
// Write it in, overwriting the first copy of the `i`th
// element.
mem::move_val_init(&mut *p, x);
......@@ -1567,7 +1567,7 @@ fn remove(&mut self, i: uint) -> Option<T> {
let ret = Some(ptr::read_ptr(ptr as *T));
// Shift everything down to fill in that spot.
ptr::copy_memory(ptr, ptr.offset(1), len - i - 1);
ptr::copy_memory(ptr, &*ptr.offset(1), len - i - 1);
self.set_len(len - 1);
ret
......@@ -1842,7 +1842,7 @@ fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
if i != j {
let tmp = ptr::read_ptr(read_ptr);
ptr::copy_memory(buf_v.offset(j + 1),
buf_v.offset(j),
&*buf_v.offset(j),
(i - j) as uint);
ptr::copy_nonoverlapping_memory(buf_v.offset(j),
&tmp as *T,
......@@ -1920,7 +1920,7 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
// that case, `i == j` so we don't copy. The
// `.offset(j)` is always in bounds.
ptr::copy_memory(buf_dat.offset(j + 1),
buf_dat.offset(j),
&*buf_dat.offset(j),
i - j as uint);
ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1);
}
......@@ -1970,11 +1970,11 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
if left == right_start {
// the number remaining in this run.
let elems = (right_end as uint - right as uint) / mem::size_of::<T>();
ptr::copy_nonoverlapping_memory(out, right, elems);
ptr::copy_nonoverlapping_memory(out, &*right, elems);
break;
} else if right == right_end {
let elems = (right_start as uint - left as uint) / mem::size_of::<T>();
ptr::copy_nonoverlapping_memory(out, left, elems);
ptr::copy_nonoverlapping_memory(out, &*left, elems);
break;
}
......@@ -1988,7 +1988,7 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
} else {
step(&mut left)
};
ptr::copy_nonoverlapping_memory(out, to_copy, 1);
ptr::copy_nonoverlapping_memory(out, &*to_copy, 1);
step(&mut out);
}
}
......@@ -2002,7 +2002,7 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
// write the result to `v` in one go, so that there are never two copies
// of the same object in `v`.
unsafe {
ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), buf_dat, len);
ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len);
}
// increment the pointer, returning the old pointer.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册