pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize)
Expand description
Swaps count * size_of::<T>()
bytes between the two regions of memory
beginning at x
and y
. The two regions must not overlap.
The operation is “untyped” in the sense that data may be uninitialized or otherwise violate the
requirements of T
. The initialization state is preserved exactly.
§Safety
Behavior is undefined if any of the following conditions are violated:
-
Both
x
andy
must be valid for both reads and writes ofcount * size_of::<T>()
bytes. -
Both
x
andy
must be properly aligned. -
The region of memory beginning at
x
with a size ofcount * size_of::<T>()
bytes must not overlap with the region of memory beginning aty
with the same size.
Note that even if the effectively copied size (count * size_of::<T>()
) is 0
,
the pointers must be properly aligned.
§Examples
Basic usage:
use std::ptr;
let mut x = [1, 2, 3, 4];
let mut y = [7, 8, 9];
unsafe {
ptr::swap_nonoverlapping(x.as_mut_ptr(), y.as_mut_ptr(), 2);
}
assert_eq!(x, [7, 8, 3, 4]);
assert_eq!(y, [1, 2, 9]);
§Const evaluation limitations
If this function is invoked during const-evaluation, the current implementation has a small (and
rarely relevant) limitation: if count
is at least 2 and the data pointed to by x
or y
contains a pointer that crosses the boundary of two T
-sized chunks of memory, the function may
fail to evaluate (similar to a panic during const-evaluation). This behavior may change in the
future.
The limitation is illustrated by the following example:
use std::mem::size_of;
use std::ptr;
const { unsafe {
const PTR_SIZE: usize = size_of::<*const i32>();
let mut data1 = [0u8; PTR_SIZE];
let mut data2 = [0u8; PTR_SIZE];
// Store a pointer in `data1`.
data1.as_mut_ptr().cast::<*const i32>().write_unaligned(&42);
// Swap the contents of `data1` and `data2` by swapping `PTR_SIZE` many `u8`-sized chunks.
// This call will fail, because the pointer in `data1` crosses the boundary
// between several of the 1-byte chunks that are being swapped here.
//ptr::swap_nonoverlapping(data1.as_mut_ptr(), data2.as_mut_ptr(), PTR_SIZE);
// Swap the contents of `data1` and `data2` by swapping a single chunk of size
// `[u8; PTR_SIZE]`. That works, as there is no pointer crossing the boundary between
// two chunks.
ptr::swap_nonoverlapping(&mut data1, &mut data2, 1);
// Read the pointer from `data2` and dereference it.
let ptr = data2.as_ptr().cast::<*const i32>().read_unaligned();
assert!(*ptr == 42);
} }