11pub use ctutils:: Choice as ConstChoice ;
2- use subtle:: CtOption ;
3-
4- use crate :: {
5- Int , Limb , NonZero , NonZeroInt , Odd , OddInt , Uint ,
6- modular:: { ConstMontyForm , ConstMontyParams , SafeGcdInverter } ,
7- } ;
2+ pub use ctutils:: CtOption as ConstCtOption ;
83
94/// `const` equivalent of `u32::max(a, b)`.
105pub const fn u32_max ( a : u32 , b : u32 ) -> u32 {
@@ -16,272 +11,6 @@ pub const fn u32_min(a: u32, b: u32) -> u32 {
1611 ConstChoice :: from_u32_lt ( a, b) . select_u32 ( b, a)
1712}
1813
19- /// An equivalent of `subtle::CtOption` usable in a `const fn` context.
20- #[ derive( Debug , Clone ) ]
21- pub struct ConstCtOption < T > {
22- value : T ,
23- is_some : ConstChoice ,
24- }
25-
26- impl < T > ConstCtOption < T > {
27- #[ inline]
28- pub ( crate ) const fn new ( value : T , is_some : ConstChoice ) -> Self {
29- Self { value, is_some }
30- }
31-
32- #[ inline]
33- pub ( crate ) const fn some ( value : T ) -> Self {
34- Self {
35- value,
36- is_some : ConstChoice :: TRUE ,
37- }
38- }
39-
40- #[ inline]
41- pub ( crate ) const fn none ( dummy_value : T ) -> Self {
42- Self {
43- value : dummy_value,
44- is_some : ConstChoice :: FALSE ,
45- }
46- }
47-
48- /// Returns a reference to the contents of this structure.
49- ///
50- /// **Note:** if the second element is `None`, the first value may take any value.
51- #[ inline]
52- pub ( crate ) const fn components_ref ( & self ) -> ( & T , ConstChoice ) {
53- // Since Rust is not smart enough to tell that we would be moving the value,
54- // and hence no destructors will be called, we have to return a reference instead.
55- // See https://github.com/rust-lang/rust/issues/66753
56- ( & self . value , self . is_some )
57- }
58-
59- /// Returns a true [`ConstChoice`] if this value is `Some`.
60- #[ inline]
61- pub const fn is_some ( & self ) -> ConstChoice {
62- self . is_some
63- }
64-
65- /// Returns a true [`ConstChoice`] if this value is `None`.
66- #[ inline]
67- pub const fn is_none ( & self ) -> ConstChoice {
68- self . is_some . not ( )
69- }
70-
71- /// This returns the underlying value but panics if it is not `Some`.
72- #[ inline]
73- #[ track_caller]
74- pub fn unwrap ( self ) -> T {
75- assert ! (
76- self . is_some. to_bool_vartime( ) ,
77- "called `ConstCtOption::unwrap()` on a `None` value"
78- ) ;
79- self . value
80- }
81-
82- /// Apply an additional [`ConstChoice`] requirement to `is_some`.
83- #[ inline]
84- pub ( crate ) const fn and_choice ( mut self , is_some : ConstChoice ) -> Self {
85- self . is_some = self . is_some . and ( is_some) ;
86- self
87- }
88- }
89-
90- impl < T > From < ConstCtOption < T > > for CtOption < T > {
91- #[ inline]
92- fn from ( value : ConstCtOption < T > ) -> Self {
93- CtOption :: new ( value. value , value. is_some . into ( ) )
94- }
95- }
96-
97- impl < T > From < ConstCtOption < T > > for Option < T > {
98- #[ inline]
99- fn from ( value : ConstCtOption < T > ) -> Self {
100- if value. is_some . into ( ) {
101- Some ( value. value )
102- } else {
103- None
104- }
105- }
106- }
107-
108- // Need specific implementations to work around the
109- // "destructors cannot be evaluated at compile-time" error
110- // See https://github.com/rust-lang/rust/issues/66753
111-
112- impl < const LIMBS : usize > ConstCtOption < Uint < LIMBS > > {
113- /// This returns the underlying value if it is `Some` or the provided value otherwise.
114- #[ inline]
115- pub const fn unwrap_or ( self , def : Uint < LIMBS > ) -> Uint < LIMBS > {
116- Uint :: select ( & def, & self . value , self . is_some )
117- }
118-
119- /// Returns the contained value, consuming the `self` value.
120- ///
121- /// # Panics
122- ///
123- /// Panics if the value is none with a custom panic message provided by
124- /// `msg`.
125- #[ inline]
126- #[ track_caller]
127- pub const fn expect ( self , msg : & str ) -> Uint < LIMBS > {
128- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
129- self . value
130- }
131-
132- /// Returns the contained value, interpreting the underlying [`Uint`] value as an [`Int`].
133- #[ inline]
134- pub const fn as_int ( & self ) -> ConstCtOption < Int < LIMBS > > {
135- ConstCtOption :: new ( * self . value . as_int ( ) , self . is_some )
136- }
137- }
138-
139- impl < const LIMBS : usize > ConstCtOption < ( Uint < LIMBS > , Uint < LIMBS > ) > {
140- /// Returns the contained value, consuming the `self` value.
141- ///
142- /// # Panics
143- ///
144- /// Panics if the value is none with a custom panic message provided by
145- /// `msg`.
146- #[ inline]
147- #[ track_caller]
148- pub const fn expect ( self , msg : & str ) -> ( Uint < LIMBS > , Uint < LIMBS > ) {
149- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
150- self . value
151- }
152- }
153-
154- impl < const LIMBS : usize > ConstCtOption < NonZero < Uint < LIMBS > > > {
155- /// Returns the contained value, consuming the `self` value.
156- ///
157- /// # Panics
158- ///
159- /// Panics if the value is none with a custom panic message provided by
160- /// `msg`.
161- #[ inline]
162- #[ track_caller]
163- pub const fn expect ( self , msg : & str ) -> NonZero < Uint < LIMBS > > {
164- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
165- self . value
166- }
167- }
168-
169- impl < const LIMBS : usize > ConstCtOption < Odd < Uint < LIMBS > > > {
170- /// Returns the contained value, consuming the `self` value.
171- ///
172- /// # Panics
173- ///
174- /// Panics if the value is none with a custom panic message provided by
175- /// `msg`.
176- #[ inline]
177- #[ track_caller]
178- pub const fn expect ( self , msg : & str ) -> Odd < Uint < LIMBS > > {
179- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
180- self . value
181- }
182- }
183-
184- impl < const LIMBS : usize > ConstCtOption < Int < LIMBS > > {
185- /// This returns the underlying value if it is `Some` or the provided value otherwise.
186- #[ inline]
187- pub const fn unwrap_or ( self , def : Int < LIMBS > ) -> Int < LIMBS > {
188- Int :: select ( & def, & self . value , self . is_some )
189- }
190-
191- /// Returns the contained value, consuming the `self` value.
192- ///
193- /// # Panics
194- ///
195- /// Panics if the value is none with a custom panic message provided by
196- /// `msg`.
197- #[ inline]
198- #[ track_caller]
199- pub const fn expect ( self , msg : & str ) -> Int < LIMBS > {
200- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
201- self . value
202- }
203- }
204-
205- impl < const LIMBS : usize > ConstCtOption < NonZeroInt < LIMBS > > {
206- /// Returns the contained value, consuming the `self` value.
207- ///
208- /// # Panics
209- ///
210- /// Panics if the value is none with a custom panic message provided by
211- /// `msg`.
212- #[ inline]
213- #[ track_caller]
214- pub const fn expect ( self , msg : & str ) -> NonZeroInt < LIMBS > {
215- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
216- self . value
217- }
218- }
219-
220- impl < const LIMBS : usize > ConstCtOption < OddInt < LIMBS > > {
221- /// Returns the contained value, consuming the `self` value.
222- ///
223- /// # Panics
224- ///
225- /// Panics if the value is none with a custom panic message provided by
226- /// `msg`.
227- #[ inline]
228- #[ track_caller]
229- pub const fn expect ( self , msg : & str ) -> OddInt < LIMBS > {
230- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
231- self . value
232- }
233- }
234-
235- impl ConstCtOption < NonZero < Limb > > {
236- /// Returns the contained value, consuming the `self` value.
237- ///
238- /// # Panics
239- ///
240- /// Panics if the value is none with a custom panic message provided by
241- /// `msg`.
242- #[ inline]
243- #[ track_caller]
244- pub const fn expect ( self , msg : & str ) -> NonZero < Limb > {
245- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
246- self . value
247- }
248- }
249-
250- impl < const LIMBS : usize > ConstCtOption < SafeGcdInverter < LIMBS > > {
251- /// Returns the contained value, consuming the `self` value.
252- ///
253- /// # Panics
254- ///
255- /// Panics if the value is none with a custom panic message provided by
256- /// `msg`.
257- #[ inline]
258- #[ track_caller]
259- pub const fn expect ( self , msg : & str ) -> SafeGcdInverter < LIMBS > {
260- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
261- self . value
262- }
263- }
264-
265- impl < MOD : ConstMontyParams < LIMBS > , const LIMBS : usize > ConstCtOption < ConstMontyForm < MOD , LIMBS > > {
266- /// This returns the underlying value if it is `Some` or the provided value otherwise.
267- #[ inline]
268- pub const fn unwrap_or ( self , def : ConstMontyForm < MOD , LIMBS > ) -> ConstMontyForm < MOD , LIMBS > {
269- ConstMontyForm :: < MOD , LIMBS > :: select ( & def, & self . value , self . is_some )
270- }
271-
272- /// Returns the contained value, consuming the `self` value.
273- ///
274- /// # Panics
275- ///
276- /// Panics if the value is none with a custom panic message provided by `msg`.
277- #[ inline]
278- #[ track_caller]
279- pub const fn expect ( self , msg : & str ) -> ConstMontyForm < MOD , LIMBS > {
280- assert ! ( self . is_some. to_bool_vartime( ) , "{}" , msg) ;
281- self . value
282- }
283- }
284-
28514#[ cfg( test) ]
28615mod tests {
28716 use super :: { u32_max, u32_min} ;
0 commit comments