]> git.lizzy.rs Git - rust.git/blob - src/libcore/option.rs
17192b4257b16a6b9b5a0dc11c65a7c38a375ec9
[rust.git] / src / libcore / 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 old_iter::{BaseIter, MutableIter, ExtendedIter};
50 use old_iter;
51
52 #[cfg(test)] use str;
53
54 /// The option type
55 #[deriving(Clone, Eq)]
56 pub enum Option<T> {
57     None,
58     Some(T),
59 }
60
61 impl<T:Ord> Ord for Option<T> {
62     fn lt(&self, other: &Option<T>) -> bool {
63         match (self, other) {
64             (&None, &None) => false,
65             (&None, &Some(_)) => true,
66             (&Some(_), &None) => false,
67             (&Some(ref a), &Some(ref b)) => *a < *b
68         }
69     }
70
71     fn le(&self, other: &Option<T>) -> bool {
72         match (self, other) {
73             (&None, &None) => true,
74             (&None, &Some(_)) => true,
75             (&Some(_), &None) => false,
76             (&Some(ref a), &Some(ref b)) => *a <= *b
77         }
78     }
79
80     fn ge(&self, other: &Option<T>) -> bool {
81         ! (self < other)
82     }
83
84     fn gt(&self, other: &Option<T>) -> bool {
85         ! (self <= other)
86     }
87 }
88
89 impl<T: Copy + Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
90     #[inline(always)]
91     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
101 impl<T> BaseIter<T> for Option<T> {
102     /// Performs an operation on the contained value by reference
103     #[cfg(stage0)]
104     #[inline(always)]
105     fn each(&self, f: &fn(x: &'self T) -> bool) {
106         match *self { None => (), Some(ref t) => { f(t); } }
107     }
108
109     /// Performs an operation on the contained value by reference
110     #[cfg(stage1)]
111     #[cfg(stage2)]
112     #[cfg(stage3)]
113     #[inline(always)]
114     fn each<'a>(&'a self, f: &fn(x: &'a T) -> bool) {
115         match *self { None => (), Some(ref t) => { f(t); } }
116     }
117
118     #[inline(always)]
119     fn size_hint(&self) -> Option<uint> {
120         if self.is_some() { Some(1) } else { Some(0) }
121     }
122 }
123
124 impl<T> MutableIter<T> for Option<T> {
125     #[cfg(stage0)]
126     #[inline(always)]
127     fn each_mut(&mut self, f: &fn(&'self mut T) -> bool) {
128         match *self { None => (), Some(ref mut t) => { f(t); } }
129     }
130
131     #[cfg(stage1)]
132     #[cfg(stage2)]
133     #[cfg(stage3)]
134     #[inline(always)]
135     fn each_mut<'a>(&'a mut self, f: &fn(&'a mut T) -> bool) {
136         match *self { None => (), Some(ref mut t) => { f(t); } }
137     }
138 }
139
140 impl<A> ExtendedIter<A> for Option<A> {
141     pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) {
142         old_iter::eachi(self, blk)
143     }
144     pub fn all(&self, blk: &fn(&A) -> bool) -> bool {
145         old_iter::all(self, blk)
146     }
147     pub fn any(&self, blk: &fn(&A) -> bool) -> bool {
148         old_iter::any(self, blk)
149     }
150     pub fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B {
151         old_iter::foldl(self, b0, blk)
152     }
153     pub fn position(&self, f: &fn(&A) -> bool) -> Option<uint> {
154         old_iter::position(self, f)
155     }
156     fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B] {
157         old_iter::map_to_vec(self, op)
158     }
159     fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: &fn(&A) -> IB)
160         -> ~[B] {
161         old_iter::flat_map_to_vec(self, op)
162     }
163 }
164
165 pub impl<T> Option<T> {
166     /// Returns true if the option equals `none`
167     fn is_none(&const self) -> bool {
168         match *self { None => true, Some(_) => false }
169     }
170
171     /// Returns true if the option contains some value
172     #[inline(always)]
173     fn is_some(&const self) -> bool { !self.is_none() }
174
175     #[inline(always)]
176     fn chain<U>(self, f: &fn(t: T) -> Option<U>) -> Option<U> {
177         /*!
178          * Update an optional value by optionally running its content through a
179          * function that returns an option.
180          */
181
182         match self {
183             Some(t) => f(t),
184             None => None
185         }
186     }
187
188     #[inline(always)]
189     fn or(self, optb: Option<T>) -> Option<T> {
190         /*!
191          * Returns the leftmost Some() value, or None if both are None.
192          */
193         match self {
194             Some(opta) => Some(opta),
195             _ => optb
196         }
197     }
198
199     /**
200      * Update an optional value by optionally running its content by reference
201      * through a function that returns an option.
202      */
203     #[cfg(stage0)]
204     #[inline(always)]
205     fn chain_ref<U>(&self, f: &fn(x: &'self T) -> Option<U>) -> Option<U> {
206         match *self { Some(ref x) => f(x), None => None }
207     }
208
209     /**
210      * Update an optional value by optionally running its content by reference
211      * through a function that returns an option.
212      */
213     #[cfg(stage1)]
214     #[cfg(stage2)]
215     #[cfg(stage3)]
216     #[inline(always)]
217     fn chain_ref<'a, U>(&'a self, f: &fn(x: &'a T) -> Option<U>) -> Option<U> {
218         match *self { Some(ref x) => f(x), None => None }
219     }
220
221     /// Maps a `some` value from one type to another by reference
222     #[cfg(stage0)]
223     #[inline(always)]
224     fn map<U>(&self, f: &fn(&'self T) -> U) -> Option<U> {
225         match *self { Some(ref x) => Some(f(x)), None => None }
226     }
227
228     /// Maps a `some` value from one type to another by reference
229     #[cfg(stage1)]
230     #[cfg(stage2)]
231     #[cfg(stage3)]
232     #[inline(always)]
233     fn map<'a, U>(&self, f: &fn(&'a T) -> U) -> Option<U> {
234         match *self { Some(ref x) => Some(f(x)), None => None }
235     }
236
237     /// As `map`, but consumes the option and gives `f` ownership to avoid
238     /// copying.
239     #[inline(always)]
240     fn map_consume<U>(self, f: &fn(v: T) -> U) -> Option<U> {
241         match self { None => None, Some(v) => Some(f(v)) }
242     }
243
244     /// Applies a function to the contained value or returns a default
245     #[cfg(stage0)]
246     #[inline(always)]
247     fn map_default<U>(&self, def: U, f: &fn(&'self T) -> U) -> U {
248         match *self { None => def, Some(ref t) => f(t) }
249     }
250
251     /// Applies a function to the contained value or returns a default
252     #[cfg(stage1)]
253     #[cfg(stage2)]
254     #[cfg(stage3)]
255     #[inline(always)]
256     fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
257         match *self { None => def, Some(ref t) => f(t) }
258     }
259
260     /// As `map_default`, but consumes the option and gives `f`
261     /// ownership to avoid copying.
262     #[inline(always)]
263     fn map_consume_default<U>(self, def: U, f: &fn(v: T) -> U) -> U {
264         match self { None => def, Some(v) => f(v) }
265     }
266
267     /// Apply a function to the contained value or do nothing
268     fn mutate(&mut self, f: &fn(T) -> T) {
269         if self.is_some() {
270             *self = Some(f(self.swap_unwrap()));
271         }
272     }
273
274     /// Apply a function to the contained value or set it to a default
275     fn mutate_default(&mut self, def: T, f: &fn(T) -> T) {
276         if self.is_some() {
277             *self = Some(f(self.swap_unwrap()));
278         } else {
279             *self = Some(def);
280         }
281     }
282
283     /**
284     Gets an immutable reference to the value inside an option.
285
286     # Failure
287
288     Fails if the value equals `None`
289
290     # Safety note
291
292     In general, because this function may fail, its use is discouraged
293     (calling `get` on `None` is akin to dereferencing a null pointer).
294     Instead, prefer to use pattern matching and handle the `None`
295     case explicitly.
296      */
297     #[inline(always)]
298     #[cfg(stage0)]
299     fn get_ref(&self) -> &'self T {
300         match *self {
301           Some(ref x) => x,
302           None => fail!(~"option::get_ref none")
303         }
304     }
305
306     /**
307     Gets an immutable reference to the value inside an option.
308
309     # Failure
310
311     Fails if the value equals `None`
312
313     # Safety note
314
315     In general, because this function may fail, its use is discouraged
316     (calling `get` on `None` is akin to dereferencing a null pointer).
317     Instead, prefer to use pattern matching and handle the `None`
318     case explicitly.
319      */
320     #[inline(always)]
321     #[cfg(stage1)]
322     #[cfg(stage2)]
323     #[cfg(stage3)]
324     fn get_ref<'a>(&'a self) -> &'a T {
325         match *self {
326           Some(ref x) => x,
327           None => fail!(~"option::get_ref none")
328         }
329     }
330
331     /**
332     Gets a mutable reference to the value inside an option.
333
334     # Failure
335
336     Fails if the value equals `None`
337
338     # Safety note
339
340     In general, because this function may fail, its use is discouraged
341     (calling `get` on `None` is akin to dereferencing a null pointer).
342     Instead, prefer to use pattern matching and handle the `None`
343     case explicitly.
344      */
345     #[inline(always)]
346     #[cfg(stage0)]
347     fn get_mut_ref(&mut self) -> &'self mut T {
348         match *self {
349           Some(ref mut x) => x,
350           None => fail!(~"option::get_mut_ref none")
351         }
352     }
353
354     /**
355     Gets a mutable reference to the value inside an option.
356
357     # Failure
358
359     Fails if the value equals `None`
360
361     # Safety note
362
363     In general, because this function may fail, its use is discouraged
364     (calling `get` on `None` is akin to dereferencing a null pointer).
365     Instead, prefer to use pattern matching and handle the `None`
366     case explicitly.
367      */
368     #[inline(always)]
369     #[cfg(stage1)]
370     #[cfg(stage2)]
371     #[cfg(stage3)]
372     fn get_mut_ref<'a>(&'a mut self) -> &'a mut T {
373         match *self {
374           Some(ref mut x) => x,
375           None => fail!(~"option::get_mut_ref none")
376         }
377     }
378
379     #[inline(always)]
380     fn unwrap(self) -> T {
381         /*!
382         Moves a value out of an option type and returns it.
383
384         Useful primarily for getting strings, vectors and unique pointers out
385         of option types without copying them.
386
387         # Failure
388
389         Fails if the value equals `None`.
390
391         # Safety note
392
393         In general, because this function may fail, its use is discouraged.
394         Instead, prefer to use pattern matching and handle the `None`
395         case explicitly.
396          */
397         match self {
398           Some(x) => x,
399           None => fail!(~"option::unwrap none")
400         }
401     }
402
403     /**
404      * The option dance. Moves a value out of an option type and returns it,
405      * replacing the original with `None`.
406      *
407      * # Failure
408      *
409      * Fails if the value equals `None`.
410      */
411     #[inline(always)]
412     fn swap_unwrap(&mut self) -> T {
413         if self.is_none() { fail!(~"option::swap_unwrap none") }
414         util::replace(self, None).unwrap()
415     }
416
417     /**
418      * Gets the value out of an option, printing a specified message on
419      * failure
420      *
421      * # Failure
422      *
423      * Fails if the value equals `none`
424      */
425     #[inline(always)]
426     fn expect(self, reason: &str) -> T {
427         match self {
428           Some(val) => val,
429           None => fail!(reason.to_owned()),
430         }
431     }
432 }
433
434 pub impl<T:Copy> Option<T> {
435     /**
436     Gets the value out of an option
437
438     # Failure
439
440     Fails if the value equals `None`
441
442     # Safety note
443
444     In general, because this function may fail, its use is discouraged
445     (calling `get` on `None` is akin to dereferencing a null pointer).
446     Instead, prefer to use pattern matching and handle the `None`
447     case explicitly.
448     */
449     #[inline(always)]
450     fn get(self) -> T {
451         match self {
452           Some(copy x) => return x,
453           None => fail!(~"option::get none")
454         }
455     }
456
457     /// Returns the contained value or a default
458     #[inline(always)]
459     fn get_or_default(self, def: T) -> T {
460         match self { Some(copy x) => x, None => def }
461     }
462
463     /// Applies a function zero or more times until the result is none.
464     #[inline(always)]
465     fn while_some(self, blk: &fn(v: T) -> Option<T>) {
466         let mut opt = self;
467         while opt.is_some() {
468             opt = blk(opt.unwrap());
469         }
470     }
471 }
472
473 pub impl<T:Copy + Zero> Option<T> {
474     /// Returns the contained value or zero (for this type)
475     #[inline(always)]
476     fn get_or_zero(self) -> T {
477         match self { Some(copy x) => x, None => Zero::zero() }
478     }
479 }
480
481 #[test]
482 fn test_unwrap_ptr() {
483     unsafe {
484         let x = ~0;
485         let addr_x: *int = ::cast::transmute(&*x);
486         let opt = Some(x);
487         let y = opt.unwrap();
488         let addr_y: *int = ::cast::transmute(&*y);
489         assert!(addr_x == addr_y);
490     }
491 }
492
493 #[test]
494 fn test_unwrap_str() {
495     let x = ~"test";
496     let addr_x = str::as_buf(x, |buf, _len| buf);
497     let opt = Some(x);
498     let y = opt.unwrap();
499     let addr_y = str::as_buf(y, |buf, _len| buf);
500     assert!(addr_x == addr_y);
501 }
502
503 #[test]
504 fn test_unwrap_resource() {
505     struct R {
506        i: @mut int,
507     }
508
509     #[unsafe_destructor]
510     impl ::ops::Drop for R {
511        fn finalize(&self) { *(self.i) += 1; }
512     }
513
514     fn R(i: @mut int) -> R {
515         R {
516             i: i
517         }
518     }
519
520     let i = @mut 0;
521     {
522         let x = R(i);
523         let opt = Some(x);
524         let _y = opt.unwrap();
525     }
526     assert!(*i == 1);
527 }
528
529 #[test]
530 fn test_option_dance() {
531     let x = Some(());
532     let mut y = Some(5);
533     let mut y2 = 0;
534     for x.each |_x| {
535         y2 = y.swap_unwrap();
536     }
537     assert!(y2 == 5);
538     assert!(y.is_none());
539 }
540 #[test] #[should_fail] #[ignore(cfg(windows))]
541 fn test_option_too_much_dance() {
542     let mut y = Some(util::NonCopyable());
543     let _y2 = y.swap_unwrap();
544     let _y3 = y.swap_unwrap();
545 }
546
547 #[test]
548 fn test_option_while_some() {
549     let mut i = 0;
550     do Some(10).while_some |j| {
551         i += 1;
552         if (j > 0) {
553             Some(j-1)
554         } else {
555             None
556         }
557     }
558     assert!(i == 11);
559 }
560
561 #[test]
562 fn test_get_or_zero() {
563     let some_stuff = Some(42);
564     assert!(some_stuff.get_or_zero() == 42);
565     let no_stuff: Option<int> = None;
566     assert!(no_stuff.get_or_zero() == 0);
567 }
568
569 // Local Variables:
570 // mode: rust;
571 // fill-column: 78;
572 // indent-tabs-mode: nil
573 // c-basic-offset: 4
574 // buffer-file-coding-system: utf-8-unix
575 // End: