about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-03-12 00:57:43 -0700
committerbors <bors@rust-lang.org>2013-03-12 00:57:43 -0700
commita95b933350e1e403c8a4118977049e38505f2a90 (patch)
tree1636797507af611e42a7c6c04d4ff02c150b12b3
parent4e350c7ce7574259dd0aad9f981e615b2b917d20 (diff)
parenta21b43c6bbb0edcf4dfe9913a084f28eb950b364 (diff)
auto merge of #5328 : bstrie/rust/optadd, r=graydon
This will allow you to use the `+` operator to add together any two
Options, assuming that the contents of each Option likewise implement
`+`. So Some(4) + Some(1) == Some(5), and adding with None leaves the
other value unchanged.

This might be monoidic? I don't know what that word means!
-rw-r--r--src/libcore/option.rs13
-rw-r--r--src/test/run-pass/option_addition.rs27
2 files changed, 40 insertions, 0 deletions
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 6a38eff0343..64135b3b8e1 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -42,6 +42,7 @@ let unwrapped_msg = match msg {
 */
 
 use cmp::{Eq,Ord};
+use ops::Add;
 use kinds::Copy;
 use util;
 use num::Zero;
@@ -85,6 +86,18 @@ impl<T:Ord> Ord for Option<T> {
     }
 }
 
+impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
+    #[inline(always)]
+    pure fn add(&self, other: &Option<T>) -> Option<T> {
+        match (*self, *other) {
+            (None, None) => None,
+            (_, None) => *self,
+            (None, _) => *other,
+            (Some(ref lhs), Some(ref rhs)) => Some(*lhs + *rhs)
+        }
+    }
+}
+
 #[inline(always)]
 pub pure fn get<T:Copy>(opt: Option<T>) -> T {
     /*!
diff --git a/src/test/run-pass/option_addition.rs b/src/test/run-pass/option_addition.rs
new file mode 100644
index 00000000000..92420562706
--- /dev/null
+++ b/src/test/run-pass/option_addition.rs
@@ -0,0 +1,27 @@
+fn main() {
+    let foo = 1;
+    let bar = 2;
+    let foobar = foo + bar;
+
+    let nope = optint(0) + optint(0);
+    let somefoo = optint(foo) + optint(0);
+    let somebar = optint(bar) + optint(0);
+    let somefoobar = optint(foo) + optint(bar);
+
+    match nope {
+        None => (),
+        Some(foo) => fail!(fmt!("expected None, but found %?", foo))
+    }
+    fail_unless!(foo == somefoo.get());
+    fail_unless!(bar == somebar.get());
+    fail_unless!(foobar == somefoobar.get());
+}
+
+fn optint(in: int) -> Option<int> {
+    if in == 0 {
+        return None;
+    }
+    else {
+        return Some(in);
+    }
+}