use std::fmt::Debug;
use std::mem;
use crate::base::allocator::{Allocator, SameShapeC, SameShapeR};
use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Dim, U1};
use crate::base::Scalar;
pub type SameShapeStorage<N, R1, C1, R2, C2> =
<DefaultAllocator as Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>>>::Buffer;
pub type Owned<N, R, C = U1> = <DefaultAllocator as Allocator<N, R, C>>::Buffer;
pub type RStride<N, R, C = U1> =
<<DefaultAllocator as Allocator<N, R, C>>::Buffer as Storage<N, R, C>>::RStride;
pub type CStride<N, R, C = U1> =
<<DefaultAllocator as Allocator<N, R, C>>::Buffer as Storage<N, R, C>>::CStride;
pub unsafe trait Storage<N: Scalar, R: Dim, C: Dim = U1>: Debug + Sized {
type RStride: Dim;
type CStride: Dim;
fn ptr(&self) -> *const N;
fn shape(&self) -> (R, C);
fn strides(&self) -> (Self::RStride, Self::CStride);
#[inline]
fn linear_index(&self, irow: usize, icol: usize) -> usize {
let (rstride, cstride) = self.strides();
irow * rstride.value() + icol * cstride.value()
}
#[inline]
unsafe fn get_address_unchecked_linear(&self, i: usize) -> *const N {
self.ptr().wrapping_add(i)
}
#[inline]
unsafe fn get_address_unchecked(&self, irow: usize, icol: usize) -> *const N {
self.get_address_unchecked_linear(self.linear_index(irow, icol))
}
#[inline]
unsafe fn get_unchecked_linear(&self, i: usize) -> &N {
&*self.get_address_unchecked_linear(i)
}
#[inline]
unsafe fn get_unchecked(&self, irow: usize, icol: usize) -> &N {
self.get_unchecked_linear(self.linear_index(irow, icol))
}
fn is_contiguous(&self) -> bool;
fn as_slice(&self) -> &[N];
fn into_owned(self) -> Owned<N, R, C>
where
DefaultAllocator: Allocator<N, R, C>;
fn clone_owned(&self) -> Owned<N, R, C>
where
DefaultAllocator: Allocator<N, R, C>;
}
pub unsafe trait StorageMut<N: Scalar, R: Dim, C: Dim = U1>: Storage<N, R, C> {
fn ptr_mut(&mut self) -> *mut N;
#[inline]
unsafe fn get_address_unchecked_linear_mut(&mut self, i: usize) -> *mut N {
self.ptr_mut().wrapping_add(i)
}
#[inline]
unsafe fn get_address_unchecked_mut(&mut self, irow: usize, icol: usize) -> *mut N {
let lid = self.linear_index(irow, icol);
self.get_address_unchecked_linear_mut(lid)
}
unsafe fn get_unchecked_linear_mut(&mut self, i: usize) -> &mut N {
&mut *self.get_address_unchecked_linear_mut(i)
}
#[inline]
unsafe fn get_unchecked_mut(&mut self, irow: usize, icol: usize) -> &mut N {
&mut *self.get_address_unchecked_mut(irow, icol)
}
#[inline]
unsafe fn swap_unchecked_linear(&mut self, i1: usize, i2: usize) {
let a = self.get_address_unchecked_linear_mut(i1);
let b = self.get_address_unchecked_linear_mut(i2);
mem::swap(&mut *a, &mut *b);
}
#[inline]
unsafe fn swap_unchecked(&mut self, row_col1: (usize, usize), row_col2: (usize, usize)) {
let lid1 = self.linear_index(row_col1.0, row_col1.1);
let lid2 = self.linear_index(row_col2.0, row_col2.1);
self.swap_unchecked_linear(lid1, lid2)
}
fn as_mut_slice(&mut self) -> &mut [N];
}
pub unsafe trait ContiguousStorage<N: Scalar, R: Dim, C: Dim = U1>:
Storage<N, R, C>
{
}
pub unsafe trait ContiguousStorageMut<N: Scalar, R: Dim, C: Dim = U1>:
ContiguousStorage<N, R, C> + StorageMut<N, R, C>
{
}
pub trait ReshapableStorage<N, R1, C1, R2, C2>: Storage<N, R1, C1>
where
N: Scalar,
R1: Dim,
C1: Dim,
R2: Dim,
C2: Dim,
{
type Output: Storage<N, R2, C2>;
fn reshape_generic(self, nrows: R2, ncols: C2) -> Self::Output;
}