Skip to main content

slop_alloc/
init.rs

1use std::{
2    alloc::Layout,
3    marker::PhantomData,
4    mem::MaybeUninit,
5    ops::{Deref, DerefMut},
6};
7
8use crate::{backend::CpuBackend, mem::CopyDirection, Allocator, Backend};
9
10#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
11#[repr(transparent)]
12pub struct Init<T, A = CpuBackend> {
13    inner: T,
14    _marker: PhantomData<A>,
15}
16
17impl<T, A: Allocator> Init<T, A> {
18    #[inline]
19    pub const fn as_ptr(&self) -> *const T {
20        &self.inner
21    }
22
23    #[inline]
24    pub fn as_mut_ptr(&mut self) -> *mut T {
25        &mut self.inner
26    }
27
28    pub fn copy_into_host(&self, alloc: &A) -> T
29    where
30        A: Backend,
31        T: Copy,
32    {
33        let mut value = MaybeUninit::<T>::uninit();
34        let layout = Layout::new::<T>();
35        unsafe {
36            alloc
37                .copy_nonoverlapping(
38                    self.as_ptr() as *const u8,
39                    value.as_mut_ptr() as *mut u8,
40                    layout.size(),
41                    CopyDirection::DeviceToHost,
42                )
43                .unwrap();
44
45            value.assume_init()
46        }
47    }
48}
49
50impl<T> Deref for Init<T, CpuBackend> {
51    type Target = T;
52
53    #[inline]
54    fn deref(&self) -> &Self::Target {
55        &self.inner
56    }
57}
58
59impl<T> DerefMut for Init<T, CpuBackend> {
60    #[inline]
61    fn deref_mut(&mut self) -> &mut Self::Target {
62        &mut self.inner
63    }
64}
65
66impl<T: Clone> Clone for Init<T, CpuBackend> {
67    fn clone(&self) -> Self {
68        Self { inner: self.inner.clone(), _marker: PhantomData }
69    }
70}
71
72impl<T: Copy> Copy for Init<T, CpuBackend> {}