1use crate::EmplaceInitializer;
2use std::alloc::{alloc, AllocError, Allocator};
3use std::ptr::NonNull;
4
5pub trait EmplaceAllocator {
7 fn emplace<Init: EmplaceInitializer>(
8 &self,
9 init: Init,
10 ) -> Result<NonNull<Init::Output>, (AllocError, Init)>;
11}
12
13impl<T: Allocator> EmplaceAllocator for T {
14 #[inline(always)]
16 fn emplace<Init: EmplaceInitializer>(
17 &self,
18 mut init: Init,
19 ) -> Result<NonNull<Init::Output>, (AllocError, Init)> {
20 match self.allocate(init.layout()) {
21 Ok(mem) => Ok(init.emplace(mem.cast())),
22 Err(e) => Err((e, init)),
23 }
24 }
25}
26
27#[inline(always)]
29pub unsafe fn alloc_emplace<Init: EmplaceInitializer>(
30 mut init: Init,
31) -> Result<NonNull<Init::Output>, Init> {
32 let mem = alloc(init.layout());
33 let Some(mem) = NonNull::new(mem) else{
34 return Err(init);
35 };
36 Ok(init.emplace(mem))
37}