blob: 4b461d611375f506f8b0b10fa30031f6e61167b8 [file] [log] [blame] [view]
# Bit-wise `memcpy`
This copies bits from a region beginning at `src` into a region beginning at
`dst`, each extending upwards in the address space for `count` bits.
The two regions may overlap.
If the two regions are known to *never* overlap, then [`copy_nonoverlapping`][0]
can be used instead.
## Original
[`ptr::copy`](core::ptr::copy)
## Overlap Definition
`bitvec` defines region overlap only when the bit-pointers used to access them
have the same `O: BitOrder` type parameter. When this parameter differs, the
regions are always assumed to not overlap in real memory, because `bitvec` does
not define the effects of different orderings mapping to the same locations.
## Safety
In addition to the bit-ordering constraints, this inherits the restrictions of
the original `ptr::copy`:
- `src` must be valid to read the next `count` bits out of memory.
- `dst` must be valid to write into the next `count` bits.
- Both `src` and `dst` must satisfy [`BitPtr`]’s non-null, well-aligned,
requirements.
## Behavior
This reads and writes each bit individually. It is incapable of optimizing its
behavior to perform batched memory accesses that have better awareness of the
underlying memory.
The [`BitSlice::copy_from_bitslice`][1] method *is* able to perform this
optimization. You should always prefer to use `BitSlice` if you are sensitive to
performance.
## Examples
This example performs a simple copy across independent regions. You can see that
it follows the ordering parameter for the source and destination regions as it
walks each bit individually.
```rust
use bitvec::prelude::*;
use bitvec::ptr as bv_ptr;
let start = 0b1011u8;
let mut end = 0u16;
let src = BitPtr::<_, _, Lsb0>::from_ref(&start);
let dst = BitPtr::<_, _, Msb0>::from_mut(&mut end);
unsafe {
bv_ptr::copy(src, dst, 4);
}
assert_eq!(end, 0b1101_0000_0000_0000);
```
This can detect overlapping regions. Note again that overlap only exists when
the ordering parameter is the same! Using bit-pointers that overlap in real
memory with different ordering is not defined, and `bitvec` does not specify any
result.
```rust
use bitvec::prelude::*;
use bitvec::ptr as bv_ptr;
let mut x = 0b1111_0010u8;
let src = BitPtr::<_, _, Lsb0>::from_mut(&mut x);
let dst = unsafe { src.add(2) };
unsafe {
bv_ptr::copy(src.to_const(), dst, 4);
}
assert_eq!(x, 0b1100_1010);
// bottom nibble ^^ ^^ moved here
```
[`BitPtr`]: crate::ptr::BitPtr
[0]: crate::ptr::copy_nonoverlapping
[1]: crate::slice::BitSlice::copy_from_bitslice