use crate::dim::Dim;
use crate::mapping::{DenseMapping, FlatMapping, GeneralMapping, Mapping, StridedMapping};
pub trait Layout {
type NonUniform: Layout;
type NonUnitStrided: Layout;
type Uniform: Uniform;
type UnitStrided: UnitStrided;
type Layout<D: Dim, L: Layout>: Layout;
type Mapping<D: Dim>: Mapping<Dim = D, Layout = Self>;
const IS_UNIFORM: bool;
const IS_UNIT_STRIDED: bool;
}
pub trait Uniform: Layout<Uniform = Self> {}
pub trait UnitStrided: Layout<UnitStrided = Self> {}
pub struct Dense;
pub struct Flat;
pub struct General;
pub struct Strided;
impl Layout for Dense {
type NonUniform = General;
type NonUnitStrided = Flat;
type Uniform = Self;
type UnitStrided = Self;
type Layout<D: Dim, L: Layout> = D::Layout<L>;
type Mapping<D: Dim> = DenseMapping<D>;
const IS_UNIFORM: bool = true;
const IS_UNIT_STRIDED: bool = true;
}
impl Layout for Flat {
type NonUniform = Strided;
type NonUnitStrided = Self;
type Uniform = Self;
type UnitStrided = Dense;
type Layout<D: Dim, L: Layout> = D::Layout<L::NonUnitStrided>;
type Mapping<D: Dim> = FlatMapping<D>;
const IS_UNIFORM: bool = true;
const IS_UNIT_STRIDED: bool = false;
}
impl Layout for General {
type NonUniform = Self;
type NonUnitStrided = Strided;
type Uniform = Dense;
type UnitStrided = Self;
type Layout<D: Dim, L: Layout> = D::Layout<L::NonUniform>;
type Mapping<D: Dim> = GeneralMapping<D>;
const IS_UNIFORM: bool = false;
const IS_UNIT_STRIDED: bool = true;
}
impl Layout for Strided {
type NonUniform = Self;
type NonUnitStrided = Self;
type Uniform = Flat;
type UnitStrided = General;
type Layout<D: Dim, L: Layout> = D::Layout<Self>;
type Mapping<D: Dim> = StridedMapping<D>;
const IS_UNIFORM: bool = false;
const IS_UNIT_STRIDED: bool = false;
}
impl Uniform for Dense {}
impl Uniform for Flat {}
impl UnitStrided for Dense {}
impl UnitStrided for General {}