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.
This commit is contained in:
commit
f3a87a7f1f
@ -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 @@ impl<T> OwnedVector<T> for ~[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 @@ impl<T> OwnedVector<T> for ~[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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user