Skip to content

Commit a95b933

Browse files
committed
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!
2 parents 4e350c7 + a21b43c commit a95b933

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

src/libcore/option.rs

+13
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ let unwrapped_msg = match msg {
4242
*/
4343

4444
use cmp::{Eq,Ord};
45+
use ops::Add;
4546
use kinds::Copy;
4647
use util;
4748
use num::Zero;
@@ -85,6 +86,18 @@ impl<T:Ord> Ord for Option<T> {
8586
}
8687
}
8788

89+
impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
90+
#[inline(always)]
91+
pure fn add(&self, other: &Option<T>) -> Option<T> {
92+
match (*self, *other) {
93+
(None, None) => None,
94+
(_, None) => *self,
95+
(None, _) => *other,
96+
(Some(ref lhs), Some(ref rhs)) => Some(*lhs + *rhs)
97+
}
98+
}
99+
}
100+
88101
#[inline(always)]
89102
pub pure fn get<T:Copy>(opt: Option<T>) -> T {
90103
/*!

src/test/run-pass/option_addition.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
fn main() {
2+
let foo = 1;
3+
let bar = 2;
4+
let foobar = foo + bar;
5+
6+
let nope = optint(0) + optint(0);
7+
let somefoo = optint(foo) + optint(0);
8+
let somebar = optint(bar) + optint(0);
9+
let somefoobar = optint(foo) + optint(bar);
10+
11+
match nope {
12+
None => (),
13+
Some(foo) => fail!(fmt!("expected None, but found %?", foo))
14+
}
15+
fail_unless!(foo == somefoo.get());
16+
fail_unless!(bar == somebar.get());
17+
fail_unless!(foobar == somefoobar.get());
18+
}
19+
20+
fn optint(in: int) -> Option<int> {
21+
if in == 0 {
22+
return None;
23+
}
24+
else {
25+
return Some(in);
26+
}
27+
}

0 commit comments

Comments
 (0)