1use ::core::alloc::Layout;
11use ::core::mem;
12use ::core::ptr::{self, NonNull};
13
14pub use allocator_api2::alloc::{AllocError, Allocator, Global};
15
16#[cfg(feature = "alloc")]
17pub use allocator_api2::{boxed, collections, vec};
18
19pub trait TryCloneIn: Sized {
21 type Target<A: Allocator + Clone>;
23
24 fn try_clone_in<A: Allocator + Clone>(&self, alloc: A) -> Result<Self::Target<A>, AllocError>;
26}
27
28pub fn allocate<T, A>(value: T, alloc: &A) -> Result<NonNull<T>, AllocError>
38where
39 A: Allocator,
40{
41 let layout = Layout::for_value(&value);
42 let ptr: NonNull<T> = alloc.allocate(layout)?.cast();
43
44 unsafe { ptr.cast::<mem::MaybeUninit<T>>().as_mut().write(value) };
47
48 Ok(ptr)
49}
50#[inline(always)]
55pub(crate) const fn dangling_for_layout(layout: &Layout) -> NonNull<u8> {
56 unsafe {
57 let ptr = ptr::null_mut::<u8>().byte_add(layout.align());
58 NonNull::new_unchecked(ptr)
59 }
60}
61
62#[cfg(feature = "alloc")]
63mod impls {
64 use allocator_api2::boxed::Box;
65
66 use super::*;
67
68 impl<T, OA> TryCloneIn for Box<T, OA>
69 where
70 T: TryCloneIn,
71 OA: Allocator,
72 {
73 type Target<A: Allocator + Clone> = Box<<T as TryCloneIn>::Target<A>, A>;
74
75 fn try_clone_in<A: Allocator + Clone>(
76 &self,
77 alloc: A,
78 ) -> Result<Self::Target<A>, AllocError> {
79 let x = self.as_ref().try_clone_in(alloc.clone())?;
80 Box::try_new_in(x, alloc)
81 }
82 }
83}