const_type_layout/
typeset.rs1#[doc(hidden)]
5pub trait ComputeSet: sealed::ComputeSet {
6 const LEN: usize;
7
8 type Output<H: ComputeTypeSet>: ExpandTypeSet;
9
10 type TyHList: 'static + Copy + core::marker::Freeze;
11 const TYS: &'static Self::TyHList;
12}
13
14mod sealed {
15 pub trait ComputeSet {}
16
17 impl ComputeSet for super::private::Empty {}
18 impl<H2: super::ComputeTypeSet, T: ComputeSet> ComputeSet for super::private::Cons<H2, T> {}
19}
20
21type Set<H, T> = <T as ComputeSet>::Output<H>;
22
23pub unsafe trait ComputeTypeSet: crate::TypeLayout {
81 type Output<T: ExpandTypeSet>: ExpandTypeSet;
88}
89
90pub macro tset {
96 () => { private::Empty },
97 (.. @ $T:tt) => { $T },
98 ($H:ty $(, $R:ty)*) => {
99 Set<$H, tset![$($R),*]>
100 },
101 ($H:ty, $($R:ty,)* .. @ $T:ty ) => {
102 Set<$H, tset![$($R,)* .. @ $T]>
103 },
104}
105
106#[doc(hidden)]
107pub trait ExpandTypeSet: ComputeSet {
108 type Output<T: ExpandTypeSet>: ExpandTypeSet;
109}
110
111impl ExpandTypeSet for private::Empty {
112 type Output<T: ExpandTypeSet> = T;
113}
114
115impl<H: ComputeTypeSet, T: ExpandTypeSet> ExpandTypeSet for private::Cons<H, T> {
116 type Output<R: ExpandTypeSet> =
117 <T as ExpandTypeSet>::Output<Set<H, <H as ComputeTypeSet>::Output<R>>>;
118}
119
120#[doc(hidden)]
121pub trait TypeSetFixedPoint: ExpandTypeSet {
122 type Output: ExpandTypeSet;
123}
124
125impl<T: ExpandTypeSet> TypeSetFixedPoint for T {
126 type Output = <T as private::ComputeTypeSetFixedPoint<
127 <T as ExpandTypeSet>::Output<private::Empty>,
128 >>::Output;
129}
130
131mod private {
132 use super::{sealed, ComputeSet, ComputeTypeSet, ExpandTypeSet, Set};
133
134 #[repr(C)]
135 #[derive(Copy, Clone)]
136 pub struct Empty;
137
138 #[repr(C)]
139 #[derive(Copy, Clone)]
140 pub struct Cons<H, T> {
141 head: H,
142 tail: T,
143 }
144
145 impl ComputeSet for Empty {
146 type Output<H: ComputeTypeSet> = Cons<H, Self>;
147 type TyHList = Self;
148
149 const LEN: usize = 0;
150 const TYS: &'static Self::TyHList = &Self;
151 }
152
153 impl<H2: ComputeTypeSet, T: ExpandTypeSet> ComputeSet for Cons<H2, T> {
154 type Output<H1: ComputeTypeSet> = <Self as ComputeCons<H1>>::Output;
155 type TyHList = Cons<&'static crate::TypeLayoutInfo<'static>, T::TyHList>;
156
157 const LEN: usize = T::LEN + 1;
158 const TYS: &'static Self::TyHList = &Cons {
159 head: &H2::TYPE_LAYOUT,
160 tail: *T::TYS,
161 };
162 }
163
164 pub trait ComputeCons<H: ComputeTypeSet>: sealed::ComputeSet {
165 type Output: ExpandTypeSet;
166 }
167
168 impl<H: ComputeTypeSet> ComputeCons<H> for Empty {
169 type Output = Cons<H, Self>;
170 }
171
172 impl<H: ComputeTypeSet, T: ExpandTypeSet> ComputeCons<H> for Cons<H, T> {
173 type Output = Self;
174 }
175
176 impl<H1: ComputeTypeSet, H2: ComputeTypeSet, T: ExpandTypeSet> ComputeCons<H1> for Cons<H2, T> {
177 default type Output = Cons<H2, Set<H1, T>>;
178 }
179
180 pub trait ComputeTypeSetFixedPoint<E: ExpandTypeSet>: ExpandTypeSet {
181 type Output: ExpandTypeSet;
182 }
183
184 impl<T: ExpandTypeSet, E: ExpandTypeSet> ComputeTypeSetFixedPoint<E> for T {
185 default type Output = <E as ComputeTypeSetFixedPoint<<E as ExpandTypeSet>::Output<Empty>>>::Output;
186 }
187
188 trait True {}
189 struct Assert<const ASSERT: bool>;
190 impl True for Assert<true> {}
191
192 impl<T: ExpandTypeSet, E: ExpandTypeSet> ComputeTypeSetFixedPoint<E> for T
193 where
194 Assert<{ T::LEN == E::LEN }>: True,
195 {
196 type Output = T;
197 }
198}
199
200pub(super) type TypeSet<T> =
201 <Set<T, <T as ComputeTypeSet>::Output<private::Empty>> as TypeSetFixedPoint>::Output;