diff options
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/cell.rs | 2 | ||||
| -rw-r--r-- | src/libcore/iter.rs | 7 | ||||
| -rw-r--r-- | src/libcore/option.rs | 151 | ||||
| -rw-r--r-- | src/libcore/result.rs | 214 |
4 files changed, 286 insertions, 88 deletions
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 4cbe7d6d963..569cf98ebc8 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -99,7 +99,7 @@ //! // Take a reference to the inside of cache cell //! let mut cache = self.span_tree_cache.borrow_mut(); //! if cache.is_some() { -//! return cache.get_ref().clone(); +//! return cache.as_ref().unwrap().clone(); //! } //! //! let span_tree = self.calc_span_tree(); diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 7df8a7864d9..f8a56b3d6fc 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2199,7 +2199,12 @@ pub fn iterate<'a, T: Clone>(f: |T|: 'a -> T, seed: T) -> Iterate<'a, T> { if *first { *first = false; } else { - val.mutate(|x| (*f)(x)); + match val.take() { + Some(x) => { + *val = Some((*f)(x)) + } + None => {} + } } val.clone() }) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 7773e03416e..537d78a67fe 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -141,6 +141,8 @@ //! } //! ``` +#![stable] + use cmp::{PartialEq, Eq, Ord}; use default::Default; use slice::Slice; @@ -155,6 +157,7 @@ use slice; /// The `Option` type. #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show)] +#[stable] pub enum Option<T> { /// No value None, @@ -173,6 +176,7 @@ impl<T> Option<T> { /// Returns `true` if the option is a `Some` value #[inline] + #[stable] pub fn is_some(&self) -> bool { match *self { Some(_) => true, @@ -182,6 +186,7 @@ impl<T> Option<T> { /// Returns `true` if the option is a `None` value #[inline] + #[stable] pub fn is_none(&self) -> bool { !self.is_some() } @@ -207,18 +212,21 @@ impl<T> Option<T> { /// println!("still can print num_as_str: {}", num_as_str); /// ``` #[inline] + #[stable] pub fn as_ref<'r>(&'r self) -> Option<&'r T> { match *self { Some(ref x) => Some(x), None => None } } /// Convert from `Option<T>` to `Option<&mut T>` #[inline] + #[unstable = "waiting for mut conventions"] pub fn as_mut<'r>(&'r mut self) -> Option<&'r mut T> { match *self { Some(ref mut x) => Some(x), None => None } } /// Convert from `Option<T>` to `&mut [T]` (without copying) #[inline] + #[unstable = "waiting for mut conventions"] pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] { match *self { Some(ref mut x) => { @@ -243,6 +251,7 @@ impl<T> Option<T> { /// Fails if the value is a `None` with a custom failure message provided by /// `msg`. #[inline] + #[unstable = "waiting for conventions"] pub fn expect(self, msg: &str) -> T { match self { Some(val) => val, @@ -262,6 +271,7 @@ impl<T> Option<T> { /// Instead, prefer to use pattern matching and handle the `None` /// case explicitly. #[inline] + #[unstable = "waiting for conventions"] pub fn unwrap(self) -> T { match self { Some(val) => val, @@ -271,6 +281,7 @@ impl<T> Option<T> { /// Returns the contained value or a default. #[inline] + #[unstable = "waiting for conventions"] pub fn unwrap_or(self, def: T) -> T { match self { Some(x) => x, @@ -280,6 +291,7 @@ impl<T> Option<T> { /// Returns the contained value or computes it from a closure. #[inline] + #[unstable = "waiting for conventions"] pub fn unwrap_or_else(self, f: || -> T) -> T { match self { Some(x) => x, @@ -303,30 +315,45 @@ impl<T> Option<T> { /// let num_as_int: Option<uint> = num_as_str.map(|n| n.len()); /// ``` #[inline] + #[unstable = "waiting for unboxed closures"] pub fn map<U>(self, f: |T| -> U) -> Option<U> { match self { Some(x) => Some(f(x)), None => None } } /// Applies a function to the contained value or returns a default. #[inline] + #[unstable = "waiting for unboxed closures"] pub fn map_or<U>(self, def: U, f: |T| -> U) -> U { match self { None => def, Some(t) => f(t) } } + /// Applies a function to the contained value or computes a default. + #[inline] + #[unstable = "waiting for unboxed closures"] + pub fn map_or_else<U>(self, def: || -> U, f: |T| -> U) -> U { + match self { None => def(), Some(t) => f(t) } + } + + /// Deprecated. + /// /// Applies a function to the contained value or does nothing. /// Returns true if the contained value was mutated. + #[deprecated = "removed due to lack of use"] pub fn mutate(&mut self, f: |T| -> T) -> bool { if self.is_some() { - *self = Some(f(self.take_unwrap())); + *self = Some(f(self.take().unwrap())); true } else { false } } + /// Deprecated. + /// /// Applies a function to the contained value or sets it to a default. /// Returns true if the contained value was mutated, or false if set to the default. + #[deprecated = "removed due to lack of use"] pub fn mutate_or_set(&mut self, def: T, f: |T| -> T) -> bool { if self.is_some() { - *self = Some(f(self.take_unwrap())); + *self = Some(f(self.take().unwrap())); true } else { *self = Some(def); @@ -340,18 +367,21 @@ impl<T> Option<T> { /// Returns an iterator over the possibly contained value. #[inline] + #[unstable = "waiting for iterator conventions"] pub fn iter<'r>(&'r self) -> Item<&'r T> { Item{opt: self.as_ref()} } /// Returns a mutable iterator over the possibly contained value. #[inline] + #[unstable = "waiting for iterator conventions"] pub fn mut_iter<'r>(&'r mut self) -> Item<&'r mut T> { Item{opt: self.as_mut()} } /// Returns a consuming iterator over the possibly contained value. #[inline] + #[unstable = "waiting for iterator conventions"] pub fn move_iter(self) -> Item<T> { Item{opt: self} } @@ -362,6 +392,7 @@ impl<T> Option<T> { /// Returns `None` if the option is `None`, otherwise returns `optb`. #[inline] + #[stable] pub fn and<U>(self, optb: Option<U>) -> Option<U> { match self { Some(_) => optb, @@ -372,6 +403,7 @@ impl<T> Option<T> { /// Returns `None` if the option is `None`, otherwise calls `f` with the /// wrapped value and returns the result. #[inline] + #[unstable = "waiting for unboxed closures"] pub fn and_then<U>(self, f: |T| -> Option<U>) -> Option<U> { match self { Some(x) => f(x), @@ -381,6 +413,7 @@ impl<T> Option<T> { /// Returns the option if it contains a value, otherwise returns `optb`. #[inline] + #[stable] pub fn or(self, optb: Option<T>) -> Option<T> { match self { Some(_) => self, @@ -391,6 +424,7 @@ impl<T> Option<T> { /// Returns the option if it contains a value, otherwise calls `f` and /// returns the result. #[inline] + #[unstable = "waiting for unboxed closures"] pub fn or_else(self, f: || -> Option<T>) -> Option<T> { match self { Some(_) => self, @@ -404,12 +438,16 @@ impl<T> Option<T> { /// Takes the value out of the option, leaving a `None` in its place. #[inline] + #[stable] pub fn take(&mut self) -> Option<T> { mem::replace(self, None) } + /// Deprecated. + /// /// Filters an optional value using a given function. #[inline(always)] + #[deprecated = "removed due to lack of use"] pub fn filtered(self, f: |t: &T| -> bool) -> Option<T> { match self { Some(x) => if f(&x) { Some(x) } else { None }, @@ -417,8 +455,11 @@ impl<T> Option<T> { } } + /// Deprecated. + /// /// Applies a function zero or more times until the result is `None`. #[inline] + #[deprecated = "removed due to lack of use"] pub fn while_some(self, f: |v: T| -> Option<T>) { let mut opt = self; loop { @@ -433,6 +474,8 @@ impl<T> Option<T> { // Common special cases ///////////////////////////////////////////////////////////////////////// + /// Deprecated: use `take().unwrap()` instead. + /// /// The option dance. Moves a value out of an option type and returns it, /// replacing the original with `None`. /// @@ -440,6 +483,7 @@ impl<T> Option<T> { /// /// Fails if the value equals `None`. #[inline] + #[deprecated = "use take().unwrap() instead"] pub fn take_unwrap(&mut self) -> T { match self.take() { Some(x) => x, @@ -447,6 +491,8 @@ impl<T> Option<T> { } } + /// Deprecated: use `as_ref().unwrap()` instead. + /// /// Gets an immutable reference to the value inside an option. /// /// # Failure @@ -460,6 +506,7 @@ impl<T> Option<T> { /// Instead, prefer to use pattern matching and handle the `None` /// case explicitly. #[inline] + #[deprecated = "use .as_ref().unwrap() instead"] pub fn get_ref<'a>(&'a self) -> &'a T { match *self { Some(ref x) => x, @@ -467,6 +514,8 @@ impl<T> Option<T> { } } + /// Deprecated: use `as_mut().unwrap()` instead. + /// /// Gets a mutable reference to the value inside an option. /// /// # Failure @@ -480,6 +529,7 @@ impl<T> Option<T> { /// Instead, prefer to use pattern matching and handle the `None` /// case explicitly. #[inline] + #[deprecated = "use .as_mut().unwrap() instead"] pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut T { match *self { Some(ref mut x) => x, @@ -512,6 +562,7 @@ impl<T: Default> Option<T> { /// assert_eq!(0i, bad_year); /// ``` #[inline] + #[unstable = "waiting for conventions"] pub fn unwrap_or_default(self) -> T { match self { Some(x) => x, @@ -527,6 +578,7 @@ impl<T: Default> Option<T> { impl<T> Slice<T> for Option<T> { /// Convert from `Option<T>` to `&[T]` (without copying) #[inline] + #[stable] fn as_slice<'a>(&'a self) -> &'a [T] { match *self { Some(ref x) => slice::ref_slice(x), @@ -552,6 +604,7 @@ impl<T> Default for Option<T> { /// The `Item` iterator is returned by the `iter`, `mut_iter` and `move_iter` /// methods on `Option`. #[deriving(Clone)] +#[unstable = "waiting for iterator conventions"] pub struct Item<A> { opt: Option<A> } @@ -584,54 +637,62 @@ impl<A> ExactSize<A> for Item<A> {} // Free functions ///////////////////////////////////////////////////////////////////////////// -/// Takes each element in the `Iterator`: if it is `None`, no further -/// elements are taken, and the `None` is returned. Should no `None` occur, a -/// vector containing the values of each `Option` is returned. -/// -/// Here is an example which increments every integer in a vector, -/// checking for overflow: -/// -/// ```rust -/// use std::option; -/// use std::uint; -/// -/// let v = vec!(1u, 2u); -/// let res: Option<Vec<uint>> = option::collect(v.iter().map(|x: &uint| -/// if *x == uint::MAX { None } -/// else { Some(x + 1) } -/// )); -/// assert!(res == Some(vec!(2u, 3u))); -/// ``` +/// Deprecated: use `Iterator::collect` instead. #[inline] -pub fn collect<T, Iter: Iterator<Option<T>>, V: FromIterator<T>>(iter: Iter) -> Option<V> { - // FIXME(#11084): This could be replaced with Iterator::scan when this - // performance bug is closed. - - struct Adapter<Iter> { - iter: Iter, - found_none: bool, - } - - impl<T, Iter: Iterator<Option<T>>> Iterator<T> for Adapter<Iter> { - #[inline] - fn next(&mut self) -> Option<T> { - match self.iter.next() { - Some(Some(value)) => Some(value), - Some(None) => { - self.found_none = true; - None +#[deprecated = "use Iterator::collect instead"] +pub fn collect<T, Iter: Iterator<Option<T>>, V: FromIterator<T>>(mut iter: Iter) -> Option<V> { + iter.collect() +} + +impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> { + /// Takes each element in the `Iterator`: if it is `None`, no further + /// elements are taken, and the `None` is returned. Should no `None` occur, a + /// container with the values of each `Option` is returned. + /// + /// Here is an example which increments every integer in a vector, + /// checking for overflow: + /// + /// ```rust + /// use std::uint; + /// + /// let v = vec!(1u, 2u); + /// let res: Option<Vec<uint>> = v.iter().map(|x: &uint| + /// if *x == uint::MAX { None } + /// else { Some(x + 1) } + /// ).collect(); + /// assert!(res == Some(vec!(2u, 3u))); + /// ``` + #[inline] + fn from_iter<I: Iterator<Option<A>>>(iter: I) -> Option<V> { + // FIXME(#11084): This could be replaced with Iterator::scan when this + // performance bug is closed. + + struct Adapter<Iter> { + iter: Iter, + found_none: bool, + } + + impl<T, Iter: Iterator<Option<T>>> Iterator<T> for Adapter<Iter> { + #[inline] + fn next(&mut self) -> Option<T> { + match self.iter.next() { + Some(Some(value)) => Some(value), + Some(None) => { + self.found_none = true; + None + } + None => None, } - None => None, } } - } - let mut adapter = Adapter { iter: iter, found_none: false }; - let v: V = FromIterator::from_iter(adapter.by_ref()); + let mut adapter = Adapter { iter: iter, found_none: false }; + let v: V = FromIterator::from_iter(adapter.by_ref()); - if adapter.found_none { - None - } else { - Some(v) + if adapter.found_none { + None + } else { + Some(v) + } } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 980a9c7506f..bf351ecc89b 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -274,10 +274,14 @@ //! the context. The caller of `fail!` should assume that execution //! will not resume after failure, that failure is catastrophic. +#![stable] + use clone::Clone; use cmp::PartialEq; use std::fmt::Show; -use iter::{Iterator, FromIterator}; +use slice; +use slice::Slice; +use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize}; use option::{None, Option, Some}; /// `Result` is a type that represents either success (`Ok`) or failure (`Err`). @@ -285,6 +289,7 @@ use option::{None, Option, Some}; /// See the [`std::result`](index.html) module documentation for details. #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show)] #[must_use] +#[stable] pub enum Result<T, E> { /// Contains the success value Ok(T), @@ -315,6 +320,7 @@ impl<T, E> Result<T, E> { /// # } /// ~~~ #[inline] + #[stable] pub fn is_ok(&self) -> bool { match *self { Ok(_) => true, @@ -335,6 +341,7 @@ impl<T, E> Result<T, E> { /// assert!(bogus.is_err()); /// ~~~ #[inline] + #[stable] pub fn is_err(&self) -> bool { !self.is_ok() } @@ -362,6 +369,7 @@ impl<T, E> Result<T, E> { /// let bdays: File = bdays.ok().expect("unable to open birthday file"); /// ~~~ #[inline] + #[stable] pub fn ok(self) -> Option<T> { match self { Ok(x) => Some(x), @@ -374,6 +382,7 @@ impl<T, E> Result<T, E> { /// Converts `self` into an `Option<T>`, consuming `self`, /// and discarding the value, if any. #[inline] + #[stable] pub fn err(self) -> Option<E> { match self { Ok(_) => None, @@ -390,6 +399,7 @@ impl<T, E> Result<T, E> { /// Produces a new `Result`, containing a reference /// into the original, leaving the original in place. #[inline] + #[stable] pub fn as_ref<'r>(&'r self) -> Result<&'r T, &'r E> { match *self { Ok(ref x) => Ok(x), @@ -399,6 +409,7 @@ impl<T, E> Result<T, E> { /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>` #[inline] + #[unstable = "waiting for mut conventions"] pub fn as_mut<'r>(&'r mut self) -> Result<&'r mut T, &'r mut E> { match *self { Ok(ref mut x) => Ok(x), @@ -406,6 +417,20 @@ impl<T, E> Result<T, E> { } } + /// Convert from `Result<T, E>` to `&mut [T]` (without copying) + #[inline] + #[unstable = "waiting for mut conventions"] + pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] { + match *self { + Ok(ref mut x) => slice::mut_ref_slice(x), + Err(_) => { + // work around lack of implicit coercion from fixed-size array to slice + let emp: &mut [_] = &mut []; + emp + } + } + } + ///////////////////////////////////////////////////////////////////////// // Transforming contained values ///////////////////////////////////////////////////////////////////////// @@ -441,6 +466,7 @@ impl<T, E> Result<T, E> { /// assert!(sum == 10); /// ~~~ #[inline] + #[unstable = "waiting for unboxed closures"] pub fn map<U>(self, op: |T| -> U) -> Result<U,E> { match self { Ok(t) => Ok(op(t)), @@ -454,6 +480,7 @@ impl<T, E> Result<T, E> { /// This function can be used to pass through a successful result while handling /// an error. #[inline] + #[unstable = "waiting for unboxed closures"] pub fn map_err<F>(self, op: |E| -> F) -> Result<T,F> { match self { Ok(t) => Ok(t), @@ -461,12 +488,39 @@ impl<T, E> Result<T, E> { } } + + ///////////////////////////////////////////////////////////////////////// + // Iterator constructors + ///////////////////////////////////////////////////////////////////////// + + /// Returns an iterator over the possibly contained value. + #[inline] + #[unstable = "waiting for iterator conventions"] + pub fn iter<'r>(&'r self) -> Item<&'r T> { + Item{opt: self.as_ref().ok()} + } + + /// Returns a mutable iterator over the possibly contained value. + #[inline] + #[unstable = "waiting for iterator conventions"] + pub fn mut_iter<'r>(&'r mut self) -> Item<&'r mut T> { + Item{opt: self.as_mut().ok()} + } + + /// Returns a consuming iterator over the possibly contained value. + #[inline] + #[unstable = "waiting for iterator conventions"] + pub fn move_iter(self) -> Item<T> { + Item{opt: self.ok()} + } + //////////////////////////////////////////////////////////////////////// // Boolean operations on the values, eager and lazy ///////////////////////////////////////////////////////////////////////// /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`. #[inline] + #[stable] pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> { match self { Ok(_) => res, @@ -478,6 +532,7 @@ impl<T, E> Result<T, E> { /// /// This function can be used for control flow based on result values #[inline] + #[unstable = "waiting for unboxed closures"] pub fn and_then<U>(self, op: |T| -> Result<U, E>) -> Result<U, E> { match self { Ok(t) => op(t), @@ -487,6 +542,7 @@ impl<T, E> Result<T, E> { /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`. #[inline] + #[stable] pub fn or(self, res: Result<T, E>) -> Result<T, E> { match self { Ok(_) => self, @@ -498,6 +554,7 @@ impl<T, E> Result<T, E> { /// /// This function can be used for control flow based on result values #[inline] + #[unstable = "waiting for unboxed closures"] pub fn or_else<F>(self, op: |E| -> Result<T, F>) -> Result<T, F> { match self { Ok(t) => Ok(t), @@ -508,6 +565,7 @@ impl<T, E> Result<T, E> { /// Unwraps a result, yielding the content of an `Ok`. /// Else it returns `optb`. #[inline] + #[unstable = "waiting for conventions"] pub fn unwrap_or(self, optb: T) -> T { match self { Ok(t) => t, @@ -518,6 +576,7 @@ impl<T, E> Result<T, E> { /// Unwraps a result, yielding the content of an `Ok`. /// If the value is an `Err` then it calls `op` with its value. #[inline] + #[unstable = "waiting for conventions"] pub fn unwrap_or_else(self, op: |E| -> T) -> T { match self { Ok(t) => t, @@ -541,6 +600,7 @@ impl<T, E: Show> Result<T, E> { /// Fails if the value is an `Err`, with a custom failure message provided /// by the `Err`'s value. #[inline] + #[unstable = "waiting for conventions"] pub fn unwrap(self) -> T { match self { Ok(t) => t, @@ -558,6 +618,7 @@ impl<T: Show, E> Result<T, E> { /// Fails if the value is an `Ok`, with a custom failure message provided /// by the `Ok`'s value. #[inline] + #[unstable = "waiting for conventions"] pub fn unwrap_err(self) -> E { match self { Ok(t) => @@ -568,57 +629,124 @@ impl<T: Show, E> Result<T, E> { } ///////////////////////////////////////////////////////////////////////////// -// Free functions +// Trait implementations ///////////////////////////////////////////////////////////////////////////// -/// Takes each element in the `Iterator`: if it is an `Err`, no further -/// elements are taken, and the `Err` is returned. Should no `Err` occur, a -/// vector containing the values of each `Result` is returned. -/// -/// Here is an example which increments every integer in a vector, -/// checking for overflow: -/// -/// ```rust -/// use std::result; -/// use std::uint; +impl<T, E> Slice<T> for Result<T, E> { + /// Convert from `Result<T, E>` to `&[T]` (without copying) + #[inline] + #[stable] + fn as_slice<'a>(&'a self) -> &'a [T] { + match *self { + Ok(ref x) => slice::ref_slice(x), + Err(_) => { + // work around lack of implicit coercion from fixed-size array to slice + let emp: &[_] = &[]; + emp + } + } + } +} + +///////////////////////////////////////////////////////////////////////////// +// The Result Iterator +///////////////////////////////////////////////////////////////////////////// + +/// A `Result` iterator that yields either one or zero elements /// -/// let v = vec!(1u, 2u); -/// let res: Result<Vec<uint>, &'static str> = result::collect(v.iter().map(|x: &uint| -/// if *x == uint::MAX { Err("Overflow!") } -/// else { Ok(x + 1) } -/// )); -/// assert!(res == Ok(vec!(2u, 3u))); -/// ``` -#[inline] -pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Iter) -> Result<V, E> { - // FIXME(#11084): This could be replaced with Iterator::scan when this - // performance bug is closed. +/// The `Item` iterator is returned by the `iter`, `mut_iter` and `move_iter` +/// methods on `Result`. +#[deriving(Clone)] +#[unstable = "waiting for iterator conventions"] +pub struct Item<T> { + opt: Option<T> +} + +impl<T> Iterator<T> for Item<T> { + #[inline] + fn next(&mut self) -> Option<T> { + self.opt.take() + } + + #[inline] + fn size_hint(&self) -> (uint, Option<uint>) { + match self.opt { + Some(_) => (1, Some(1)), + None => (0, Some(0)), + } + } +} - struct Adapter<Iter, E> { - iter: Iter, - err: Option<E>, +impl<A> DoubleEndedIterator<A> for Item<A> { + #[inline] + fn next_back(&mut self) -> Option<A> { + self.opt.take() } +} + +impl<A> ExactSize<A> for Item<A> {} - impl<T, E, Iter: Iterator<Result<T, E>>> Iterator<T> for Adapter<Iter, E> { - #[inline] - fn next(&mut self) -> Option<T> { - match self.iter.next() { - Some(Ok(value)) => Some(value), - Some(Err(err)) => { - self.err = Some(err); - None +///////////////////////////////////////////////////////////////////////////// +// Free functions +///////////////////////////////////////////////////////////////////////////// + +/// Deprecated: use `Iterator::collect`. +#[inline] +#[deprecated = "use Iterator::collect instead"] +pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(mut iter: Iter) + -> Result<V, E> { + iter.collect() +} + +impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> { + /// Takes each element in the `Iterator`: if it is an `Err`, no further + /// elements are taken, and the `Err` is returned. Should no `Err` occur, a + /// container with the values of each `Result` is returned. + /// + /// Here is an example which increments every integer in a vector, + /// checking for overflow: + /// + /// ```rust + /// use std::uint; + /// + /// let v = vec!(1u, 2u); + /// let res: Result<Vec<uint>, &'static str> = v.iter().map(|x: &uint| + /// if *x == uint::MAX { Err("Overflow!") } + /// else { Ok(x + 1) } + /// ).collect(); + /// assert!(res == Ok(vec!(2u, 3u))); + /// ``` + #[inline] + fn from_iter<I: Iterator<Result<A, E>>>(iter: I) -> Result<V, E> { + // FIXME(#11084): This could be replaced with Iterator::scan when this + // performance bug is closed. + + struct Adapter<Iter, E> { + iter: Iter, + err: Option<E>, + } + + impl<T, E, Iter: Iterator<Result<T, E>>> Iterator<T> for Adapter<Iter, E> { + #[inline] + fn next(&mut self) -> Option<T> { + match self.iter.next() { + Some(Ok(value)) => Some(value), + Some(Err(err)) => { + self.err = Some(err); + None + } + None => None, } - None => None, } } - } - let mut adapter = Adapter { iter: iter, err: None }; - let v: V = FromIterator::from_iter(adapter.by_ref()); + let mut adapter = Adapter { iter: iter, err: None }; + let v: V = FromIterator::from_iter(adapter.by_ref()); - match adapter.err { - Some(err) => Err(err), - None => Ok(v), + match adapter.err { + Some(err) => Err(err), + None => Ok(v), + } } } @@ -627,6 +755,7 @@ pub fn collect<T, E, Iter: Iterator<Result<T, E>>, V: FromIterator<T>>(iter: Ite /// If an `Err` is encountered, it is immediately returned. /// Otherwise, the folded value is returned. #[inline] +#[experimental] pub fn fold<T, V, E, @@ -644,12 +773,15 @@ pub fn fold<T, Ok(init) } +/// Deprecated. +/// /// Perform a trivial fold operation over the result values /// from an iterator. /// /// If an `Err` is encountered, it is immediately returned. /// Otherwise, a simple `Ok(())` is returned. #[inline] +#[deprecated = "use fold instead"] pub fn fold_<T,E,Iter:Iterator<Result<T,E>>>(iterator: Iter) -> Result<(),E> { fold(iterator, (), |_, _| ()) } |
