dst_init/
alloc.rs

1use crate::EmplaceInitializer;
2use std::alloc::{alloc, AllocError, Allocator};
3use std::ptr::NonNull;
4
5/// Extension for allocators to support `emplace(initializer)` method
6pub 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    /// Allocate memory for value and emplace in it.
15    #[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/// Allocate memory for value by `std::alloc::alloc` and emplace in it.
28#[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}