From 91ede1f09a9f60c06b91583b3102482c249f31ab Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 30 Apr 2014 22:54:25 -0700 Subject: core: Inherit non-allocating slice functionality This commit adds a new trait, MutableVectorAllocating, which represents functions on vectors which can allocate. This is another extension trait to slices which should be removed once a lang item exists for the ~ allocation. --- src/libstd/vec.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libstd/vec.rs') diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index f0f126bcf16..35eb5359311 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -30,6 +30,7 @@ use rt::global_heap::{malloc_raw, realloc_raw}; use raw::Slice; use slice::{ImmutableEqVector, ImmutableVector, Items, MutItems, MutableVector}; use slice::{MutableTotalOrdVector, OwnedVector, Vector}; +use slice::{MutableVectorAllocating}; /// An owned, growable vector. /// -- cgit 1.4.1-3-g733a5 From 0d8f5fa618da00653897be2050980c800389be82 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 6 May 2014 21:25:36 -0700 Subject: core: Move Option::expect to libstd from libcore See #14008 for more details --- src/libcore/option.rs | 24 ------ src/libcore/should_not_exist.rs | 10 +-- src/libstd/io/timer.rs | 1 + src/libstd/lib.rs | 3 +- src/libstd/option.rs | 167 ++++++++++++++++++++++++++++++++++++++++ src/libstd/prelude.rs | 1 + src/libstd/rt/env.rs | 2 +- src/libstd/vec.rs | 2 +- 8 files changed, 177 insertions(+), 33 deletions(-) create mode 100644 src/libstd/option.rs (limited to 'src/libstd/vec.rs') diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 143e8bf2622..c6884a8002f 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -230,30 +230,6 @@ impl Option { // 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 diff --git a/src/libcore/should_not_exist.rs b/src/libcore/should_not_exist.rs index 587723563eb..50447f0c5b3 100644 --- a/src/libcore/should_not_exist.rs +++ b/src/libcore/should_not_exist.rs @@ -34,7 +34,7 @@ extern { } unsafe fn alloc(cap: uint) -> *mut Vec<()> { - let cap = cap.checked_add(&mem::size_of::>()).expect("cap overflow"); + let cap = cap.checked_add(&mem::size_of::>()).unwrap(); let ret = malloc(cap) as *mut Vec<()>; if ret.is_null() { intrinsics::abort(); @@ -94,7 +94,7 @@ impl FromIterator 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 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; let base = &mut (*ptr).data as *mut _; @@ -155,7 +155,7 @@ impl FromIterator for ~[A] { fn from_iter>(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::()).expect("cap overflow"); + let mut cap = cap.checked_mul(&mem::size_of::()).unwrap(); let mut len = 0; unsafe { @@ -163,7 +163,7 @@ impl FromIterator for ~[A] { let mut ret = cast::transmute(ptr); for elt in iterator { if len * mem::size_of::() >= cap { - cap = cap.checked_mul(&2).expect("cap overflow"); + cap = cap.checked_mul(&2).unwrap(); let ptr2 = alloc(cap) as *mut Vec; ptr::copy_nonoverlapping_memory(&mut (*ptr2).data, &(*ptr).data, diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs index 96c4083e7ed..5565918ef85 100644 --- a/src/libstd/io/timer.rs +++ b/src/libstd/io/timer.rs @@ -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 diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 4a555035a08..abcc1f099b4 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -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 */ diff --git a/src/libstd/option.rs b/src/libstd/option.rs new file mode 100644 index 00000000000..17249f567e5 --- /dev/null +++ b/src/libstd/option.rs @@ -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 or the MIT license +// , 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 { + /// 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(self, m: M) -> T; +} + +impl Expect for Option { + #[inline] + fn expect(self, msg: M) -> T { + match self { + Some(val) => val, + None => fail!(msg), + } + } +} diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 75eb56ffa52..6cd9e96496f 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -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; diff --git a/src/libstd/rt/env.rs b/src/libstd/rt/env.rs index 94f56d42613..708c42030ab 100644 --- a/src/libstd/rt/env.rs +++ b/src/libstd/rt/env.rs @@ -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. diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 35eb5359311..af146b96e50 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -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}; -- cgit 1.4.1-3-g733a5