1use crate::{
2 bool::{Bool, False, True},
3 seal, Invalid,
4};
5
6#[derive(Default)]
8pub struct B0;
9#[derive(Default)]
11pub struct B1;
12
13impl seal::Sealed for B0 {}
14impl seal::Sealed for B1 {}
15
16pub trait Bit: seal::Sealed {
18 const USIZE: usize;
20 #[doc(hidden)]
21 type IsZero: Bool;
23 #[doc(hidden)]
24 type Not: Bit;
26 #[doc(hidden)]
27 type And<Rhs: Bit>: Bit;
29 #[doc(hidden)]
30 type Or<Rhs: Bit>: Bit;
32 #[doc(hidden)]
33 type Xor<Rhs: Bit>: Bit;
35
36 #[doc(hidden)]
37 type Add<Rhs: Bit>: Bit;
39 #[doc(hidden)]
40 type Carry<Rhs: Bit>: Bit;
42 #[doc(hidden)]
43 type FullAdd<Rhs: Bit, C: Bit>: Bit;
45 #[doc(hidden)]
46 type FullCarry<Rhs: Bit, C: Bit>: Bit;
48
49 #[doc(hidden)]
50 type Diff<Rhs: Bit>: Bit;
52 #[doc(hidden)]
53 type Borrow<Rhs: Bit>: Bit;
55 #[doc(hidden)]
56 type FullDiff<Rhs: Bit, B: Bit>: Bit;
58 #[doc(hidden)]
59 type FullBorrow<Rhs: Bit, B: Bit>: Bit;
61}
62
63pub type IsZero<B> = <B as Bit>::IsZero;
65pub type Not<B> = <B as Bit>::Not;
67pub type And<Lhs, Rhs> = <Lhs as Bit>::And<Rhs>;
69pub type Or<Lhs, Rhs> = <Lhs as Bit>::Or<Rhs>;
71pub type Xor<Lhs, Rhs> = <Lhs as Bit>::Xor<Rhs>;
73
74pub type Add<Lhs, Rhs> = <Lhs as Bit>::Add<Rhs>;
76pub type Carry<Lhs, Rhs> = <Lhs as Bit>::Carry<Rhs>;
78pub type FullAdd<Lhs, Rhs, C> = <Lhs as Bit>::FullAdd<Rhs, C>;
80pub type FullCarry<Lhs, Rhs, C> = <Lhs as Bit>::FullCarry<Rhs, C>;
82
83pub type Diff<Lhs, Rhs> = <Lhs as Bit>::Diff<Rhs>;
85pub type Borrow<Lhs, Rhs> = <Lhs as Bit>::Borrow<Rhs>;
87pub type FullDiff<Lhs, Rhs, C> = <Lhs as Bit>::FullDiff<Rhs, C>;
89pub type FullBorrow<Lhs, Rhs, C> = <Lhs as Bit>::FullBorrow<Rhs, C>;
91
92impl Bit for Invalid {
93 #[doc(hidden)]
94 const USIZE: usize = { panic!("Invlid Bit type value!") };
95
96 type IsZero = Invalid;
97
98 type Not = Invalid;
99
100 type And<Rhs: Bit> = Invalid;
101
102 type Or<Rhs: Bit> = Invalid;
103
104 type Xor<Rhs: Bit> = Invalid;
105
106 type Add<Rhs: Bit> = Invalid;
107
108 type Carry<Rhs: Bit> = Invalid;
109
110 type FullAdd<Rhs: Bit, C: Bit> = Invalid;
111
112 type FullCarry<Rhs: Bit, C: Bit> = Invalid;
113
114 type Diff<Rhs: Bit> = Invalid;
115
116 type Borrow<Rhs: Bit> = Invalid;
117
118 type FullDiff<Rhs: Bit, B: Bit> = Invalid;
119
120 type FullBorrow<Rhs: Bit, B: Bit> = Invalid;
121}
122
123impl Bit for B0 {
124 const USIZE: usize = 0;
125 type IsZero = True;
126 type Not = B1;
127 type And<Rhs: Bit> = B0;
128 type Or<Rhs: Bit> = Rhs;
129 type Xor<Rhs: Bit> = Rhs;
130
131 type Add<Rhs: Bit> = Rhs;
132 type Carry<Rhs: Bit> = B0;
133 type FullAdd<Rhs: Bit, C: Bit> = Rhs::Add<C>;
134 type FullCarry<Rhs: Bit, C: Bit> = Rhs::Carry<C>;
135
136 type Diff<Rhs: Bit> = Rhs;
137 type Borrow<Rhs: Bit> = Rhs;
138 type FullDiff<Rhs: Bit, B: Bit> = Rhs::Xor<B>;
139 type FullBorrow<Rhs: Bit, B: Bit> = Rhs::Or<B>;
140}
141
142impl Bit for B1 {
143 const USIZE: usize = 1;
144 type IsZero = False;
145 type Not = B0;
146 type And<Rhs: Bit> = B0;
147 type Or<Rhs: Bit> = Rhs;
148 type Xor<Rhs: Bit> = Rhs::Not;
149
150 type Add<Rhs: Bit> = Self::Xor<Rhs>;
151 type Carry<Rhs: Bit> = Self::And<Rhs>;
152 type FullAdd<Rhs: Bit, C: Bit> = <Self::Add<Rhs> as Bit>::Add<C>;
153
154 type FullCarry<Rhs: Bit, C: Bit> =
155 <<Self::Add<Rhs> as Bit>::Carry<C> as Bit>::Xor<Self::Carry<Rhs>>;
156
157 type Diff<Rhs: Bit> = Rhs::Not;
158 type Borrow<Rhs: Bit> = B0;
159 type FullDiff<Rhs: Bit, B: Bit> = <Self::Diff<Rhs> as Bit>::Diff<B>;
160 type FullBorrow<Rhs: Bit, B: Bit> =
161 <Self::Borrow<Rhs> as Bit>::Xor<<Self::Diff<Rhs> as Bit>::Borrow<B>>;
162}