memconstruct/lib.rs
1pub mod alloc;
2
3mod array;
4mod primitive;
5
6pub use memconstruct_macros::MemConstruct;
7
8pub use alloc::construct_box;
9
10use std::mem::MaybeUninit;
11
12pub unsafe trait MemConstruct {
13 type Constructor: MemConstructConstructor<Target = Self>;
14 type ConstructorFinishedToken;
15
16 #[doc(hidden)]
17 fn new_boxed_zst() -> Box<Self>
18 where
19 Self: Sized,
20 {
21 unreachable!("Only zsts should implement this function")
22 }
23}
24
25/// A type used to construct a heap constructable object.
26///
27/// This trait is unsafe to implement and shouldn't be manually implemented. A safe implementation
28/// of this is generated when you derive `MemConstruct` for your type.
29////
30/// # Implementation for Structs:
31/// For normal structs a `set` function is generated for every field, each of these `set` functions
32/// has to be called exactly once, this is checked via typestate.
33///
34/// # Implementation for ZSTs:
35/// For `ZSTs` the generated constructor has no functions and is always "ready". The construct
36/// functions will still be called for ZSTs.
37pub unsafe trait MemConstructConstructor {
38 type Target;
39
40 /// Create a new `MemConstructConstructor`
41 ///
42 /// # Safety
43 ///
44 /// The pointer has to be a valid, non dangling pointer. The pointer must be well
45 /// aligned and non null if not documented otherwise.
46 unsafe fn new(ptr: *mut Self::Target) -> Self;
47}
48
49pub unsafe fn init_ptr<
50 T: MemConstruct,
51 F: FnOnce(T::Constructor) -> T::ConstructorFinishedToken,
52>(
53 ptr: *mut T,
54 func: F,
55) {
56 func(T::Constructor::new(ptr));
57}
58
59pub fn init_maybe_uninit<
60 T: MemConstruct,
61 F: FnOnce(T::Constructor) -> T::ConstructorFinishedToken,
62>(
63 uninit: &mut MaybeUninit<T>,
64 func: F,
65) {
66 unsafe { init_ptr(uninit.as_mut_ptr(), func) }
67}
68