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> {}