From 5eb254b1ccf196ea0856782eba96f92ae0786617 Mon Sep 17 00:00:00 2001 From: Sebastian Gesemann Date: Fri, 16 Jan 2015 05:44:19 +0100 Subject: [PATCH] libcore: implement many operators for references as well --- src/libcore/ops.rs | 102 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index e7eb307689fb..144019147af7 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -96,6 +96,80 @@ pub trait Drop { fn drop(&mut self); } +// implements the unary operator "op &T" +// based on "op T" where T is expected to be `Copy`able +macro_rules! forward_ref_unop { + (impl $imp:ident, $method:ident for $t:ty) => { + #[unstable] + impl<'a> $imp for &'a $t { + type Output = <$t as $imp>::Output; + + #[inline] + fn $method(self) -> <$t as $imp>::Output { + $imp::$method(*self) + } + } + } +} + +// implements the binary operator "&T op U" +// based on "T + U" where T and U are expected `Copy`able +macro_rules! forward_ref_val_binop { + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { + #[unstable] + impl<'a> $imp<$u> for &'a $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, other) + } + } + } +} + +// implements the binary operator "T op &U" +// based on "T + U" where T and U are expected `Copy`able +macro_rules! forward_val_ref_binop { + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { + #[unstable] + impl<'a> $imp<&'a $u> for $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { + $imp::$method(self, *other) + } + } + } +} + +// implements the binary operator "&T op &U" +// based on "T + U" where T and U are expected `Copy`able +macro_rules! forward_ref_ref_binop { + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { + #[unstable] + impl<'a, 'b> $imp<&'a $u> for &'b $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, *other) + } + } + } +} + +// implements binary operators "&T op U", "T op &U", "&T op &U" +// based on "T + U" where T and U are expected `Copy`able +macro_rules! forward_ref_binop { + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { + forward_ref_val_binop! { impl $imp, $method for $t, $u } + forward_val_ref_binop! { impl $imp, $method for $t, $u } + forward_ref_ref_binop! { impl $imp, $method for $t, $u } + } +} + /// The `Add` trait is used to specify the functionality of `+`. /// /// # Example @@ -144,6 +218,8 @@ macro_rules! add_impl { #[inline] fn add(self, other: $t) -> $t { self + other } } + + forward_ref_binop! { impl Add, add for $t, $t } )*) } @@ -197,6 +273,8 @@ macro_rules! sub_impl { #[inline] fn sub(self, other: $t) -> $t { self - other } } + + forward_ref_binop! { impl Sub, sub for $t, $t } )*) } @@ -250,6 +328,8 @@ macro_rules! mul_impl { #[inline] fn mul(self, other: $t) -> $t { self * other } } + + forward_ref_binop! { impl Mul, mul for $t, $t } )*) } @@ -303,6 +383,8 @@ macro_rules! div_impl { #[inline] fn div(self, other: $t) -> $t { self / other } } + + forward_ref_binop! { impl Div, div for $t, $t } )*) } @@ -356,6 +438,8 @@ macro_rules! rem_impl { #[inline] fn rem(self, other: $t) -> $t { self % other } } + + forward_ref_binop! { impl Rem, rem for $t, $t } )*) } @@ -371,6 +455,8 @@ macro_rules! rem_float_impl { unsafe { $fmod(self, other) } } } + + forward_ref_binop! { impl Rem, rem for $t, $t } } } @@ -429,6 +515,8 @@ macro_rules! neg_impl { #[stable] fn neg(self) -> $t { -self } } + + forward_ref_unop! { impl Neg, neg for $t } )*) } @@ -441,6 +529,8 @@ macro_rules! neg_uint_impl { #[inline] fn neg(self) -> $t { -(self as $t_signed) as $t } } + + forward_ref_unop! { impl Neg, neg for $t } } } @@ -502,6 +592,8 @@ macro_rules! not_impl { #[inline] fn not(self) -> $t { !self } } + + forward_ref_unop! { impl Not, not for $t } )*) } @@ -555,6 +647,8 @@ macro_rules! bitand_impl { #[inline] fn bitand(self, rhs: $t) -> $t { self & rhs } } + + forward_ref_binop! { impl BitAnd, bitand for $t, $t } )*) } @@ -608,6 +702,8 @@ macro_rules! bitor_impl { #[inline] fn bitor(self, rhs: $t) -> $t { self | rhs } } + + forward_ref_binop! { impl BitOr, bitor for $t, $t } )*) } @@ -661,6 +757,8 @@ macro_rules! bitxor_impl { #[inline] fn bitxor(self, other: $t) -> $t { self ^ other } } + + forward_ref_binop! { impl BitXor, bitxor for $t, $t } )*) } @@ -716,6 +814,8 @@ macro_rules! shl_impl { self << other } } + + forward_ref_binop! { impl Shl, shl for $t, $f } ) } @@ -795,6 +895,8 @@ macro_rules! shr_impl { self >> other } } + + forward_ref_binop! { impl Shr, shr for $t, $f } ) }