about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSebastian Gesemann <s.gesemann@gmail.com>2015-01-16 05:44:19 +0100
committerSebastian Gesemann <s.gesemann@gmail.com>2015-01-16 05:44:19 +0100
commit5eb254b1ccf196ea0856782eba96f92ae0786617 (patch)
tree05da4ed99b50c8d27ba1ea7ac978e59494560ee7
parent8903c21d618fd25dca61d9bb668c5299d21feac9 (diff)
downloadrust-5eb254b1ccf196ea0856782eba96f92ae0786617.tar.gz
rust-5eb254b1ccf196ea0856782eba96f92ae0786617.zip
libcore: implement many operators for references as well
-rw-r--r--src/libcore/ops.rs102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index e7eb307689f..144019147af 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 }
     )
 }