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
xandymust be valid for both reads and writes ofcount * size_of::<T>()bytes. -
Both
xandymust be properly aligned. -
The region of memory beginning at
xwith a size ofcount * size_of::<T>()bytes must not overlap with the region of memory beginning atywith 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);
} }