@@ -909,8 +909,8 @@ impl_basic_traits! {
909
909
910
910
macro_rules! impl_bin_ops {
911
911
( ) => { } ;
912
- ( for <$generic_param: ident : $generic_param_bound: tt> <$lhs_ty: ty> ~ <$rhs_ty: ty> -> $output: ty { { $lhs_body: expr } ~ { $rhs_body: expr } } $( $rest: tt) * ) => {
913
- impl <$generic_param: $generic_param_bound> Add <$rhs_ty> for $lhs_ty {
912
+ ( for <$( $ generic_param: ident : $generic_param_bound: tt) , * > <$lhs_ty: ty> ~ <$rhs_ty: ty> -> $output: ty { { $lhs_body: expr } ~ { $rhs_body: expr } } $( $rest: tt) * ) => {
913
+ impl <$( $ generic_param: $generic_param_bound) , * > Add <$rhs_ty> for $lhs_ty {
914
914
type Output = $output;
915
915
916
916
#[ inline]
@@ -919,7 +919,7 @@ macro_rules! impl_bin_ops {
919
919
}
920
920
}
921
921
922
- impl <$generic_param: $generic_param_bound> Sub <$rhs_ty> for $lhs_ty {
922
+ impl <$( $ generic_param: $generic_param_bound) , * > Sub <$rhs_ty> for $lhs_ty {
923
923
type Output = $output;
924
924
925
925
#[ inline]
@@ -928,7 +928,7 @@ macro_rules! impl_bin_ops {
928
928
}
929
929
}
930
930
931
- impl <$generic_param: $generic_param_bound> Mul <$rhs_ty> for $lhs_ty {
931
+ impl <$( $ generic_param: $generic_param_bound) , * > Mul <$rhs_ty> for $lhs_ty {
932
932
type Output = $output;
933
933
934
934
#[ inline]
@@ -937,7 +937,7 @@ macro_rules! impl_bin_ops {
937
937
}
938
938
}
939
939
940
- impl <$generic_param: $generic_param_bound> Div <$rhs_ty> for $lhs_ty {
940
+ impl <$( $ generic_param: $generic_param_bound) , * > Div <$rhs_ty> for $lhs_ty {
941
941
type Output = $output;
942
942
943
943
#[ inline]
@@ -952,29 +952,29 @@ macro_rules! impl_bin_ops {
952
952
953
953
macro_rules! impl_assign_ops {
954
954
( ) => { } ;
955
- ( for <$generic_param: ident : $generic_param_bound: tt> <$lhs_ty: ty> ~= <$rhs_ty: ty> { _ ~= { $rhs_body: expr } } $( $rest: tt) * ) => {
956
- impl <$generic_param: $generic_param_bound> AddAssign <$rhs_ty> for $lhs_ty {
955
+ ( for <$( $ generic_param: ident : $generic_param_bound: tt) , * > <$lhs_ty: ty> ~= <$rhs_ty: ty> { _ ~= { $rhs_body: expr } } $( $rest: tt) * ) => {
956
+ impl <$( $ generic_param: $generic_param_bound) , * > AddAssign <$rhs_ty> for $lhs_ty {
957
957
#[ inline]
958
958
fn add_assign( & mut self , rhs: $rhs_ty) {
959
959
* self = * self + apply( $rhs_body, rhs) ;
960
960
}
961
961
}
962
962
963
- impl <$generic_param: $generic_param_bound> SubAssign <$rhs_ty> for $lhs_ty {
963
+ impl <$( $ generic_param: $generic_param_bound) , * > SubAssign <$rhs_ty> for $lhs_ty {
964
964
#[ inline]
965
965
fn sub_assign( & mut self , rhs: $rhs_ty) {
966
966
* self = * self - apply( $rhs_body, rhs) ;
967
967
}
968
968
}
969
969
970
- impl <$generic_param: $generic_param_bound> MulAssign <$rhs_ty> for $lhs_ty {
970
+ impl <$( $ generic_param: $generic_param_bound) , * > MulAssign <$rhs_ty> for $lhs_ty {
971
971
#[ inline]
972
972
fn mul_assign( & mut self , rhs: $rhs_ty) {
973
973
* self = * self * apply( $rhs_body, rhs) ;
974
974
}
975
975
}
976
976
977
- impl <$generic_param: $generic_param_bound> DivAssign <$rhs_ty> for $lhs_ty {
977
+ impl <$( $ generic_param: $generic_param_bound) , * > DivAssign <$rhs_ty> for $lhs_ty {
978
978
#[ inline]
979
979
fn div_assign( & mut self , rhs: $rhs_ty) {
980
980
* self = * self / apply( $rhs_body, rhs) ;
@@ -999,13 +999,19 @@ impl_bin_ops! {
999
999
for <I : Id > <DynamicModInt <I > > ~ <& ' _ DynamicModInt <I >> -> DynamicModInt <I > { { |x| x } ~ { |& x| x } }
1000
1000
for <I : Id > <& ' _ DynamicModInt <I >> ~ <DynamicModInt <I > > -> DynamicModInt <I > { { |& x| x } ~ { |x| x } }
1001
1001
for <I : Id > <& ' _ DynamicModInt <I >> ~ <& ' _ DynamicModInt <I >> -> DynamicModInt <I > { { |& x| x } ~ { |& x| x } }
1002
+
1003
+ for <M : Modulus , T : RemEuclidU32 > <StaticModInt <M > > ~ <T > -> StaticModInt <M > { { |x| x } ~ { StaticModInt :: <M >:: new } }
1004
+ for <I : Id , T : RemEuclidU32 > <DynamicModInt <I > > ~ <T > -> DynamicModInt <I > { { |x| x } ~ { DynamicModInt :: <I >:: new } }
1002
1005
}
1003
1006
1004
1007
impl_assign_ops ! {
1005
1008
for <M : Modulus > <StaticModInt <M > > ~= <StaticModInt <M > > { _ ~= { |x| x } }
1006
1009
for <M : Modulus > <StaticModInt <M > > ~= <& ' _ StaticModInt <M > > { _ ~= { |& x| x } }
1007
1010
for <I : Id > <DynamicModInt <I >> ~= <DynamicModInt <I > > { _ ~= { |x| x } }
1008
1011
for <I : Id > <DynamicModInt <I >> ~= <& ' _ DynamicModInt <I >> { _ ~= { |& x| x } }
1012
+
1013
+ for <M : Modulus , T : RemEuclidU32 > <StaticModInt <M > > ~= <T > { _ ~= { StaticModInt :: <M >:: new } }
1014
+ for <I : Id , T : RemEuclidU32 > <DynamicModInt <I >> ~= <T > { _ ~= { DynamicModInt :: <I >:: new } }
1009
1015
}
1010
1016
1011
1017
macro_rules! impl_folding {
@@ -1126,4 +1132,29 @@ mod tests {
1126
1132
1127
1133
assert_eq ! ( ModInt1000000007 :: new( -120 ) , product( & [ -1 , 2 , -3 , 4 , -5 ] ) ) ;
1128
1134
}
1135
+
1136
+ #[ test]
1137
+ fn static_modint_binop_coercion ( ) {
1138
+ let f = ModInt1000000007 :: new;
1139
+ let a = 10_293_812_usize ;
1140
+ let b = 9_083_240_982_usize ;
1141
+ assert_eq ! ( f( a) + f( b) , f( a) + b) ;
1142
+ assert_eq ! ( f( a) - f( b) , f( a) - b) ;
1143
+ assert_eq ! ( f( a) * f( b) , f( a) * b) ;
1144
+ assert_eq ! ( f( a) / f( b) , f( a) / b) ;
1145
+ }
1146
+
1147
+ #[ test]
1148
+ fn static_modint_assign_coercion ( ) {
1149
+ let f = ModInt1000000007 :: new;
1150
+ let a = f ( 10_293_812_usize ) ;
1151
+ let b = 9_083_240_982_usize ;
1152
+ let expected = ( ( ( a + b) * b) - b) / b;
1153
+ let mut c = a;
1154
+ c += b;
1155
+ c *= b;
1156
+ c -= b;
1157
+ c /= b;
1158
+ assert_eq ! ( expected, c) ;
1159
+ }
1129
1160
}
0 commit comments