@@ -891,8 +891,8 @@ impl_basic_traits! {
891891
892892macro_rules! impl_bin_ops {
893893 ( ) => { } ;
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 {
896896 type Output = $output;
897897
898898 #[ inline]
@@ -901,7 +901,7 @@ macro_rules! impl_bin_ops {
901901 }
902902 }
903903
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 {
905905 type Output = $output;
906906
907907 #[ inline]
@@ -910,7 +910,7 @@ macro_rules! impl_bin_ops {
910910 }
911911 }
912912
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 {
914914 type Output = $output;
915915
916916 #[ inline]
@@ -919,7 +919,7 @@ macro_rules! impl_bin_ops {
919919 }
920920 }
921921
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 {
923923 type Output = $output;
924924
925925 #[ inline]
@@ -934,29 +934,29 @@ macro_rules! impl_bin_ops {
934934
935935macro_rules! impl_assign_ops {
936936 ( ) => { } ;
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 {
939939 #[ inline]
940940 fn add_assign( & mut self , rhs: $rhs_ty) {
941941 * self = * self + apply( $rhs_body, rhs) ;
942942 }
943943 }
944944
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 {
946946 #[ inline]
947947 fn sub_assign( & mut self , rhs: $rhs_ty) {
948948 * self = * self - apply( $rhs_body, rhs) ;
949949 }
950950 }
951951
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 {
953953 #[ inline]
954954 fn mul_assign( & mut self , rhs: $rhs_ty) {
955955 * self = * self * apply( $rhs_body, rhs) ;
956956 }
957957 }
958958
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 {
960960 #[ inline]
961961 fn div_assign( & mut self , rhs: $rhs_ty) {
962962 * self = * self / apply( $rhs_body, rhs) ;
@@ -981,13 +981,19 @@ impl_bin_ops! {
981981 for <I : Id > <DynamicModInt <I > > ~ <& ' _ DynamicModInt <I >> -> DynamicModInt <I > { { |x| x } ~ { |& x| x } }
982982 for <I : Id > <& ' _ DynamicModInt <I >> ~ <DynamicModInt <I > > -> DynamicModInt <I > { { |& x| x } ~ { |x| x } }
983983 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 } }
984987}
985988
986989impl_assign_ops ! {
987990 for <M : Modulus > <StaticModInt <M > > ~= <StaticModInt <M > > { _ ~= { |x| x } }
988991 for <M : Modulus > <StaticModInt <M > > ~= <& ' _ StaticModInt <M > > { _ ~= { |& x| x } }
989992 for <I : Id > <DynamicModInt <I >> ~= <DynamicModInt <I > > { _ ~= { |x| x } }
990993 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 } }
991997}
992998
993999macro_rules! impl_folding {
@@ -1108,4 +1114,29 @@ mod tests {
11081114
11091115 assert_eq ! ( ModInt1000000007 :: new( -120 ) , product( & [ -1 , 2 , -3 , 4 , -5 ] ) ) ;
11101116 }
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+ }
11111142}
0 commit comments