Skip to main content

slop_alloc/backend/
io.rs

1use crate::mem::CopyError;
2
3use super::{Backend, CpuBackend, GlobalBackend, HasBackend};
4
5/// Copy data between different backends
6pub 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> {}