use crate::prelude_dev::*;
pub trait DeviceBaseAPI {
fn same_device(&self, other: &Self) -> bool;
fn default_order(&self) -> FlagOrder;
fn set_default_order(&mut self, order: FlagOrder);
}
pub trait DeviceRawAPI<T>: DeviceBaseAPI + Clone {
type Raw;
}
#[derive(Debug)]
pub struct Storage<R, T, B>
where
B: DeviceRawAPI<T>,
{
pub(crate) data: R,
pub(crate) device: B,
_phantom: PhantomData<T>,
}
pub trait DeviceStorageAPI<T>: DeviceRawAPI<T> {
fn len<R>(storage: &Storage<R, T, Self>) -> usize
where
R: DataAPI<Data = Self::Raw>;
fn is_empty<R>(storage: &Storage<R, T, Self>) -> bool
where
R: DataAPI<Data = Self::Raw>,
{
Self::len::<R>(storage) == 0
}
fn to_cpu_vec<R>(storage: &Storage<R, T, Self>) -> Result<Vec<T>>
where
Self::Raw: Clone,
R: DataAPI<Data = Self::Raw>;
fn into_cpu_vec<R>(storage: Storage<R, T, Self>) -> Result<Vec<T>>
where
Self::Raw: Clone,
R: DataCloneAPI<Data = Self::Raw>;
fn get_index<R>(storage: &Storage<R, T, Self>, index: usize) -> T
where
T: Clone,
R: DataAPI<Data = Self::Raw>;
fn get_index_ptr<R>(storage: &Storage<R, T, Self>, index: usize) -> *const T
where
R: DataAPI<Data = Self::Raw>;
fn get_index_mut_ptr<R>(storage: &mut Storage<R, T, Self>, index: usize) -> *mut T
where
R: DataMutAPI<Data = Self::Raw>;
fn set_index<R>(storage: &mut Storage<R, T, Self>, index: usize, value: T)
where
R: DataMutAPI<Data = Self::Raw>;
}
impl<R, T, B> Storage<R, T, B>
where
B: DeviceStorageAPI<T>,
R: DataAPI<Data = B::Raw>,
{
pub fn device(&self) -> &B {
&self.device
}
pub fn device_mut(&mut self) -> &mut B {
&mut self.device
}
pub fn data(&self) -> &R {
&self.data
}
pub fn data_mut(&mut self) -> &mut R {
&mut self.data
}
pub fn into_raw_parts(self) -> (R, B) {
(self.data, self.device)
}
pub fn new(data: R, device: B) -> Self {
Self { data, device, _phantom: PhantomData }
}
pub fn len(&self) -> usize {
B::len(self)
}
pub fn is_empty(&self) -> bool {
B::is_empty(self)
}
pub fn to_cpu_vec(&self) -> Result<Vec<T>>
where
B::Raw: Clone,
R: DataCloneAPI<Data = B::Raw>,
{
B::to_cpu_vec(self)
}
pub fn into_cpu_vec(self) -> Result<Vec<T>>
where
B::Raw: Clone,
R: DataCloneAPI<Data = B::Raw>,
{
B::into_cpu_vec(self)
}
#[inline]
pub fn get_index(&self, index: usize) -> T
where
T: Clone,
{
B::get_index(self, index)
}
#[inline]
pub fn get_index_ptr(&self, index: usize) -> *const T {
B::get_index_ptr(self, index)
}
#[inline]
pub fn get_index_mut_ptr(&mut self, index: usize) -> *mut T
where
R: DataMutAPI<Data = B::Raw>,
{
B::get_index_mut_ptr(self, index)
}
#[inline]
pub fn set_index(&mut self, index: usize, value: T)
where
R: DataMutAPI<Data = B::Raw>,
{
B::set_index(self, index, value)
}
}
impl<R, T, B> Storage<R, T, B>
where
R: DataAPI<Data = B::Raw>,
B: DeviceRawAPI<T>,
{
pub fn raw(&self) -> &B::Raw {
self.data.raw()
}
}
impl<R, T, B> Storage<R, T, B>
where
R: DataMutAPI<Data = B::Raw>,
B: DeviceRawAPI<T>,
{
pub fn raw_mut(&mut self) -> &mut B::Raw {
self.data.raw_mut()
}
}
pub trait DeviceAPI<T>: DeviceBaseAPI + DeviceRawAPI<T> + DeviceStorageAPI<T> + Clone + Default {}