yume_pdq/kernel/
type_traits.rs1use core::{
23 fmt::Debug,
24 marker::PhantomData,
25 ops::{BitAnd, BitOr, Mul},
26};
27
28#[allow(unused_imports)]
29use crate::alignment::AlignerTo;
30use generic_array::{
31 ArrayLength,
32 typenum::{B0, B1, Bit, UInt},
33};
34use kernel_sealing::KernelSealed;
35
36mod sealing {
37 pub trait Sealed {}
38}
39
40impl<U, B: Bit> sealing::Sealed for UInt<U, B> {}
41
42pub trait SquareOf: ArrayLength + sealing::Sealed {
46 type Output: ArrayLength;
48}
49
50include!(concat!(env!("OUT_DIR"), "/square_generic_array.rs"));
51
52pub trait DivisibleBy8: ArrayLength + sealing::Sealed
54where
55 <Self::Output as Mul<Self>>::Output: ArrayLength,
56{
57 type Output: ArrayLength + Mul<Self>;
59}
60
61impl<U: ArrayLength> DivisibleBy8 for UInt<UInt<UInt<U, B0>, B0>, B0>
62where
63 U: Mul<UInt<UInt<UInt<U, B0>, B0>, B0>>,
64 <U as Mul<UInt<UInt<UInt<U, B0>, B0>, B0>>>::Output: ArrayLength,
65{
66 type Output = U;
67}
68
69pub(crate) mod kernel_sealing {
70 pub trait KernelSealed {}
71}
72
73pub struct RequireCompilerTimeHardwareFeature<Cur, Next> {
75 _cur: PhantomData<Cur>,
76 _next: PhantomData<Next>,
77}
78
79impl<S: KernelSealed, N: KernelSealed> KernelSealed for RequireCompilerTimeHardwareFeature<S, N> {}
80
81pub struct FallbackRequirements<S: KernelSealed, N: KernelSealed> {
83 _preferred: PhantomData<S>,
84 _fallback: PhantomData<N>,
85}
86
87impl<S: KernelSealed, N: KernelSealed> KernelSealed for FallbackRequirements<S, N> {}
88
89pub trait EvaluateHardwareFeature: KernelSealed {
91 type EnabledStatic: Bit + BitOr<B0> + BitAnd<B1> + BitOr<B1> + BitAnd<B0>;
93 type MustCheck: Bit;
95 type Name: Debug + Clone + Copy + 'static + PartialEq;
97
98 fn name() -> Self::Name;
100
101 fn met_runtime() -> bool;
103}
104
105#[derive(Debug, Clone, Copy, PartialEq)]
106pub struct AndName<A, B>(A, B);
108
109impl<F: EvaluateHardwareFeature, N: EvaluateHardwareFeature> EvaluateHardwareFeature
110 for RequireCompilerTimeHardwareFeature<F, N>
111where
112 <F as EvaluateHardwareFeature>::EnabledStatic:
113 BitAnd<<N as EvaluateHardwareFeature>::EnabledStatic>,
114 <F::EnabledStatic as BitAnd<N::EnabledStatic>>::Output: Bit,
115 <F as EvaluateHardwareFeature>::MustCheck: BitOr<<N as EvaluateHardwareFeature>::MustCheck>,
116 <F::MustCheck as BitOr<N::MustCheck>>::Output: Bit,
117 <<F as EvaluateHardwareFeature>::EnabledStatic as BitAnd<
118 <N as EvaluateHardwareFeature>::EnabledStatic,
119 >>::Output: BitAnd<B0>,
120 <<F as EvaluateHardwareFeature>::EnabledStatic as BitAnd<
121 <N as EvaluateHardwareFeature>::EnabledStatic,
122 >>::Output: BitAnd<B0>,
123 <<F as EvaluateHardwareFeature>::EnabledStatic as BitAnd<
124 <N as EvaluateHardwareFeature>::EnabledStatic,
125 >>::Output: BitAnd<B0>,
126 <<F as EvaluateHardwareFeature>::EnabledStatic as BitAnd<
127 <N as EvaluateHardwareFeature>::EnabledStatic,
128 >>::Output: BitOr<B1>,
129 <<F as EvaluateHardwareFeature>::EnabledStatic as BitAnd<
130 <N as EvaluateHardwareFeature>::EnabledStatic,
131 >>::Output: BitAnd<B1>,
132 <<F as EvaluateHardwareFeature>::EnabledStatic as BitAnd<
133 <N as EvaluateHardwareFeature>::EnabledStatic,
134 >>::Output: BitOr<B0>,
135{
136 type Name = AndName<F::Name, N::Name>;
137 type EnabledStatic = <F::EnabledStatic as BitAnd<N::EnabledStatic>>::Output;
138 type MustCheck = <F::MustCheck as BitOr<N::MustCheck>>::Output;
139
140 fn name() -> Self::Name {
141 AndName(F::name(), N::name())
142 }
143
144 fn met_runtime() -> bool {
145 F::met_runtime() && N::met_runtime()
146 }
147}
148
149#[derive(Debug, Clone, Copy, PartialEq)]
150pub struct FallbackName<A, B>(A, B);
152
153impl<P: EvaluateHardwareFeature, F: EvaluateHardwareFeature<EnabledStatic = B1>>
154 EvaluateHardwareFeature for FallbackRequirements<P, F>
155{
156 type Name = FallbackName<P::Name, F::Name>;
157 type EnabledStatic = B1;
158 type MustCheck = B0;
159
160 fn name() -> Self::Name {
161 FallbackName(P::name(), F::name())
162 }
163
164 fn met_runtime() -> bool {
165 P::met_runtime()
166 }
167}
168
169impl EvaluateHardwareFeature for Term {
170 type Name = &'static str;
171 type EnabledStatic = B1;
172 type MustCheck = B0;
173
174 fn name() -> Self::Name {
175 "."
176 }
177
178 fn met_runtime() -> bool {
179 true
180 }
181}
182
183pub struct Term {
185 _private: (),
186}
187
188impl KernelSealed for Term {}
189
190#[cfg(test)]
191mod tests {
192 #![allow(dead_code, unused)]
193
194 use generic_array::typenum::{U7, U9, U56, U81};
195
196 use super::*;
197
198 type TestSquareOf9 = <U9 as SquareOf>::Output;
199 type ExpectedSquareOf9 = U81;
200 type Test56DivisibleBy8 = <U56 as DivisibleBy8>::Output;
201 type Expected56DivisibleBy8 = U7;
202 const ASSERT_SQUARE_OF_9_IS_U81: PhantomData<ExpectedSquareOf9> = PhantomData::<TestSquareOf9>;
203 const ASSERT_56_DIVISIBLE_BY_8_IS_U7: PhantomData<Expected56DivisibleBy8> =
204 PhantomData::<Test56DivisibleBy8>;
205}