@@ -891,8 +891,8 @@ impl_basic_traits! {
891
891
892
892
macro_rules! impl_bin_ops {
893
893
( ) => { } ;
894
- ( for <$generic_param: ident : $generic_param_bound: tt> <$lhs_ty: ty> ~ <$rhs_ty: ty> -> $output: ty { { $lhs_body: expr } ~ { $rhs_body: expr } } $( $rest: tt) * ) => {
895
- impl <$generic_param: $generic_param_bound> Add <$rhs_ty> for $lhs_ty {
894
+ ( for <$( $ generic_param: ident : $generic_param_bound: tt) , * > <$lhs_ty: ty> ~ <$rhs_ty: ty> -> $output: ty { { $lhs_body: expr } ~ { $rhs_body: expr } } $( $rest: tt) * ) => {
895
+ impl <$( $ generic_param: $generic_param_bound) , * > Add <$rhs_ty> for $lhs_ty {
896
896
type Output = $output;
897
897
898
898
#[ inline]
@@ -901,7 +901,7 @@ macro_rules! impl_bin_ops {
901
901
}
902
902
}
903
903
904
- impl <$generic_param: $generic_param_bound> Sub <$rhs_ty> for $lhs_ty {
904
+ impl <$( $ generic_param: $generic_param_bound) , * > Sub <$rhs_ty> for $lhs_ty {
905
905
type Output = $output;
906
906
907
907
#[ inline]
@@ -910,7 +910,7 @@ macro_rules! impl_bin_ops {
910
910
}
911
911
}
912
912
913
- impl <$generic_param: $generic_param_bound> Mul <$rhs_ty> for $lhs_ty {
913
+ impl <$( $ generic_param: $generic_param_bound) , * > Mul <$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> Div <$rhs_ty> for $lhs_ty {
922
+ impl <$( $ generic_param: $generic_param_bound) , * > Div <$rhs_ty> for $lhs_ty {
923
923
type Output = $output;
924
924
925
925
#[ inline]
@@ -934,29 +934,29 @@ macro_rules! impl_bin_ops {
934
934
935
935
macro_rules! impl_assign_ops {
936
936
( ) => { } ;
937
- ( for <$generic_param: ident : $generic_param_bound: tt> <$lhs_ty: ty> ~= <$rhs_ty: ty> { _ ~= { $rhs_body: expr } } $( $rest: tt) * ) => {
938
- impl <$generic_param: $generic_param_bound> AddAssign <$rhs_ty> for $lhs_ty {
937
+ ( for <$( $ generic_param: ident : $generic_param_bound: tt) , * > <$lhs_ty: ty> ~= <$rhs_ty: ty> { _ ~= { $rhs_body: expr } } $( $rest: tt) * ) => {
938
+ impl <$( $ generic_param: $generic_param_bound) , * > AddAssign <$rhs_ty> for $lhs_ty {
939
939
#[ inline]
940
940
fn add_assign( & mut self , rhs: $rhs_ty) {
941
941
* self = * self + apply( $rhs_body, rhs) ;
942
942
}
943
943
}
944
944
945
- impl <$generic_param: $generic_param_bound> SubAssign <$rhs_ty> for $lhs_ty {
945
+ impl <$( $ generic_param: $generic_param_bound) , * > SubAssign <$rhs_ty> for $lhs_ty {
946
946
#[ inline]
947
947
fn sub_assign( & mut self , rhs: $rhs_ty) {
948
948
* self = * self - apply( $rhs_body, rhs) ;
949
949
}
950
950
}
951
951
952
- impl <$generic_param: $generic_param_bound> MulAssign <$rhs_ty> for $lhs_ty {
952
+ impl <$( $ generic_param: $generic_param_bound) , * > MulAssign <$rhs_ty> for $lhs_ty {
953
953
#[ inline]
954
954
fn mul_assign( & mut self , rhs: $rhs_ty) {
955
955
* self = * self * apply( $rhs_body, rhs) ;
956
956
}
957
957
}
958
958
959
- impl <$generic_param: $generic_param_bound> DivAssign <$rhs_ty> for $lhs_ty {
959
+ impl <$( $ generic_param: $generic_param_bound) , * > DivAssign <$rhs_ty> for $lhs_ty {
960
960
#[ inline]
961
961
fn div_assign( & mut self , rhs: $rhs_ty) {
962
962
* self = * self / apply( $rhs_body, rhs) ;
@@ -981,13 +981,19 @@ impl_bin_ops! {
981
981
for <I : Id > <DynamicModInt <I > > ~ <& ' _ DynamicModInt <I >> -> DynamicModInt <I > { { |x| x } ~ { |& x| x } }
982
982
for <I : Id > <& ' _ DynamicModInt <I >> ~ <DynamicModInt <I > > -> DynamicModInt <I > { { |& x| x } ~ { |x| x } }
983
983
for <I : Id > <& ' _ DynamicModInt <I >> ~ <& ' _ DynamicModInt <I >> -> DynamicModInt <I > { { |& x| x } ~ { |& x| x } }
984
+
985
+ for <M : Modulus , T : RemEuclidU32 > <StaticModInt <M > > ~ <T > -> StaticModInt <M > { { |x| x } ~ { StaticModInt :: <M >:: new } }
986
+ for <I : Id , T : RemEuclidU32 > <DynamicModInt <I > > ~ <T > -> DynamicModInt <I > { { |x| x } ~ { DynamicModInt :: <I >:: new } }
984
987
}
985
988
986
989
impl_assign_ops ! {
987
990
for <M : Modulus > <StaticModInt <M > > ~= <StaticModInt <M > > { _ ~= { |x| x } }
988
991
for <M : Modulus > <StaticModInt <M > > ~= <& ' _ StaticModInt <M > > { _ ~= { |& x| x } }
989
992
for <I : Id > <DynamicModInt <I >> ~= <DynamicModInt <I > > { _ ~= { |x| x } }
990
993
for <I : Id > <DynamicModInt <I >> ~= <& ' _ DynamicModInt <I >> { _ ~= { |& x| x } }
994
+
995
+ for <M : Modulus , T : RemEuclidU32 > <StaticModInt <M > > ~= <T > { _ ~= { StaticModInt :: <M >:: new } }
996
+ for <I : Id , T : RemEuclidU32 > <DynamicModInt <I >> ~= <T > { _ ~= { DynamicModInt :: <I >:: new } }
991
997
}
992
998
993
999
macro_rules! impl_folding {
@@ -1108,4 +1114,29 @@ mod tests {
1108
1114
1109
1115
assert_eq ! ( ModInt1000000007 :: new( -120 ) , product( & [ -1 , 2 , -3 , 4 , -5 ] ) ) ;
1110
1116
}
1117
+
1118
+ #[ test]
1119
+ fn static_modint_binop_coercion ( ) {
1120
+ let f = ModInt1000000007 :: new;
1121
+ let a = 10_293_812_usize ;
1122
+ let b = 9_083_240_982_usize ;
1123
+ assert_eq ! ( f( a) + f( b) , f( a) + b) ;
1124
+ assert_eq ! ( f( a) - f( b) , f( a) - b) ;
1125
+ assert_eq ! ( f( a) * f( b) , f( a) * b) ;
1126
+ assert_eq ! ( f( a) / f( b) , f( a) / b) ;
1127
+ }
1128
+
1129
+ #[ test]
1130
+ fn static_modint_assign_coercion ( ) {
1131
+ let f = ModInt1000000007 :: new;
1132
+ let a = f ( 10_293_812_usize ) ;
1133
+ let b = 9_083_240_982_usize ;
1134
+ let expected = ( ( ( a + b) * b) - b) / b;
1135
+ let mut c = a;
1136
+ c += b;
1137
+ c *= b;
1138
+ c -= b;
1139
+ c /= b;
1140
+ assert_eq ! ( expected, c) ;
1141
+ }
1111
1142
}
0 commit comments