use frunk::{hlist::HList, HCons, HNil};
use super::{element::LayoutElement, FlatLayout};
use crate::primitive_types::MaybeFlatType;
pub trait Sealed {}
pub trait Layout: Sealed + HList {
const ALIGNMENT: u32;
type Flat: FlatLayout;
fn flatten(self) -> Self::Flat;
}
impl Sealed for HNil {}
impl<Head, Tail> Sealed for HCons<Head, Tail>
where
Head: LayoutElement,
Tail: Layout,
{
}
impl Layout for HNil {
const ALIGNMENT: u32 = 1;
type Flat = HNil;
fn flatten(self) -> Self::Flat {
HNil
}
}
impl<Head, Tail> Layout for HCons<Head, Tail>
where
Head: LayoutElement,
Tail: Layout,
{
const ALIGNMENT: u32 = if Head::ALIGNMENT > Tail::ALIGNMENT {
Head::ALIGNMENT
} else {
Tail::ALIGNMENT
};
type Flat = <Head::Flat as MaybeFlatType>::Flatten<Tail>;
fn flatten(self) -> Self::Flat {
self.head.flatten().flatten(self.tail)
}
}