1use crate::mem::CopyError;
2
3use super::{Backend, CpuBackend, GlobalBackend, HasBackend};
4
5pub trait CopyIntoBackend<Dst: Backend, Src: Backend>: HasBackend<Backend = Src> {
7 type Output: HasBackend<Backend = Dst>;
8 fn copy_into_backend(self, backend: &Dst) -> Result<Self::Output, CopyError>;
9}
10
11impl<T, A> CopyIntoBackend<A, A> for T
12where
13 A: Backend,
14 T: HasBackend<Backend = A> + Send + Sync,
15{
16 type Output = T;
17 fn copy_into_backend(self, _backend: &A) -> Result<Self::Output, CopyError> {
18 Ok(self)
19 }
20}
21
22pub trait CanCopyFrom<T, Src>: Backend
23where
24 Src: Backend,
25{
26 type Output;
27 fn copy_into(&self, value: T) -> Result<Self::Output, CopyError>;
28}
29
30pub trait CanCopyInto<T, Dst>: Backend
31where
32 Dst: Backend,
33{
34 type Output;
35 fn copy_to_dst(dst: &Dst, value: T) -> Result<Self::Output, CopyError>;
36}
37
38impl<T, Dst, A> CanCopyInto<T, Dst> for A
39where
40 A: Backend,
41 Dst: Backend,
42 T: HasBackend<Backend = Self>,
43 Dst: CanCopyFrom<T, Self>,
44{
45 type Output = <Dst as CanCopyFrom<T, Self>>::Output;
46 fn copy_to_dst(dst: &Dst, value: T) -> Result<Self::Output, CopyError> {
47 dst.copy_into(value)
48 }
49}
50
51impl<T, Src, A> CanCopyFrom<T, Src> for A
52where
53 A: Backend,
54 Src: Backend,
55 T: CopyIntoBackend<Self, Src>,
56{
57 type Output = T::Output;
58 fn copy_into(&self, value: T) -> Result<Self::Output, CopyError> {
59 value.copy_into_backend(self)
60 }
61}
62
63pub trait CanCopyFromRef<T, Src>: Backend
64where
65 Src: Backend,
66{
67 type Output;
68 fn copy_to(&self, value: &T) -> Result<Self::Output, CopyError>;
69}
70
71pub trait CanCopyIntoRef<T, Dst>: Backend
72where
73 Dst: Backend,
74{
75 type Output;
76 fn copy_to_dst(dst: &Dst, value: &T) -> Result<Self::Output, CopyError>;
77}
78
79impl<T, Dst, Src> CanCopyIntoRef<T, Dst> for Src
80where
81 Src: Backend,
82 Dst: Backend,
83 T: HasBackend<Backend = Self>,
84 Dst: CanCopyFromRef<T, Self>,
85{
86 type Output = <Dst as CanCopyFromRef<T, Self>>::Output;
87 fn copy_to_dst(dst: &Dst, value: &T) -> Result<Self::Output, CopyError> {
88 dst.copy_to(value)
89 }
90}
91
92impl<T, Src, A> CanCopyFromRef<T, Src> for A
93where
94 A: Backend,
95 Src: Backend,
96 T: CopyToBackend<Self, Src>,
97{
98 type Output = <T as CopyToBackend<Self, Src>>::Output;
99 fn copy_to(&self, value: &T) -> Result<Self::Output, CopyError> {
100 value.copy_to_backend(self)
101 }
102}
103
104pub trait CopyToBackend<Dst: Backend, Src: Backend>: HasBackend<Backend = Src> {
105 type Output: HasBackend<Backend = Dst>;
106 fn copy_to_backend(&self, backend: &Dst) -> Result<Self::Output, CopyError>;
107}
108
109impl<T: HasBackend<Backend = A> + Clone + Sync, A: Backend> CopyToBackend<A, A> for T {
110 type Output = T;
111 fn copy_to_backend(&self, _backend: &A) -> Result<Self::Output, CopyError> {
112 Ok(self.clone())
113 }
114}
115
116pub trait IntoGlobal<Dst: GlobalBackend>: HasBackend {
117 type Output;
118 fn into_global(self) -> Result<Self::Output, CopyError>;
119}
120
121impl<T, Dst: GlobalBackend> IntoGlobal<Dst> for T
122where
123 T: HasBackend,
124 T::Backend: CanCopyInto<T, Dst>,
125{
126 type Output = <T::Backend as CanCopyInto<T, Dst>>::Output;
127 #[inline]
128 fn into_global(self) -> Result<Self::Output, CopyError> {
129 <T::Backend as CanCopyInto<T, Dst>>::copy_to_dst(Dst::global(), self)
130 }
131}
132
133pub trait ToGlobal<Dst: GlobalBackend>: HasBackend {
134 type Output;
135 fn to_global(&self) -> Result<Self::Output, CopyError>;
136}
137
138impl<T, Dst: GlobalBackend> ToGlobal<Dst> for T
139where
140 T: HasBackend,
141 T::Backend: CanCopyIntoRef<T, Dst>,
142{
143 type Output = <T::Backend as CanCopyIntoRef<T, Dst>>::Output;
144 #[inline]
145 fn to_global(&self) -> Result<Self::Output, CopyError> {
146 <T::Backend as CanCopyIntoRef<T, Dst>>::copy_to_dst(Dst::global(), self)
147 }
148}
149
150pub trait IntoHost: IntoGlobal<CpuBackend> + Sized {
151 #[inline]
152 fn into_host(self) -> Result<Self::Output, CopyError> {
153 self.into_global()
154 }
155}
156
157impl<T> IntoHost for T where T: IntoGlobal<CpuBackend> {}
158
159pub trait ToHost: ToGlobal<CpuBackend> {
160 #[inline]
161 fn to_host(&self) -> Result<Self::Output, CopyError> {
162 self.to_global()
163 }
164}
165
166impl<T> ToHost for T where T: ToGlobal<CpuBackend> {}