@@ -909,8 +909,8 @@ impl_basic_traits! {
909909
910910macro_rules! impl_bin_ops {
911911 ( ) => { } ;
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 {
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> Sub <$rhs_ty> for $lhs_ty {
922+ impl <$( $ generic_param: $generic_param_bound) , * > Sub <$rhs_ty> for $lhs_ty {
923923 type Output = $output;
924924
925925 #[ inline]
@@ -928,7 +928,7 @@ macro_rules! impl_bin_ops {
928928 }
929929 }
930930
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 {
932932 type Output = $output;
933933
934934 #[ inline]
@@ -937,7 +937,7 @@ macro_rules! impl_bin_ops {
937937 }
938938 }
939939
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 {
941941 type Output = $output;
942942
943943 #[ inline]
@@ -952,29 +952,29 @@ macro_rules! impl_bin_ops {
952952
953953macro_rules! impl_assign_ops {
954954 ( ) => { } ;
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 {
957957 #[ inline]
958958 fn add_assign( & mut self , rhs: $rhs_ty) {
959959 * self = * self + apply( $rhs_body, rhs) ;
960960 }
961961 }
962962
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 {
964964 #[ inline]
965965 fn sub_assign( & mut self , rhs: $rhs_ty) {
966966 * self = * self - apply( $rhs_body, rhs) ;
967967 }
968968 }
969969
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 {
971971 #[ inline]
972972 fn mul_assign( & mut self , rhs: $rhs_ty) {
973973 * self = * self * apply( $rhs_body, rhs) ;
974974 }
975975 }
976976
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 {
978978 #[ inline]
979979 fn div_assign( & mut self , rhs: $rhs_ty) {
980980 * self = * self / apply( $rhs_body, rhs) ;
@@ -999,13 +999,19 @@ impl_bin_ops! {
999999 for <I : Id > <DynamicModInt <I > > ~ <& ' _ DynamicModInt <I >> -> DynamicModInt <I > { { |x| x } ~ { |& x| x } }
10001000 for <I : Id > <& ' _ DynamicModInt <I >> ~ <DynamicModInt <I > > -> DynamicModInt <I > { { |& x| x } ~ { |x| x } }
10011001 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 } }
10021005}
10031006
10041007impl_assign_ops ! {
10051008 for <M : Modulus > <StaticModInt <M > > ~= <StaticModInt <M > > { _ ~= { |x| x } }
10061009 for <M : Modulus > <StaticModInt <M > > ~= <& ' _ StaticModInt <M > > { _ ~= { |& x| x } }
10071010 for <I : Id > <DynamicModInt <I >> ~= <DynamicModInt <I > > { _ ~= { |x| x } }
10081011 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 } }
10091015}
10101016
10111017macro_rules! impl_folding {
@@ -1126,4 +1132,29 @@ mod tests {
11261132
11271133 assert_eq ! ( ModInt1000000007 :: new( -120 ) , product( & [ -1 , 2 , -3 , 4 , -5 ] ) ) ;
11281134 }
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+ }
11291160}
0 commit comments