memapi2/data/
misc_traits.rs

1use {
2    crate::data::{marker::UnsizedCopy, type_props::PtrProps},
3    core::ptr::{self, NonNull}
4};
5
6/// A trait for copying unsized types to uninitialized memory.
7pub trait CopyToUninit: UnsizedCopy {
8    /// Copies `self` to an uninitialized portion of possibly overlapping memory.
9    ///
10    /// # Safety
11    ///
12    /// The caller must ensure `dst` is:
13    /// - valid for writes for <code>self.[sz](PtrProps::sz)()</code> bytes.
14    /// - properly aligned to <code>self.[aln](PtrProps::aln)()</code>.
15    /// - uninitialized, or its data doesn't need to be dropped.
16    unsafe fn copy_to(&self, dst: NonNull<u8>) {
17        assume!(u_pre
18                crate::helpers::ptr_max_align(dst) >= self.aln(),
19                "`CopyToUninit::copy_to` requires that `dst` is properly aligned."
20        );
21
22        ptr::copy((self as *const Self).cast::<u8>(), dst.as_ptr(), self.sz());
23    }
24
25    /// Copies `self` to an uninitialized portion of non-overlapping memory.
26    ///
27    /// # Safety
28    ///
29    /// The caller must ensure `dst`:
30    /// - is valid for writes for <code>self.[sz](PtrProps::sz)()</code> bytes.
31    /// - is properly aligned to <code>self.[aln](PtrProps::aln)()</code>.
32    /// - is uninitialized, or its data doesn't need to be dropped.
33    /// - doesn't overlap with `self`.
34    #[allow(unknown_lints, clippy::ptr_as_ptr, clippy::borrow_as_ptr)]
35    unsafe fn copy_to_nonoverlapping(&self, dst: NonNull<u8>) {
36        assume!(u_pre
37            crate::helpers::ptr_max_align(dst) >= self.aln(),
38            "`CopyToUninit::copy_to_nonoverlapping` requires that `dst` is properly aligned."
39        );
40        let sz = self.sz();
41        assume!(u_pre
42            crate::helpers::check_ptr_overlap(*(&self as *const _ as *const NonNull<u8>), dst, sz),
43            "`CopyToUninit::copy_to_nonoverlapping` requires that `self` doesn't overlap with \
44            `dst`."
45        );
46
47        ptr::copy_nonoverlapping((self as *const Self).cast::<u8>(), dst.as_ptr(), sz);
48    }
49}
50
51impl<T: ?Sized + UnsizedCopy> CopyToUninit for T {}