From 99873d06e53c0de622829cb0517757b4bd510327 Mon Sep 17 00:00:00 2001 From: Sam Cappleman-Lynes Date: Thu, 29 Jun 2017 18:29:14 +0100 Subject: [PATCH] Scalar operations on integer types up to 32 bits --- bigint/src/bigint.rs | 5 ++++ bigint/src/biguint.rs | 5 ++++ bigint/src/macros.rs | 63 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/bigint/src/bigint.rs b/bigint/src/bigint.rs index 848eb09..ff68886 100644 --- a/bigint/src/bigint.rs +++ b/bigint/src/bigint.rs @@ -370,6 +370,7 @@ impl Add for BigInt { } } +promote_all_scalars!(impl Add for BigInt, add); forward_all_scalar_binop_to_val_val_commutative!(impl Add for BigInt, add); impl Add for BigInt { @@ -468,6 +469,7 @@ impl Sub for BigInt { } } +promote_all_scalars!(impl Sub for BigInt, sub); forward_all_scalar_binop_to_val_val!(impl Sub for BigInt, sub); impl Sub for BigInt { @@ -536,6 +538,7 @@ impl<'a, 'b> Mul<&'b BigInt> for &'a BigInt { } } +promote_all_scalars!(impl Mul for BigInt, mul); forward_all_scalar_binop_to_val_val_commutative!(impl Mul for BigInt, mul); impl Mul for BigInt { @@ -574,6 +577,7 @@ impl<'a, 'b> Div<&'b BigInt> for &'a BigInt { } } +promote_all_scalars!(impl Div for BigInt, div); forward_all_scalar_binop_to_val_val!(impl Div for BigInt, div); impl Div for BigInt { @@ -634,6 +638,7 @@ impl<'a, 'b> Rem<&'b BigInt> for &'a BigInt { } } +promote_all_scalars!(impl Rem for BigInt, rem); forward_all_scalar_binop_to_val_val!(impl Rem for BigInt, rem); impl Rem for BigInt { diff --git a/bigint/src/biguint.rs b/bigint/src/biguint.rs index 28b6e73..6a00cbf 100644 --- a/bigint/src/biguint.rs +++ b/bigint/src/biguint.rs @@ -394,6 +394,7 @@ impl<'a> Add<&'a BigUint> for BigUint { } } +promote_unsigned_scalars!(impl Add for BigUint, add); forward_all_scalar_binop_to_val_val_commutative!(impl Add for BigUint, add); impl Add for BigUint { @@ -439,6 +440,7 @@ impl<'a> Sub for &'a BigUint { } } +promote_unsigned_scalars!(impl Sub for BigUint, sub); forward_all_scalar_binop_to_val_val!(impl Sub for BigUint, sub); impl Sub for BigUint { @@ -476,6 +478,7 @@ impl<'a, 'b> Mul<&'b BigUint> for &'a BigUint { } } +promote_unsigned_scalars!(impl Mul for BigUint, mul); forward_all_scalar_binop_to_val_val_commutative!(impl Mul for BigUint, mul); impl Mul for BigUint { @@ -507,6 +510,7 @@ impl<'a, 'b> Div<&'b BigUint> for &'a BigUint { } } +promote_unsigned_scalars!(impl Div for BigUint, div); forward_all_scalar_binop_to_val_val!(impl Div for BigUint, div); impl Div for BigUint { @@ -544,6 +548,7 @@ impl<'a, 'b> Rem<&'b BigUint> for &'a BigUint { } } +promote_unsigned_scalars!(impl Rem for BigUint, rem); forward_all_scalar_binop_to_val_val!(impl Rem for BigUint, rem); impl Rem for BigUint { diff --git a/bigint/src/macros.rs b/bigint/src/macros.rs index f81bd84..76d805e 100644 --- a/bigint/src/macros.rs +++ b/bigint/src/macros.rs @@ -184,6 +184,50 @@ macro_rules! forward_scalar_ref_ref_binop { } } +macro_rules! promote_scalars { + (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => { + $( + forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method); + + impl $imp<$scalar> for $res { + type Output = $res; + + #[inline] + fn $method(self, other: $scalar) -> $res { + $imp::$method(self, other as $promo) + } + } + + impl $imp<$res> for $scalar { + type Output = $res; + + #[inline] + fn $method(self, other: $res) -> $res { + $imp::$method(self as $promo, other) + } + } + )* + } +} + +macro_rules! promote_unsigned_scalars_to_u32 { + (impl $imp:ident for $res:ty, $method:ident) => { + #[cfg(target_pointer_width = "32")] + promote_scalars!(impl $imp for $res, $method, u8, u16, usize); + #[cfg(target_pointer_width = "64")] + promote_scalars!(impl $imp for $res, $method, u8, u16); + } +} + +macro_rules! promote_signed_scalars_to_i32 { + (impl $imp:ident for $res:ty, $method:ident) => { + #[cfg(target_pointer_width = "32")] + promote_scalars!(impl $imp for $res, $method, i8, i16, isize); + #[cfg(target_pointer_width = "64")] + promote_scalars!(impl $imp for $res, $method, i8, i16); + } +} + // Forward everything to ref-ref, when reusing storage is not helpful macro_rules! forward_all_binop_to_ref_ref { (impl $imp:ident for $res:ty, $method:ident) => { @@ -224,4 +268,23 @@ macro_rules! forward_all_scalar_binop_to_val_val_commutative { forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method); forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method); } +} + +macro_rules! promote_unsigned_scalars { + (impl $imp:ident for $res:ty, $method:ident) => { + promote_unsigned_scalars_to_u32!(impl $imp for $res, $method); + } +} + +macro_rules! promote_signed_scalars { + (impl $imp:ident for $res:ty, $method:ident) => { + promote_signed_scalars_to_i32!(impl $imp for $res, $method); + } +} + +macro_rules! promote_all_scalars { + (impl $imp:ident for $res:ty, $method:ident) => { + promote_unsigned_scalars!(impl $imp for $res, $method); + promote_signed_scalars!(impl $imp for $res, $method); + } } \ No newline at end of file