core: Move Option::expect to libstd from libcore
See #14008 for more details
This commit is contained in:
parent
4a974413dc
commit
0d8f5fa618
8 changed files with 177 additions and 33 deletions
|
@ -230,30 +230,6 @@ impl<T> Option<T> {
|
|||
// Getting to contained values
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Unwraps an option, yielding the content of a `Some`
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the value is a `None` with a custom failure message provided by `msg`.
|
||||
#[inline]
|
||||
#[cfg(not(test))]
|
||||
pub fn expect(self, msg: &str) -> T {
|
||||
match self {
|
||||
Some(val) => val,
|
||||
None => fail!(msg),
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: once std::fmt is in libcore, this extra variant should not be
|
||||
// necessary.
|
||||
#[cfg(test)]
|
||||
pub fn expect(self, msg: &str) -> T {
|
||||
match self {
|
||||
Some(val) => val,
|
||||
None => fail!("{}", msg),
|
||||
}
|
||||
}
|
||||
|
||||
/// Moves a value out of an option type and returns it, consuming the `Option`.
|
||||
///
|
||||
/// # Failure
|
||||
|
|
|
@ -34,7 +34,7 @@ extern {
|
|||
}
|
||||
|
||||
unsafe fn alloc(cap: uint) -> *mut Vec<()> {
|
||||
let cap = cap.checked_add(&mem::size_of::<Vec<()>>()).expect("cap overflow");
|
||||
let cap = cap.checked_add(&mem::size_of::<Vec<()>>()).unwrap();
|
||||
let ret = malloc(cap) as *mut Vec<()>;
|
||||
if ret.is_null() {
|
||||
intrinsics::abort();
|
||||
|
@ -94,7 +94,7 @@ impl FromIterator<char> for ~str {
|
|||
let amt = ch.encode_utf8(tmp);
|
||||
|
||||
if len + amt > cap {
|
||||
cap = cap.checked_mul(&2).expect("cap overflow");
|
||||
cap = cap.checked_mul(&2).unwrap();
|
||||
if cap < len + amt {
|
||||
cap = len + amt;
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ impl FromIterator<char> for ~str {
|
|||
impl<'a> Add<&'a str,~str> for &'a str {
|
||||
#[inline]
|
||||
fn add(&self, rhs: & &'a str) -> ~str {
|
||||
let amt = self.len().checked_add(&rhs.len()).expect("len overflow");
|
||||
let amt = self.len().checked_add(&rhs.len()).unwrap();
|
||||
unsafe {
|
||||
let ptr = alloc(amt) as *mut Vec<u8>;
|
||||
let base = &mut (*ptr).data as *mut _;
|
||||
|
@ -155,7 +155,7 @@ impl<A> FromIterator<A> for ~[A] {
|
|||
fn from_iter<T: Iterator<A>>(mut iterator: T) -> ~[A] {
|
||||
let (lower, _) = iterator.size_hint();
|
||||
let cap = if lower == 0 {16} else {lower};
|
||||
let mut cap = cap.checked_mul(&mem::size_of::<A>()).expect("cap overflow");
|
||||
let mut cap = cap.checked_mul(&mem::size_of::<A>()).unwrap();
|
||||
let mut len = 0;
|
||||
|
||||
unsafe {
|
||||
|
@ -163,7 +163,7 @@ impl<A> FromIterator<A> for ~[A] {
|
|||
let mut ret = cast::transmute(ptr);
|
||||
for elt in iterator {
|
||||
if len * mem::size_of::<A>() >= cap {
|
||||
cap = cap.checked_mul(&2).expect("cap overflow");
|
||||
cap = cap.checked_mul(&2).unwrap();
|
||||
let ptr2 = alloc(cap) as *mut Vec<A>;
|
||||
ptr::copy_nonoverlapping_memory(&mut (*ptr2).data,
|
||||
&(*ptr).data,
|
||||
|
|
|
@ -21,6 +21,7 @@ use comm::Receiver;
|
|||
use io::IoResult;
|
||||
use kinds::Send;
|
||||
use owned::Box;
|
||||
use option::Expect;
|
||||
use rt::rtio::{IoFactory, LocalIo, RtioTimer};
|
||||
|
||||
/// A synchronous timer object
|
||||
|
|
|
@ -149,7 +149,6 @@ pub use core::default;
|
|||
pub use core::intrinsics;
|
||||
pub use core::iter;
|
||||
pub use core::mem;
|
||||
pub use core::option;
|
||||
pub use core::ptr;
|
||||
pub use core::raw;
|
||||
pub use core::tuple;
|
||||
|
@ -221,7 +220,7 @@ pub mod hash;
|
|||
/* Common data structures */
|
||||
|
||||
pub mod result;
|
||||
|
||||
pub mod option;
|
||||
|
||||
/* Tasks and communication */
|
||||
|
||||
|
|
167
src/libstd/option.rs
Normal file
167
src/libstd/option.rs
Normal file
|
@ -0,0 +1,167 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Optional values
|
||||
//!
|
||||
//! Type `Option` represents an optional value: every `Option`
|
||||
//! is either `Some` and contains a value, or `None`, and
|
||||
//! does not. `Option` types are very common in Rust code, as
|
||||
//! they have a number of uses:
|
||||
//!
|
||||
//! * Initial values
|
||||
//! * Return values for functions that are not defined
|
||||
//! over their entire input range (partial functions)
|
||||
//! * Return value for otherwise reporting simple errors, where `None` is
|
||||
//! returned on error
|
||||
//! * Optional struct fields
|
||||
//! * Struct fields that can be loaned or "taken"
|
||||
//! * Optional function arguments
|
||||
//! * Nullable pointers
|
||||
//! * Swapping things out of difficult situations
|
||||
//!
|
||||
//! Options are commonly paired with pattern matching to query the presence
|
||||
//! of a value and take action, always accounting for the `None` case.
|
||||
//!
|
||||
//! ```
|
||||
//! # // FIXME This is not the greatest first example
|
||||
//! // cow_says contains the word "moo"
|
||||
//! let cow_says = Some("moo");
|
||||
//! // dog_says does not contain a value
|
||||
//! let dog_says: Option<&str> = None;
|
||||
//!
|
||||
//! // Pattern match to retrieve the value
|
||||
//! match (cow_says, dog_says) {
|
||||
//! (Some(cow_words), Some(dog_words)) => {
|
||||
//! println!("Cow says {} and dog says {}!", cow_words, dog_words);
|
||||
//! }
|
||||
//! (Some(cow_words), None) => println!("Cow says {}", cow_words),
|
||||
//! (None, Some(dog_words)) => println!("Dog says {}", dog_words),
|
||||
//! (None, None) => println!("Cow and dog are suspiciously silent")
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//
|
||||
// FIXME: Show how `Option` is used in practice, with lots of methods
|
||||
//
|
||||
//! # Options and pointers ("nullable" pointers)
|
||||
//!
|
||||
//! Rust's pointer types must always point to a valid location; there are
|
||||
//! no "null" pointers. Instead, Rust has *optional* pointers, like
|
||||
//! the optional owned box, `Option<~T>`.
|
||||
//!
|
||||
//! The following example uses `Option` to create an optional box of
|
||||
//! `int`. Notice that in order to use the inner `int` value first the
|
||||
//! `check_optional` function needs to use pattern matching to
|
||||
//! determine whether the box has a value (i.e. it is `Some(...)`) or
|
||||
//! not (`None`).
|
||||
//!
|
||||
//! ```
|
||||
//! let optional: Option<~int> = None;
|
||||
//! check_optional(&optional);
|
||||
//!
|
||||
//! let optional: Option<~int> = Some(~9000);
|
||||
//! check_optional(&optional);
|
||||
//!
|
||||
//! fn check_optional(optional: &Option<~int>) {
|
||||
//! match *optional {
|
||||
//! Some(ref p) => println!("have value {}", p),
|
||||
//! None => println!("have no value")
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! This usage of `Option` to create safe nullable pointers is so
|
||||
//! common that Rust does special optimizations to make the
|
||||
//! representation of `Option<~T>` a single pointer. Optional pointers
|
||||
//! in Rust are stored as efficiently as any other pointer type.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! Basic pattern matching on `Option`:
|
||||
//!
|
||||
//! ```
|
||||
//! let msg = Some("howdy");
|
||||
//!
|
||||
//! // Take a reference to the contained string
|
||||
//! match msg {
|
||||
//! Some(ref m) => println!("{}", *m),
|
||||
//! None => ()
|
||||
//! }
|
||||
//!
|
||||
//! // Remove the contained string, destroying the Option
|
||||
//! let unwrapped_msg = match msg {
|
||||
//! Some(m) => m,
|
||||
//! None => "default message"
|
||||
//! };
|
||||
//! ```
|
||||
//!
|
||||
//! Initialize a result to `None` before a loop:
|
||||
//!
|
||||
//! ```
|
||||
//! enum Kingdom { Plant(uint, &'static str), Animal(uint, &'static str) }
|
||||
//!
|
||||
//! // A list of data to search through.
|
||||
//! let all_the_big_things = [
|
||||
//! Plant(250, "redwood"),
|
||||
//! Plant(230, "noble fir"),
|
||||
//! Plant(229, "sugar pine"),
|
||||
//! Animal(25, "blue whale"),
|
||||
//! Animal(19, "fin whale"),
|
||||
//! Animal(15, "north pacific right whale"),
|
||||
//! ];
|
||||
//!
|
||||
//! // We're going to search for the name of the biggest animal,
|
||||
//! // but to start with we've just got `None`.
|
||||
//! let mut name_of_biggest_animal = None;
|
||||
//! let mut size_of_biggest_animal = 0;
|
||||
//! for big_thing in all_the_big_things.iter() {
|
||||
//! match *big_thing {
|
||||
//! Animal(size, name) if size > size_of_biggest_animal => {
|
||||
//! // Now we've found the name of some big animal
|
||||
//! size_of_biggest_animal = size;
|
||||
//! name_of_biggest_animal = Some(name);
|
||||
//! }
|
||||
//! Animal(..) | Plant(..) => ()
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! match name_of_biggest_animal {
|
||||
//! Some(name) => println!("the biggest animal is {}", name),
|
||||
//! None => println!("there are no animals :(")
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use any::Any;
|
||||
use kinds::Send;
|
||||
|
||||
pub use core::option::{Option, Some, None, Item, collect};
|
||||
|
||||
/// Extension trait for the `Option` type to add an `expect` method
|
||||
|
||||
// FIXME(#14008) should this trait even exist?
|
||||
pub trait Expect<T> {
|
||||
/// Unwraps an option, yielding the content of a `Some`
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the value is a `None` with a custom failure message provided by
|
||||
/// `msg`.
|
||||
fn expect<M: Any + Send>(self, m: M) -> T;
|
||||
}
|
||||
|
||||
impl<T> Expect<T> for Option<T> {
|
||||
#[inline]
|
||||
fn expect<M: Any + Send>(self, msg: M) -> T {
|
||||
match self {
|
||||
Some(val) => val,
|
||||
None => fail!(msg),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,6 +65,7 @@ pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
|
|||
pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
|
||||
pub use num::{Signed, Unsigned};
|
||||
pub use num::{Primitive, Int, Float, ToPrimitive, FromPrimitive};
|
||||
pub use option::Expect;
|
||||
pub use owned::Box;
|
||||
pub use path::{GenericPath, Path, PosixPath, WindowsPath};
|
||||
pub use ptr::RawPtr;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
//! Runtime environment settings
|
||||
|
||||
use from_str::from_str;
|
||||
use option::{Some, None};
|
||||
use option::{Some, None, Expect};
|
||||
use os;
|
||||
|
||||
// Note that these are all accessed without any synchronization.
|
||||
|
|
|
@ -23,7 +23,7 @@ use mem;
|
|||
use num;
|
||||
use num::{CheckedMul, CheckedAdd};
|
||||
use ops::Drop;
|
||||
use option::{None, Option, Some};
|
||||
use option::{None, Option, Some, Expect};
|
||||
use ptr::RawPtr;
|
||||
use ptr;
|
||||
use rt::global_heap::{malloc_raw, realloc_raw};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue