]> git.lizzy.rs Git - rust.git/blob - src/libstd/option.rs
Change finalize -> drop.
[rust.git] / src / libstd / option.rs
1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12
13 Operations on the ubiquitous `Option` type.
14
15 Type `Option` represents an optional value.
16
17 Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
18 languages you might use a nullable type, in Rust you would use an option
19 type.
20
21 Options are most commonly used with pattern matching to query the presence
22 of a value and take action, always accounting for the `None` case.
23
24 # Example
25
26 ~~~
27 let msg = Some(~"howdy");
28
29 // Take a reference to the contained string
30 match msg {
31     Some(ref m) => io::println(m),
32     None => ()
33 }
34
35 // Remove the contained string, destroying the Option
36 let unwrapped_msg = match msg {
37     Some(m) => m,
38     None => ~"default message"
39 };
40 ~~~
41
42 */
43
44 use cmp::{Eq,Ord};
45 use ops::Add;
46 use kinds::Copy;
47 use util;
48 use num::Zero;
49 use iterator::Iterator;
50 use str::StrSlice;
51 use clone::DeepClone;
52
53 #[cfg(test)] use str;
54 #[cfg(test)] use iterator::IteratorUtil;
55
56 /// The option type
57 #[deriving(Clone, DeepClone, Eq)]
58 pub enum Option<T> {
59     None,
60     Some(T),
61 }
62
63 impl<T:Ord> Ord for Option<T> {
64     fn lt(&self, other: &Option<T>) -> bool {
65         match (self, other) {
66             (&None, &None) => false,
67             (&None, &Some(_)) => true,
68             (&Some(_), &None) => false,
69             (&Some(ref a), &Some(ref b)) => *a < *b
70         }
71     }
72
73     fn le(&self, other: &Option<T>) -> bool {
74         match (self, other) {
75             (&None, &None) => true,
76             (&None, &Some(_)) => true,
77             (&Some(_), &None) => false,
78             (&Some(ref a), &Some(ref b)) => *a <= *b
79         }
80     }
81
82     fn ge(&self, other: &Option<T>) -> bool {
83         !(self < other)
84     }
85
86     fn gt(&self, other: &Option<T>) -> bool {
87         !(self <= other)
88     }
89 }
90
91 impl<T: Copy+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
92     #[inline]
93     fn add(&self, other: &Option<T>) -> Option<T> {
94         match (&*self, &*other) {
95             (&None, &None) => None,
96             (_, &None) => copy *self,
97             (&None, _) => copy *other,
98             (&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs)
99         }
100     }
101 }
102
103 impl<T> Option<T> {
104     /// Return an iterator over the possibly contained value
105     #[inline]
106     pub fn iter<'r>(&'r self) -> OptionIterator<'r, T> {
107         match *self {
108             Some(ref x) => OptionIterator{opt: Some(x)},
109             None => OptionIterator{opt: None}
110         }
111     }
112
113     /// Return a mutable iterator over the possibly contained value
114     #[inline]
115     pub fn mut_iter<'r>(&'r mut self) -> OptionMutIterator<'r, T> {
116         match *self {
117             Some(ref mut x) => OptionMutIterator{opt: Some(x)},
118             None => OptionMutIterator{opt: None}
119         }
120     }
121
122     /// Returns true if the option equals `none`
123     #[inline]
124     pub fn is_none(&const self) -> bool {
125         match *self { None => true, Some(_) => false }
126     }
127
128     /// Returns true if the option contains some value
129     #[inline]
130     pub fn is_some(&const self) -> bool { !self.is_none() }
131
132     /// Update an optional value by optionally running its content through a
133     /// function that returns an option.
134     #[inline]
135     pub fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
136         match self {
137             Some(t) => f(t),
138             None => None
139         }
140     }
141
142     /// Returns the leftmost Some() value, or None if both are None.
143     #[inline]
144     pub fn or(self, optb: Option<T>) -> Option<T> {
145         match self {
146             Some(opta) => Some(opta),
147             _ => optb
148         }
149     }
150
151     /// Update an optional value by optionally running its content by reference
152     /// through a function that returns an option.
153     #[inline]
154     pub fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>)
155                             -> Option<U> {
156         match *self {
157             Some(ref x) => f(x),
158             None => None
159         }
160     }
161
162     /// Filters an optional value using given function.
163     #[inline(always)]
164     pub fn filtered<'a>(self, f: &fn(t: &'a T) -> bool) -> Option<T> {
165         match self {
166             Some(x) => if(f(&x)) {Some(x)} else {None},
167             None => None
168         }
169     }
170
171     /// Maps a `some` value from one type to another by reference
172     #[inline]
173     pub fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option<U> {
174         match *self { Some(ref x) => Some(f(x)), None => None }
175     }
176
177     /// As `map`, but consumes the option and gives `f` ownership to avoid
178     /// copying.
179     #[inline]
180     pub fn map_consume<U>(self, f: &fn(v: T) -> U) -> Option<U> {
181         match self { None => None, Some(v) => Some(f(v)) }
182     }
183
184     /// Applies a function to the contained value or returns a default
185     #[inline]
186     pub fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
187         match *self { None => def, Some(ref t) => f(t) }
188     }
189
190     /// As `map_default`, but consumes the option and gives `f`
191     /// ownership to avoid copying.
192     #[inline]
193     pub fn map_consume_default<U>(self, def: U, f: &fn(v: T) -> U) -> U {
194         match self { None => def, Some(v) => f(v) }
195     }
196
197     /// Apply a function to the contained value or do nothing
198     pub fn mutate(&mut self, f: &fn(T) -> T) {
199         if self.is_some() {
200             *self = Some(f(self.swap_unwrap()));
201         }
202     }
203
204     /// Apply a function to the contained value or set it to a default
205     pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) {
206         if self.is_some() {
207             *self = Some(f(self.swap_unwrap()));
208         } else {
209             *self = Some(def);
210         }
211     }
212
213     /**
214     Gets an immutable reference to the value inside an option.
215
216     # Failure
217
218     Fails if the value equals `None`
219
220     # Safety note
221
222     In general, because this function may fail, its use is discouraged
223     (calling `get` on `None` is akin to dereferencing a null pointer).
224     Instead, prefer to use pattern matching and handle the `None`
225     case explicitly.
226      */
227     #[inline]
228     pub fn get_ref<'a>(&'a self) -> &'a T {
229         match *self {
230           Some(ref x) => x,
231           None => fail!("option::get_ref none")
232         }
233     }
234
235     /**
236     Gets a mutable reference to the value inside an option.
237
238     # Failure
239
240     Fails if the value equals `None`
241
242     # Safety note
243
244     In general, because this function may fail, its use is discouraged
245     (calling `get` on `None` is akin to dereferencing a null pointer).
246     Instead, prefer to use pattern matching and handle the `None`
247     case explicitly.
248      */
249     #[inline]
250     pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
251         match *self {
252           Some(ref mut x) => x,
253           None => fail!("option::get_mut_ref none")
254         }
255     }
256
257     #[inline]
258     pub fn unwrap(self) -> T {
259         /*!
260         Moves a value out of an option type and returns it.
261
262         Useful primarily for getting strings, vectors and unique pointers out
263         of option types without copying them.
264
265         # Failure
266
267         Fails if the value equals `None`.
268
269         # Safety note
270
271         In general, because this function may fail, its use is discouraged.
272         Instead, prefer to use pattern matching and handle the `None`
273         case explicitly.
274          */
275         match self {
276           Some(x) => x,
277           None => fail!("option::unwrap none")
278         }
279     }
280
281     /**
282      * The option dance. Moves a value out of an option type and returns it,
283      * replacing the original with `None`.
284      *
285      * # Failure
286      *
287      * Fails if the value equals `None`.
288      */
289     #[inline]
290     pub fn swap_unwrap(&mut self) -> T {
291         if self.is_none() { fail!("option::swap_unwrap none") }
292         util::replace(self, None).unwrap()
293     }
294
295     /**
296      * Gets the value out of an option, printing a specified message on
297      * failure
298      *
299      * # Failure
300      *
301      * Fails if the value equals `none`
302      */
303     #[inline]
304     pub fn expect(self, reason: &str) -> T {
305         match self {
306           Some(val) => val,
307           None => fail!(reason.to_owned()),
308         }
309     }
310 }
311
312 impl<T:Copy> Option<T> {
313     /**
314     Gets the value out of an option
315
316     # Failure
317
318     Fails if the value equals `None`
319
320     # Safety note
321
322     In general, because this function may fail, its use is discouraged
323     (calling `get` on `None` is akin to dereferencing a null pointer).
324     Instead, prefer to use pattern matching and handle the `None`
325     case explicitly.
326     */
327     #[inline]
328     pub fn get(self) -> T {
329         match self {
330           Some(x) => return x,
331           None => fail!("option::get none")
332         }
333     }
334
335     /// Returns the contained value or a default
336     #[inline]
337     pub fn get_or_default(self, def: T) -> T {
338         match self { Some(x) => x, None => def }
339     }
340
341     /// Applies a function zero or more times until the result is none.
342     #[inline]
343     pub fn while_some(self, blk: &fn(v: T) -> Option<T>) {
344         let mut opt = self;
345         while opt.is_some() {
346             opt = blk(opt.unwrap());
347         }
348     }
349 }
350
351 impl<T:Copy + Zero> Option<T> {
352     /// Returns the contained value or zero (for this type)
353     #[inline]
354     pub fn get_or_zero(self) -> T {
355         match self {
356             Some(x) => x,
357             None => Zero::zero()
358         }
359     }
360 }
361
362 impl<T> Zero for Option<T> {
363     fn zero() -> Option<T> { None }
364     fn is_zero(&self) -> bool { self.is_none() }
365 }
366
367 /// Immutable iterator over an `Option<A>`
368 pub struct OptionIterator<'self, A> {
369     priv opt: Option<&'self A>
370 }
371
372 impl<'self, A> Iterator<&'self A> for OptionIterator<'self, A> {
373     fn next(&mut self) -> Option<&'self A> {
374         util::replace(&mut self.opt, None)
375     }
376 }
377
378 /// Mutable iterator over an `Option<A>`
379 pub struct OptionMutIterator<'self, A> {
380     priv opt: Option<&'self mut A>
381 }
382
383 impl<'self, A> Iterator<&'self mut A> for OptionMutIterator<'self, A> {
384     fn next(&mut self) -> Option<&'self mut A> {
385         util::replace(&mut self.opt, None)
386     }
387 }
388
389 #[test]
390 fn test_unwrap_ptr() {
391     unsafe {
392         let x = ~0;
393         let addr_x: *int = ::cast::transmute(&*x);
394         let opt = Some(x);
395         let y = opt.unwrap();
396         let addr_y: *int = ::cast::transmute(&*y);
397         assert_eq!(addr_x, addr_y);
398     }
399 }
400
401 #[test]
402 fn test_unwrap_str() {
403     let x = ~"test";
404     let addr_x = str::as_buf(x, |buf, _len| buf);
405     let opt = Some(x);
406     let y = opt.unwrap();
407     let addr_y = str::as_buf(y, |buf, _len| buf);
408     assert_eq!(addr_x, addr_y);
409 }
410
411 #[test]
412 fn test_unwrap_resource() {
413     struct R {
414        i: @mut int,
415     }
416
417     #[unsafe_destructor]
418     impl ::ops::Drop for R {
419        fn drop(&self) { *(self.i) += 1; }
420     }
421
422     fn R(i: @mut int) -> R {
423         R {
424             i: i
425         }
426     }
427
428     let i = @mut 0;
429     {
430         let x = R(i);
431         let opt = Some(x);
432         let _y = opt.unwrap();
433     }
434     assert_eq!(*i, 1);
435 }
436
437 #[test]
438 fn test_option_dance() {
439     let x = Some(());
440     let mut y = Some(5);
441     let mut y2 = 0;
442     for x.iter().advance |_x| {
443         y2 = y.swap_unwrap();
444     }
445     assert_eq!(y2, 5);
446     assert!(y.is_none());
447 }
448 #[test] #[should_fail] #[ignore(cfg(windows))]
449 fn test_option_too_much_dance() {
450     let mut y = Some(util::NonCopyable::new());
451     let _y2 = y.swap_unwrap();
452     let _y3 = y.swap_unwrap();
453 }
454
455 #[test]
456 fn test_option_while_some() {
457     let mut i = 0;
458     do Some(10).while_some |j| {
459         i += 1;
460         if (j > 0) {
461             Some(j-1)
462         } else {
463             None
464         }
465     }
466     assert_eq!(i, 11);
467 }
468
469 #[test]
470 fn test_get_or_zero() {
471     let some_stuff = Some(42);
472     assert_eq!(some_stuff.get_or_zero(), 42);
473     let no_stuff: Option<int> = None;
474     assert_eq!(no_stuff.get_or_zero(), 0);
475 }
476
477 #[test]
478 fn test_filtered() {
479     let some_stuff = Some(42);
480     let modified_stuff = some_stuff.filtered(|&x| {x < 10});
481     assert_eq!(some_stuff.get(), 42);
482     assert!(modified_stuff.is_none());
483 }