]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2012-2014 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 | ||
54a0048b | 11 | //! Optional values. |
1a4d82fc | 12 | //! |
9e0c209e SL |
13 | //! Type [`Option`] represents an optional value: every [`Option`] |
14 | //! is either [`Some`] and contains a value, or [`None`], and | |
15 | //! does not. [`Option`] types are very common in Rust code, as | |
1a4d82fc JJ |
16 | //! they have a number of uses: |
17 | //! | |
18 | //! * Initial values | |
19 | //! * Return values for functions that are not defined | |
20 | //! over their entire input range (partial functions) | |
21 | //! * Return value for otherwise reporting simple errors, where `None` is | |
22 | //! returned on error | |
23 | //! * Optional struct fields | |
24 | //! * Struct fields that can be loaned or "taken" | |
25 | //! * Optional function arguments | |
26 | //! * Nullable pointers | |
27 | //! * Swapping things out of difficult situations | |
28 | //! | |
9e0c209e SL |
29 | //! [`Option`]s are commonly paired with pattern matching to query the presence |
30 | //! of a value and take action, always accounting for the [`None`] case. | |
1a4d82fc JJ |
31 | //! |
32 | //! ``` | |
33 | //! fn divide(numerator: f64, denominator: f64) -> Option<f64> { | |
34 | //! if denominator == 0.0 { | |
35 | //! None | |
36 | //! } else { | |
37 | //! Some(numerator / denominator) | |
38 | //! } | |
39 | //! } | |
40 | //! | |
41 | //! // The return value of the function is an option | |
42 | //! let result = divide(2.0, 3.0); | |
43 | //! | |
44 | //! // Pattern match to retrieve the value | |
45 | //! match result { | |
46 | //! // The division was valid | |
47 | //! Some(x) => println!("Result: {}", x), | |
48 | //! // The division was invalid | |
c1a9b12d | 49 | //! None => println!("Cannot divide by 0"), |
1a4d82fc JJ |
50 | //! } |
51 | //! ``` | |
52 | //! | |
53 | // | |
54 | // FIXME: Show how `Option` is used in practice, with lots of methods | |
55 | // | |
56 | //! # Options and pointers ("nullable" pointers) | |
57 | //! | |
58 | //! Rust's pointer types must always point to a valid location; there are | |
59 | //! no "null" pointers. Instead, Rust has *optional* pointers, like | |
9e0c209e | 60 | //! the optional owned box, [`Option`]`<`[`Box<T>`]`>`. |
1a4d82fc | 61 | //! |
9e0c209e | 62 | //! The following example uses [`Option`] to create an optional box of |
32a655c1 | 63 | //! [`i32`]. Notice that in order to use the inner [`i32`] value first, the |
1a4d82fc | 64 | //! `check_optional` function needs to use pattern matching to |
9e0c209e SL |
65 | //! determine whether the box has a value (i.e. it is [`Some(...)`][`Some`]) or |
66 | //! not ([`None`]). | |
1a4d82fc JJ |
67 | //! |
68 | //! ``` | |
85aaf69f | 69 | //! let optional: Option<Box<i32>> = None; |
1a4d82fc JJ |
70 | //! check_optional(&optional); |
71 | //! | |
85aaf69f | 72 | //! let optional: Option<Box<i32>> = Some(Box::new(9000)); |
1a4d82fc JJ |
73 | //! check_optional(&optional); |
74 | //! | |
85aaf69f | 75 | //! fn check_optional(optional: &Option<Box<i32>>) { |
1a4d82fc | 76 | //! match *optional { |
32a655c1 SL |
77 | //! Some(ref p) => println!("has value {}", p), |
78 | //! None => println!("has no value"), | |
1a4d82fc JJ |
79 | //! } |
80 | //! } | |
81 | //! ``` | |
82 | //! | |
9e0c209e | 83 | //! This usage of [`Option`] to create safe nullable pointers is so |
1a4d82fc | 84 | //! common that Rust does special optimizations to make the |
9e0c209e | 85 | //! representation of [`Option`]`<`[`Box<T>`]`>` a single pointer. Optional pointers |
1a4d82fc JJ |
86 | //! in Rust are stored as efficiently as any other pointer type. |
87 | //! | |
88 | //! # Examples | |
89 | //! | |
9e0c209e | 90 | //! Basic pattern matching on [`Option`]: |
1a4d82fc JJ |
91 | //! |
92 | //! ``` | |
93 | //! let msg = Some("howdy"); | |
94 | //! | |
95 | //! // Take a reference to the contained string | |
54a0048b SL |
96 | //! if let Some(ref m) = msg { |
97 | //! println!("{}", *m); | |
1a4d82fc JJ |
98 | //! } |
99 | //! | |
100 | //! // Remove the contained string, destroying the Option | |
54a0048b | 101 | //! let unwrapped_msg = msg.unwrap_or("default message"); |
1a4d82fc JJ |
102 | //! ``` |
103 | //! | |
9e0c209e | 104 | //! Initialize a result to [`None`] before a loop: |
1a4d82fc JJ |
105 | //! |
106 | //! ``` | |
85aaf69f | 107 | //! enum Kingdom { Plant(u32, &'static str), Animal(u32, &'static str) } |
1a4d82fc JJ |
108 | //! |
109 | //! // A list of data to search through. | |
110 | //! let all_the_big_things = [ | |
111 | //! Kingdom::Plant(250, "redwood"), | |
112 | //! Kingdom::Plant(230, "noble fir"), | |
113 | //! Kingdom::Plant(229, "sugar pine"), | |
114 | //! Kingdom::Animal(25, "blue whale"), | |
115 | //! Kingdom::Animal(19, "fin whale"), | |
116 | //! Kingdom::Animal(15, "north pacific right whale"), | |
117 | //! ]; | |
118 | //! | |
119 | //! // We're going to search for the name of the biggest animal, | |
120 | //! // but to start with we've just got `None`. | |
121 | //! let mut name_of_biggest_animal = None; | |
122 | //! let mut size_of_biggest_animal = 0; | |
62682a34 | 123 | //! for big_thing in &all_the_big_things { |
1a4d82fc JJ |
124 | //! match *big_thing { |
125 | //! Kingdom::Animal(size, name) if size > size_of_biggest_animal => { | |
126 | //! // Now we've found the name of some big animal | |
127 | //! size_of_biggest_animal = size; | |
128 | //! name_of_biggest_animal = Some(name); | |
129 | //! } | |
130 | //! Kingdom::Animal(..) | Kingdom::Plant(..) => () | |
131 | //! } | |
132 | //! } | |
133 | //! | |
134 | //! match name_of_biggest_animal { | |
135 | //! Some(name) => println!("the biggest animal is {}", name), | |
c1a9b12d | 136 | //! None => println!("there are no animals :("), |
1a4d82fc JJ |
137 | //! } |
138 | //! ``` | |
9e0c209e SL |
139 | //! |
140 | //! [`Option`]: enum.Option.html | |
141 | //! [`Some`]: enum.Option.html#variant.Some | |
142 | //! [`None`]: enum.Option.html#variant.None | |
143 | //! [`Box<T>`]: ../../std/boxed/struct.Box.html | |
144 | //! [`i32`]: ../../std/primitive.i32.html | |
1a4d82fc | 145 | |
85aaf69f | 146 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 147 | |
c30ab7b3 | 148 | use iter::{FromIterator, FusedIterator, TrustedLen}; |
1a4d82fc | 149 | use mem; |
1a4d82fc JJ |
150 | |
151 | // Note that this is not a lang item per se, but it has a hidden dependency on | |
152 | // `Iterator`, which is one. The compiler assumes that the `next` method of | |
153 | // `Iterator` is an enumeration with one type parameter and two variants, | |
154 | // which basically means it must be `Option`. | |
155 | ||
d9579d0f | 156 | /// The `Option` type. See [the module level documentation](index.html) for more. |
85aaf69f SL |
157 | #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] |
158 | #[stable(feature = "rust1", since = "1.0.0")] | |
1a4d82fc JJ |
159 | pub enum Option<T> { |
160 | /// No value | |
85aaf69f | 161 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
162 | None, |
163 | /// Some value `T` | |
85aaf69f | 164 | #[stable(feature = "rust1", since = "1.0.0")] |
9e0c209e | 165 | Some(#[stable(feature = "rust1", since = "1.0.0")] T), |
1a4d82fc JJ |
166 | } |
167 | ||
168 | ///////////////////////////////////////////////////////////////////////////// | |
169 | // Type implementation | |
170 | ///////////////////////////////////////////////////////////////////////////// | |
171 | ||
172 | impl<T> Option<T> { | |
173 | ///////////////////////////////////////////////////////////////////////// | |
174 | // Querying the contained values | |
175 | ///////////////////////////////////////////////////////////////////////// | |
176 | ||
9e0c209e | 177 | /// Returns `true` if the option is a `Some` value. |
1a4d82fc | 178 | /// |
c34b1796 | 179 | /// # Examples |
1a4d82fc JJ |
180 | /// |
181 | /// ``` | |
85aaf69f | 182 | /// let x: Option<u32> = Some(2); |
1a4d82fc JJ |
183 | /// assert_eq!(x.is_some(), true); |
184 | /// | |
85aaf69f | 185 | /// let x: Option<u32> = None; |
1a4d82fc JJ |
186 | /// assert_eq!(x.is_some(), false); |
187 | /// ``` | |
188 | #[inline] | |
85aaf69f | 189 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
190 | pub fn is_some(&self) -> bool { |
191 | match *self { | |
192 | Some(_) => true, | |
c1a9b12d | 193 | None => false, |
1a4d82fc JJ |
194 | } |
195 | } | |
196 | ||
9e0c209e | 197 | /// Returns `true` if the option is a `None` value. |
1a4d82fc | 198 | /// |
c34b1796 | 199 | /// # Examples |
1a4d82fc JJ |
200 | /// |
201 | /// ``` | |
85aaf69f | 202 | /// let x: Option<u32> = Some(2); |
1a4d82fc JJ |
203 | /// assert_eq!(x.is_none(), false); |
204 | /// | |
85aaf69f | 205 | /// let x: Option<u32> = None; |
1a4d82fc JJ |
206 | /// assert_eq!(x.is_none(), true); |
207 | /// ``` | |
208 | #[inline] | |
85aaf69f | 209 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
210 | pub fn is_none(&self) -> bool { |
211 | !self.is_some() | |
212 | } | |
213 | ||
214 | ///////////////////////////////////////////////////////////////////////// | |
215 | // Adapter for working with references | |
216 | ///////////////////////////////////////////////////////////////////////// | |
217 | ||
9e0c209e | 218 | /// Converts from `Option<T>` to `Option<&T>`. |
1a4d82fc | 219 | /// |
c34b1796 | 220 | /// # Examples |
1a4d82fc | 221 | /// |
85aaf69f | 222 | /// Convert an `Option<String>` into an `Option<usize>`, preserving the original. |
9e0c209e | 223 | /// The [`map`] method takes the `self` argument by value, consuming the original, |
1a4d82fc JJ |
224 | /// so this technique uses `as_ref` to first take an `Option` to a reference |
225 | /// to the value inside the original. | |
226 | /// | |
9e0c209e SL |
227 | /// [`map`]: enum.Option.html#method.map |
228 | /// | |
1a4d82fc JJ |
229 | /// ``` |
230 | /// let num_as_str: Option<String> = Some("10".to_string()); | |
231 | /// // First, cast `Option<String>` to `Option<&String>` with `as_ref`, | |
232 | /// // then consume *that* with `map`, leaving `num_as_str` on the stack. | |
85aaf69f | 233 | /// let num_as_int: Option<usize> = num_as_str.as_ref().map(|n| n.len()); |
1a4d82fc JJ |
234 | /// println!("still can print num_as_str: {:?}", num_as_str); |
235 | /// ``` | |
236 | #[inline] | |
85aaf69f | 237 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 238 | pub fn as_ref(&self) -> Option<&T> { |
1a4d82fc JJ |
239 | match *self { |
240 | Some(ref x) => Some(x), | |
c1a9b12d | 241 | None => None, |
1a4d82fc JJ |
242 | } |
243 | } | |
244 | ||
9e0c209e | 245 | /// Converts from `Option<T>` to `Option<&mut T>`. |
1a4d82fc | 246 | /// |
c34b1796 | 247 | /// # Examples |
1a4d82fc JJ |
248 | /// |
249 | /// ``` | |
85aaf69f | 250 | /// let mut x = Some(2); |
1a4d82fc JJ |
251 | /// match x.as_mut() { |
252 | /// Some(v) => *v = 42, | |
253 | /// None => {}, | |
254 | /// } | |
85aaf69f | 255 | /// assert_eq!(x, Some(42)); |
1a4d82fc JJ |
256 | /// ``` |
257 | #[inline] | |
85aaf69f | 258 | #[stable(feature = "rust1", since = "1.0.0")] |
e9174d1e | 259 | pub fn as_mut(&mut self) -> Option<&mut T> { |
1a4d82fc JJ |
260 | match *self { |
261 | Some(ref mut x) => Some(x), | |
c1a9b12d | 262 | None => None, |
1a4d82fc JJ |
263 | } |
264 | } | |
265 | ||
1a4d82fc JJ |
266 | ///////////////////////////////////////////////////////////////////////// |
267 | // Getting to contained values | |
268 | ///////////////////////////////////////////////////////////////////////// | |
269 | ||
9cc50fc6 | 270 | /// Unwraps an option, yielding the content of a `Some`. |
1a4d82fc JJ |
271 | /// |
272 | /// # Panics | |
273 | /// | |
274 | /// Panics if the value is a `None` with a custom panic message provided by | |
275 | /// `msg`. | |
276 | /// | |
c34b1796 | 277 | /// # Examples |
1a4d82fc JJ |
278 | /// |
279 | /// ``` | |
280 | /// let x = Some("value"); | |
281 | /// assert_eq!(x.expect("the world is ending"), "value"); | |
282 | /// ``` | |
283 | /// | |
c34b1796 | 284 | /// ```{.should_panic} |
1a4d82fc | 285 | /// let x: Option<&str> = None; |
62682a34 | 286 | /// x.expect("the world is ending"); // panics with `the world is ending` |
1a4d82fc JJ |
287 | /// ``` |
288 | #[inline] | |
85aaf69f | 289 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
290 | pub fn expect(self, msg: &str) -> T { |
291 | match self { | |
292 | Some(val) => val, | |
7453a54e | 293 | None => expect_failed(msg), |
1a4d82fc JJ |
294 | } |
295 | } | |
296 | ||
c34b1796 | 297 | /// Moves the value `v` out of the `Option<T>` if it is `Some(v)`. |
1a4d82fc | 298 | /// |
1a4d82fc JJ |
299 | /// In general, because this function may panic, its use is discouraged. |
300 | /// Instead, prefer to use pattern matching and handle the `None` | |
301 | /// case explicitly. | |
302 | /// | |
9e0c209e SL |
303 | /// # Panics |
304 | /// | |
305 | /// Panics if the self value equals `None`. | |
306 | /// | |
c34b1796 | 307 | /// # Examples |
1a4d82fc JJ |
308 | /// |
309 | /// ``` | |
310 | /// let x = Some("air"); | |
311 | /// assert_eq!(x.unwrap(), "air"); | |
312 | /// ``` | |
313 | /// | |
c34b1796 | 314 | /// ```{.should_panic} |
1a4d82fc JJ |
315 | /// let x: Option<&str> = None; |
316 | /// assert_eq!(x.unwrap(), "air"); // fails | |
317 | /// ``` | |
318 | #[inline] | |
85aaf69f | 319 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
320 | pub fn unwrap(self) -> T { |
321 | match self { | |
322 | Some(val) => val, | |
323 | None => panic!("called `Option::unwrap()` on a `None` value"), | |
324 | } | |
325 | } | |
326 | ||
327 | /// Returns the contained value or a default. | |
328 | /// | |
c34b1796 | 329 | /// # Examples |
1a4d82fc JJ |
330 | /// |
331 | /// ``` | |
332 | /// assert_eq!(Some("car").unwrap_or("bike"), "car"); | |
333 | /// assert_eq!(None.unwrap_or("bike"), "bike"); | |
334 | /// ``` | |
335 | #[inline] | |
85aaf69f | 336 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
337 | pub fn unwrap_or(self, def: T) -> T { |
338 | match self { | |
339 | Some(x) => x, | |
c1a9b12d | 340 | None => def, |
1a4d82fc JJ |
341 | } |
342 | } | |
343 | ||
344 | /// Returns the contained value or computes it from a closure. | |
345 | /// | |
c34b1796 | 346 | /// # Examples |
1a4d82fc JJ |
347 | /// |
348 | /// ``` | |
c34b1796 | 349 | /// let k = 10; |
85aaf69f SL |
350 | /// assert_eq!(Some(4).unwrap_or_else(|| 2 * k), 4); |
351 | /// assert_eq!(None.unwrap_or_else(|| 2 * k), 20); | |
1a4d82fc JJ |
352 | /// ``` |
353 | #[inline] | |
85aaf69f | 354 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
355 | pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T { |
356 | match self { | |
357 | Some(x) => x, | |
c1a9b12d | 358 | None => f(), |
1a4d82fc JJ |
359 | } |
360 | } | |
361 | ||
362 | ///////////////////////////////////////////////////////////////////////// | |
363 | // Transforming contained values | |
364 | ///////////////////////////////////////////////////////////////////////// | |
365 | ||
9e0c209e | 366 | /// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value. |
1a4d82fc | 367 | /// |
c34b1796 | 368 | /// # Examples |
1a4d82fc | 369 | /// |
85aaf69f | 370 | /// Convert an `Option<String>` into an `Option<usize>`, consuming the original: |
1a4d82fc JJ |
371 | /// |
372 | /// ``` | |
62682a34 SL |
373 | /// let maybe_some_string = Some(String::from("Hello, World!")); |
374 | /// // `Option::map` takes self *by value*, consuming `maybe_some_string` | |
375 | /// let maybe_some_len = maybe_some_string.map(|s| s.len()); | |
376 | /// | |
377 | /// assert_eq!(maybe_some_len, Some(13)); | |
1a4d82fc JJ |
378 | /// ``` |
379 | #[inline] | |
85aaf69f | 380 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
381 | pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { |
382 | match self { | |
383 | Some(x) => Some(f(x)), | |
c1a9b12d | 384 | None => None, |
1a4d82fc JJ |
385 | } |
386 | } | |
387 | ||
62682a34 SL |
388 | /// Applies a function to the contained value (if any), |
389 | /// or returns a `default` (if not). | |
1a4d82fc | 390 | /// |
c34b1796 | 391 | /// # Examples |
1a4d82fc JJ |
392 | /// |
393 | /// ``` | |
394 | /// let x = Some("foo"); | |
85aaf69f | 395 | /// assert_eq!(x.map_or(42, |v| v.len()), 3); |
1a4d82fc JJ |
396 | /// |
397 | /// let x: Option<&str> = None; | |
85aaf69f | 398 | /// assert_eq!(x.map_or(42, |v| v.len()), 42); |
1a4d82fc JJ |
399 | /// ``` |
400 | #[inline] | |
85aaf69f | 401 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 402 | pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U { |
1a4d82fc JJ |
403 | match self { |
404 | Some(t) => f(t), | |
62682a34 | 405 | None => default, |
1a4d82fc JJ |
406 | } |
407 | } | |
408 | ||
62682a34 SL |
409 | /// Applies a function to the contained value (if any), |
410 | /// or computes a `default` (if not). | |
1a4d82fc | 411 | /// |
c34b1796 | 412 | /// # Examples |
1a4d82fc JJ |
413 | /// |
414 | /// ``` | |
85aaf69f | 415 | /// let k = 21; |
1a4d82fc JJ |
416 | /// |
417 | /// let x = Some("foo"); | |
85aaf69f | 418 | /// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 3); |
1a4d82fc JJ |
419 | /// |
420 | /// let x: Option<&str> = None; | |
85aaf69f | 421 | /// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 42); |
1a4d82fc JJ |
422 | /// ``` |
423 | #[inline] | |
85aaf69f | 424 | #[stable(feature = "rust1", since = "1.0.0")] |
62682a34 | 425 | pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U { |
1a4d82fc JJ |
426 | match self { |
427 | Some(t) => f(t), | |
c1a9b12d | 428 | None => default(), |
1a4d82fc JJ |
429 | } |
430 | } | |
431 | ||
9e0c209e SL |
432 | /// Transforms the `Option<T>` into a [`Result<T, E>`], mapping `Some(v)` to |
433 | /// [`Ok(v)`] and `None` to [`Err(err)`][Err]. | |
434 | /// | |
435 | /// [`Result<T, E>`]: ../../std/result/enum.Result.html | |
436 | /// [`Ok(v)`]: ../../std/result/enum.Result.html#variant.Ok | |
437 | /// [Err]: ../../std/result/enum.Result.html#variant.Err | |
1a4d82fc | 438 | /// |
c34b1796 | 439 | /// # Examples |
1a4d82fc JJ |
440 | /// |
441 | /// ``` | |
442 | /// let x = Some("foo"); | |
85aaf69f | 443 | /// assert_eq!(x.ok_or(0), Ok("foo")); |
1a4d82fc JJ |
444 | /// |
445 | /// let x: Option<&str> = None; | |
85aaf69f | 446 | /// assert_eq!(x.ok_or(0), Err(0)); |
1a4d82fc JJ |
447 | /// ``` |
448 | #[inline] | |
c34b1796 | 449 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
450 | pub fn ok_or<E>(self, err: E) -> Result<T, E> { |
451 | match self { | |
452 | Some(v) => Ok(v), | |
453 | None => Err(err), | |
454 | } | |
455 | } | |
456 | ||
9e0c209e SL |
457 | /// Transforms the `Option<T>` into a [`Result<T, E>`], mapping `Some(v)` to |
458 | /// [`Ok(v)`] and `None` to [`Err(err())`][Err]. | |
459 | /// | |
460 | /// [`Result<T, E>`]: ../../std/result/enum.Result.html | |
461 | /// [`Ok(v)`]: ../../std/result/enum.Result.html#variant.Ok | |
462 | /// [Err]: ../../std/result/enum.Result.html#variant.Err | |
1a4d82fc | 463 | /// |
c34b1796 | 464 | /// # Examples |
1a4d82fc JJ |
465 | /// |
466 | /// ``` | |
467 | /// let x = Some("foo"); | |
85aaf69f | 468 | /// assert_eq!(x.ok_or_else(|| 0), Ok("foo")); |
1a4d82fc JJ |
469 | /// |
470 | /// let x: Option<&str> = None; | |
85aaf69f | 471 | /// assert_eq!(x.ok_or_else(|| 0), Err(0)); |
1a4d82fc JJ |
472 | /// ``` |
473 | #[inline] | |
c34b1796 | 474 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
475 | pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> { |
476 | match self { | |
477 | Some(v) => Ok(v), | |
478 | None => Err(err()), | |
479 | } | |
480 | } | |
481 | ||
482 | ///////////////////////////////////////////////////////////////////////// | |
483 | // Iterator constructors | |
484 | ///////////////////////////////////////////////////////////////////////// | |
485 | ||
486 | /// Returns an iterator over the possibly contained value. | |
487 | /// | |
c34b1796 | 488 | /// # Examples |
1a4d82fc JJ |
489 | /// |
490 | /// ``` | |
85aaf69f | 491 | /// let x = Some(4); |
1a4d82fc JJ |
492 | /// assert_eq!(x.iter().next(), Some(&4)); |
493 | /// | |
85aaf69f | 494 | /// let x: Option<u32> = None; |
1a4d82fc JJ |
495 | /// assert_eq!(x.iter().next(), None); |
496 | /// ``` | |
497 | #[inline] | |
85aaf69f | 498 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
499 | pub fn iter(&self) -> Iter<T> { |
500 | Iter { inner: Item { opt: self.as_ref() } } | |
501 | } | |
502 | ||
503 | /// Returns a mutable iterator over the possibly contained value. | |
504 | /// | |
c34b1796 | 505 | /// # Examples |
1a4d82fc JJ |
506 | /// |
507 | /// ``` | |
85aaf69f | 508 | /// let mut x = Some(4); |
1a4d82fc | 509 | /// match x.iter_mut().next() { |
b039eaaf | 510 | /// Some(v) => *v = 42, |
1a4d82fc JJ |
511 | /// None => {}, |
512 | /// } | |
513 | /// assert_eq!(x, Some(42)); | |
514 | /// | |
85aaf69f | 515 | /// let mut x: Option<u32> = None; |
1a4d82fc JJ |
516 | /// assert_eq!(x.iter_mut().next(), None); |
517 | /// ``` | |
518 | #[inline] | |
c34b1796 | 519 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
520 | pub fn iter_mut(&mut self) -> IterMut<T> { |
521 | IterMut { inner: Item { opt: self.as_mut() } } | |
522 | } | |
523 | ||
1a4d82fc JJ |
524 | ///////////////////////////////////////////////////////////////////////// |
525 | // Boolean operations on the values, eager and lazy | |
526 | ///////////////////////////////////////////////////////////////////////// | |
527 | ||
528 | /// Returns `None` if the option is `None`, otherwise returns `optb`. | |
529 | /// | |
c34b1796 | 530 | /// # Examples |
1a4d82fc JJ |
531 | /// |
532 | /// ``` | |
85aaf69f | 533 | /// let x = Some(2); |
1a4d82fc JJ |
534 | /// let y: Option<&str> = None; |
535 | /// assert_eq!(x.and(y), None); | |
536 | /// | |
85aaf69f | 537 | /// let x: Option<u32> = None; |
1a4d82fc JJ |
538 | /// let y = Some("foo"); |
539 | /// assert_eq!(x.and(y), None); | |
540 | /// | |
85aaf69f | 541 | /// let x = Some(2); |
1a4d82fc JJ |
542 | /// let y = Some("foo"); |
543 | /// assert_eq!(x.and(y), Some("foo")); | |
544 | /// | |
85aaf69f | 545 | /// let x: Option<u32> = None; |
1a4d82fc JJ |
546 | /// let y: Option<&str> = None; |
547 | /// assert_eq!(x.and(y), None); | |
548 | /// ``` | |
549 | #[inline] | |
85aaf69f | 550 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
551 | pub fn and<U>(self, optb: Option<U>) -> Option<U> { |
552 | match self { | |
553 | Some(_) => optb, | |
554 | None => None, | |
555 | } | |
556 | } | |
557 | ||
558 | /// Returns `None` if the option is `None`, otherwise calls `f` with the | |
559 | /// wrapped value and returns the result. | |
560 | /// | |
85aaf69f SL |
561 | /// Some languages call this operation flatmap. |
562 | /// | |
c34b1796 | 563 | /// # Examples |
1a4d82fc JJ |
564 | /// |
565 | /// ``` | |
85aaf69f SL |
566 | /// fn sq(x: u32) -> Option<u32> { Some(x * x) } |
567 | /// fn nope(_: u32) -> Option<u32> { None } | |
1a4d82fc JJ |
568 | /// |
569 | /// assert_eq!(Some(2).and_then(sq).and_then(sq), Some(16)); | |
570 | /// assert_eq!(Some(2).and_then(sq).and_then(nope), None); | |
571 | /// assert_eq!(Some(2).and_then(nope).and_then(sq), None); | |
572 | /// assert_eq!(None.and_then(sq).and_then(sq), None); | |
573 | /// ``` | |
574 | #[inline] | |
85aaf69f | 575 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
576 | pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> { |
577 | match self { | |
578 | Some(x) => f(x), | |
579 | None => None, | |
580 | } | |
581 | } | |
582 | ||
583 | /// Returns the option if it contains a value, otherwise returns `optb`. | |
584 | /// | |
c34b1796 | 585 | /// # Examples |
1a4d82fc JJ |
586 | /// |
587 | /// ``` | |
85aaf69f | 588 | /// let x = Some(2); |
1a4d82fc | 589 | /// let y = None; |
85aaf69f | 590 | /// assert_eq!(x.or(y), Some(2)); |
1a4d82fc JJ |
591 | /// |
592 | /// let x = None; | |
85aaf69f SL |
593 | /// let y = Some(100); |
594 | /// assert_eq!(x.or(y), Some(100)); | |
1a4d82fc | 595 | /// |
85aaf69f SL |
596 | /// let x = Some(2); |
597 | /// let y = Some(100); | |
598 | /// assert_eq!(x.or(y), Some(2)); | |
1a4d82fc | 599 | /// |
85aaf69f | 600 | /// let x: Option<u32> = None; |
1a4d82fc JJ |
601 | /// let y = None; |
602 | /// assert_eq!(x.or(y), None); | |
603 | /// ``` | |
604 | #[inline] | |
85aaf69f | 605 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
606 | pub fn or(self, optb: Option<T>) -> Option<T> { |
607 | match self { | |
608 | Some(_) => self, | |
c1a9b12d | 609 | None => optb, |
1a4d82fc JJ |
610 | } |
611 | } | |
612 | ||
613 | /// Returns the option if it contains a value, otherwise calls `f` and | |
614 | /// returns the result. | |
615 | /// | |
c34b1796 | 616 | /// # Examples |
1a4d82fc JJ |
617 | /// |
618 | /// ``` | |
619 | /// fn nobody() -> Option<&'static str> { None } | |
620 | /// fn vikings() -> Option<&'static str> { Some("vikings") } | |
621 | /// | |
622 | /// assert_eq!(Some("barbarians").or_else(vikings), Some("barbarians")); | |
623 | /// assert_eq!(None.or_else(vikings), Some("vikings")); | |
624 | /// assert_eq!(None.or_else(nobody), None); | |
625 | /// ``` | |
626 | #[inline] | |
85aaf69f | 627 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
628 | pub fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> { |
629 | match self { | |
630 | Some(_) => self, | |
c1a9b12d | 631 | None => f(), |
1a4d82fc JJ |
632 | } |
633 | } | |
634 | ||
8bb4bdeb XL |
635 | ///////////////////////////////////////////////////////////////////////// |
636 | // Entry-like operations to insert if None and return a reference | |
637 | ///////////////////////////////////////////////////////////////////////// | |
638 | ||
639 | /// Inserts `v` into the option if it is `None`, then | |
640 | /// returns a mutable reference to the contained value. | |
641 | /// | |
642 | /// # Examples | |
643 | /// | |
644 | /// ``` | |
645 | /// #![feature(option_entry)] | |
646 | /// | |
647 | /// let mut x = None; | |
648 | /// | |
649 | /// { | |
650 | /// let y: &mut u32 = x.get_or_insert(5); | |
651 | /// assert_eq!(y, &5); | |
652 | /// | |
653 | /// *y = 7; | |
654 | /// } | |
655 | /// | |
656 | /// assert_eq!(x, Some(7)); | |
657 | /// ``` | |
658 | #[inline] | |
659 | #[unstable(feature = "option_entry", issue = "39288")] | |
660 | pub fn get_or_insert(&mut self, v: T) -> &mut T { | |
661 | match *self { | |
662 | None => *self = Some(v), | |
663 | _ => (), | |
664 | } | |
665 | ||
666 | match *self { | |
667 | Some(ref mut v) => v, | |
668 | _ => unreachable!(), | |
669 | } | |
670 | } | |
671 | ||
672 | /// Inserts a value computed from `f` into the option if it is `None`, then | |
673 | /// returns a mutable reference to the contained value. | |
674 | /// | |
675 | /// # Examples | |
676 | /// | |
677 | /// ``` | |
678 | /// #![feature(option_entry)] | |
679 | /// | |
680 | /// let mut x = None; | |
681 | /// | |
682 | /// { | |
683 | /// let y: &mut u32 = x.get_or_insert_with(|| 5); | |
684 | /// assert_eq!(y, &5); | |
685 | /// | |
686 | /// *y = 7; | |
687 | /// } | |
688 | /// | |
689 | /// assert_eq!(x, Some(7)); | |
690 | /// ``` | |
691 | #[inline] | |
692 | #[unstable(feature = "option_entry", issue = "39288")] | |
693 | pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T { | |
694 | match *self { | |
695 | None => *self = Some(f()), | |
696 | _ => (), | |
697 | } | |
698 | ||
699 | match *self { | |
700 | Some(ref mut v) => v, | |
701 | _ => unreachable!(), | |
702 | } | |
703 | } | |
704 | ||
1a4d82fc JJ |
705 | ///////////////////////////////////////////////////////////////////////// |
706 | // Misc | |
707 | ///////////////////////////////////////////////////////////////////////// | |
708 | ||
709 | /// Takes the value out of the option, leaving a `None` in its place. | |
710 | /// | |
c34b1796 | 711 | /// # Examples |
1a4d82fc JJ |
712 | /// |
713 | /// ``` | |
85aaf69f | 714 | /// let mut x = Some(2); |
1a4d82fc JJ |
715 | /// x.take(); |
716 | /// assert_eq!(x, None); | |
717 | /// | |
85aaf69f | 718 | /// let mut x: Option<u32> = None; |
1a4d82fc JJ |
719 | /// x.take(); |
720 | /// assert_eq!(x, None); | |
721 | /// ``` | |
722 | #[inline] | |
85aaf69f | 723 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
724 | pub fn take(&mut self) -> Option<T> { |
725 | mem::replace(self, None) | |
726 | } | |
727 | } | |
728 | ||
c34b1796 | 729 | impl<'a, T: Clone> Option<&'a T> { |
b039eaaf SL |
730 | /// Maps an `Option<&T>` to an `Option<T>` by cloning the contents of the |
731 | /// option. | |
476ff2be SL |
732 | /// |
733 | /// # Examples | |
734 | /// | |
735 | /// ``` | |
736 | /// let x = 12; | |
737 | /// let opt_x = Some(&x); | |
738 | /// assert_eq!(opt_x, Some(&12)); | |
739 | /// let cloned = opt_x.cloned(); | |
740 | /// assert_eq!(cloned, Some(12)); | |
741 | /// ``` | |
c34b1796 | 742 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 743 | pub fn cloned(self) -> Option<T> { |
c34b1796 | 744 | self.map(|t| t.clone()) |
1a4d82fc JJ |
745 | } |
746 | } | |
747 | ||
748 | impl<T: Default> Option<T> { | |
749 | /// Returns the contained value or a default | |
750 | /// | |
751 | /// Consumes the `self` argument then, if `Some`, returns the contained | |
752 | /// value, otherwise if `None`, returns the default value for that | |
753 | /// type. | |
754 | /// | |
c34b1796 | 755 | /// # Examples |
1a4d82fc JJ |
756 | /// |
757 | /// Convert a string to an integer, turning poorly-formed strings | |
758 | /// into 0 (the default value for integers). `parse` converts | |
759 | /// a string to any other type that implements `FromStr`, returning | |
760 | /// `None` on error. | |
761 | /// | |
762 | /// ``` | |
763 | /// let good_year_from_input = "1909"; | |
764 | /// let bad_year_from_input = "190blarg"; | |
85aaf69f SL |
765 | /// let good_year = good_year_from_input.parse().ok().unwrap_or_default(); |
766 | /// let bad_year = bad_year_from_input.parse().ok().unwrap_or_default(); | |
1a4d82fc | 767 | /// |
85aaf69f SL |
768 | /// assert_eq!(1909, good_year); |
769 | /// assert_eq!(0, bad_year); | |
1a4d82fc JJ |
770 | /// ``` |
771 | #[inline] | |
85aaf69f | 772 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
773 | pub fn unwrap_or_default(self) -> T { |
774 | match self { | |
775 | Some(x) => x, | |
c1a9b12d | 776 | None => Default::default(), |
1a4d82fc JJ |
777 | } |
778 | } | |
779 | } | |
780 | ||
7453a54e SL |
781 | // This is a separate function to reduce the code size of .expect() itself. |
782 | #[inline(never)] | |
783 | #[cold] | |
784 | fn expect_failed(msg: &str) -> ! { | |
785 | panic!("{}", msg) | |
786 | } | |
787 | ||
788 | ||
1a4d82fc JJ |
789 | ///////////////////////////////////////////////////////////////////////////// |
790 | // Trait implementations | |
791 | ///////////////////////////////////////////////////////////////////////////// | |
792 | ||
85aaf69f | 793 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 794 | impl<T> Default for Option<T> { |
9e0c209e | 795 | /// Returns None. |
1a4d82fc | 796 | #[inline] |
1a4d82fc JJ |
797 | fn default() -> Option<T> { None } |
798 | } | |
799 | ||
9346a6ac AL |
800 | #[stable(feature = "rust1", since = "1.0.0")] |
801 | impl<T> IntoIterator for Option<T> { | |
802 | type Item = T; | |
803 | type IntoIter = IntoIter<T>; | |
804 | ||
805 | /// Returns a consuming iterator over the possibly contained value. | |
806 | /// | |
807 | /// # Examples | |
808 | /// | |
809 | /// ``` | |
810 | /// let x = Some("string"); | |
811 | /// let v: Vec<&str> = x.into_iter().collect(); | |
812 | /// assert_eq!(v, ["string"]); | |
813 | /// | |
814 | /// let x = None; | |
815 | /// let v: Vec<&str> = x.into_iter().collect(); | |
816 | /// assert!(v.is_empty()); | |
817 | /// ``` | |
818 | #[inline] | |
819 | fn into_iter(self) -> IntoIter<T> { | |
820 | IntoIter { inner: Item { opt: self } } | |
821 | } | |
822 | } | |
823 | ||
e9174d1e SL |
824 | #[stable(since = "1.4.0", feature = "option_iter")] |
825 | impl<'a, T> IntoIterator for &'a Option<T> { | |
826 | type Item = &'a T; | |
827 | type IntoIter = Iter<'a, T>; | |
828 | ||
829 | fn into_iter(self) -> Iter<'a, T> { | |
830 | self.iter() | |
831 | } | |
832 | } | |
833 | ||
834 | #[stable(since = "1.4.0", feature = "option_iter")] | |
835 | impl<'a, T> IntoIterator for &'a mut Option<T> { | |
836 | type Item = &'a mut T; | |
837 | type IntoIter = IterMut<'a, T>; | |
838 | ||
839 | fn into_iter(mut self) -> IterMut<'a, T> { | |
840 | self.iter_mut() | |
841 | } | |
842 | } | |
843 | ||
5bcae85e SL |
844 | #[stable(since = "1.12.0", feature = "option_from")] |
845 | impl<T> From<T> for Option<T> { | |
846 | fn from(val: T) -> Option<T> { | |
847 | Some(val) | |
848 | } | |
849 | } | |
850 | ||
1a4d82fc JJ |
851 | ///////////////////////////////////////////////////////////////////////////// |
852 | // The Option Iterators | |
853 | ///////////////////////////////////////////////////////////////////////////// | |
854 | ||
54a0048b | 855 | #[derive(Clone, Debug)] |
1a4d82fc JJ |
856 | struct Item<A> { |
857 | opt: Option<A> | |
858 | } | |
859 | ||
860 | impl<A> Iterator for Item<A> { | |
861 | type Item = A; | |
862 | ||
863 | #[inline] | |
864 | fn next(&mut self) -> Option<A> { | |
865 | self.opt.take() | |
866 | } | |
867 | ||
868 | #[inline] | |
85aaf69f | 869 | fn size_hint(&self) -> (usize, Option<usize>) { |
1a4d82fc JJ |
870 | match self.opt { |
871 | Some(_) => (1, Some(1)), | |
872 | None => (0, Some(0)), | |
873 | } | |
874 | } | |
875 | } | |
876 | ||
877 | impl<A> DoubleEndedIterator for Item<A> { | |
878 | #[inline] | |
879 | fn next_back(&mut self) -> Option<A> { | |
880 | self.opt.take() | |
881 | } | |
882 | } | |
883 | ||
884 | impl<A> ExactSizeIterator for Item<A> {} | |
9e0c209e | 885 | impl<A> FusedIterator for Item<A> {} |
c30ab7b3 | 886 | unsafe impl<A> TrustedLen for Item<A> {} |
1a4d82fc | 887 | |
9e0c209e SL |
888 | /// An iterator over a reference of the contained item in an [`Option`]. |
889 | /// | |
890 | /// [`Option`]: enum.Option.html | |
85aaf69f | 891 | #[stable(feature = "rust1", since = "1.0.0")] |
54a0048b | 892 | #[derive(Debug)] |
1a4d82fc JJ |
893 | pub struct Iter<'a, A: 'a> { inner: Item<&'a A> } |
894 | ||
85aaf69f | 895 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
896 | impl<'a, A> Iterator for Iter<'a, A> { |
897 | type Item = &'a A; | |
898 | ||
899 | #[inline] | |
900 | fn next(&mut self) -> Option<&'a A> { self.inner.next() } | |
901 | #[inline] | |
85aaf69f | 902 | fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } |
1a4d82fc JJ |
903 | } |
904 | ||
85aaf69f | 905 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
906 | impl<'a, A> DoubleEndedIterator for Iter<'a, A> { |
907 | #[inline] | |
908 | fn next_back(&mut self) -> Option<&'a A> { self.inner.next_back() } | |
909 | } | |
910 | ||
85aaf69f | 911 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
912 | impl<'a, A> ExactSizeIterator for Iter<'a, A> {} |
913 | ||
9e0c209e SL |
914 | #[unstable(feature = "fused", issue = "35602")] |
915 | impl<'a, A> FusedIterator for Iter<'a, A> {} | |
916 | ||
c30ab7b3 SL |
917 | #[unstable(feature = "trusted_len", issue = "37572")] |
918 | unsafe impl<'a, A> TrustedLen for Iter<'a, A> {} | |
919 | ||
85aaf69f | 920 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
921 | impl<'a, A> Clone for Iter<'a, A> { |
922 | fn clone(&self) -> Iter<'a, A> { | |
923 | Iter { inner: self.inner.clone() } | |
924 | } | |
925 | } | |
926 | ||
9e0c209e SL |
927 | /// An iterator over a mutable reference of the contained item in an [`Option`]. |
928 | /// | |
929 | /// [`Option`]: enum.Option.html | |
85aaf69f | 930 | #[stable(feature = "rust1", since = "1.0.0")] |
54a0048b | 931 | #[derive(Debug)] |
1a4d82fc JJ |
932 | pub struct IterMut<'a, A: 'a> { inner: Item<&'a mut A> } |
933 | ||
85aaf69f | 934 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
935 | impl<'a, A> Iterator for IterMut<'a, A> { |
936 | type Item = &'a mut A; | |
937 | ||
938 | #[inline] | |
939 | fn next(&mut self) -> Option<&'a mut A> { self.inner.next() } | |
940 | #[inline] | |
85aaf69f | 941 | fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } |
1a4d82fc JJ |
942 | } |
943 | ||
85aaf69f | 944 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
945 | impl<'a, A> DoubleEndedIterator for IterMut<'a, A> { |
946 | #[inline] | |
947 | fn next_back(&mut self) -> Option<&'a mut A> { self.inner.next_back() } | |
948 | } | |
949 | ||
85aaf69f | 950 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
951 | impl<'a, A> ExactSizeIterator for IterMut<'a, A> {} |
952 | ||
9e0c209e SL |
953 | #[unstable(feature = "fused", issue = "35602")] |
954 | impl<'a, A> FusedIterator for IterMut<'a, A> {} | |
c30ab7b3 SL |
955 | #[unstable(feature = "trusted_len", issue = "37572")] |
956 | unsafe impl<'a, A> TrustedLen for IterMut<'a, A> {} | |
9e0c209e SL |
957 | |
958 | /// An iterator over the item contained inside an [`Option`]. | |
959 | /// | |
960 | /// [`Option`]: enum.Option.html | |
54a0048b | 961 | #[derive(Clone, Debug)] |
85aaf69f | 962 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
963 | pub struct IntoIter<A> { inner: Item<A> } |
964 | ||
85aaf69f | 965 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
966 | impl<A> Iterator for IntoIter<A> { |
967 | type Item = A; | |
968 | ||
969 | #[inline] | |
970 | fn next(&mut self) -> Option<A> { self.inner.next() } | |
971 | #[inline] | |
85aaf69f | 972 | fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } |
1a4d82fc JJ |
973 | } |
974 | ||
85aaf69f | 975 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
976 | impl<A> DoubleEndedIterator for IntoIter<A> { |
977 | #[inline] | |
978 | fn next_back(&mut self) -> Option<A> { self.inner.next_back() } | |
979 | } | |
980 | ||
85aaf69f | 981 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
982 | impl<A> ExactSizeIterator for IntoIter<A> {} |
983 | ||
9e0c209e SL |
984 | #[unstable(feature = "fused", issue = "35602")] |
985 | impl<A> FusedIterator for IntoIter<A> {} | |
986 | ||
c30ab7b3 SL |
987 | #[unstable(feature = "trusted_len", issue = "37572")] |
988 | unsafe impl<A> TrustedLen for IntoIter<A> {} | |
989 | ||
1a4d82fc JJ |
990 | ///////////////////////////////////////////////////////////////////////////// |
991 | // FromIterator | |
992 | ///////////////////////////////////////////////////////////////////////////// | |
993 | ||
85aaf69f | 994 | #[stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
995 | impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> { |
996 | /// Takes each element in the `Iterator`: if it is `None`, no further | |
997 | /// elements are taken, and the `None` is returned. Should no `None` occur, a | |
998 | /// container with the values of each `Option` is returned. | |
999 | /// | |
1000 | /// Here is an example which increments every integer in a vector, | |
1001 | /// checking for overflow: | |
1002 | /// | |
c34b1796 | 1003 | /// ``` |
85aaf69f | 1004 | /// use std::u16; |
1a4d82fc | 1005 | /// |
c30ab7b3 | 1006 | /// let v = vec![1, 2]; |
85aaf69f SL |
1007 | /// let res: Option<Vec<u16>> = v.iter().map(|&x: &u16| |
1008 | /// if x == u16::MAX { None } | |
1a4d82fc JJ |
1009 | /// else { Some(x + 1) } |
1010 | /// ).collect(); | |
c30ab7b3 | 1011 | /// assert!(res == Some(vec![2, 3])); |
1a4d82fc JJ |
1012 | /// ``` |
1013 | #[inline] | |
85aaf69f | 1014 | fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> { |
1a4d82fc JJ |
1015 | // FIXME(#11084): This could be replaced with Iterator::scan when this |
1016 | // performance bug is closed. | |
1017 | ||
1018 | struct Adapter<Iter> { | |
1019 | iter: Iter, | |
1020 | found_none: bool, | |
1021 | } | |
1022 | ||
1023 | impl<T, Iter: Iterator<Item=Option<T>>> Iterator for Adapter<Iter> { | |
1024 | type Item = T; | |
1025 | ||
1026 | #[inline] | |
1027 | fn next(&mut self) -> Option<T> { | |
1028 | match self.iter.next() { | |
1029 | Some(Some(value)) => Some(value), | |
1030 | Some(None) => { | |
1031 | self.found_none = true; | |
1032 | None | |
1033 | } | |
1034 | None => None, | |
1035 | } | |
1036 | } | |
1037 | } | |
1038 | ||
85aaf69f | 1039 | let mut adapter = Adapter { iter: iter.into_iter(), found_none: false }; |
1a4d82fc JJ |
1040 | let v: V = FromIterator::from_iter(adapter.by_ref()); |
1041 | ||
1042 | if adapter.found_none { | |
1043 | None | |
1044 | } else { | |
1045 | Some(v) | |
1046 | } | |
1047 | } | |
1048 | } |