1pub mod typenames {
17 use super::{UInt, UTerm, B0, B1};
18 include!(concat!(env!("OUT_DIR"), "/unsigned.rs"));
19}
20use stabby_macros::tyeval;
21use typenames::*;
22
23use crate::{
24 istable::{IBitMask, IForbiddenValues, ISaturatingAdd, ISingleForbiddenValue, Saturator},
25 Array, End, IStable, Tuple,
26};
27#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
29pub struct UTerm;
30#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
34pub struct UInt<Msbs: IUnsignedBase, Bit: IBit>(Msbs, Bit);
35
36#[repr(transparent)]
38#[derive(Debug, Default, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
39pub struct PadByte(u8);
40unsafe impl IStable for PadByte {
42 type Size = U1;
44 type Align = U1;
46 type ForbiddenValues = End;
48 type UnusedBits = Array<U0, UxFF, End>;
50 type HasExactlyOneNiche = B0;
52 type ContainsIndirections = B0;
53 #[cfg(feature = "experimental-ctypes")]
54 type CType = u8;
55 primitive_report!("PadByte");
56}
57
58pub trait IBitBase {
60 const _BOOL: bool;
62 type _And<T: IBit>: IBit;
64 type _Or<T: IBit>: IBit;
66 type _Not: IBit;
68 type _Ternary<A, B>;
70 type _UTernary<A: IUnsigned, B: IUnsigned>: IUnsigned;
72 type _NzTernary<A: NonZero, B: NonZero>: NonZero;
74 type _BTernary<A: IBit, B: IBit>: IBit;
76 type _BmTernary<A: IBitMask, B: IBitMask>: IBitMask;
78 type _PTernary<A: IPowerOf2, B: IPowerOf2>: IPowerOf2;
80 type _FvTernary<A: IForbiddenValues, B: IForbiddenValues>: IForbiddenValues;
82 type _SfvTernary<A: ISingleForbiddenValue, B: ISingleForbiddenValue>: ISingleForbiddenValue;
84 type _SaddTernary<A: ISaturatingAdd, B: ISaturatingAdd>: ISaturatingAdd;
86 type _StabTernary<A: IStable, B: IStable>: IStable;
88 type _ATernary<A: Alignment, B: Alignment>: Alignment;
90 type AsForbiddenValue: ISingleForbiddenValue;
92 type _Padding: IStable<Align = U1> + Default + Copy + Unpin;
94}
95#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
97pub struct B0;
98impl IBitBase for B0 {
99 const _BOOL: bool = false;
100 type _And<T: IBit> = Self;
101 type _Or<T: IBit> = T;
102 type _Not = B1;
103 type _Ternary<A, B> = B;
104 type _UTernary<A: IUnsigned, B: IUnsigned> = B;
105 type _NzTernary<A: NonZero, B: NonZero> = B;
106 type _BTernary<A: IBit, B: IBit> = B;
107 type _BmTernary<A: IBitMask, B: IBitMask> = B;
108 type _PTernary<A: IPowerOf2, B: IPowerOf2> = B;
109 type _FvTernary<A: IForbiddenValues, B: IForbiddenValues> = B;
110 type _SfvTernary<A: ISingleForbiddenValue, B: ISingleForbiddenValue> = B;
111 type _SaddTernary<A: ISaturatingAdd, B: ISaturatingAdd> = B;
112 type _StabTernary<A: IStable, B: IStable> = B;
113 type _ATernary<A: Alignment, B: Alignment> = B;
114 type _Padding = ();
115 type AsForbiddenValue = Saturator;
116}
117#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
119pub struct B1;
120impl IBitBase for B1 {
121 const _BOOL: bool = true;
122 type _And<T: IBit> = T;
123 type _Or<T: IBit> = Self;
124 type _Not = B0;
125 type _Ternary<A, B> = A;
126 type _UTernary<A: IUnsigned, B: IUnsigned> = A;
127 type _NzTernary<A: NonZero, B: NonZero> = A;
128 type _BTernary<A: IBit, B: IBit> = A;
129 type _BmTernary<A: IBitMask, B: IBitMask> = A;
130 type _PTernary<A: IPowerOf2, B: IPowerOf2> = A;
131 type _FvTernary<A: IForbiddenValues, B: IForbiddenValues> = A;
132 type _SfvTernary<A: ISingleForbiddenValue, B: ISingleForbiddenValue> = A;
133 type _SaddTernary<A: ISaturatingAdd, B: ISaturatingAdd> = A;
134 type _StabTernary<A: IStable, B: IStable> = A;
135 type _ATernary<A: Alignment, B: Alignment> = A;
136 type _Padding = PadByte;
137 type AsForbiddenValue = End;
138}
139#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
141pub struct Bool<const B: bool>;
142macro_rules! same_as_bitbase {
143 ($src: ty) => {
144 const _BOOL: bool = <$src as IBitBase>::_BOOL;
145 type _And<T: IBit> = <$src as IBitBase>::_And<T>;
146 type _Or<T: IBit> = <$src as IBitBase>::_Or<T>;
147 type _Not = <$src as IBitBase>::_Not;
148 type _Ternary<A, B> = <$src as IBitBase>::_Ternary<A, B>;
149 type _UTernary<A: IUnsigned, B: IUnsigned> = <$src as IBitBase>::_UTernary<A, B>;
150 type _NzTernary<A: NonZero, B: NonZero> = <$src as IBitBase>::_NzTernary<A, B>;
151 type _BTernary<A: IBit, B: IBit> = <$src as IBitBase>::_BTernary<A, B>;
152 type _BmTernary<A: IBitMask, B: IBitMask> = <$src as IBitBase>::_BmTernary<A, B>;
153 type _PTernary<A: IPowerOf2, B: IPowerOf2> = <$src as IBitBase>::_PTernary<A, B>;
154 type _FvTernary<A: IForbiddenValues, B: IForbiddenValues> =
155 <$src as IBitBase>::_FvTernary<A, B>;
156 type _SfvTernary<A: ISingleForbiddenValue, B: ISingleForbiddenValue> =
157 <$src as IBitBase>::_SfvTernary<A, B>;
158 type _SaddTernary<A: ISaturatingAdd, B: ISaturatingAdd> =
159 <$src as IBitBase>::_SaddTernary<A, B>;
160 type _StabTernary<A: IStable, B: IStable> = <$src as IBitBase>::_StabTernary<A, B>;
161 type _ATernary<A: Alignment, B: Alignment> = <$src as IBitBase>::_ATernary<A, B>;
162 type _Padding = <$src as IBitBase>::_Padding;
163 type AsForbiddenValue = <$src as IBitBase>::AsForbiddenValue;
164 };
165}
166impl IBitBase for Bool<false> {
167 same_as_bitbase!(B0);
168}
169impl IBitBase for Bool<true> {
170 same_as_bitbase!(B1);
171}
172pub trait IBit: IBitBase {
174 const BOOL: bool;
176 type And<T: IBit>: IBit + Sized;
178 type Or<T: IBit>: IBit + Sized;
180 type Not: IBit + Sized;
182 type Ternary<A, B>;
184 type UTernary<A: IUnsigned + Sized, B: IUnsigned + Sized>: IUnsigned + Sized;
186 type NzTernary<A: NonZero, B: NonZero>: NonZero + Sized;
188 type BTernary<A: IBit, B: IBit>: IBit + Sized;
190 type BmTernary<A: IBitMask, B: IBitMask>: IBitMask + Sized;
192 type PTernary<A: IPowerOf2, B: IPowerOf2>: IPowerOf2 + Sized;
194 type FvTernary<A: IForbiddenValues, B: IForbiddenValues>: IForbiddenValues;
196 type SaddTernary<A: ISaturatingAdd, B: ISaturatingAdd>: ISaturatingAdd;
198 type StabTernary<A: IStable, B: IStable>: IStable;
200 type Nand<T: IBit>: IBit + Sized;
202 type Xor<T: IBit>: IBit + Sized;
204 type Equals<T: IBit>: IBit + Sized;
206 type AdderSum<Rhs: IBit, Carry: IBit>: IBit + Sized;
208 type AdderCarry<Rhs: IBit, Carry: IBit>: IBit + Sized;
210 type SuberSum<Rhs: IBit, Carry: IBit>: IBit + Sized;
212 type SuberCarry<Rhs: IBit, Carry: IBit>: IBit + Sized;
214}
215impl<Bit: IBitBase> IBit for Bit {
216 const BOOL: bool = Self::_BOOL;
217 type And<T: IBit> = Self::_And<T>;
218 type Or<T: IBit> = Self::_Or<T>;
219 type Not = Self::_Not;
220 type Ternary<A, B> = Self::_Ternary<A, B>;
221 type UTernary<A: IUnsigned, B: IUnsigned> = Self::_UTernary<A, B>;
222 type NzTernary<A: NonZero, B: NonZero> = Self::_NzTernary<A, B>;
223 type BTernary<A: IBit, B: IBit> = Self::_BTernary<A, B>;
224 type BmTernary<A: IBitMask, B: IBitMask> = Self::_BmTernary<A, B>;
225 type PTernary<A: IPowerOf2, B: IPowerOf2> = Self::_PTernary<A, B>;
226 type FvTernary<A: IForbiddenValues, B: IForbiddenValues> = Self::_FvTernary<A, B>;
227 type SaddTernary<A: ISaturatingAdd, B: ISaturatingAdd> = Self::_SaddTernary<A, B>;
228 type StabTernary<A: IStable, B: IStable> = Self::_StabTernary<A, B>;
229 type Nand<T: IBit> = <Self::_And<T> as IBitBase>::_Not;
230 type Xor<T: IBit> = <Self::_And<T::_Not> as IBitBase>::_Or<T::_And<Self::_Not>>;
231 type Equals<T: IBit> = <Self::Xor<T> as IBitBase>::_Not;
232 type AdderSum<Rhs: IBit, Carry: IBit> = <Self::Xor<Rhs> as IBit>::Xor<Carry>;
233 type AdderCarry<Rhs: IBit, Carry: IBit> =
234 <Rhs::_And<Carry> as IBitBase>::_Or<Self::_And<Rhs::Xor<Carry>>>;
235 type SuberSum<Rhs: IBit, Carry: IBit> = Self::AdderSum<Rhs, Carry>;
236 type SuberCarry<Rhs: IBit, Carry: IBit> =
237 <<Self::_Not as IBitBase>::_And<Rhs::_Or<Carry>> as IBitBase>::_Or<
238 Self::_And<Rhs::_And<Carry>>,
239 >;
240}
241pub trait IUnsignedBase {
243 const _U128: u128;
245 type Bit: IBitBase;
247 type Msb: IUnsigned;
249 type _BitAndInner<T: IUnsigned>: IUnsigned;
251 type _IsUTerm: IBit;
253 type _BitOrInner<T: IUnsigned>: IUnsigned;
255 type _Simplified: IUnsigned;
257 type _Equals<T: IUnsigned>: IBit;
259 type _Add<T: IUnsigned, Carry: IBit>: IUnsigned;
261 type _Sub<T: IUnsigned, Carry: IBit>: IUnsigned;
263 type _Greater<T: IUnsigned, Hint: IBit>: IBit;
265 type _Truncate<T: IUnsigned>: IUnsigned;
267 type NextPow2: IUnsigned;
269 type Increment: IUnsigned;
271 type _Padding: IStable<Align = U1> + Default + Copy + Unpin;
273 type _SatDecrement: IUnsigned;
275 type _TruncateAtRightmostOne: NonZero;
277 type _NonZero: NonZero;
279 type _Mul<T: IUnsigned>: IUnsigned;
281 type PaddingBitMask: IBitMask;
283 type _AddToArray<LsbArray: IStable, ArrayStack: IStable>: IStable;
285 type Array<T: IStable>: IStable;
287}
288pub struct Lesser;
290pub struct Equal;
292pub struct Greater;
294
295pub trait IUnsigned: IUnsignedBase {
297 const U128: u128;
299 const USIZE: usize;
301 const U64: u64;
303 const U32: u32;
305 const U16: u16;
307 const U8: u8;
309 type BitAnd<T: IUnsigned>: IUnsigned;
311 type BitOr<T: IUnsigned>: IUnsigned;
313 type Equal<T: IUnsigned>: IBit;
315 type NotEqual<T: IUnsigned>: IBit;
317 type Greater<T: IUnsigned>: IBit;
319 type GreaterOrEq<T: IUnsigned>: IBit;
321 type Smaller<T: IUnsigned>: IBit;
323 type SmallerOrEq<T: IUnsigned>: IBit;
325 type Add<T: IUnsigned>: IUnsigned;
327 type AbsSub<T: IUnsigned>: IUnsigned;
329 type Min<T: IUnsigned>: IUnsigned;
331 type Max<T: IUnsigned>: IUnsigned;
333 type Truncate<T: IUnsigned>: IUnsigned;
335 type Mod<T: IPowerOf2>: IUnsigned;
337 type Padding: IStable<Align = U1> + Sized + Default + Copy + Unpin;
339 type NonZero: NonZero;
341 type NextMultipleOf<T: IPowerOf2>: IUnsigned;
343 type Cmp<T: IUnsigned>;
345 type Mul<T: IUnsigned>: IUnsigned;
347}
348
349pub trait IPowerOf2: IUnsigned {
351 type Log2: IUnsigned;
353 type Min<T: IPowerOf2>: IPowerOf2;
355 type Max<T: IPowerOf2>: IPowerOf2;
357 type Modulate<T: IUnsigned>: IUnsigned;
359 type Divide<T: IUnsigned>: IUnsigned;
361}
362impl<U: IUnsignedBase> IUnsigned for U {
363 const U128: u128 = Self::_U128;
364 const USIZE: usize = Self::_U128 as usize;
365 const U64: u64 = Self::_U128 as u64;
366 const U32: u32 = Self::_U128 as u32;
367 const U16: u16 = Self::_U128 as u16;
368 const U8: u8 = Self::_U128 as u8;
369 type BitAnd<T: IUnsigned> = <Self::_BitAndInner<T> as IUnsignedBase>::_Simplified;
370 type BitOr<T: IUnsigned> = <Self::_BitOrInner<T> as IUnsignedBase>::_Simplified;
371 type Equal<T: IUnsigned> = Self::_Equals<T>;
372 type NotEqual<T: IUnsigned> = <Self::Equal<T> as IBit>::Not;
373 type Greater<T: IUnsigned> = Self::_Greater<T, B0>;
374 type GreaterOrEq<T: IUnsigned> = <Self::Greater<T> as IBit>::Or<Self::Equal<T>>;
375 type SmallerOrEq<T: IUnsigned> = <Self::Greater<T> as IBit>::Not;
376 type Smaller<T: IUnsigned> = <Self::GreaterOrEq<T> as IBit>::Not;
377 type Add<T: IUnsigned> = Self::_Add<T, B0>;
378 type AbsSub<T: IUnsigned> = <<Self::Greater<T> as IBit>::UTernary<
379 Self::_Sub<T, B0>,
380 T::_Sub<Self, B0>,
381 > as IUnsignedBase>::_Simplified;
382 type Min<T: IUnsigned> = <Self::Greater<T> as IBit>::UTernary<T, Self>;
383 type Max<T: IUnsigned> = <Self::Greater<T> as IBit>::UTernary<Self, T>;
384 type Truncate<T: IUnsigned> = <Self::_Truncate<T> as IUnsignedBase>::_Simplified;
385 type Mod<T: IPowerOf2> = T::Modulate<Self>;
386 type Padding = Self::_Padding;
387 type NonZero = Self::_NonZero;
388 type NextMultipleOf<T: IPowerOf2> =
389 tyeval!(((Self % T) == U0) ? Self : (Self + (T - (Self % T))));
390 type Cmp<T: IUnsigned> = <Self::Equal<T> as IBit>::Ternary<
391 Equal,
392 <Self::Greater<T> as IBit>::Ternary<Greater, Lesser>,
393 >;
394 type Mul<T: IUnsigned> = Self::_Mul<T>;
395}
396impl IUnsignedBase for UTerm {
397 const _U128: u128 = 0;
398 type Bit = B0;
399 type Msb = UTerm;
400 type _IsUTerm = B1;
401 type _BitAndInner<T: IUnsignedBase> = UTerm;
402 type _BitOrInner<T: IUnsigned> = T;
403 type _Simplified = UTerm;
404 type _Equals<T: IUnsigned> = T::_IsUTerm;
405 type Increment = U1;
406 type _Add<T: IUnsigned, Carry: IBit> = Carry::UTernary<T::Increment, T>;
407 type _Greater<T: IUnsigned, Hint: IBit> = Hint::And<T::_IsUTerm>;
408 type _Sub<T: IUnsigned, Carry: IBit> = UTerm;
409 type _Truncate<T: IUnsigned> = UTerm;
410 type _Padding = ();
411 type _SatDecrement = U0;
412 type NextPow2 = U0;
413 type _TruncateAtRightmostOne = Saturator;
414 type _NonZero = Saturator;
415 type _Mul<T: IUnsigned> = UTerm;
416 type PaddingBitMask = End;
417 type _AddToArray<LsbArray: IStable, ArrayStack: IStable> = LsbArray;
418 type Array<T: IStable> = ();
419}
420impl IUnsignedBase for Saturator {
421 #[cfg(not(doc))]
422 const _U128: u128 = { panic!("Attempted to convert Saturator into u128") };
423 #[cfg(doc)]
424 const _U128: u128 = u128::MAX;
425 type Bit = B0;
426 type Msb = Saturator;
427 type _IsUTerm = B1;
428 type _BitAndInner<T: IUnsignedBase> = Saturator;
429 type _BitOrInner<T: IUnsigned> = Saturator;
430 type _Simplified = Saturator;
431 type _Equals<T: IUnsigned> = T::_IsUTerm;
432 type Increment = Saturator;
433 type _Add<T: IUnsigned, Carry: IBit> = Carry::UTernary<T::Increment, T>;
434 type _Greater<T: IUnsigned, Hint: IBit> = Hint::And<T::_IsUTerm>;
435 type _Sub<T: IUnsigned, Carry: IBit> = Saturator;
436 type _Truncate<T: IUnsigned> = Saturator;
437 type _Padding = ();
438 type _SatDecrement = Saturator;
439 type NextPow2 = Saturator;
440 type _TruncateAtRightmostOne = Saturator;
441 type _NonZero = Saturator;
442 type _Mul<T: IUnsigned> = Saturator;
443 type PaddingBitMask = End;
444 type _AddToArray<LsbArray: IStable, ArrayStack: IStable> = ();
445 type Array<T: IStable> = ();
446}
447
448pub trait NonZero: IUnsigned {
450 type Decrement: IUnsigned;
452 type TruncateAtRightmostOne: IUnsigned;
454}
455impl NonZero for Saturator {
456 type Decrement = Saturator;
457 type TruncateAtRightmostOne = Saturator;
458}
459#[repr(C)]
461#[derive(Default, Clone, Copy)]
462pub struct OneMoreByte<L: IStable<Align = U1> + Copy + Default> {
463 l: L,
464 r: PadByte,
465}
466unsafe impl<L: IStable<Align = U1> + Copy + Default> IStable for OneMoreByte<L> {
468 type Size = <L::Size as IUnsignedBase>::Increment;
470 type Align = U1;
472 type ForbiddenValues = L::ForbiddenValues;
474 type UnusedBits = <L::UnusedBits as IBitMask>::BitOr<Array<L::Size, UxFF, End>>;
476 type HasExactlyOneNiche = L::HasExactlyOneNiche;
478 type ContainsIndirections = L::ContainsIndirections;
480 #[cfg(feature = "experimental-ctypes")]
481 type CType = Tuple<L, u8>;
482 primitive_report!("OneMoreByte");
483}
484impl<Msb: IUnsigned, Bit: IBit> NonZero for UInt<Msb, Bit> {
485 type Decrement =
486 <Bit::UTernary<UInt<Msb, B0>, UInt<Msb::_SatDecrement, B1>> as IUnsignedBase>::_Simplified;
487 type TruncateAtRightmostOne = Self::_TruncateAtRightmostOne;
488}
489#[repr(C)]
491pub struct PaddingHelper<Double: IStable<Align = U1>, Bit: IBitBase>(Double, Double, Bit::_Padding);
492impl<Double: IStable<Align = U1> + Default, Bit: IBitBase> Default for PaddingHelper<Double, Bit> {
493 fn default() -> Self {
494 Self(Default::default(), Default::default(), Default::default())
495 }
496}
497impl<Double: IStable<Align = U1> + Copy, Bit: IBitBase> Copy for PaddingHelper<Double, Bit> {}
498impl<Double: IStable<Align = U1> + Copy, Bit: IBitBase> Clone for PaddingHelper<Double, Bit> {
499 fn clone(&self) -> Self {
500 *self
501 }
502}
503unsafe impl<Double: IStable<Align = U1>, Bit: IBitBase> IStable for PaddingHelper<Double, Bit> {
504 type Align = U1;
505 type Size = <<U2 as IUnsigned>::Mul<Double::Size> as IUnsigned>::Add<Bit::_UTernary<U1, U0>>;
506 type ForbiddenValues = End;
507 type ContainsIndirections = B0;
508 type HasExactlyOneNiche = B0;
509 type UnusedBits = <crate::tuple::Tuple3<Double, Double, Bit::_Padding> as IStable>::UnusedBits;
510 #[cfg(feature = "experimental-ctypes")]
511 type CType = crate::tuple::Tuple3<Double, Double, Bit::_Padding>;
512 primitive_report!("Padding");
513}
514impl<Msb: IUnsigned, Bit: IBit> IUnsignedBase for UInt<Msb, Bit> {
515 const _U128: u128 = (Msb::_U128 << 1) | (<Self::Bit as IBit>::BOOL as u128);
516 type Bit = Bit;
517 type Msb = Msb;
518 type _IsUTerm = <Bit::Not as IBit>::And<Msb::_IsUTerm>;
519 type _Simplified = <Self::_IsUTerm as IBit>::UTernary<UTerm, UInt<Msb::_Simplified, Bit>>;
520 type _BitAndInner<T: IUnsigned> = UInt<Msb::_BitAndInner<T::Msb>, Bit::And<T::Bit>>;
521 type _BitOrInner<T: IUnsigned> = UInt<Msb::_BitOrInner<T::Msb>, Bit::Or<T::Bit>>;
522 type _Equals<T: IUnsigned> = <Bit::Equals<T::Bit> as IBit>::And<Msb::Equal<T::Msb>>;
523 type _Greater<T: IUnsigned, Hint: IBit> =
524 Msb::_Greater<T::Msb, <T::Bit as IBit>::BTernary<Hint::And<Bit>, Hint::Or<Bit>>>;
525 type Increment = Self::_Add<UTerm, B1>;
526 type _Add<T: IUnsigned, Carry: IBit> =
527 UInt<Msb::_Add<T::Msb, Bit::AdderCarry<T::Bit, Carry>>, Bit::AdderSum<T::Bit, Carry>>;
528 type _Sub<T: IUnsigned, Carry: IBit> =
529 UInt<Msb::_Sub<T::Msb, Bit::SuberCarry<T::Bit, Carry>>, Bit::SuberSum<T::Bit, Carry>>;
530 type _Truncate<T: IUnsigned> =
531 <T::_IsUTerm as IBit>::UTernary<UTerm, UInt<Msb::_Truncate<T::AbsSub<U1>>, Bit>>;
532 type _SatDecrement =
533 <Bit::UTernary<UInt<Msb, B0>, UInt<Msb::_SatDecrement, B1>> as IUnsignedBase>::_Simplified;
534 type _Padding = PaddingHelper<Msb::Padding, Bit>;
535 type NextPow2 = <Msb::NextPow2 as IUnsigned>::Add<<Self::_IsUTerm as IBit>::UTernary<U0, U1>>;
536 type _TruncateAtRightmostOne = Bit::NzTernary<U1, UInt<Msb::_TruncateAtRightmostOne, B0>>;
537 type _NonZero = Self;
538 type _Mul<T: IUnsigned> = <Bit::UTernary<T, UTerm> as IUnsigned>::Add<
539 <UInt<Msb::Mul<T>, B0> as IUnsignedBase>::_Simplified,
540 >;
541 type PaddingBitMask = Array<
542 U0,
543 U255,
544 <<Self::_SatDecrement as IUnsignedBase>::PaddingBitMask as IBitMask>::Shift<U1>,
545 >;
546 type _AddToArray<LsbArray: IStable, ArrayStack: IStable> = Msb::_AddToArray<
547 Bit::StabTernary<
548 <<LsbArray::Size as IUnsignedBase>::_IsUTerm as IBit>::StabTernary<
549 ArrayStack,
550 Tuple<ArrayStack, LsbArray>,
551 >,
552 LsbArray,
553 >,
554 Tuple<ArrayStack, ArrayStack>,
555 >;
556 type Array<T: IStable> = Self::_AddToArray<(), T>;
557}
558impl<Msb: IUnsigned<_IsUTerm = B1>> IPowerOf2 for UInt<Msb, B1> {
559 type Log2 = U0;
560 type Min<T: IPowerOf2> = <Self::Greater<T> as IBit>::PTernary<T, Self>;
561 type Max<T: IPowerOf2> = <Self::Greater<T> as IBit>::PTernary<Self, T>;
562 type Modulate<T: IUnsigned> = UTerm;
563 type Divide<T: IUnsigned> = T;
564}
565impl<Msb: IPowerOf2> IPowerOf2 for UInt<Msb, B0> {
566 type Log2 = <Msb::Log2 as IUnsignedBase>::Increment;
567 type Min<T: IPowerOf2> = <Self::Greater<T> as IBit>::PTernary<T, Self>;
568 type Max<T: IPowerOf2> = <Self::Greater<T> as IBit>::PTernary<Self, T>;
569 type Modulate<T: IUnsigned> =
570 <UInt<Msb::Modulate<T::Msb>, T::Bit> as IUnsignedBase>::_Simplified;
571 type Divide<T: IUnsigned> = Msb::Divide<T::Msb>;
572}
573
574pub trait Alignment: IPowerOf2 {
576 type Max<T: Alignment>: Alignment;
578 type AsUint: Copy + Default + IStable;
580}
581impl Alignment for U1 {
582 type Max<T: Alignment> = <Self::Greater<T> as IBitBase>::_ATernary<Self, T>;
583 type AsUint = u8;
584}
585impl Alignment for U2 {
586 type Max<T: Alignment> = <Self::Greater<T> as IBitBase>::_ATernary<Self, T>;
587 type AsUint = u16;
588}
589impl Alignment for U4 {
590 type Max<T: Alignment> = <Self::Greater<T> as IBitBase>::_ATernary<Self, T>;
591 type AsUint = u32;
592}
593impl Alignment for U8 {
594 type Max<T: Alignment> = <Self::Greater<T> as IBitBase>::_ATernary<Self, T>;
595 type AsUint = u64;
596}
597impl Alignment for U16 {
598 type Max<T: Alignment> = <Self::Greater<T> as IBitBase>::_ATernary<Self, T>;
599 type AsUint = u128;
600}
601macro_rules! gen_align {
602 ($n: literal, $path: ident, $u: ident, $backing: ty) => {
603 #[crate::stabby]
607 #[repr(align($n))]
608 #[derive(Debug, Default, Copy, Clone)]
609 pub struct $path(pub $backing);
610 impl Alignment for $u {
611 type Max<T: Alignment> = <Self::Greater<T> as IBitBase>::_ATernary<Self, T>;
612 type AsUint = $path;
613 }
614 };
615}
616gen_align!(32, Align32, U32, [u8; 32]);
617gen_align!(64, Align64, U64, [[u8; 32]; 2]);
618gen_align!(128, Align128, U128, [[u8; 32]; 4]);
619gen_align!(256, Align256, U256, [[u8; 32]; 8]);
620gen_align!(512, Align512, U512, [[u8; 32]; 16]);
621gen_align!(1024, Align1024, U1024, [[u8; 32]; 32]);
622gen_align!(2048, Align2048, U2048, [[[u8; 32]; 32]; 2]);
623gen_align!(4096, Align4096, U4096, [[[u8; 32]; 32]; 4]);
624gen_align!(8192, Align8192, U8192, [[[u8; 32]; 32]; 8]);
625gen_align!(16384, Align16384, U16384, [[[u8; 32]; 32]; 16]);
626gen_align!(32768, Align32768, U32768, [[[u8; 32]; 32]; 32]);
627gen_align!(65536, Align65536, U65536, [[[[u8; 32]; 32]; 32]; 2]);
628
629#[allow(unknown_lints)]
630#[allow(clippy::missing_transmute_annotations)]
631#[test]
632fn ops() {
633 fn test_pair<A: IUnsigned, B: IUnsigned>() {
634 assert_eq!(
635 <A::BitAnd<B> as IUnsigned>::U128,
636 A::U128 & B::U128,
637 "{} & {} ({} & {})",
638 A::U128,
639 B::U128,
640 core::any::type_name::<A>(),
641 core::any::type_name::<B>(),
642 );
643 assert_eq!(
644 <A::BitOr<B> as IUnsigned>::U128,
645 A::U128 | B::U128,
646 "{} | {} ({} | {})",
647 A::U128,
648 B::U128,
649 core::any::type_name::<A>(),
650 core::any::type_name::<B>(),
651 );
652 assert_eq!(
653 <A::Add<B> as IUnsigned>::U128,
654 A::U128 + B::U128,
655 "{} + {} ({} + {})",
656 A::U128,
657 B::U128,
658 core::any::type_name::<A>(),
659 core::any::type_name::<B>(),
660 );
661
662 let mask = if B::U32 == 0 {
663 0
664 } else {
665 u128::MAX.wrapping_shr(128 - B::U32)
666 };
667 assert_eq!(
668 <A::_Truncate<B> as IUnsigned>::U128,
669 A::U128 & mask,
670 "{} trunc {} ({mask:x}) ({} trunc {})",
671 A::U128,
672 B::U128,
673 core::any::type_name::<A>(),
674 core::any::type_name::<B>(),
675 );
676 assert_eq!(
677 <A::Greater<B> as IBitBase>::_BOOL,
678 A::U128 > B::U128,
679 "{} > {}",
680 A::U128,
681 B::U128,
682 );
683 assert_eq!(
684 <A::Smaller<B> as IBitBase>::_BOOL,
685 A::U128 < B::U128,
686 "{} < {}",
687 A::U128,
688 B::U128,
689 );
690 assert_eq!(
691 <A::Equal<B> as IBitBase>::_BOOL,
692 A::U128 == B::U128,
693 "{} == {}",
694 A::U128,
695 B::U128,
696 );
697 assert_eq!(
698 <A::Max<B> as IUnsigned>::U128,
699 A::U128.max(B::U128),
700 "{} max {}",
701 A::U128,
702 B::U128,
703 );
704 assert_eq!(
705 <A::Min<B> as IUnsigned>::U128,
706 A::U128.min(B::U128),
707 "{} min {}",
708 A::U128,
709 B::U128,
710 );
711 assert_eq!(
712 <A::AbsSub<B> as IUnsigned>::U128,
713 A::U128.abs_diff(B::U128),
714 "|{} - {}| (|{} - {}|)",
715 A::U128,
716 B::U128,
717 core::any::type_name::<A>(),
718 core::any::type_name::<B>(),
719 );
720 assert_eq!(
721 <A::NextPow2 as IUnsigned>::U32,
722 128 - A::U128.leading_zeros(),
723 "nextpow2 {}",
724 A::U128,
725 );
726 }
727 test_pair::<U0, U0>();
728 test_pair::<U0, U1>();
729 test_pair::<U1, U0>();
730 test_pair::<U1, U1>();
731 test_pair::<U1, U2>();
732 test_pair::<U2, U2>();
733 test_pair::<U3, U1>();
734 test_pair::<U4, U1>();
735 test_pair::<U2, U1>();
736 test_pair::<U4, U2>();
737 test_pair::<U4, U3>();
738 test_pair::<U4, U4>();
739 test_pair::<U4, U5>();
740 test_pair::<U5, U1>();
741 test_pair::<U1, U5>();
742 test_pair::<U5, U4>();
743 test_pair::<U2, U3>();
744 test_pair::<U3, U2>();
745 test_pair::<U10, U0>();
746 test_pair::<U10, U5>();
747 test_pair::<U10, U4>();
748 let _: <U0 as IUnsigned>::BitOr<U1> = <<U1 as IUnsigned>::BitOr<U0>>::default();
749 let _: B0 = <<U0 as IUnsigned>::NotEqual<U0>>::default();
750 let _: B1 = <<U1 as IUnsigned>::NotEqual<U0>>::default();
751 let _: B1 = <<U2 as IUnsigned>::NotEqual<U0>>::default();
752 let _: B1 = <<U3 as IUnsigned>::NotEqual<U0>>::default();
753 let _: B1 = <<U4 as IUnsigned>::NotEqual<U0>>::default();
754 let _: U2 = <<U10 as IUnsigned>::BitAnd<U6>>::default();
755 let _: B1 = <<U2 as IUnsigned>::Equal<<U10 as IUnsigned>::BitAnd<U6>>>::default();
756 let _: B0 = <<U3 as IUnsigned>::Equal<<U10 as IUnsigned>::BitAnd<U6>>>::default();
757 let _: U11 = <<U16 as IPowerOf2>::Modulate<U11>>::default();
758 let _: U11 = <<U11 as IUnsigned>::Mod<U16>>::default();
759 let _: U10 = <<U10 as IUnsigned>::Mod<U16>>::default();
760 let _: U3 = <<U11 as IUnsigned>::Mod<U8>>::default();
761 let _: U2 = <<U10 as IUnsigned>::Mod<U8>>::default();
762 let _: U3 = <<U11 as IUnsigned>::Mod<U4>>::default();
763 let _: U2 = <<U10 as IUnsigned>::Mod<U4>>::default();
764 let _: U1 = <<U11 as IUnsigned>::Mod<U2>>::default();
765 let _: U0 = <<U10 as IUnsigned>::Mod<U2>>::default();
766 let _: U0 = <<U10 as IUnsigned>::Mod<U1>>::default();
767 let _: U255 = UxFF::default();
768 let _: Ub111100 = <<Ub11111100 as IUnsigned>::BitAnd<Ub111111>>::default();
769 let _: U0 = <<U0 as IUnsigned>::NextMultipleOf<U8>>::default();
770 let _: U16 = <<U10 as IUnsigned>::NextMultipleOf<U8>>::default();
771 let _: U16 = <<U16 as IUnsigned>::NextMultipleOf<U8>>::default();
772 let _: U32 = <<U26 as IUnsigned>::NextMultipleOf<U8>>::default();
773 let _: U32 = <<U26 as IUnsigned>::NextMultipleOf<U32>>::default();
774 assert_eq!(U0::_U128, 0);
775 assert_eq!(U1::_U128, 1);
776 assert_eq!(U2::_U128, 2);
777 assert_eq!(U3::_U128, 3);
778 assert_eq!(U4::_U128, 4);
779 assert_eq!(U5::_U128, 5);
780 assert_eq!(U10::_U128, 10);
781 unsafe { core::mem::transmute::<_, <U22 as IUnsignedBase>::Array<u8>>([0u8; 22]) };
783 unsafe { core::mem::transmute::<_, <U122 as IUnsignedBase>::Array<u16>>([0u16; 122]) };
785 unsafe { core::mem::transmute::<[u8; 0], <U0 as IUnsignedBase>::Array<u8>>([]) };
787}