@@ -10,10 +10,10 @@ use core::{
1010#[ cfg( feature = "subtle" ) ]
1111use crate :: CtOption ;
1212#[ cfg( feature = "alloc" ) ]
13- use alloc :: { boxed :: Box , vec :: Vec } ;
14-
15- # [ cfg ( doc ) ]
16- use crate :: CtAssignSlice ;
13+ use {
14+ crate :: CtAssignSlice ,
15+ alloc :: { boxed :: Box , vec :: Vec } ,
16+ } ;
1717
1818/// Constant-time selection: choose between two values based on a given [`Choice`].
1919///
@@ -79,26 +79,22 @@ where
7979 }
8080}
8181
82- /// Impl `CtSelect` using the `CtAssign` trait.
83- ///
84- /// In cases where `CtAssign` is more straightforward to implement, but you want to use a provided
85- /// implementation of `CtSelect` based on it, you can use this macro to write it for you.
86- ///
87- /// Requires the provided type(s) impl `Clone`.
88- #[ macro_export]
82+ /// Marker trait which enables a blanket impl of [`CtSelect`] for types which also impl
83+ /// [`Clone`] + [`CtAssign`].
84+ pub trait CtSelectUsingCtAssign : Clone + CtAssign { }
85+
86+ impl < T : CtSelectUsingCtAssign > CtSelect for T {
87+ #[ inline]
88+ fn ct_select ( & self , other : & Self , choice : Choice ) -> Self {
89+ let mut ret = self . clone ( ) ;
90+ ret. ct_assign ( other, choice) ;
91+ ret
92+ }
93+ }
94+
95+ /// Macro to write impls of `CtSelectUsingCtAssign`.
8996macro_rules! impl_ct_select_with_ct_assign {
90- ( $( $ty: ty) ,+ ) => {
91- $(
92- impl CtSelect for $ty {
93- #[ inline]
94- fn ct_select( & self , other: & Self , choice: Choice ) -> Self {
95- let mut ret = self . clone( ) ;
96- ret. ct_assign( other, choice) ;
97- ret
98- }
99- }
100- ) +
101- } ;
97+ ( $( $ty: ty) ,+ ) => { $( impl CtSelectUsingCtAssign for $ty { } ) + } ;
10298}
10399
104100impl_ct_select_with_ct_assign ! (
@@ -159,43 +155,18 @@ impl CtSelect for cmp::Ordering {
159155}
160156
161157#[ cfg( feature = "alloc" ) ]
162- impl < T > CtSelect for Box < T >
163- where
164- T : CtSelect ,
165- {
166- #[ inline]
167- fn ct_select ( & self , other : & Self , choice : Choice ) -> Self {
168- Box :: new ( T :: ct_select ( & * * self , & * * other, choice) )
169- }
170- }
158+ impl < T : Clone + CtAssign > CtSelectUsingCtAssign for Box < T > { }
171159
172160#[ cfg( feature = "alloc" ) ]
173- impl < T > CtSelect for Box < [ T ] >
161+ impl < T > CtSelectUsingCtAssign for Box < [ T ] >
174162where
175163 T : Clone ,
176164 [ T ] : CtAssign ,
177165{
178- #[ inline]
179- fn ct_select ( & self , other : & Self , choice : Choice ) -> Self {
180- let mut ret = self . clone ( ) ;
181- ret. ct_assign ( other, choice) ;
182- ret
183- }
184166}
185167
186168#[ cfg( feature = "alloc" ) ]
187- impl < T > CtSelect for Vec < T >
188- where
189- T : Clone ,
190- [ T ] : CtAssign ,
191- {
192- #[ inline]
193- fn ct_select ( & self , other : & Self , choice : Choice ) -> Self {
194- let mut ret = self . clone ( ) ;
195- ret. ct_assign ( other, choice) ;
196- ret
197- }
198- }
169+ impl < T : Clone + CtAssignSlice > CtSelectUsingCtAssign for Vec < T > { }
199170
200171#[ cfg( feature = "subtle" ) ]
201172impl CtSelect for subtle:: Choice {
0 commit comments