speed up mem::swap
This commit is contained in:
parent
f84a517483
commit
4bcfbc36c6
1 changed files with 9 additions and 12 deletions
|
@ -109,7 +109,7 @@ pub use intrinsics::transmute;
|
||||||
/// [`Clone`][clone]. You need the value's destructor to run only once,
|
/// [`Clone`][clone]. You need the value's destructor to run only once,
|
||||||
/// because a double `free` is undefined behavior.
|
/// because a double `free` is undefined behavior.
|
||||||
///
|
///
|
||||||
/// An example is the definition of [`mem::swap`][swap] in this module:
|
/// An example is the (old) definition of [`mem::swap`][swap] in this module:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::mem;
|
/// use std::mem;
|
||||||
|
@ -447,18 +447,15 @@ pub unsafe fn uninitialized<T>() -> T {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn swap<T>(x: &mut T, y: &mut T) {
|
pub fn swap<T>(x: &mut T, y: &mut T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Give ourselves some scratch space to work with
|
let x = x as *mut T as *mut u8;
|
||||||
let mut t: T = uninitialized();
|
let y = y as *mut T as *mut u8;
|
||||||
|
|
||||||
// Perform the swap, `&mut` pointers never alias
|
// use an xor-swap as x & y are guaranteed to never alias
|
||||||
ptr::copy_nonoverlapping(&*x, &mut t, 1);
|
for i in 0..size_of::<T>() as isize {
|
||||||
ptr::copy_nonoverlapping(&*y, x, 1);
|
*x.offset(i) ^= *y.offset(i);
|
||||||
ptr::copy_nonoverlapping(&t, y, 1);
|
*y.offset(i) ^= *x.offset(i);
|
||||||
|
*x.offset(i) ^= *y.offset(i);
|
||||||
// y and t now point to the same thing, but we need to completely
|
}
|
||||||
// forget `t` because we do not want to run the destructor for `T`
|
|
||||||
// on its value, which is still owned somewhere outside this function.
|
|
||||||
forget(t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue