diff options
Diffstat (limited to 'libcore')
68 files changed, 34086 insertions, 0 deletions
diff --git a/libcore/Cargo.toml b/libcore/Cargo.toml new file mode 100644 index 0000000..98f941f --- /dev/null +++ b/libcore/Cargo.toml @@ -0,0 +1,10 @@ +[package] +authors = ["The Rust Project Developers"] +name = "core" +version = "0.0.0" +build = "build.rs" + +[lib] +name = "core" +path = "lib.rs" +test = false diff --git a/libcore/any.rs b/libcore/any.rs new file mode 100644 index 0000000..dfd2ba9 --- /dev/null +++ b/libcore/any.rs @@ -0,0 +1,230 @@ +// Copyright 2013-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. + +//! This module implements the `Any` trait, which enables dynamic typing +//! of any `'static` type through runtime reflection. +//! +//! `Any` itself can be used to get a `TypeId`, and has more features when used +//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and +//! `downcast_ref` methods, to test if the contained value is of a given type, +//! and to get a reference to the inner value as a type. As `&mut Any`, there +//! is also the `downcast_mut` method, for getting a mutable reference to the +//! inner value. `Box<Any>` adds the `downcast` method, which attempts to +//! convert to a `Box<T>`. See the [`Box`] documentation for the full details. +//! +//! Note that &Any is limited to testing whether a value is of a specified +//! concrete type, and cannot be used to test whether a type implements a trait. +//! +//! [`Box`]: ../../std/boxed/struct.Box.html +//! +//! # Examples +//! +//! Consider a situation where we want to log out a value passed to a function. +//! We know the value we're working on implements Debug, but we don't know its +//! concrete type. We want to give special treatment to certain types: in this +//! case printing out the length of String values prior to their value. +//! We don't know the concrete type of our value at compile time, so we need to +//! use runtime reflection instead. +//! +//! ```rust +//! use std::fmt::Debug; +//! use std::any::Any; +//! +//! // Logger function for any type that implements Debug. +//! fn log<T: Any + Debug>(value: &T) { +//! let value_any = value as &Any; +//! +//! // try to convert our value to a String. If successful, we want to +//! // output the String's length as well as its value. If not, it's a +//! // different type: just print it out unadorned. +//! match value_any.downcast_ref::<String>() { +//! Some(as_string) => { +//! println!("String ({}): {}", as_string.len(), as_string); +//! } +//! None => { +//! println!("{:?}", value); +//! } +//! } +//! } +//! +//! // This function wants to log its parameter out prior to doing work with it. +//! fn do_work<T: Any + Debug>(value: &T) { +//! log(value); +//! // ...do some other work +//! } +//! +//! fn main() { +//! let my_string = "Hello World".to_string(); +//! do_work(&my_string); +//! +//! let my_i8: i8 = 100; +//! do_work(&my_i8); +//! } +//! ``` + +#![stable(feature = "rust1", since = "1.0.0")] + +use fmt; +use marker::Send; +use mem::transmute; +use option::Option::{self, Some, None}; +use raw::TraitObject; +use intrinsics; +use marker::{Reflect, Sized}; + +/////////////////////////////////////////////////////////////////////////////// +// Any trait +/////////////////////////////////////////////////////////////////////////////// + +/// A type to emulate dynamic typing. +/// +/// Every type with no non-`'static` references implements `Any`. +/// See the [module-level documentation][mod] for more details. +/// +/// [mod]: index.html +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Any: Reflect + 'static { + /// Gets the `TypeId` of `self`. + #[unstable(feature = "get_type_id", + reason = "this method will likely be replaced by an associated static", + issue = "27745")] + fn get_type_id(&self) -> TypeId; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: Reflect + 'static + ?Sized > Any for T { + fn get_type_id(&self) -> TypeId { TypeId::of::<T>() } +} + +/////////////////////////////////////////////////////////////////////////////// +// Extension methods for Any trait objects. +/////////////////////////////////////////////////////////////////////////////// + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for Any { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("Any") + } +} + +// Ensure that the result of e.g. joining a thread can be printed and +// hence used with `unwrap`. May eventually no longer be needed if +// dispatch works with upcasting. +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for Any + Send { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("Any") + } +} + +impl Any { + /// Returns true if the boxed type is the same as `T` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is<T: Any>(&self) -> bool { + // Get TypeId of the type this function is instantiated with + let t = TypeId::of::<T>(); + + // Get TypeId of the type in the trait object + let boxed = self.get_type_id(); + + // Compare both TypeIds on equality + t == boxed + } + + /// Returns some reference to the boxed value if it is of type `T`, or + /// `None` if it isn't. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn downcast_ref<T: Any>(&self) -> Option<&T> { + if self.is::<T>() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = transmute(self); + + // Extract the data pointer + Some(&*(to.data as *const T)) + } + } else { + None + } + } + + /// Returns some mutable reference to the boxed value if it is of type `T`, or + /// `None` if it isn't. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> { + if self.is::<T>() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = transmute(self); + + // Extract the data pointer + Some(&mut *(to.data as *const T as *mut T)) + } + } else { + None + } + } +} + +impl Any+Send { + /// Forwards to the method defined on the type `Any`. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is<T: Any>(&self) -> bool { + Any::is::<T>(self) + } + + /// Forwards to the method defined on the type `Any`. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn downcast_ref<T: Any>(&self) -> Option<&T> { + Any::downcast_ref::<T>(self) + } + + /// Forwards to the method defined on the type `Any`. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> { + Any::downcast_mut::<T>(self) + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// TypeID and its methods +/////////////////////////////////////////////////////////////////////////////// + +/// A `TypeId` represents a globally unique identifier for a type. +/// +/// Each `TypeId` is an opaque object which does not allow inspection of what's +/// inside but does allow basic operations such as cloning, comparison, +/// printing, and showing. +/// +/// A `TypeId` is currently only available for types which ascribe to `'static`, +/// but this limitation may be removed in the future. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct TypeId { + t: u64, +} + +impl TypeId { + /// Returns the `TypeId` of the type this generic function has been + /// instantiated with + #[stable(feature = "rust1", since = "1.0.0")] + pub fn of<T: ?Sized + Reflect + 'static>() -> TypeId { + TypeId { + t: unsafe { intrinsics::type_id::<T>() }, + } + } +} diff --git a/libcore/array.rs b/libcore/array.rs new file mode 100644 index 0000000..45fc5ff --- /dev/null +++ b/libcore/array.rs @@ -0,0 +1,244 @@ +// 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. + +//! Implementations of things like `Eq` for fixed-length arrays +//! up to a certain length. Eventually we should able to generalize +//! to all lengths. +//! +//! *[See also the array primitive type](../../std/primitive.array.html).* + +#![unstable(feature = "fixed_size_array", + reason = "traits and impls are better expressed through generic \ + integer constants", + issue = "27778")] + +use borrow::{Borrow, BorrowMut}; +use clone::Clone; +use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; +use convert::{AsRef, AsMut}; +use default::Default; +use fmt; +use hash::{Hash, self}; +use iter::IntoIterator; +use marker::{Copy, Sized, Unsize}; +use option::Option; +use slice::{Iter, IterMut, SliceExt}; + +/// Utility trait implemented only on arrays of fixed size +/// +/// This trait can be used to implement other traits on fixed-size arrays +/// without causing much metadata bloat. +/// +/// The trait is marked unsafe in order to restrict implementors to fixed-size +/// arrays. User of this trait can assume that implementors have the exact +/// layout in memory of a fixed size array (for example, for unsafe +/// initialization). +/// +/// Note that the traits AsRef and AsMut provide similar methods for types that +/// may not be fixed-size arrays. Implementors should prefer those traits +/// instead. +pub unsafe trait FixedSizeArray<T> { + /// Converts the array to immutable slice + fn as_slice(&self) -> &[T]; + /// Converts the array to mutable slice + fn as_mut_slice(&mut self) -> &mut [T]; +} + +unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A { + #[inline] + fn as_slice(&self) -> &[T] { + self + } + #[inline] + fn as_mut_slice(&mut self) -> &mut [T] { + self + } +} + +macro_rules! __impl_slice_eq1 { + ($Lhs: ty, $Rhs: ty) => { + __impl_slice_eq1! { $Lhs, $Rhs, Sized } + }; + ($Lhs: ty, $Rhs: ty, $Bound: ident) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> { + #[inline] + fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] } + #[inline] + fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] } + } + } +} + +macro_rules! __impl_slice_eq2 { + ($Lhs: ty, $Rhs: ty) => { + __impl_slice_eq2! { $Lhs, $Rhs, Sized } + }; + ($Lhs: ty, $Rhs: ty, $Bound: ident) => { + __impl_slice_eq1!($Lhs, $Rhs, $Bound); + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> { + #[inline] + fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] } + #[inline] + fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] } + } + } +} + +// macro for implementing n-ary tuple functions and operations +macro_rules! array_impls { + ($($N:expr)+) => { + $( + impl<T> AsRef<[T]> for [T; $N] { + #[inline] + fn as_ref(&self) -> &[T] { + &self[..] + } + } + + impl<T> AsMut<[T]> for [T; $N] { + #[inline] + fn as_mut(&mut self) -> &mut [T] { + &mut self[..] + } + } + + #[stable(feature = "array_borrow", since = "1.4.0")] + impl<T> Borrow<[T]> for [T; $N] { + fn borrow(&self) -> &[T] { + self + } + } + + #[stable(feature = "array_borrow", since = "1.4.0")] + impl<T> BorrowMut<[T]> for [T; $N] { + fn borrow_mut(&mut self) -> &mut [T] { + self + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:Copy> Clone for [T; $N] { + fn clone(&self) -> [T; $N] { + *self + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T: Hash> Hash for [T; $N] { + fn hash<H: hash::Hasher>(&self, state: &mut H) { + Hash::hash(&self[..], state) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T: fmt::Debug> fmt::Debug for [T; $N] { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&&self[..], f) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T> IntoIterator for &'a [T; $N] { + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T> IntoIterator for &'a mut [T; $N] { + type Item = &'a mut T; + type IntoIter = IterMut<'a, T>; + + fn into_iter(self) -> IterMut<'a, T> { + self.iter_mut() + } + } + + // NOTE: some less important impls are omitted to reduce code bloat + __impl_slice_eq1! { [A; $N], [B; $N] } + __impl_slice_eq2! { [A; $N], [B] } + __impl_slice_eq2! { [A; $N], &'b [B] } + __impl_slice_eq2! { [A; $N], &'b mut [B] } + // __impl_slice_eq2! { [A; $N], &'b [B; $N] } + // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:Eq> Eq for [T; $N] { } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:PartialOrd> PartialOrd for [T; $N] { + #[inline] + fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> { + PartialOrd::partial_cmp(&&self[..], &&other[..]) + } + #[inline] + fn lt(&self, other: &[T; $N]) -> bool { + PartialOrd::lt(&&self[..], &&other[..]) + } + #[inline] + fn le(&self, other: &[T; $N]) -> bool { + PartialOrd::le(&&self[..], &&other[..]) + } + #[inline] + fn ge(&self, other: &[T; $N]) -> bool { + PartialOrd::ge(&&self[..], &&other[..]) + } + #[inline] + fn gt(&self, other: &[T; $N]) -> bool { + PartialOrd::gt(&&self[..], &&other[..]) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:Ord> Ord for [T; $N] { + #[inline] + fn cmp(&self, other: &[T; $N]) -> Ordering { + Ord::cmp(&&self[..], &&other[..]) + } + } + )+ + } +} + +array_impls! { + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 +} + +// The Default impls cannot be generated using the array_impls! macro because +// they require array literals. + +macro_rules! array_impl_default { + {$n:expr, $t:ident $($ts:ident)*} => { + #[stable(since = "1.4.0", feature = "array_default")] + impl<T> Default for [T; $n] where T: Default { + fn default() -> [T; $n] { + [$t::default(), $($ts::default()),*] + } + } + array_impl_default!{($n - 1), $($ts)*} + }; + {$n:expr,} => { + #[stable(since = "1.4.0", feature = "array_default")] + impl<T> Default for [T; $n] { + fn default() -> [T; $n] { [] } + } + }; +} + +array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T} diff --git a/libcore/borrow.rs b/libcore/borrow.rs new file mode 100644 index 0000000..79330d3 --- /dev/null +++ b/libcore/borrow.rs @@ -0,0 +1,109 @@ +// 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. + +//! A module for working with borrowed data. + +#![stable(feature = "rust1", since = "1.0.0")] + +use marker::Sized; + +/// A trait for borrowing data. +/// +/// In general, there may be several ways to "borrow" a piece of data. The +/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` +/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of +/// borrows: the borrowed slices `&[T]` and `&mut [T]`. +/// +/// When writing generic code, it is often desirable to abstract over all ways +/// of borrowing data from a given type. That is the role of the `Borrow` +/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`. A given +/// type can be borrowed as multiple different types. In particular, `Vec<T>: +/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`. +/// +/// If you are implementing `Borrow` and both `Self` and `Borrowed` implement +/// `Hash`, `Eq`, and/or `Ord`, they must produce the same result. +/// +/// `Borrow` is very similar to, but different than, `AsRef`. See +/// [the book][book] for more. +/// +/// [book]: ../../book/borrow-and-asref.html +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Borrow<Borrowed: ?Sized> { + /// Immutably borrows from an owned value. + /// + /// # Examples + /// + /// ``` + /// use std::borrow::Borrow; + /// + /// fn check<T: Borrow<str>>(s: T) { + /// assert_eq!("Hello", s.borrow()); + /// } + /// + /// let s = "Hello".to_string(); + /// + /// check(s); + /// + /// let s = "Hello"; + /// + /// check(s); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow(&self) -> &Borrowed; +} + +/// A trait for mutably borrowing data. +/// +/// Similar to `Borrow`, but for mutable borrows. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> { + /// Mutably borrows from an owned value. + /// + /// # Examples + /// + /// ``` + /// use std::borrow::BorrowMut; + /// + /// fn check<T: BorrowMut<[i32]>>(mut v: T) { + /// assert_eq!(&mut [1, 2, 3], v.borrow_mut()); + /// } + /// + /// let v = vec![1, 2, 3]; + /// + /// check(v); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn borrow_mut(&mut self) -> &mut Borrowed; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Borrow<T> for T { + fn borrow(&self) -> &T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> BorrowMut<T> for T { + fn borrow_mut(&mut self) -> &mut T { self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow<T> for &'a T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Borrow<T> for &'a mut T { + fn borrow(&self) -> &T { &**self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T { + fn borrow_mut(&mut self) -> &mut T { &mut **self } +} diff --git a/libcore/build.rs b/libcore/build.rs new file mode 100644 index 0000000..a991ac0 --- /dev/null +++ b/libcore/build.rs @@ -0,0 +1,14 @@ +// Copyright 2016 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. + +fn main() { + // Remove this whenever snapshots and rustbuild nightlies are synced. + println!("cargo:rustc-cfg=cargobuild"); +} diff --git a/libcore/cell.rs b/libcore/cell.rs new file mode 100644 index 0000000..a1c7a29 --- /dev/null +++ b/libcore/cell.rs @@ -0,0 +1,861 @@ +// Copyright 2012-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. + +//! Shareable mutable containers. +//! +//! Values of the `Cell<T>` and `RefCell<T>` types may be mutated through shared references (i.e. +//! the common `&T` type), whereas most Rust types can only be mutated through unique (`&mut T`) +//! references. We say that `Cell<T>` and `RefCell<T>` provide 'interior mutability', in contrast +//! with typical Rust types that exhibit 'inherited mutability'. +//! +//! Cell types come in two flavors: `Cell<T>` and `RefCell<T>`. `Cell<T>` provides `get` and `set` +//! methods that change the interior value with a single method call. `Cell<T>` though is only +//! compatible with types that implement `Copy`. For other types, one must use the `RefCell<T>` +//! type, acquiring a write lock before mutating. +//! +//! `RefCell<T>` uses Rust's lifetimes to implement 'dynamic borrowing', a process whereby one can +//! claim temporary, exclusive, mutable access to the inner value. Borrows for `RefCell<T>`s are +//! tracked 'at runtime', unlike Rust's native reference types which are entirely tracked +//! statically, at compile time. Because `RefCell<T>` borrows are dynamic it is possible to attempt +//! to borrow a value that is already mutably borrowed; when this happens it results in thread +//! panic. +//! +//! # When to choose interior mutability +//! +//! The more common inherited mutability, where one must have unique access to mutate a value, is +//! one of the key language elements that enables Rust to reason strongly about pointer aliasing, +//! statically preventing crash bugs. Because of that, inherited mutability is preferred, and +//! interior mutability is something of a last resort. Since cell types enable mutation where it +//! would otherwise be disallowed though, there are occasions when interior mutability might be +//! appropriate, or even *must* be used, e.g. +//! +//! * Introducing mutability 'inside' of something immutable +//! * Implementation details of logically-immutable methods. +//! * Mutating implementations of `Clone`. +//! +//! ## Introducing mutability 'inside' of something immutable +//! +//! Many shared smart pointer types, including `Rc<T>` and `Arc<T>`, provide containers that can be +//! cloned and shared between multiple parties. Because the contained values may be +//! multiply-aliased, they can only be borrowed with `&`, not `&mut`. Without cells it would be +//! impossible to mutate data inside of these smart pointers at all. +//! +//! It's very common then to put a `RefCell<T>` inside shared pointer types to reintroduce +//! mutability: +//! +//! ``` +//! use std::collections::HashMap; +//! use std::cell::RefCell; +//! use std::rc::Rc; +//! +//! fn main() { +//! let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new())); +//! shared_map.borrow_mut().insert("africa", 92388); +//! shared_map.borrow_mut().insert("kyoto", 11837); +//! shared_map.borrow_mut().insert("piccadilly", 11826); +//! shared_map.borrow_mut().insert("marbles", 38); +//! } +//! ``` +//! +//! Note that this example uses `Rc<T>` and not `Arc<T>`. `RefCell<T>`s are for single-threaded +//! scenarios. Consider using `RwLock<T>` or `Mutex<T>` if you need shared mutability in a +//! multi-threaded situation. +//! +//! ## Implementation details of logically-immutable methods +//! +//! Occasionally it may be desirable not to expose in an API that there is mutation happening +//! "under the hood". This may be because logically the operation is immutable, but e.g. caching +//! forces the implementation to perform mutation; or because you must employ mutation to implement +//! a trait method that was originally defined to take `&self`. +//! +//! ``` +//! # #![allow(dead_code)] +//! use std::cell::RefCell; +//! +//! struct Graph { +//! edges: Vec<(i32, i32)>, +//! span_tree_cache: RefCell<Option<Vec<(i32, i32)>>> +//! } +//! +//! impl Graph { +//! fn minimum_spanning_tree(&self) -> Vec<(i32, i32)> { +//! // Create a new scope to contain the lifetime of the +//! // dynamic borrow +//! { +//! // Take a reference to the inside of cache cell +//! let mut cache = self.span_tree_cache.borrow_mut(); +//! if cache.is_some() { +//! return cache.as_ref().unwrap().clone(); +//! } +//! +//! let span_tree = self.calc_span_tree(); +//! *cache = Some(span_tree); +//! } +//! +//! // Recursive call to return the just-cached value. +//! // Note that if we had not let the previous borrow +//! // of the cache fall out of scope then the subsequent +//! // recursive borrow would cause a dynamic thread panic. +//! // This is the major hazard of using `RefCell`. +//! self.minimum_spanning_tree() +//! } +//! # fn calc_span_tree(&self) -> Vec<(i32, i32)> { vec![] } +//! } +//! ``` +//! +//! ## Mutating implementations of `Clone` +//! +//! This is simply a special - but common - case of the previous: hiding mutability for operations +//! that appear to be immutable. The `clone` method is expected to not change the source value, and +//! is declared to take `&self`, not `&mut self`. Therefore any mutation that happens in the +//! `clone` method must use cell types. For example, `Rc<T>` maintains its reference counts within a +//! `Cell<T>`. +//! +//! ``` +//! use std::cell::Cell; +//! +//! struct Rc<T> { +//! ptr: *mut RcBox<T> +//! } +//! +//! struct RcBox<T> { +//! # #[allow(dead_code)] +//! value: T, +//! refcount: Cell<usize> +//! } +//! +//! impl<T> Clone for Rc<T> { +//! fn clone(&self) -> Rc<T> { +//! unsafe { +//! (*self.ptr).refcount.set((*self.ptr).refcount.get() + 1); +//! Rc { ptr: self.ptr } +//! } +//! } +//! } +//! ``` +//! + +#![stable(feature = "rust1", since = "1.0.0")] + +use clone::Clone; +use cmp::{PartialEq, Eq}; +use default::Default; +use marker::{Copy, Send, Sync, Sized, Unsize}; +use ops::{Deref, DerefMut, Drop, FnOnce, CoerceUnsized}; +use option::Option; +use option::Option::{None, Some}; + +/// A mutable memory location that admits only `Copy` data. +/// +/// See the [module-level documentation](index.html) for more. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Cell<T> { + value: UnsafeCell<T>, +} + +impl<T:Copy> Cell<T> { + /// Creates a new `Cell` containing the given value. + /// + /// # Examples + /// + /// ``` + /// use std::cell::Cell; + /// + /// let c = Cell::new(5); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn new(value: T) -> Cell<T> { + Cell { + value: UnsafeCell::new(value), + } + } + + /// Returns a copy of the contained value. + /// + /// # Examples + /// + /// ``` + /// use std::cell::Cell; + /// + /// let c = Cell::new(5); + /// + /// let five = c.get(); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get(&self) -> T { + unsafe{ *self.value.get() } + } + + /// Sets the contained value. + /// + /// # Examples + /// + /// ``` + /// use std::cell::Cell; + /// + /// let c = Cell::new(5); + /// + /// c.set(10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn set(&self, value: T) { + unsafe { + *self.value.get() = value; + } + } + + /// Returns a reference to the underlying `UnsafeCell`. + /// + /// # Examples + /// + /// ``` + /// #![feature(as_unsafe_cell)] + /// + /// use std::cell::Cell; + /// + /// let c = Cell::new(5); + /// + /// let uc = c.as_unsafe_cell(); + /// ``` + #[inline] + #[unstable(feature = "as_unsafe_cell", issue = "27708")] + pub fn as_unsafe_cell(&self) -> &UnsafeCell<T> { + &self.value + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<T> Send for Cell<T> where T: Send {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> !Sync for Cell<T> {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T:Copy> Clone for Cell<T> { + #[inline] + fn clone(&self) -> Cell<T> { + Cell::new(self.get()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T:Default + Copy> Default for Cell<T> { + #[inline] + fn default() -> Cell<T> { + Cell::new(Default::default()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T:PartialEq + Copy> PartialEq for Cell<T> { + #[inline] + fn eq(&self, other: &Cell<T>) -> bool { + self.get() == other.get() + } +} + +#[stable(feature = "cell_eq", since = "1.2.0")] +impl<T:Eq + Copy> Eq for Cell<T> {} + +/// A mutable memory location with dynamically checked borrow rules +/// +/// See the [module-level documentation](index.html) for more. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct RefCell<T: ?Sized> { + borrow: Cell<BorrowFlag>, + value: UnsafeCell<T>, +} + +/// An enumeration of values returned from the `state` method on a `RefCell<T>`. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[unstable(feature = "borrow_state", issue = "27733")] +pub enum BorrowState { + /// The cell is currently being read, there is at least one active `borrow`. + Reading, + /// The cell is currently being written to, there is an active `borrow_mut`. + Writing, + /// There are no outstanding borrows on this cell. + Unused, +} + +// Values [1, MAX-1] represent the number of `Ref` active +// (will not outgrow its range since `usize` is the size of the address space) +type BorrowFlag = usize; +const UNUSED: BorrowFlag = 0; +const WRITING: BorrowFlag = !0; + +impl<T> RefCell<T> { + /// Creates a new `RefCell` containing `value`. + /// + /// # Examples + /// + /// ``` + /// use std::cell::RefCell; + /// + /// let c = RefCell::new(5); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn new(value: T) -> RefCell<T> { + RefCell { + value: UnsafeCell::new(value), + borrow: Cell::new(UNUSED), + } + } + + /// Consumes the `RefCell`, returning the wrapped value. + /// + /// # Examples + /// + /// ``` + /// use std::cell::RefCell; + /// + /// let c = RefCell::new(5); + /// + /// let five = c.into_inner(); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn into_inner(self) -> T { + // Since this function takes `self` (the `RefCell`) by value, the + // compiler statically verifies that it is not currently borrowed. + // Therefore the following assertion is just a `debug_assert!`. + debug_assert!(self.borrow.get() == UNUSED); + unsafe { self.value.into_inner() } + } +} + +impl<T: ?Sized> RefCell<T> { + /// Query the current state of this `RefCell` + /// + /// The returned value can be dispatched on to determine if a call to + /// `borrow` or `borrow_mut` would succeed. + #[unstable(feature = "borrow_state", issue = "27733")] + #[inline] + pub fn borrow_state(&self) -> BorrowState { + match self.borrow.get() { + WRITING => BorrowState::Writing, + UNUSED => BorrowState::Unused, + _ => BorrowState::Reading, + } + } + + /// Immutably borrows the wrapped value. + /// + /// The borrow lasts until the returned `Ref` exits scope. Multiple + /// immutable borrows can be taken out at the same time. + /// + /// # Panics + /// + /// Panics if the value is currently mutably borrowed. + /// + /// # Examples + /// + /// ``` + /// use std::cell::RefCell; + /// + /// let c = RefCell::new(5); + /// + /// let borrowed_five = c.borrow(); + /// let borrowed_five2 = c.borrow(); + /// ``` + /// + /// An example of panic: + /// + /// ``` + /// use std::cell::RefCell; + /// use std::thread; + /// + /// let result = thread::spawn(move || { + /// let c = RefCell::new(5); + /// let m = c.borrow_mut(); + /// + /// let b = c.borrow(); // this causes a panic + /// }).join(); + /// + /// assert!(result.is_err()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn borrow(&self) -> Ref<T> { + match BorrowRef::new(&self.borrow) { + Some(b) => Ref { + value: unsafe { &*self.value.get() }, + borrow: b, + }, + None => panic!("RefCell<T> already mutably borrowed"), + } + } + + /// Mutably borrows the wrapped value. + /// + /// The borrow lasts until the returned `RefMut` exits scope. The value + /// cannot be borrowed while this borrow is active. + /// + /// # Panics + /// + /// Panics if the value is currently borrowed. + /// + /// # Examples + /// + /// ``` + /// use std::cell::RefCell; + /// + /// let c = RefCell::new(5); + /// + /// *c.borrow_mut() = 7; + /// + /// assert_eq!(*c.borrow(), 7); + /// ``` + /// + /// An example of panic: + /// + /// ``` + /// use std::cell::RefCell; + /// use std::thread; + /// + /// let result = thread::spawn(move || { + /// let c = RefCell::new(5); + /// let m = c.borrow(); + /// + /// let b = c.borrow_mut(); // this causes a panic + /// }).join(); + /// + /// assert!(result.is_err()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn borrow_mut(&self) -> RefMut<T> { + match BorrowRefMut::new(&self.borrow) { + Some(b) => RefMut { + value: unsafe { &mut *self.value.get() }, + borrow: b, + }, + None => panic!("RefCell<T> already borrowed"), + } + } + + /// Returns a reference to the underlying `UnsafeCell`. + /// + /// This can be used to circumvent `RefCell`'s safety checks. + /// + /// This function is `unsafe` because `UnsafeCell`'s field is public. + #[inline] + #[unstable(feature = "as_unsafe_cell", issue = "27708")] + pub unsafe fn as_unsafe_cell(&self) -> &UnsafeCell<T> { + &self.value + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> !Sync for RefCell<T> {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: Clone> Clone for RefCell<T> { + #[inline] + fn clone(&self) -> RefCell<T> { + RefCell::new(self.borrow().clone()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T:Default> Default for RefCell<T> { + #[inline] + fn default() -> RefCell<T> { + RefCell::new(Default::default()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> { + #[inline] + fn eq(&self, other: &RefCell<T>) -> bool { + *self.borrow() == *other.borrow() + } +} + +#[stable(feature = "cell_eq", since = "1.2.0")] +impl<T: ?Sized + Eq> Eq for RefCell<T> {} + +struct BorrowRef<'b> { + borrow: &'b Cell<BorrowFlag>, +} + +impl<'b> BorrowRef<'b> { + #[inline] + fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> { + match borrow.get() { + WRITING => None, + b => { + borrow.set(b + 1); + Some(BorrowRef { borrow: borrow }) + }, + } + } +} + +impl<'b> Drop for BorrowRef<'b> { + #[inline] + fn drop(&mut self) { + let borrow = self.borrow.get(); + debug_assert!(borrow != WRITING && borrow != UNUSED); + self.borrow.set(borrow - 1); + } +} + +impl<'b> Clone for BorrowRef<'b> { + #[inline] + fn clone(&self) -> BorrowRef<'b> { + // Since this Ref exists, we know the borrow flag + // is not set to WRITING. + let borrow = self.borrow.get(); + debug_assert!(borrow != WRITING && borrow != UNUSED); + self.borrow.set(borrow + 1); + BorrowRef { borrow: self.borrow } + } +} + +/// Wraps a borrowed reference to a value in a `RefCell` box. +/// A wrapper type for an immutably borrowed value from a `RefCell<T>`. +/// +/// See the [module-level documentation](index.html) for more. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Ref<'b, T: ?Sized + 'b> { + value: &'b T, + borrow: BorrowRef<'b>, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'b, T: ?Sized> Deref for Ref<'b, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + self.value + } +} + +impl<'b, T: ?Sized> Ref<'b, T> { + /// Copies a `Ref`. + /// + /// The `RefCell` is already immutably borrowed, so this cannot fail. + /// + /// This is an associated function that needs to be used as + /// `Ref::clone(...)`. A `Clone` implementation or a method would interfere + /// with the widespread use of `r.borrow().clone()` to clone the contents of + /// a `RefCell`. + #[unstable(feature = "cell_extras", + reason = "likely to be moved to a method, pending language changes", + issue = "27746")] + #[inline] + pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> { + Ref { + value: orig.value, + borrow: orig.borrow.clone(), + } + } + + /// Make a new `Ref` for a component of the borrowed data. + /// + /// The `RefCell` is already immutably borrowed, so this cannot fail. + /// + /// This is an associated function that needs to be used as `Ref::map(...)`. + /// A method would interfere with methods of the same name on the contents + /// of a `RefCell` used through `Deref`. + /// + /// # Example + /// + /// ``` + /// use std::cell::{RefCell, Ref}; + /// + /// let c = RefCell::new((5, 'b')); + /// let b1: Ref<(u32, char)> = c.borrow(); + /// let b2: Ref<u32> = Ref::map(b1, |t| &t.0); + /// assert_eq!(*b2, 5) + /// ``` + #[stable(feature = "cell_map", since = "1.8.0")] + #[inline] + pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U> + where F: FnOnce(&T) -> &U + { + Ref { + value: f(orig.value), + borrow: orig.borrow, + } + } + + /// Make a new `Ref` for an optional component of the borrowed data, e.g. an + /// enum variant. + /// + /// The `RefCell` is already immutably borrowed, so this cannot fail. + /// + /// This is an associated function that needs to be used as + /// `Ref::filter_map(...)`. A method would interfere with methods of the + /// same name on the contents of a `RefCell` used through `Deref`. + /// + /// # Example + /// + /// ``` + /// # #![feature(cell_extras)] + /// use std::cell::{RefCell, Ref}; + /// + /// let c = RefCell::new(Ok(5)); + /// let b1: Ref<Result<u32, ()>> = c.borrow(); + /// let b2: Ref<u32> = Ref::filter_map(b1, |o| o.as_ref().ok()).unwrap(); + /// assert_eq!(*b2, 5) + /// ``` + #[unstable(feature = "cell_extras", reason = "recently added", + issue = "27746")] + #[rustc_deprecated(since = "1.8.0", reason = "can be built on `Ref::map`: \ + https://crates.io/crates/ref_filter_map")] + #[inline] + pub fn filter_map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Option<Ref<'b, U>> + where F: FnOnce(&T) -> Option<&U> + { + f(orig.value).map(move |new| Ref { + value: new, + borrow: orig.borrow, + }) + } +} + +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Ref<'b, U>> for Ref<'b, T> {} + +impl<'b, T: ?Sized> RefMut<'b, T> { + /// Make a new `RefMut` for a component of the borrowed data, e.g. an enum + /// variant. + /// + /// The `RefCell` is already mutably borrowed, so this cannot fail. + /// + /// This is an associated function that needs to be used as + /// `RefMut::map(...)`. A method would interfere with methods of the same + /// name on the contents of a `RefCell` used through `Deref`. + /// + /// # Example + /// + /// ``` + /// use std::cell::{RefCell, RefMut}; + /// + /// let c = RefCell::new((5, 'b')); + /// { + /// let b1: RefMut<(u32, char)> = c.borrow_mut(); + /// let mut b2: RefMut<u32> = RefMut::map(b1, |t| &mut t.0); + /// assert_eq!(*b2, 5); + /// *b2 = 42; + /// } + /// assert_eq!(*c.borrow(), (42, 'b')); + /// ``` + #[stable(feature = "cell_map", since = "1.8.0")] + #[inline] + pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U> + where F: FnOnce(&mut T) -> &mut U + { + RefMut { + value: f(orig.value), + borrow: orig.borrow, + } + } + + /// Make a new `RefMut` for an optional component of the borrowed data, e.g. + /// an enum variant. + /// + /// The `RefCell` is already mutably borrowed, so this cannot fail. + /// + /// This is an associated function that needs to be used as + /// `RefMut::filter_map(...)`. A method would interfere with methods of the + /// same name on the contents of a `RefCell` used through `Deref`. + /// + /// # Example + /// + /// ``` + /// # #![feature(cell_extras)] + /// use std::cell::{RefCell, RefMut}; + /// + /// let c = RefCell::new(Ok(5)); + /// { + /// let b1: RefMut<Result<u32, ()>> = c.borrow_mut(); + /// let mut b2: RefMut<u32> = RefMut::filter_map(b1, |o| { + /// o.as_mut().ok() + /// }).unwrap(); + /// assert_eq!(*b2, 5); + /// *b2 = 42; + /// } + /// assert_eq!(*c.borrow(), Ok(42)); + /// ``` + #[unstable(feature = "cell_extras", reason = "recently added", + issue = "27746")] + #[rustc_deprecated(since = "1.8.0", reason = "can be built on `RefMut::map`: \ + https://crates.io/crates/ref_filter_map")] + #[inline] + pub fn filter_map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> Option<RefMut<'b, U>> + where F: FnOnce(&mut T) -> Option<&mut U> + { + let RefMut { value, borrow } = orig; + f(value).map(move |new| RefMut { + value: new, + borrow: borrow, + }) + } +} + +struct BorrowRefMut<'b> { + borrow: &'b Cell<BorrowFlag>, +} + +impl<'b> Drop for BorrowRefMut<'b> { + #[inline] + fn drop(&mut self) { + let borrow = self.borrow.get(); + debug_assert!(borrow == WRITING); + self.borrow.set(UNUSED); + } +} + +impl<'b> BorrowRefMut<'b> { + #[inline] + fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> { + match borrow.get() { + UNUSED => { + borrow.set(WRITING); + Some(BorrowRefMut { borrow: borrow }) + }, + _ => None, + } + } +} + +/// A wrapper type for a mutably borrowed value from a `RefCell<T>`. +/// +/// See the [module-level documentation](index.html) for more. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct RefMut<'b, T: ?Sized + 'b> { + value: &'b mut T, + borrow: BorrowRefMut<'b>, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'b, T: ?Sized> Deref for RefMut<'b, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + self.value + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> { + #[inline] + fn deref_mut(&mut self) -> &mut T { + self.value + } +} + +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, T> {} + +/// The core primitive for interior mutability in Rust. +/// +/// `UnsafeCell<T>` is a type that wraps some `T` and indicates unsafe interior operations on the +/// wrapped type. Types with an `UnsafeCell<T>` field are considered to have an 'unsafe interior'. +/// The `UnsafeCell<T>` type is the only legal way to obtain aliasable data that is considered +/// mutable. In general, transmuting an `&T` type into an `&mut T` is considered undefined behavior. +/// +/// Types like `Cell<T>` and `RefCell<T>` use this type to wrap their internal data. +/// +/// # Examples +/// +/// ``` +/// use std::cell::UnsafeCell; +/// use std::marker::Sync; +/// +/// # #[allow(dead_code)] +/// struct NotThreadSafe<T> { +/// value: UnsafeCell<T>, +/// } +/// +/// unsafe impl<T> Sync for NotThreadSafe<T> {} +/// ``` +#[lang = "unsafe_cell"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct UnsafeCell<T: ?Sized> { + value: T, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> !Sync for UnsafeCell<T> {} + +impl<T> UnsafeCell<T> { + /// Constructs a new instance of `UnsafeCell` which will wrap the specified + /// value. + /// + /// All access to the inner value through methods is `unsafe`. + /// + /// # Examples + /// + /// ``` + /// use std::cell::UnsafeCell; + /// + /// let uc = UnsafeCell::new(5); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn new(value: T) -> UnsafeCell<T> { + UnsafeCell { value: value } + } + + /// Unwraps the value. + /// + /// # Safety + /// + /// This function is unsafe because this thread or another thread may currently be + /// inspecting the inner value. + /// + /// # Examples + /// + /// ``` + /// use std::cell::UnsafeCell; + /// + /// let uc = UnsafeCell::new(5); + /// + /// let five = unsafe { uc.into_inner() }; + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub unsafe fn into_inner(self) -> T { + self.value + } +} + +impl<T: ?Sized> UnsafeCell<T> { + /// Gets a mutable pointer to the wrapped value. + /// + /// # Examples + /// + /// ``` + /// use std::cell::UnsafeCell; + /// + /// let uc = UnsafeCell::new(5); + /// + /// let five = uc.get(); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn get(&self) -> *mut T { + &self.value as *const T as *mut T + } +} diff --git a/libcore/char.rs b/libcore/char.rs new file mode 100644 index 0000000..b2b1dc5 --- /dev/null +++ b/libcore/char.rs @@ -0,0 +1,634 @@ +// Copyright 2012-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. + +//! Character manipulation. +//! +//! For more details, see ::rustc_unicode::char (a.k.a. std::char) + +#![allow(non_snake_case)] +#![stable(feature = "core_char", since = "1.2.0")] + +use iter::Iterator; +use mem::transmute; +use option::Option::{None, Some}; +use option::Option; +use slice::SliceExt; + +// UTF-8 ranges and tags for encoding characters +const TAG_CONT: u8 = 0b1000_0000; +const TAG_TWO_B: u8 = 0b1100_0000; +const TAG_THREE_B: u8 = 0b1110_0000; +const TAG_FOUR_B: u8 = 0b1111_0000; +const MAX_ONE_B: u32 = 0x80; +const MAX_TWO_B: u32 = 0x800; +const MAX_THREE_B: u32 = 0x10000; + +/* + Lu Uppercase_Letter an uppercase letter + Ll Lowercase_Letter a lowercase letter + Lt Titlecase_Letter a digraphic character, with first part uppercase + Lm Modifier_Letter a modifier letter + Lo Other_Letter other letters, including syllables and ideographs + Mn Nonspacing_Mark a nonspacing combining mark (zero advance width) + Mc Spacing_Mark a spacing combining mark (positive advance width) + Me Enclosing_Mark an enclosing combining mark + Nd Decimal_Number a decimal digit + Nl Letter_Number a letterlike numeric character + No Other_Number a numeric character of other type + Pc Connector_Punctuation a connecting punctuation mark, like a tie + Pd Dash_Punctuation a dash or hyphen punctuation mark + Ps Open_Punctuation an opening punctuation mark (of a pair) + Pe Close_Punctuation a closing punctuation mark (of a pair) + Pi Initial_Punctuation an initial quotation mark + Pf Final_Punctuation a final quotation mark + Po Other_Punctuation a punctuation mark of other type + Sm Math_Symbol a symbol of primarily mathematical use + Sc Currency_Symbol a currency sign + Sk Modifier_Symbol a non-letterlike modifier symbol + So Other_Symbol a symbol of other type + Zs Space_Separator a space character (of various non-zero widths) + Zl Line_Separator U+2028 LINE SEPARATOR only + Zp Paragraph_Separator U+2029 PARAGRAPH SEPARATOR only + Cc Control a C0 or C1 control code + Cf Format a format control character + Cs Surrogate a surrogate code point + Co Private_Use a private-use character + Cn Unassigned a reserved unassigned code point or a noncharacter +*/ + +/// The highest valid code point a `char` can have. +/// +/// A [`char`] is a [Unicode Scalar Value], which means that it is a [Code +/// Point], but only ones within a certain range. `MAX` is the highest valid +/// code point that's a valid [Unicode Scalar Value]. +/// +/// [`char`]: ../../std/primitive.char.html +/// [Unicode Scalar Value]: http://www.unicode.org/glossary/#unicode_scalar_value +/// [Code Point]: http://www.unicode.org/glossary/#code_point +#[stable(feature = "rust1", since = "1.0.0")] +pub const MAX: char = '\u{10ffff}'; + +/// Converts a `u32` to a `char`. +/// +/// Note that all [`char`]s are valid [`u32`]s, and can be casted to one with +/// [`as`]: +/// +/// ``` +/// let c = '💯'; +/// let i = c as u32; +/// +/// assert_eq!(128175, i); +/// ``` +/// +/// However, the reverse is not true: not all valid [`u32`]s are valid +/// [`char`]s. `from_u32()` will return `None` if the input is not a valid value +/// for a [`char`]. +/// +/// [`char`]: ../../std/primitive.char.html +/// [`u32`]: ../../std/primitive.u32.html +/// [`as`]: ../../book/casting-between-types.html#as +/// +/// For an unsafe version of this function which ignores these checks, see +/// [`from_u32_unchecked()`]. +/// +/// [`from_u32_unchecked()`]: fn.from_u32_unchecked.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::char; +/// +/// let c = char::from_u32(0x2764); +/// +/// assert_eq!(Some('❤'), c); +/// ``` +/// +/// Returning `None` when the input is not a valid [`char`]: +/// +/// ``` +/// use std::char; +/// +/// let c = char::from_u32(0x110000); +/// +/// assert_eq!(None, c); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn from_u32(i: u32) -> Option<char> { + // catch out-of-bounds and surrogates + if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) { + None + } else { + Some(unsafe { from_u32_unchecked(i) }) + } +} + +/// Converts a `u32` to a `char`, ignoring validity. +/// +/// Note that all [`char`]s are valid [`u32`]s, and can be casted to one with +/// [`as`]: +/// +/// ``` +/// let c = '💯'; +/// let i = c as u32; +/// +/// assert_eq!(128175, i); +/// ``` +/// +/// However, the reverse is not true: not all valid [`u32`]s are valid +/// [`char`]s. `from_u32_unchecked()` will ignore this, and blindly cast to +/// [`char`], possibly creating an invalid one. +/// +/// [`char`]: ../../std/primitive.char.html +/// [`u32`]: ../../std/primitive.u32.html +/// [`as`]: ../../book/casting-between-types.html#as +/// +/// # Safety +/// +/// This function is unsafe, as it may construct invalid `char` values. +/// +/// For a safe version of this function, see the [`from_u32()`] function. +/// +/// [`from_u32()`]: fn.from_u32.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::char; +/// +/// let c = unsafe { char::from_u32_unchecked(0x2764) }; +/// +/// assert_eq!('❤', c); +/// ``` +#[inline] +#[stable(feature = "char_from_unchecked", since = "1.5.0")] +pub unsafe fn from_u32_unchecked(i: u32) -> char { + transmute(i) +} + +/// Converts a digit in the given radix to a `char`. +/// +/// A 'radix' here is sometimes also called a 'base'. A radix of two +/// indicates a binary number, a radix of ten, decimal, and a radix of +/// sixteen, hexadecimal, to give some common values. Arbitrary +/// radicum are supported. +/// +/// `from_digit()` will return `None` if the input is not a digit in +/// the given radix. +/// +/// # Panics +/// +/// Panics if given a radix larger than 36. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::char; +/// +/// let c = char::from_digit(4, 10); +/// +/// assert_eq!(Some('4'), c); +/// +/// // Decimal 11 is a single digit in base 16 +/// let c = char::from_digit(11, 16); +/// +/// assert_eq!(Some('b'), c); +/// ``` +/// +/// Returning `None` when the input is not a digit: +/// +/// ``` +/// use std::char; +/// +/// let c = char::from_digit(20, 10); +/// +/// assert_eq!(None, c); +/// ``` +/// +/// Passing a large radix, causing a panic: +/// +/// ``` +/// use std::thread; +/// use std::char; +/// +/// let result = thread::spawn(|| { +/// // this panics +/// let c = char::from_digit(1, 37); +/// }).join(); +/// +/// assert!(result.is_err()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn from_digit(num: u32, radix: u32) -> Option<char> { + if radix > 36 { + panic!("from_digit: radix is too high (maximum 36)"); + } + if num < radix { + let num = num as u8; + if num < 10 { + Some((b'0' + num) as char) + } else { + Some((b'a' + num - 10) as char) + } + } else { + None + } +} + +// NB: the stabilization and documentation for this trait is in +// unicode/char.rs, not here +#[allow(missing_docs)] // docs in libunicode/u_char.rs +#[doc(hidden)] +#[unstable(feature = "core_char_ext", + reason = "the stable interface is `impl char` in later crate", + issue = "32110")] +pub trait CharExt { + #[stable(feature = "core", since = "1.6.0")] + fn is_digit(self, radix: u32) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn to_digit(self, radix: u32) -> Option<u32>; + #[stable(feature = "core", since = "1.6.0")] + fn escape_unicode(self) -> EscapeUnicode; + #[stable(feature = "core", since = "1.6.0")] + fn escape_default(self) -> EscapeDefault; + #[stable(feature = "core", since = "1.6.0")] + fn len_utf8(self) -> usize; + #[stable(feature = "core", since = "1.6.0")] + fn len_utf16(self) -> usize; + #[unstable(feature = "unicode", issue = "27784")] + fn encode_utf8(self) -> EncodeUtf8; + #[unstable(feature = "unicode", issue = "27784")] + fn encode_utf16(self) -> EncodeUtf16; +} + +#[stable(feature = "core", since = "1.6.0")] +impl CharExt for char { + #[inline] + fn is_digit(self, radix: u32) -> bool { + self.to_digit(radix).is_some() + } + + #[inline] + fn to_digit(self, radix: u32) -> Option<u32> { + if radix > 36 { + panic!("to_digit: radix is too high (maximum 36)"); + } + let val = match self { + '0' ... '9' => self as u32 - '0' as u32, + 'a' ... 'z' => self as u32 - 'a' as u32 + 10, + 'A' ... 'Z' => self as u32 - 'A' as u32 + 10, + _ => return None, + }; + if val < radix { Some(val) } + else { None } + } + + #[inline] + fn escape_unicode(self) -> EscapeUnicode { + EscapeUnicode { c: self, state: EscapeUnicodeState::Backslash } + } + + #[inline] + fn escape_default(self) -> EscapeDefault { + let init_state = match self { + '\t' => EscapeDefaultState::Backslash('t'), + '\r' => EscapeDefaultState::Backslash('r'), + '\n' => EscapeDefaultState::Backslash('n'), + '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self), + '\x20' ... '\x7e' => EscapeDefaultState::Char(self), + _ => EscapeDefaultState::Unicode(self.escape_unicode()) + }; + EscapeDefault { state: init_state } + } + + #[inline] + fn len_utf8(self) -> usize { + let code = self as u32; + if code < MAX_ONE_B { + 1 + } else if code < MAX_TWO_B { + 2 + } else if code < MAX_THREE_B { + 3 + } else { + 4 + } + } + + #[inline] + fn len_utf16(self) -> usize { + let ch = self as u32; + if (ch & 0xFFFF) == ch { 1 } else { 2 } + } + + #[inline] + fn encode_utf8(self) -> EncodeUtf8 { + let code = self as u32; + let mut buf = [0; 4]; + let pos = if code < MAX_ONE_B { + buf[3] = code as u8; + 3 + } else if code < MAX_TWO_B { + buf[2] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 2 + } else if code < MAX_THREE_B { + buf[1] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 1 + } else { + buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; + buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 0 + }; + EncodeUtf8 { buf: buf, pos: pos } + } + + #[inline] + fn encode_utf16(self) -> EncodeUtf16 { + let mut buf = [0; 2]; + let mut code = self as u32; + let pos = if (code & 0xFFFF) == code { + // The BMP falls through (assuming non-surrogate, as it should) + buf[1] = code as u16; + 1 + } else { + // Supplementary planes break into surrogates. + code -= 0x1_0000; + buf[0] = 0xD800 | ((code >> 10) as u16); + buf[1] = 0xDC00 | ((code as u16) & 0x3FF); + 0 + }; + EncodeUtf16 { buf: buf, pos: pos } + } +} + +/// Returns an iterator that yields the hexadecimal Unicode escape of a +/// character, as `char`s. +/// +/// This `struct` is created by the [`escape_unicode()`] method on [`char`]. See +/// its documentation for more. +/// +/// [`escape_unicode()`]: ../../std/primitive.char.html#method.escape_unicode +/// [`char`]: ../../std/primitive.char.html +#[derive(Clone, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct EscapeUnicode { + c: char, + state: EscapeUnicodeState +} + +#[derive(Clone, Debug)] +enum EscapeUnicodeState { + Backslash, + Type, + LeftBrace, + Value(usize), + RightBrace, + Done, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for EscapeUnicode { + type Item = char; + + fn next(&mut self) -> Option<char> { + match self.state { + EscapeUnicodeState::Backslash => { + self.state = EscapeUnicodeState::Type; + Some('\\') + } + EscapeUnicodeState::Type => { + self.state = EscapeUnicodeState::LeftBrace; + Some('u') + } + EscapeUnicodeState::LeftBrace => { + let mut n = 0; + while (self.c as u32) >> (4 * (n + 1)) != 0 { + n += 1; + } + self.state = EscapeUnicodeState::Value(n); + Some('{') + } + EscapeUnicodeState::Value(offset) => { + let c = from_digit(((self.c as u32) >> (offset * 4)) & 0xf, 16).unwrap(); + if offset == 0 { + self.state = EscapeUnicodeState::RightBrace; + } else { + self.state = EscapeUnicodeState::Value(offset - 1); + } + Some(c) + } + EscapeUnicodeState::RightBrace => { + self.state = EscapeUnicodeState::Done; + Some('}') + } + EscapeUnicodeState::Done => None, + } + } + + fn size_hint(&self) -> (usize, Option<usize>) { + let mut n = 0; + while (self.c as usize) >> (4 * (n + 1)) != 0 { + n += 1; + } + let n = match self.state { + EscapeUnicodeState::Backslash => n + 5, + EscapeUnicodeState::Type => n + 4, + EscapeUnicodeState::LeftBrace => n + 3, + EscapeUnicodeState::Value(offset) => offset + 2, + EscapeUnicodeState::RightBrace => 1, + EscapeUnicodeState::Done => 0, + }; + (n, Some(n)) + } +} + +/// An iterator that yields the literal escape code of a `char`. +/// +/// This `struct` is created by the [`escape_default()`] method on [`char`]. See +/// its documentation for more. +/// +/// [`escape_default()`]: ../../std/primitive.char.html#method.escape_default +/// [`char`]: ../../std/primitive.char.html +#[derive(Clone, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct EscapeDefault { + state: EscapeDefaultState +} + +#[derive(Clone, Debug)] +enum EscapeDefaultState { + Backslash(char), + Char(char), + Done, + Unicode(EscapeUnicode), +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for EscapeDefault { + type Item = char; + + fn next(&mut self) -> Option<char> { + match self.state { + EscapeDefaultState::Backslash(c) => { + self.state = EscapeDefaultState::Char(c); + Some('\\') + } + EscapeDefaultState::Char(c) => { + self.state = EscapeDefaultState::Done; + Some(c) + } + EscapeDefaultState::Done => None, + EscapeDefaultState::Unicode(ref mut iter) => iter.next(), + } + } + + fn size_hint(&self) -> (usize, Option<usize>) { + match self.state { + EscapeDefaultState::Char(_) => (1, Some(1)), + EscapeDefaultState::Backslash(_) => (2, Some(2)), + EscapeDefaultState::Unicode(ref iter) => iter.size_hint(), + EscapeDefaultState::Done => (0, Some(0)), + } + } + + fn count(self) -> usize { + match self.state { + EscapeDefaultState::Char(_) => 1, + EscapeDefaultState::Unicode(iter) => iter.count(), + EscapeDefaultState::Done => 0, + EscapeDefaultState::Backslash(_) => 2, + } + } + + fn nth(&mut self, n: usize) -> Option<char> { + match self.state { + EscapeDefaultState::Backslash(c) if n == 0 => { + self.state = EscapeDefaultState::Char(c); + Some('\\') + }, + EscapeDefaultState::Backslash(c) if n == 1 => { + self.state = EscapeDefaultState::Done; + Some(c) + }, + EscapeDefaultState::Backslash(_) => { + self.state = EscapeDefaultState::Done; + None + }, + EscapeDefaultState::Char(c) => { + self.state = EscapeDefaultState::Done; + + if n == 0 { + Some(c) + } else { + None + } + }, + EscapeDefaultState::Done => return None, + EscapeDefaultState::Unicode(ref mut i) => return i.nth(n), + } + } + + fn last(self) -> Option<char> { + match self.state { + EscapeDefaultState::Unicode(iter) => iter.last(), + EscapeDefaultState::Done => None, + EscapeDefaultState::Backslash(c) | EscapeDefaultState::Char(c) => Some(c), + } + } +} + +/// An iterator over `u8` entries represending the UTF-8 encoding of a `char` +/// value. +/// +/// Constructed via the `.encode_utf8()` method on `char`. +#[unstable(feature = "unicode", issue = "27784")] +#[derive(Debug)] +pub struct EncodeUtf8 { + buf: [u8; 4], + pos: usize, +} + +impl EncodeUtf8 { + /// Returns the remaining bytes of this iterator as a slice. + #[unstable(feature = "unicode", issue = "27784")] + pub fn as_slice(&self) -> &[u8] { + &self.buf[self.pos..] + } +} + +#[unstable(feature = "unicode", issue = "27784")] +impl Iterator for EncodeUtf8 { + type Item = u8; + + fn next(&mut self) -> Option<u8> { + if self.pos == self.buf.len() { + None + } else { + let ret = Some(self.buf[self.pos]); + self.pos += 1; + ret + } + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.as_slice().iter().size_hint() + } +} + +/// An iterator over `u16` entries represending the UTF-16 encoding of a `char` +/// value. +/// +/// Constructed via the `.encode_utf16()` method on `char`. +#[unstable(feature = "unicode", issue = "27784")] +#[derive(Debug)] +pub struct EncodeUtf16 { + buf: [u16; 2], + pos: usize, +} + +impl EncodeUtf16 { + /// Returns the remaining bytes of this iterator as a slice. + #[unstable(feature = "unicode", issue = "27784")] + pub fn as_slice(&self) -> &[u16] { + &self.buf[self.pos..] + } +} + + +#[unstable(feature = "unicode", issue = "27784")] +impl Iterator for EncodeUtf16 { + type Item = u16; + + fn next(&mut self) -> Option<u16> { + if self.pos == self.buf.len() { + None + } else { + let ret = Some(self.buf[self.pos]); + self.pos += 1; + ret + } + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.as_slice().iter().size_hint() + } +} diff --git a/libcore/clone.rs b/libcore/clone.rs new file mode 100644 index 0000000..a793502 --- /dev/null +++ b/libcore/clone.rs @@ -0,0 +1,113 @@ +// Copyright 2012-2013 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. + +//! The `Clone` trait for types that cannot be 'implicitly copied'. +//! +//! In Rust, some simple types are "implicitly copyable" and when you +//! assign them or pass them as arguments, the receiver will get a copy, +//! leaving the original value in place. These types do not require +//! allocation to copy and do not have finalizers (i.e. they do not +//! contain owned boxes or implement `Drop`), so the compiler considers +//! them cheap and safe to copy. For other types copies must be made +//! explicitly, by convention implementing the `Clone` trait and calling +//! the `clone` method. +//! +//! Basic usage example: +//! +//! ``` +//! let s = String::new(); // String type implements Clone +//! let copy = s.clone(); // so we can clone it +//! ``` +//! +//! To easily implement the Clone trait, you can also use +//! `#[derive(Clone)]`. Example: +//! +//! ``` +//! #[derive(Clone)] // we add the Clone trait to Morpheus struct +//! struct Morpheus { +//! blue_pill: f32, +//! red_pill: i64, +//! } +//! +//! fn main() { +//! let f = Morpheus { blue_pill: 0.0, red_pill: 0 }; +//! let copy = f.clone(); // and now we can clone it! +//! } +//! ``` + +#![stable(feature = "rust1", since = "1.0.0")] + +use marker::Sized; + +/// A common trait for cloning an object. +/// +/// This trait can be used with `#[derive]`. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Clone : Sized { + /// Returns a copy of the value. + /// + /// # Examples + /// + /// ``` + /// let hello = "Hello"; // &str implements Clone + /// + /// assert_eq!("Hello", hello.clone()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn clone(&self) -> Self; + + /// Performs copy-assignment from `source`. + /// + /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality, + /// but can be overridden to reuse the resources of `a` to avoid unnecessary + /// allocations. + #[inline(always)] + #[stable(feature = "rust1", since = "1.0.0")] + fn clone_from(&mut self, source: &Self) { + *self = source.clone() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Clone for &'a T { + /// Returns a shallow copy of the reference. + #[inline] + fn clone(&self) -> &'a T { *self } +} + +macro_rules! clone_impl { + ($t:ty) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl Clone for $t { + /// Returns a deep copy of the value. + #[inline] + fn clone(&self) -> $t { *self } + } + } +} + +clone_impl! { isize } +clone_impl! { i8 } +clone_impl! { i16 } +clone_impl! { i32 } +clone_impl! { i64 } + +clone_impl! { usize } +clone_impl! { u8 } +clone_impl! { u16 } +clone_impl! { u32 } +clone_impl! { u64 } + +clone_impl! { f32 } +clone_impl! { f64 } + +clone_impl! { () } +clone_impl! { bool } +clone_impl! { char } diff --git a/libcore/cmp.rs b/libcore/cmp.rs new file mode 100644 index 0000000..49aa023 --- /dev/null +++ b/libcore/cmp.rs @@ -0,0 +1,621 @@ +// Copyright 2012-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. + +//! Functionality for ordering and comparison. +//! +//! This module defines both `PartialOrd` and `PartialEq` traits which are used +//! by the compiler to implement comparison operators. Rust programs may +//! implement `PartialOrd` to overload the `<`, `<=`, `>`, and `>=` operators, +//! and may implement `PartialEq` to overload the `==` and `!=` operators. +//! +//! # Examples +//! +//! ``` +//! let x: u32 = 0; +//! let y: u32 = 1; +//! +//! // these two lines are equivalent +//! assert_eq!(x < y, true); +//! assert_eq!(x.lt(&y), true); +//! +//! // these two lines are also equivalent +//! assert_eq!(x == y, false); +//! assert_eq!(x.eq(&y), false); +//! ``` + +#![stable(feature = "rust1", since = "1.0.0")] + +use self::Ordering::*; + +use marker::Sized; +use option::Option::{self, Some}; + +/// Trait for equality comparisons which are [partial equivalence +/// relations](http://en.wikipedia.org/wiki/Partial_equivalence_relation). +/// +/// This trait allows for partial equality, for types that do not have a full +/// equivalence relation. For example, in floating point numbers `NaN != NaN`, +/// so floating point types implement `PartialEq` but not `Eq`. +/// +/// Formally, the equality must be (for all `a`, `b` and `c`): +/// +/// - symmetric: `a == b` implies `b == a`; and +/// - transitive: `a == b` and `b == c` implies `a == c`. +/// +/// Note that these requirements mean that the trait itself must be implemented +/// symmetrically and transitively: if `T: PartialEq<U>` and `U: PartialEq<V>` +/// then `U: PartialEq<T>` and `T: PartialEq<V>`. +/// +/// PartialEq only requires the `eq` method to be implemented; `ne` is defined +/// in terms of it by default. Any manual implementation of `ne` *must* respect +/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and +/// only if `a != b`. +/// +/// This trait can be used with `#[derive]`. +/// +/// # Examples +/// +/// ``` +/// let x: u32 = 0; +/// let y: u32 = 1; +/// +/// assert_eq!(x == y, false); +/// assert_eq!(x.eq(&y), false); +/// ``` +#[lang = "eq"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait PartialEq<Rhs: ?Sized = Self> { + /// This method tests for `self` and `other` values to be equal, and is used + /// by `==`. + #[stable(feature = "rust1", since = "1.0.0")] + fn eq(&self, other: &Rhs) -> bool; + + /// This method tests for `!=`. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } +} + +/// Trait for equality comparisons which are [equivalence relations]( +/// https://en.wikipedia.org/wiki/Equivalence_relation). +/// +/// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must +/// be (for all `a`, `b` and `c`): +/// +/// - reflexive: `a == a`; +/// - symmetric: `a == b` implies `b == a`; and +/// - transitive: `a == b` and `b == c` implies `a == c`. +/// +/// This property cannot be checked by the compiler, and therefore `Eq` implies +/// `PartialEq`, and has no extra methods. +/// +/// This trait can be used with `#[derive]`. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Eq: PartialEq<Self> { + // FIXME #13101: this method is used solely by #[deriving] to + // assert that every component of a type implements #[deriving] + // itself, the current deriving infrastructure means doing this + // assertion without using a method on this trait is nearly + // impossible. + // + // This should never be implemented by hand. + #[doc(hidden)] + #[inline(always)] + #[stable(feature = "rust1", since = "1.0.0")] + fn assert_receiver_is_total_eq(&self) {} +} + +/// An `Ordering` is the result of a comparison between two values. +/// +/// # Examples +/// +/// ``` +/// use std::cmp::Ordering; +/// +/// let result = 1.cmp(&2); +/// assert_eq!(Ordering::Less, result); +/// +/// let result = 1.cmp(&1); +/// assert_eq!(Ordering::Equal, result); +/// +/// let result = 2.cmp(&1); +/// assert_eq!(Ordering::Greater, result); +/// ``` +#[derive(Clone, Copy, PartialEq, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Ordering { + /// An ordering where a compared value is less [than another]. + #[stable(feature = "rust1", since = "1.0.0")] + Less = -1, + /// An ordering where a compared value is equal [to another]. + #[stable(feature = "rust1", since = "1.0.0")] + Equal = 0, + /// An ordering where a compared value is greater [than another]. + #[stable(feature = "rust1", since = "1.0.0")] + Greater = 1, +} + +impl Ordering { + /// Reverse the `Ordering`. + /// + /// * `Less` becomes `Greater`. + /// * `Greater` becomes `Less`. + /// * `Equal` becomes `Equal`. + /// + /// # Examples + /// + /// Basic behavior: + /// + /// ``` + /// use std::cmp::Ordering; + /// + /// assert_eq!(Ordering::Less.reverse(), Ordering::Greater); + /// assert_eq!(Ordering::Equal.reverse(), Ordering::Equal); + /// assert_eq!(Ordering::Greater.reverse(), Ordering::Less); + /// ``` + /// + /// This method can be used to reverse a comparison: + /// + /// ``` + /// let mut data: &mut [_] = &mut [2, 10, 5, 8]; + /// + /// // sort the array from largest to smallest. + /// data.sort_by(|a, b| a.cmp(b).reverse()); + /// + /// let b: &mut [_] = &mut [10, 8, 5, 2]; + /// assert!(data == b); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn reverse(self) -> Ordering { + match self { + Less => Greater, + Equal => Equal, + Greater => Less, + } + } +} + +/// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order). +/// +/// An order is a total order if it is (for all `a`, `b` and `c`): +/// +/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and +/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. +/// +/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic +/// ordering based on the top-to-bottom declaration order of the struct's members. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Ord: Eq + PartialOrd<Self> { + /// This method returns an `Ordering` between `self` and `other`. + /// + /// By convention, `self.cmp(&other)` returns the ordering matching the expression + /// `self <operator> other` if true. + /// + /// # Examples + /// + /// ``` + /// use std::cmp::Ordering; + /// + /// assert_eq!(5.cmp(&10), Ordering::Less); + /// assert_eq!(10.cmp(&5), Ordering::Greater); + /// assert_eq!(5.cmp(&5), Ordering::Equal); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn cmp(&self, other: &Self) -> Ordering; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Eq for Ordering {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Ord for Ordering { + #[inline] + fn cmp(&self, other: &Ordering) -> Ordering { + (*self as i32).cmp(&(*other as i32)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialOrd for Ordering { + #[inline] + fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> { + (*self as i32).partial_cmp(&(*other as i32)) + } +} + +/// Trait for values that can be compared for a sort-order. +/// +/// The comparison must satisfy, for all `a`, `b` and `c`: +/// +/// - antisymmetry: if `a < b` then `!(a > b)`, as well as `a > b` implying `!(a < b)`; and +/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. +/// +/// Note that these requirements mean that the trait itself must be implemented symmetrically and +/// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T: +/// PartialOrd<V>`. +/// +/// PartialOrd only requires implementation of the `partial_cmp` method, with the others generated +/// from default implementations. +/// +/// However it remains possible to implement the others separately for types which do not have a +/// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 == +/// false` (cf. IEEE 754-2008 section 5.11). +/// +/// This trait can be used with `#[derive]`. When `derive`d, it will produce an ordering +/// based on the top-to-bottom declaration order of the struct's members. +/// +/// # Examples +/// +/// ``` +/// let x : u32 = 0; +/// let y : u32 = 1; +/// +/// assert_eq!(x < y, true); +/// assert_eq!(x.lt(&y), true); +/// ``` +#[lang = "ord"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { + /// This method returns an ordering between `self` and `other` values if one exists. + /// + /// # Examples + /// + /// ``` + /// use std::cmp::Ordering; + /// + /// let result = 1.0.partial_cmp(&2.0); + /// assert_eq!(result, Some(Ordering::Less)); + /// + /// let result = 1.0.partial_cmp(&1.0); + /// assert_eq!(result, Some(Ordering::Equal)); + /// + /// let result = 2.0.partial_cmp(&1.0); + /// assert_eq!(result, Some(Ordering::Greater)); + /// ``` + /// + /// When comparison is impossible: + /// + /// ``` + /// let result = std::f64::NAN.partial_cmp(&1.0); + /// assert_eq!(result, None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>; + + /// This method tests less than (for `self` and `other`) and is used by the `<` operator. + /// + /// # Examples + /// + /// ``` + /// let result = 1.0 < 2.0; + /// assert_eq!(result, true); + /// + /// let result = 2.0 < 1.0; + /// assert_eq!(result, false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn lt(&self, other: &Rhs) -> bool { + match self.partial_cmp(other) { + Some(Less) => true, + _ => false, + } + } + + /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=` + /// operator. + /// + /// # Examples + /// + /// ``` + /// let result = 1.0 <= 2.0; + /// assert_eq!(result, true); + /// + /// let result = 2.0 <= 2.0; + /// assert_eq!(result, true); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn le(&self, other: &Rhs) -> bool { + match self.partial_cmp(other) { + Some(Less) | Some(Equal) => true, + _ => false, + } + } + + /// This method tests greater than (for `self` and `other`) and is used by the `>` operator. + /// + /// # Examples + /// + /// ``` + /// let result = 1.0 > 2.0; + /// assert_eq!(result, false); + /// + /// let result = 2.0 > 2.0; + /// assert_eq!(result, false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn gt(&self, other: &Rhs) -> bool { + match self.partial_cmp(other) { + Some(Greater) => true, + _ => false, + } + } + + /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=` + /// operator. + /// + /// # Examples + /// + /// ``` + /// let result = 2.0 >= 1.0; + /// assert_eq!(result, true); + /// + /// let result = 2.0 >= 2.0; + /// assert_eq!(result, true); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn ge(&self, other: &Rhs) -> bool { + match self.partial_cmp(other) { + Some(Greater) | Some(Equal) => true, + _ => false, + } + } +} + +/// Compare and return the minimum of two values. +/// +/// Returns the first argument if the comparison determines them to be equal. +/// +/// # Examples +/// +/// ``` +/// use std::cmp; +/// +/// assert_eq!(1, cmp::min(1, 2)); +/// assert_eq!(2, cmp::min(2, 2)); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn min<T: Ord>(v1: T, v2: T) -> T { + if v1 <= v2 { v1 } else { v2 } +} + +/// Compare and return the maximum of two values. +/// +/// Returns the second argument if the comparison determines them to be equal. +/// +/// # Examples +/// +/// ``` +/// use std::cmp; +/// +/// assert_eq!(2, cmp::max(1, 2)); +/// assert_eq!(2, cmp::max(2, 2)); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn max<T: Ord>(v1: T, v2: T) -> T { + if v2 >= v1 { v2 } else { v1 } +} + +// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types +mod impls { + use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering}; + use cmp::Ordering::{Less, Greater, Equal}; + use marker::Sized; + use option::Option; + use option::Option::{Some, None}; + + macro_rules! partial_eq_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl PartialEq for $t { + #[inline] + fn eq(&self, other: &$t) -> bool { (*self) == (*other) } + #[inline] + fn ne(&self, other: &$t) -> bool { (*self) != (*other) } + } + )*) + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl PartialEq for () { + #[inline] + fn eq(&self, _other: &()) -> bool { true } + #[inline] + fn ne(&self, _other: &()) -> bool { false } + } + + partial_eq_impl! { + bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 + } + + macro_rules! eq_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Eq for $t {} + )*) + } + + eq_impl! { () bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + + macro_rules! partial_ord_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl PartialOrd for $t { + #[inline] + fn partial_cmp(&self, other: &$t) -> Option<Ordering> { + match (self <= other, self >= other) { + (false, false) => None, + (false, true) => Some(Greater), + (true, false) => Some(Less), + (true, true) => Some(Equal), + } + } + #[inline] + fn lt(&self, other: &$t) -> bool { (*self) < (*other) } + #[inline] + fn le(&self, other: &$t) -> bool { (*self) <= (*other) } + #[inline] + fn ge(&self, other: &$t) -> bool { (*self) >= (*other) } + #[inline] + fn gt(&self, other: &$t) -> bool { (*self) > (*other) } + } + )*) + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl PartialOrd for () { + #[inline] + fn partial_cmp(&self, _: &()) -> Option<Ordering> { + Some(Equal) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl PartialOrd for bool { + #[inline] + fn partial_cmp(&self, other: &bool) -> Option<Ordering> { + (*self as u8).partial_cmp(&(*other as u8)) + } + } + + partial_ord_impl! { f32 f64 } + + macro_rules! ord_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl PartialOrd for $t { + #[inline] + fn partial_cmp(&self, other: &$t) -> Option<Ordering> { + Some(self.cmp(other)) + } + #[inline] + fn lt(&self, other: &$t) -> bool { (*self) < (*other) } + #[inline] + fn le(&self, other: &$t) -> bool { (*self) <= (*other) } + #[inline] + fn ge(&self, other: &$t) -> bool { (*self) >= (*other) } + #[inline] + fn gt(&self, other: &$t) -> bool { (*self) > (*other) } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Ord for $t { + #[inline] + fn cmp(&self, other: &$t) -> Ordering { + if *self == *other { Equal } + else if *self < *other { Less } + else { Greater } + } + } + )*) + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Ord for () { + #[inline] + fn cmp(&self, _other: &()) -> Ordering { Equal } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Ord for bool { + #[inline] + fn cmp(&self, other: &bool) -> Ordering { + (*self as u8).cmp(&(*other as u8)) + } + } + + ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + + // & pointers + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a A where A: PartialEq<B> { + #[inline] + fn eq(&self, other: & &'b B) -> bool { PartialEq::eq(*self, *other) } + #[inline] + fn ne(&self, other: & &'b B) -> bool { PartialEq::ne(*self, *other) } + } + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> { + #[inline] + fn partial_cmp(&self, other: &&'b B) -> Option<Ordering> { + PartialOrd::partial_cmp(*self, *other) + } + #[inline] + fn lt(&self, other: & &'b B) -> bool { PartialOrd::lt(*self, *other) } + #[inline] + fn le(&self, other: & &'b B) -> bool { PartialOrd::le(*self, *other) } + #[inline] + fn ge(&self, other: & &'b B) -> bool { PartialOrd::ge(*self, *other) } + #[inline] + fn gt(&self, other: & &'b B) -> bool { PartialOrd::gt(*self, *other) } + } + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, A: ?Sized> Ord for &'a A where A: Ord { + #[inline] + fn cmp(&self, other: & &'a A) -> Ordering { Ord::cmp(*self, *other) } + } + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, A: ?Sized> Eq for &'a A where A: Eq {} + + // &mut pointers + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> { + #[inline] + fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) } + #[inline] + fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) } + } + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> { + #[inline] + fn partial_cmp(&self, other: &&'b mut B) -> Option<Ordering> { + PartialOrd::partial_cmp(*self, *other) + } + #[inline] + fn lt(&self, other: &&'b mut B) -> bool { PartialOrd::lt(*self, *other) } + #[inline] + fn le(&self, other: &&'b mut B) -> bool { PartialOrd::le(*self, *other) } + #[inline] + fn ge(&self, other: &&'b mut B) -> bool { PartialOrd::ge(*self, *other) } + #[inline] + fn gt(&self, other: &&'b mut B) -> bool { PartialOrd::gt(*self, *other) } + } + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, A: ?Sized> Ord for &'a mut A where A: Ord { + #[inline] + fn cmp(&self, other: &&'a mut A) -> Ordering { Ord::cmp(*self, *other) } + } + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, A: ?Sized> Eq for &'a mut A where A: Eq {} + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> { + #[inline] + fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) } + #[inline] + fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> { + #[inline] + fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) } + #[inline] + fn ne(&self, other: &&'b B) -> bool { PartialEq::ne(*self, *other) } + } +} diff --git a/libcore/convert.rs b/libcore/convert.rs new file mode 100644 index 0000000..2d99986 --- /dev/null +++ b/libcore/convert.rs @@ -0,0 +1,243 @@ +// 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. + +//! Traits for conversions between types. +//! +//! The traits in this module provide a general way to talk about conversions +//! from one type to another. They follow the standard Rust conventions of +//! `as`/`into`/`from`. +//! +//! Like many traits, these are often used as bounds for generic functions, to +//! support arguments of multiple types. +//! +//! - Impl the `As*` traits for reference-to-reference conversions +//! - Impl the `Into` trait when you want to consume the value in the conversion +//! - The `From` trait is the most flexible, useful for value _and_ reference conversions +//! +//! As a library author, you should prefer implementing `From<T>` rather than +//! `Into<U>`, as `From` provides greater flexibility and offers an equivalent `Into` +//! implementation for free, thanks to a blanket implementation in the standard library. +//! +//! **Note: these traits must not fail**. If the conversion can fail, you must use a dedicated +//! method which returns an `Option<T>` or a `Result<T, E>`. +//! +//! # Generic impl +//! +//! - `AsRef` and `AsMut` auto-dereference if the inner type is a reference +//! - `From<U> for T` implies `Into<T> for U` +//! - `From` and `Into` are reflexive, which means that all types can `into()` +//! themselves and `from()` themselves +//! +//! See each trait for usage examples. + +#![stable(feature = "rust1", since = "1.0.0")] + +use marker::Sized; + +/// A cheap, reference-to-reference conversion. +/// +/// `AsRef` is very similar to, but different than, `Borrow`. See +/// [the book][book] for more. +/// +/// [book]: ../../book/borrow-and-asref.html +/// +/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which +/// returns an `Option<T>` or a `Result<T, E>`. +/// +/// # Examples +/// +/// Both `String` and `&str` implement `AsRef<str>`: +/// +/// ``` +/// fn is_hello<T: AsRef<str>>(s: T) { +/// assert_eq!("hello", s.as_ref()); +/// } +/// +/// let s = "hello"; +/// is_hello(s); +/// +/// let s = "hello".to_string(); +/// is_hello(s); +/// ``` +/// +/// # Generic Impls +/// +/// - `AsRef` auto-dereference if the inner type is a reference or a mutable +/// reference (eg: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) +/// +#[stable(feature = "rust1", since = "1.0.0")] +pub trait AsRef<T: ?Sized> { + /// Performs the conversion. + #[stable(feature = "rust1", since = "1.0.0")] + fn as_ref(&self) -> &T; +} + +/// A cheap, mutable reference-to-mutable reference conversion. +/// +/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which +/// returns an `Option<T>` or a `Result<T, E>`. +/// +/// # Generic Impls +/// +/// - `AsMut` auto-dereference if the inner type is a reference or a mutable +/// reference (eg: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) +/// +#[stable(feature = "rust1", since = "1.0.0")] +pub trait AsMut<T: ?Sized> { + /// Performs the conversion. + #[stable(feature = "rust1", since = "1.0.0")] + fn as_mut(&mut self) -> &mut T; +} + +/// A conversion that consumes `self`, which may or may not be expensive. +/// +/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which +/// returns an `Option<T>` or a `Result<T, E>`. +/// +/// Library authors should not directly implement this trait, but should prefer implementing +/// the `From` trait, which offers greater flexibility and provides an equivalent `Into` +/// implementation for free, thanks to a blanket implementation in the standard library. +/// +/// # Examples +/// +/// `String` implements `Into<Vec<u8>>`: +/// +/// ``` +/// fn is_hello<T: Into<Vec<u8>>>(s: T) { +/// let bytes = b"hello".to_vec(); +/// assert_eq!(bytes, s.into()); +/// } +/// +/// let s = "hello".to_string(); +/// is_hello(s); +/// ``` +/// +/// # Generic Impls +/// +/// - `From<T> for U` implies `Into<U> for T` +/// - `into()` is reflexive, which means that `Into<T> for T` is implemented +/// +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Into<T>: Sized { + /// Performs the conversion. + #[stable(feature = "rust1", since = "1.0.0")] + fn into(self) -> T; +} + +/// Construct `Self` via a conversion. +/// +/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which +/// returns an `Option<T>` or a `Result<T, E>`. +/// +/// # Examples +/// +/// `String` implements `From<&str>`: +/// +/// ``` +/// let string = "hello".to_string(); +/// let other_string = String::from("hello"); +/// +/// assert_eq!(string, other_string); +/// ``` +/// # Generic impls +/// +/// - `From<T> for U` implies `Into<U> for T` +/// - `from()` is reflexive, which means that `From<T> for T` is implemented +/// +#[stable(feature = "rust1", since = "1.0.0")] +pub trait From<T>: Sized { + /// Performs the conversion. + #[stable(feature = "rust1", since = "1.0.0")] + fn from(T) -> Self; +} + +//////////////////////////////////////////////////////////////////////////////// +// GENERIC IMPLS +//////////////////////////////////////////////////////////////////////////////// + +// As lifts over & +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> { + fn as_ref(&self) -> &U { + <T as AsRef<U>>::as_ref(*self) + } +} + +// As lifts over &mut +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> { + fn as_ref(&self) -> &U { + <T as AsRef<U>>::as_ref(*self) + } +} + +// FIXME (#23442): replace the above impls for &/&mut with the following more general one: +// // As lifts over Deref +// impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> { +// fn as_ref(&self) -> &U { +// self.deref().as_ref() +// } +// } + +// AsMut lifts over &mut +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> { + fn as_mut(&mut self) -> &mut U { + (*self).as_mut() + } +} + +// FIXME (#23442): replace the above impl for &mut with the following more general one: +// // AsMut lifts over DerefMut +// impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> { +// fn as_mut(&mut self) -> &mut U { +// self.deref_mut().as_mut() +// } +// } + +// From implies Into +#[stable(feature = "rust1", since = "1.0.0")] +impl<T, U> Into<U> for T where U: From<T> { + fn into(self) -> U { + U::from(self) + } +} + +// From (and thus Into) is reflexive +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> From<T> for T { + fn from(t: T) -> T { t } +} + +//////////////////////////////////////////////////////////////////////////////// +// CONCRETE IMPLS +//////////////////////////////////////////////////////////////////////////////// + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> AsRef<[T]> for [T] { + fn as_ref(&self) -> &[T] { + self + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> AsMut<[T]> for [T] { + fn as_mut(&mut self) -> &mut [T] { + self + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl AsRef<str> for str { + #[inline] + fn as_ref(&self) -> &str { + self + } +} diff --git a/libcore/default.rs b/libcore/default.rs new file mode 100644 index 0000000..12c4a5c --- /dev/null +++ b/libcore/default.rs @@ -0,0 +1,164 @@ +// Copyright 2013 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. + +//! The `Default` trait for types which may have meaningful default values. +//! +//! Sometimes, you want to fall back to some kind of default value, and +//! don't particularly care what it is. This comes up often with `struct`s +//! that define a set of options: +//! +//! ``` +//! # #[allow(dead_code)] +//! struct SomeOptions { +//! foo: i32, +//! bar: f32, +//! } +//! ``` +//! +//! How can we define some default values? You can use `Default`: +//! +//! ``` +//! # #[allow(dead_code)] +//! #[derive(Default)] +//! struct SomeOptions { +//! foo: i32, +//! bar: f32, +//! } +//! +//! +//! fn main() { +//! let options: SomeOptions = Default::default(); +//! } +//! ``` +//! +//! Now, you get all of the default values. Rust implements `Default` for various primitives types. +//! If you have your own type, you need to implement `Default` yourself: +//! +//! ``` +//! # #![allow(dead_code)] +//! enum Kind { +//! A, +//! B, +//! C, +//! } +//! +//! impl Default for Kind { +//! fn default() -> Kind { Kind::A } +//! } +//! +//! #[derive(Default)] +//! struct SomeOptions { +//! foo: i32, +//! bar: f32, +//! baz: Kind, +//! } +//! +//! +//! fn main() { +//! let options: SomeOptions = Default::default(); +//! } +//! ``` +//! +//! If you want to override a particular option, but still retain the other defaults: +//! +//! ``` +//! # #[allow(dead_code)] +//! # #[derive(Default)] +//! # struct SomeOptions { +//! # foo: i32, +//! # bar: f32, +//! # } +//! fn main() { +//! let options = SomeOptions { foo: 42, ..Default::default() }; +//! } +//! ``` + +#![stable(feature = "rust1", since = "1.0.0")] + +use marker::Sized; + +/// A trait for giving a type a useful default value. +/// +/// A struct can derive default implementations of `Default` for basic types using +/// `#[derive(Default)]`. +/// +/// # Examples +/// +/// ``` +/// # #[allow(dead_code)] +/// #[derive(Default)] +/// struct SomeOptions { +/// foo: i32, +/// bar: f32, +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Default: Sized { + /// Returns the "default value" for a type. + /// + /// Default values are often some kind of initial value, identity value, or anything else that + /// may make sense as a default. + /// + /// # Examples + /// + /// Using built-in default values: + /// + /// ``` + /// let i: i8 = Default::default(); + /// let (x, y): (Option<String>, f64) = Default::default(); + /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default(); + /// ``` + /// + /// Making your own: + /// + /// ``` + /// # #[allow(dead_code)] + /// enum Kind { + /// A, + /// B, + /// C, + /// } + /// + /// impl Default for Kind { + /// fn default() -> Kind { Kind::A } + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn default() -> Self; +} + +macro_rules! default_impl { + ($t:ty, $v:expr) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl Default for $t { + #[inline] + fn default() -> $t { $v } + } + } +} + +default_impl! { (), () } +default_impl! { bool, false } +default_impl! { char, '\x00' } + +default_impl! { usize, 0 } +default_impl! { u8, 0 } +default_impl! { u16, 0 } +default_impl! { u32, 0 } +default_impl! { u64, 0 } + +default_impl! { isize, 0 } +default_impl! { i8, 0 } +default_impl! { i16, 0 } +default_impl! { i32, 0 } +default_impl! { i64, 0 } + +default_impl! { f32, 0.0f32 } +default_impl! { f64, 0.0f64 } diff --git a/libcore/fmt/builders.rs b/libcore/fmt/builders.rs new file mode 100644 index 0000000..d337463 --- /dev/null +++ b/libcore/fmt/builders.rs @@ -0,0 +1,406 @@ +// Copyright 2015 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. + +use prelude::v1::*; +use fmt::{self, Write, FlagV1}; + +struct PadAdapter<'a, 'b: 'a> { + fmt: &'a mut fmt::Formatter<'b>, + on_newline: bool, +} + +impl<'a, 'b: 'a> PadAdapter<'a, 'b> { + fn new(fmt: &'a mut fmt::Formatter<'b>) -> PadAdapter<'a, 'b> { + PadAdapter { + fmt: fmt, + on_newline: false, + } + } +} + +impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> { + fn write_str(&mut self, mut s: &str) -> fmt::Result { + while !s.is_empty() { + if self.on_newline { + self.fmt.write_str(" ")?; + } + + let split = match s.find('\n') { + Some(pos) => { + self.on_newline = true; + pos + 1 + } + None => { + self.on_newline = false; + s.len() + } + }; + self.fmt.write_str(&s[..split])?; + s = &s[split..]; + } + + Ok(()) + } +} + +/// A struct to help with `fmt::Debug` implementations. +/// +/// Constructed by the `Formatter::debug_struct` method. +#[must_use] +#[allow(missing_debug_implementations)] +#[stable(feature = "debug_builders", since = "1.2.0")] +pub struct DebugStruct<'a, 'b: 'a> { + fmt: &'a mut fmt::Formatter<'b>, + result: fmt::Result, + has_fields: bool, +} + +pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, + name: &str) + -> DebugStruct<'a, 'b> { + let result = fmt.write_str(name); + DebugStruct { + fmt: fmt, + result: result, + has_fields: false, + } +} + +impl<'a, 'b: 'a> DebugStruct<'a, 'b> { + /// Adds a new field to the generated struct output. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> { + self.result = self.result.and_then(|_| { + let prefix = if self.has_fields { + "," + } else { + " {" + }; + + if self.is_pretty() { + let mut writer = PadAdapter::new(self.fmt); + fmt::write(&mut writer, + format_args!("{}\n{}: {:#?}", prefix, name, value)) + } else { + write!(self.fmt, "{} {}: {:?}", prefix, name, value) + } + }); + + self.has_fields = true; + self + } + + /// Finishes output and returns any error encountered. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn finish(&mut self) -> fmt::Result { + if self.has_fields { + self.result = self.result.and_then(|_| { + if self.is_pretty() { + self.fmt.write_str("\n}") + } else { + self.fmt.write_str(" }") + } + }); + } + self.result + } + + fn is_pretty(&self) -> bool { + self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 + } +} + +/// A struct to help with `fmt::Debug` implementations. +/// +/// Constructed by the `Formatter::debug_tuple` method. +#[must_use] +#[allow(missing_debug_implementations)] +#[stable(feature = "debug_builders", since = "1.2.0")] +pub struct DebugTuple<'a, 'b: 'a> { + fmt: &'a mut fmt::Formatter<'b>, + result: fmt::Result, + fields: usize, + empty_name: bool, +} + +pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> { + let result = fmt.write_str(name); + DebugTuple { + fmt: fmt, + result: result, + fields: 0, + empty_name: name.is_empty(), + } +} + +impl<'a, 'b: 'a> DebugTuple<'a, 'b> { + /// Adds a new field to the generated tuple struct output. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> { + self.result = self.result.and_then(|_| { + let (prefix, space) = if self.fields > 0 { + (",", " ") + } else { + ("(", "") + }; + + if self.is_pretty() { + let mut writer = PadAdapter::new(self.fmt); + fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value)) + } else { + write!(self.fmt, "{}{}{:?}", prefix, space, value) + } + }); + + self.fields += 1; + self + } + + /// Finishes output and returns any error encountered. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn finish(&mut self) -> fmt::Result { + if self.fields > 0 { + self.result = self.result.and_then(|_| { + if self.is_pretty() { + self.fmt.write_str("\n")?; + } + if self.fields == 1 && self.empty_name { + self.fmt.write_str(",")?; + } + self.fmt.write_str(")") + }); + } + self.result + } + + fn is_pretty(&self) -> bool { + self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 + } +} + +struct DebugInner<'a, 'b: 'a> { + fmt: &'a mut fmt::Formatter<'b>, + result: fmt::Result, + has_fields: bool, +} + +impl<'a, 'b: 'a> DebugInner<'a, 'b> { + fn entry(&mut self, entry: &fmt::Debug) { + self.result = self.result.and_then(|_| { + if self.is_pretty() { + let mut writer = PadAdapter::new(self.fmt); + let prefix = if self.has_fields { + "," + } else { + "" + }; + fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry)) + } else { + let prefix = if self.has_fields { + ", " + } else { + "" + }; + write!(self.fmt, "{}{:?}", prefix, entry) + } + }); + + self.has_fields = true; + } + + pub fn finish(&mut self) { + let prefix = if self.is_pretty() && self.has_fields { + "\n" + } else { + "" + }; + self.result = self.result.and_then(|_| self.fmt.write_str(prefix)); + } + + fn is_pretty(&self) -> bool { + self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 + } +} + +/// A struct to help with `fmt::Debug` implementations. +/// +/// Constructed by the `Formatter::debug_set` method. +#[must_use] +#[allow(missing_debug_implementations)] +#[stable(feature = "debug_builders", since = "1.2.0")] +pub struct DebugSet<'a, 'b: 'a> { + inner: DebugInner<'a, 'b>, +} + +pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> { + let result = write!(fmt, "{{"); + DebugSet { + inner: DebugInner { + fmt: fmt, + result: result, + has_fields: false, + }, + } +} + +impl<'a, 'b: 'a> DebugSet<'a, 'b> { + /// Adds a new entry to the set output. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> { + self.inner.entry(entry); + self + } + + /// Adds the contents of an iterator of entries to the set output. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugSet<'a, 'b> + where D: fmt::Debug, + I: IntoIterator<Item = D> + { + for entry in entries { + self.entry(&entry); + } + self + } + + /// Finishes output and returns any error encountered. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn finish(&mut self) -> fmt::Result { + self.inner.finish(); + self.inner.result.and_then(|_| self.inner.fmt.write_str("}")) + } +} + +/// A struct to help with `fmt::Debug` implementations. +/// +/// Constructed by the `Formatter::debug_list` method. +#[must_use] +#[allow(missing_debug_implementations)] +#[stable(feature = "debug_builders", since = "1.2.0")] +pub struct DebugList<'a, 'b: 'a> { + inner: DebugInner<'a, 'b>, +} + +pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> { + let result = write!(fmt, "["); + DebugList { + inner: DebugInner { + fmt: fmt, + result: result, + has_fields: false, + }, + } +} + +impl<'a, 'b: 'a> DebugList<'a, 'b> { + /// Adds a new entry to the list output. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> { + self.inner.entry(entry); + self + } + + /// Adds the contents of an iterator of entries to the list output. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugList<'a, 'b> + where D: fmt::Debug, + I: IntoIterator<Item = D> + { + for entry in entries { + self.entry(&entry); + } + self + } + + /// Finishes output and returns any error encountered. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn finish(&mut self) -> fmt::Result { + self.inner.finish(); + self.inner.result.and_then(|_| self.inner.fmt.write_str("]")) + } +} + +/// A struct to help with `fmt::Debug` implementations. +/// +/// Constructed by the `Formatter::debug_map` method. +#[must_use] +#[allow(missing_debug_implementations)] +#[stable(feature = "debug_builders", since = "1.2.0")] +pub struct DebugMap<'a, 'b: 'a> { + fmt: &'a mut fmt::Formatter<'b>, + result: fmt::Result, + has_fields: bool, +} + +pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> { + let result = write!(fmt, "{{"); + DebugMap { + fmt: fmt, + result: result, + has_fields: false, + } +} + +impl<'a, 'b: 'a> DebugMap<'a, 'b> { + /// Adds a new entry to the map output. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> { + self.result = self.result.and_then(|_| { + if self.is_pretty() { + let mut writer = PadAdapter::new(self.fmt); + let prefix = if self.has_fields { + "," + } else { + "" + }; + fmt::write(&mut writer, + format_args!("{}\n{:#?}: {:#?}", prefix, key, value)) + } else { + let prefix = if self.has_fields { + ", " + } else { + "" + }; + write!(self.fmt, "{}{:?}: {:?}", prefix, key, value) + } + }); + + self.has_fields = true; + self + } + + /// Adds the contents of an iterator of entries to the map output. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn entries<K, V, I>(&mut self, entries: I) -> &mut DebugMap<'a, 'b> + where K: fmt::Debug, + V: fmt::Debug, + I: IntoIterator<Item = (K, V)> + { + for (k, v) in entries { + self.entry(&k, &v); + } + self + } + + /// Finishes output and returns any error encountered. + #[stable(feature = "debug_builders", since = "1.2.0")] + pub fn finish(&mut self) -> fmt::Result { + let prefix = if self.is_pretty() && self.has_fields { + "\n" + } else { + "" + }; + self.result.and_then(|_| write!(self.fmt, "{}}}", prefix)) + } + + fn is_pretty(&self) -> bool { + self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 + } +} diff --git a/libcore/fmt/mod.rs b/libcore/fmt/mod.rs new file mode 100644 index 0000000..2f02f5c --- /dev/null +++ b/libcore/fmt/mod.rs @@ -0,0 +1,1636 @@ +// Copyright 2013-2015 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. + +//! Utilities for formatting and printing strings. + +#![stable(feature = "rust1", since = "1.0.0")] + +use prelude::v1::*; + +use cell::{UnsafeCell, Cell, RefCell, Ref, RefMut, BorrowState}; +use marker::PhantomData; +use mem; +use num::flt2dec; +use ops::Deref; +use result; +use slice; +use str; + +#[unstable(feature = "fmt_flags_align", issue = "27726")] +/// Possible alignments returned by `Formatter::align` +#[derive(Debug)] +pub enum Alignment { + /// Indication that contents should be left-aligned. + Left, + /// Indication that contents should be right-aligned. + Right, + /// Indication that contents should be center-aligned. + Center, + /// No alignment was requested. + Unknown, +} + +#[stable(feature = "debug_builders", since = "1.2.0")] +pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap}; + +mod num; +mod builders; + +#[unstable(feature = "fmt_internals", reason = "internal to format_args!", + issue = "0")] +#[doc(hidden)] +pub mod rt { + pub mod v1; +} + +#[stable(feature = "rust1", since = "1.0.0")] +/// The type returned by formatter methods. +pub type Result = result::Result<(), Error>; + +/// The error type which is returned from formatting a message into a stream. +/// +/// This type does not support transmission of an error other than that an error +/// occurred. Any extra information must be arranged to be transmitted through +/// some other means. +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Copy, Clone, Debug)] +pub struct Error; + +/// A collection of methods that are required to format a message into a stream. +/// +/// This trait is the type which this modules requires when formatting +/// information. This is similar to the standard library's `io::Write` trait, +/// but it is only intended for use in libcore. +/// +/// This trait should generally not be implemented by consumers of the standard +/// library. The `write!` macro accepts an instance of `io::Write`, and the +/// `io::Write` trait is favored over implementing this trait. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Write { + /// Writes a slice of bytes into this writer, returning whether the write + /// succeeded. + /// + /// This method can only succeed if the entire byte slice was successfully + /// written, and this method will not return until all data has been + /// written or an error occurs. + /// + /// # Errors + /// + /// This function will return an instance of `Error` on error. + #[stable(feature = "rust1", since = "1.0.0")] + fn write_str(&mut self, s: &str) -> Result; + + /// Writes a `char` into this writer, returning whether the write succeeded. + /// + /// A single `char` may be encoded as more than one byte. + /// This method can only succeed if the entire byte sequence was successfully + /// written, and this method will not return until all data has been + /// written or an error occurs. + /// + /// # Errors + /// + /// This function will return an instance of `Error` on error. + #[stable(feature = "fmt_write_char", since = "1.1.0")] + fn write_char(&mut self, c: char) -> Result { + self.write_str(unsafe { + str::from_utf8_unchecked(c.encode_utf8().as_slice()) + }) + } + + /// Glue for usage of the `write!` macro with implementors of this trait. + /// + /// This method should generally not be invoked manually, but rather through + /// the `write!` macro itself. + #[stable(feature = "rust1", since = "1.0.0")] + fn write_fmt(&mut self, args: Arguments) -> Result { + // This Adapter is needed to allow `self` (of type `&mut + // Self`) to be cast to a Write (below) without + // requiring a `Sized` bound. + struct Adapter<'a,T: ?Sized +'a>(&'a mut T); + + impl<'a, T: ?Sized> Write for Adapter<'a, T> + where T: Write + { + fn write_str(&mut self, s: &str) -> Result { + self.0.write_str(s) + } + + fn write_char(&mut self, c: char) -> Result { + self.0.write_char(c) + } + + fn write_fmt(&mut self, args: Arguments) -> Result { + self.0.write_fmt(args) + } + } + + write(&mut Adapter(self), args) + } +} + +#[stable(feature = "fmt_write_blanket_impl", since = "1.4.0")] +impl<'a, W: Write + ?Sized> Write for &'a mut W { + fn write_str(&mut self, s: &str) -> Result { + (**self).write_str(s) + } + + fn write_char(&mut self, c: char) -> Result { + (**self).write_char(c) + } + + fn write_fmt(&mut self, args: Arguments) -> Result { + (**self).write_fmt(args) + } +} + +/// A struct to represent both where to emit formatting strings to and how they +/// should be formatted. A mutable version of this is passed to all formatting +/// traits. +#[allow(missing_debug_implementations)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Formatter<'a> { + flags: u32, + fill: char, + align: rt::v1::Alignment, + width: Option<usize>, + precision: Option<usize>, + + buf: &'a mut (Write+'a), + curarg: slice::Iter<'a, ArgumentV1<'a>>, + args: &'a [ArgumentV1<'a>], +} + +// NB. Argument is essentially an optimized partially applied formatting function, +// equivalent to `exists T.(&T, fn(&T, &mut Formatter) -> Result`. + +enum Void {} + +/// This struct represents the generic "argument" which is taken by the Xprintf +/// family of functions. It contains a function to format the given value. At +/// compile time it is ensured that the function and the value have the correct +/// types, and then this struct is used to canonicalize arguments to one type. +#[derive(Copy)] +#[allow(missing_debug_implementations)] +#[unstable(feature = "fmt_internals", reason = "internal to format_args!", + issue = "0")] +#[doc(hidden)] +pub struct ArgumentV1<'a> { + value: &'a Void, + formatter: fn(&Void, &mut Formatter) -> Result, +} + +#[unstable(feature = "fmt_internals", reason = "internal to format_args!", + issue = "0")] +impl<'a> Clone for ArgumentV1<'a> { + fn clone(&self) -> ArgumentV1<'a> { + *self + } +} + +impl<'a> ArgumentV1<'a> { + #[inline(never)] + fn show_usize(x: &usize, f: &mut Formatter) -> Result { + Display::fmt(x, f) + } + + #[doc(hidden)] + #[unstable(feature = "fmt_internals", reason = "internal to format_args!", + issue = "0")] + pub fn new<'b, T>(x: &'b T, + f: fn(&T, &mut Formatter) -> Result) -> ArgumentV1<'b> { + unsafe { + ArgumentV1 { + formatter: mem::transmute(f), + value: mem::transmute(x) + } + } + } + + #[doc(hidden)] + #[unstable(feature = "fmt_internals", reason = "internal to format_args!", + issue = "0")] + pub fn from_usize(x: &usize) -> ArgumentV1 { + ArgumentV1::new(x, ArgumentV1::show_usize) + } + + fn as_usize(&self) -> Option<usize> { + if self.formatter as usize == ArgumentV1::show_usize as usize { + Some(unsafe { *(self.value as *const _ as *const usize) }) + } else { + None + } + } +} + +// flags available in the v1 format of format_args +#[derive(Copy, Clone)] +#[allow(dead_code)] // SignMinus isn't currently used +enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, } + +impl<'a> Arguments<'a> { + /// When using the format_args!() macro, this function is used to generate the + /// Arguments structure. + #[doc(hidden)] #[inline] + #[unstable(feature = "fmt_internals", reason = "internal to format_args!", + issue = "0")] + pub fn new_v1(pieces: &'a [&'a str], + args: &'a [ArgumentV1<'a>]) -> Arguments<'a> { + Arguments { + pieces: pieces, + fmt: None, + args: args + } + } + + /// This function is used to specify nonstandard formatting parameters. + /// The `pieces` array must be at least as long as `fmt` to construct + /// a valid Arguments structure. Also, any `Count` within `fmt` that is + /// `CountIsParam` or `CountIsNextParam` has to point to an argument + /// created with `argumentusize`. However, failing to do so doesn't cause + /// unsafety, but will ignore invalid . + #[doc(hidden)] #[inline] + #[unstable(feature = "fmt_internals", reason = "internal to format_args!", + issue = "0")] + pub fn new_v1_formatted(pieces: &'a [&'a str], + args: &'a [ArgumentV1<'a>], + fmt: &'a [rt::v1::Argument]) -> Arguments<'a> { + Arguments { + pieces: pieces, + fmt: Some(fmt), + args: args + } + } +} + +/// This structure represents a safely precompiled version of a format string +/// and its arguments. This cannot be generated at runtime because it cannot +/// safely be done so, so no constructors are given and the fields are private +/// to prevent modification. +/// +/// The `format_args!` macro will safely create an instance of this structure +/// and pass it to a function or closure, passed as the first argument. The +/// macro validates the format string at compile-time so usage of the `write` +/// and `format` functions can be safely performed. +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Copy, Clone)] +pub struct Arguments<'a> { + // Format string pieces to print. + pieces: &'a [&'a str], + + // Placeholder specs, or `None` if all specs are default (as in "{}{}"). + fmt: Option<&'a [rt::v1::Argument]>, + + // Dynamic arguments for interpolation, to be interleaved with string + // pieces. (Every argument is preceded by a string piece.) + args: &'a [ArgumentV1<'a>], +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> Debug for Arguments<'a> { + fn fmt(&self, fmt: &mut Formatter) -> Result { + Display::fmt(self, fmt) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> Display for Arguments<'a> { + fn fmt(&self, fmt: &mut Formatter) -> Result { + write(fmt.buf, *self) + } +} + +/// Format trait for the `?` character. +/// +/// `Debug` should format the output in a programmer-facing, debugging context. +/// +/// Generally speaking, you should just `derive` a `Debug` implementation. +/// +/// When used with the alternate format specifier `#?`, the output is pretty-printed. +/// +/// For more information on formatters, see [the module-level documentation][module]. +/// +/// [module]: ../../std/fmt/index.html +/// +/// This trait can be used with `#[derive]`. +/// +/// # Examples +/// +/// Deriving an implementation: +/// +/// ``` +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } +/// +/// let origin = Point { x: 0, y: 0 }; +/// +/// println!("The origin is: {:?}", origin); +/// ``` +/// +/// Manually implementing: +/// +/// ``` +/// use std::fmt; +/// +/// struct Point { +/// x: i32, +/// y: i32, +/// } +/// +/// impl fmt::Debug for Point { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// write!(f, "Point {{ x: {}, y: {} }}", self.x, self.y) +/// } +/// } +/// +/// let origin = Point { x: 0, y: 0 }; +/// +/// println!("The origin is: {:?}", origin); +/// ``` +/// +/// This outputs: +/// +/// ```text +/// The origin is: Point { x: 0, y: 0 } +/// ``` +/// +/// There are a number of `debug_*` methods on `Formatter` to help you with manual +/// implementations, such as [`debug_struct`][debug_struct]. +/// +/// `Debug` implementations using either `derive` or the debug builder API +/// on `Formatter` support pretty printing using the alternate flag: `{:#?}`. +/// +/// [debug_struct]: ../../std/fmt/struct.Formatter.html#method.debug_struct +/// +/// Pretty printing with `#?`: +/// +/// ``` +/// #[derive(Debug)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } +/// +/// let origin = Point { x: 0, y: 0 }; +/// +/// println!("The origin is: {:#?}", origin); +/// ``` +/// +/// This outputs: +/// +/// ```text +/// The origin is: Point { +/// x: 0, +/// y: 0 +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \ + defined in your crate, add `#[derive(Debug)]` or \ + manually implement it"] +#[lang = "debug_trait"] +pub trait Debug { + /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] + fn fmt(&self, &mut Formatter) -> Result; +} + +/// Format trait for an empty format, `{}`. +/// +/// `Display` is similar to [`Debug`][debug], but `Display` is for user-facing +/// output, and so cannot be derived. +/// +/// [debug]: trait.Debug.html +/// +/// For more information on formatters, see [the module-level documentation][module]. +/// +/// [module]: ../../std/fmt/index.html +/// +/// # Examples +/// +/// Implementing `Display` on a type: +/// +/// ``` +/// use std::fmt; +/// +/// struct Point { +/// x: i32, +/// y: i32, +/// } +/// +/// impl fmt::Display for Point { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// write!(f, "({}, {})", self.x, self.y) +/// } +/// } +/// +/// let origin = Point { x: 0, y: 0 }; +/// +/// println!("The origin is: {}", origin); +/// ``` +#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \ + formatter; try using `:?` instead if you are using \ + a format string"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Display { + /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] + fn fmt(&self, &mut Formatter) -> Result; +} + +/// Format trait for the `o` character. +/// +/// The `Octal` trait should format its output as a number in base-8. +/// +/// The alternate flag, `#`, adds a `0o` in front of the output. +/// +/// For more information on formatters, see [the module-level documentation][module]. +/// +/// [module]: ../../std/fmt/index.html +/// +/// # Examples +/// +/// Basic usage with `i32`: +/// +/// ``` +/// let x = 42; // 42 is '52' in octal +/// +/// assert_eq!(format!("{:o}", x), "52"); +/// assert_eq!(format!("{:#o}", x), "0o52"); +/// ``` +/// +/// Implementing `Octal` on a type: +/// +/// ``` +/// use std::fmt; +/// +/// struct Length(i32); +/// +/// impl fmt::Octal for Length { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// let val = self.0; +/// +/// write!(f, "{:o}", val) // delegate to i32's implementation +/// } +/// } +/// +/// let l = Length(9); +/// +/// println!("l as octal is: {:o}", l); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Octal { + /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] + fn fmt(&self, &mut Formatter) -> Result; +} + +/// Format trait for the `b` character. +/// +/// The `Binary` trait should format its output as a number in binary. +/// +/// The alternate flag, `#`, adds a `0b` in front of the output. +/// +/// For more information on formatters, see [the module-level documentation][module]. +/// +/// [module]: ../../std/fmt/index.html +/// +/// # Examples +/// +/// Basic usage with `i32`: +/// +/// ``` +/// let x = 42; // 42 is '101010' in binary +/// +/// assert_eq!(format!("{:b}", x), "101010"); +/// assert_eq!(format!("{:#b}", x), "0b101010"); +/// ``` +/// +/// Implementing `Binary` on a type: +/// +/// ``` +/// use std::fmt; +/// +/// struct Length(i32); +/// +/// impl fmt::Binary for Length { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// let val = self.0; +/// +/// write!(f, "{:b}", val) // delegate to i32's implementation +/// } +/// } +/// +/// let l = Length(107); +/// +/// println!("l as binary is: {:b}", l); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Binary { + /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] + fn fmt(&self, &mut Formatter) -> Result; +} + +/// Format trait for the `x` character. +/// +/// The `LowerHex` trait should format its output as a number in hexadecimal, with `a` through `f` +/// in lower case. +/// +/// The alternate flag, `#`, adds a `0x` in front of the output. +/// +/// For more information on formatters, see [the module-level documentation][module]. +/// +/// [module]: ../../std/fmt/index.html +/// +/// # Examples +/// +/// Basic usage with `i32`: +/// +/// ``` +/// let x = 42; // 42 is '2a' in hex +/// +/// assert_eq!(format!("{:x}", x), "2a"); +/// assert_eq!(format!("{:#x}", x), "0x2a"); +/// ``` +/// +/// Implementing `LowerHex` on a type: +/// +/// ``` +/// use std::fmt; +/// +/// struct Length(i32); +/// +/// impl fmt::LowerHex for Length { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// let val = self.0; +/// +/// write!(f, "{:x}", val) // delegate to i32's implementation +/// } +/// } +/// +/// let l = Length(9); +/// +/// println!("l as hex is: {:x}", l); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait LowerHex { + /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] + fn fmt(&self, &mut Formatter) -> Result; +} + +/// Format trait for the `X` character. +/// +/// The `UpperHex` trait should format its output as a number in hexadecimal, with `A` through `F` +/// in upper case. +/// +/// The alternate flag, `#`, adds a `0x` in front of the output. +/// +/// For more information on formatters, see [the module-level documentation][module]. +/// +/// [module]: ../../std/fmt/index.html +/// +/// # Examples +/// +/// Basic usage with `i32`: +/// +/// ``` +/// let x = 42; // 42 is '2A' in hex +/// +/// assert_eq!(format!("{:X}", x), "2A"); +/// assert_eq!(format!("{:#X}", x), "0x2A"); +/// ``` +/// +/// Implementing `UpperHex` on a type: +/// +/// ``` +/// use std::fmt; +/// +/// struct Length(i32); +/// +/// impl fmt::UpperHex for Length { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// let val = self.0; +/// +/// write!(f, "{:X}", val) // delegate to i32's implementation +/// } +/// } +/// +/// let l = Length(9); +/// +/// println!("l as hex is: {:X}", l); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait UpperHex { + /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] + fn fmt(&self, &mut Formatter) -> Result; +} + +/// Format trait for the `p` character. +/// +/// The `Pointer` trait should format its output as a memory location. This is commonly presented +/// as hexadecimal. +/// +/// For more information on formatters, see [the module-level documentation][module]. +/// +/// [module]: ../../std/fmt/index.html +/// +/// # Examples +/// +/// Basic usage with `&i32`: +/// +/// ``` +/// let x = &42; +/// +/// let address = format!("{:p}", x); // this produces something like '0x7f06092ac6d0' +/// ``` +/// +/// Implementing `Pointer` on a type: +/// +/// ``` +/// use std::fmt; +/// +/// struct Length(i32); +/// +/// impl fmt::Pointer for Length { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// // use `as` to convert to a `*const T`, which implements Pointer, which we can use +/// +/// write!(f, "{:p}", self as *const Length) +/// } +/// } +/// +/// let l = Length(42); +/// +/// println!("l is in memory here: {:p}", l); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Pointer { + /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] + fn fmt(&self, &mut Formatter) -> Result; +} + +/// Format trait for the `e` character. +/// +/// The `LowerExp` trait should format its output in scientific notation with a lower-case `e`. +/// +/// For more information on formatters, see [the module-level documentation][module]. +/// +/// [module]: ../../std/fmt/index.html +/// +/// # Examples +/// +/// Basic usage with `i32`: +/// +/// ``` +/// let x = 42.0; // 42.0 is '4.2e1' in scientific notation +/// +/// assert_eq!(format!("{:e}", x), "4.2e1"); +/// ``` +/// +/// Implementing `LowerExp` on a type: +/// +/// ``` +/// use std::fmt; +/// +/// struct Length(i32); +/// +/// impl fmt::LowerExp for Length { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// let val = self.0; +/// write!(f, "{}e1", val / 10) +/// } +/// } +/// +/// let l = Length(100); +/// +/// println!("l in scientific notation is: {:e}", l); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait LowerExp { + /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] + fn fmt(&self, &mut Formatter) -> Result; +} + +/// Format trait for the `E` character. +/// +/// The `UpperExp` trait should format its output in scientific notation with an upper-case `E`. +/// +/// For more information on formatters, see [the module-level documentation][module]. +/// +/// [module]: ../../std/fmt/index.html +/// +/// # Examples +/// +/// Basic usage with `f32`: +/// +/// ``` +/// let x = 42.0; // 42.0 is '4.2E1' in scientific notation +/// +/// assert_eq!(format!("{:E}", x), "4.2E1"); +/// ``` +/// +/// Implementing `UpperExp` on a type: +/// +/// ``` +/// use std::fmt; +/// +/// struct Length(i32); +/// +/// impl fmt::UpperExp for Length { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// let val = self.0; +/// write!(f, "{}E1", val / 10) +/// } +/// } +/// +/// let l = Length(100); +/// +/// println!("l in scientific notation is: {:E}", l); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait UpperExp { + /// Formats the value using the given formatter. + #[stable(feature = "rust1", since = "1.0.0")] + fn fmt(&self, &mut Formatter) -> Result; +} + +/// The `write` function takes an output stream, a precompiled format string, +/// and a list of arguments. The arguments will be formatted according to the +/// specified format string into the output stream provided. +/// +/// # Arguments +/// +/// * output - the buffer to write output to +/// * args - the precompiled arguments generated by `format_args!` +#[stable(feature = "rust1", since = "1.0.0")] +pub fn write(output: &mut Write, args: Arguments) -> Result { + let mut formatter = Formatter { + flags: 0, + width: None, + precision: None, + buf: output, + align: rt::v1::Alignment::Unknown, + fill: ' ', + args: args.args, + curarg: args.args.iter(), + }; + + let mut pieces = args.pieces.iter(); + + match args.fmt { + None => { + // We can use default formatting parameters for all arguments. + for (arg, piece) in args.args.iter().zip(pieces.by_ref()) { + formatter.buf.write_str(*piece)?; + (arg.formatter)(arg.value, &mut formatter)?; + } + } + Some(fmt) => { + // Every spec has a corresponding argument that is preceded by + // a string piece. + for (arg, piece) in fmt.iter().zip(pieces.by_ref()) { + formatter.buf.write_str(*piece)?; + formatter.run(arg)?; + } + } + } + + // There can be only one trailing string piece left. + match pieces.next() { + Some(piece) => { + formatter.buf.write_str(*piece)?; + } + None => {} + } + + Ok(()) +} + +impl<'a> Formatter<'a> { + + // First up is the collection of functions used to execute a format string + // at runtime. This consumes all of the compile-time statics generated by + // the format! syntax extension. + fn run(&mut self, arg: &rt::v1::Argument) -> Result { + // Fill in the format parameters into the formatter + self.fill = arg.format.fill; + self.align = arg.format.align; + self.flags = arg.format.flags; + self.width = self.getcount(&arg.format.width); + self.precision = self.getcount(&arg.format.precision); + + // Extract the correct argument + let value = match arg.position { + rt::v1::Position::Next => { *self.curarg.next().unwrap() } + rt::v1::Position::At(i) => self.args[i], + }; + + // Then actually do some printing + (value.formatter)(value.value, self) + } + + fn getcount(&mut self, cnt: &rt::v1::Count) -> Option<usize> { + match *cnt { + rt::v1::Count::Is(n) => Some(n), + rt::v1::Count::Implied => None, + rt::v1::Count::Param(i) => { + self.args[i].as_usize() + } + rt::v1::Count::NextParam => { + self.curarg.next().and_then(|arg| arg.as_usize()) + } + } + } + + // Helper methods used for padding and processing formatting arguments that + // all formatting traits can use. + + /// Performs the correct padding for an integer which has already been + /// emitted into a str. The str should *not* contain the sign for the + /// integer, that will be added by this method. + /// + /// # Arguments + /// + /// * is_nonnegative - whether the original integer was either positive or zero. + /// * prefix - if the '#' character (Alternate) is provided, this + /// is the prefix to put in front of the number. + /// * buf - the byte array that the number has been formatted into + /// + /// This function will correctly account for the flags provided as well as + /// the minimum width. It will not take precision into account. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn pad_integral(&mut self, + is_nonnegative: bool, + prefix: &str, + buf: &str) + -> Result { + use char::CharExt; + + let mut width = buf.len(); + + let mut sign = None; + if !is_nonnegative { + sign = Some('-'); width += 1; + } else if self.sign_plus() { + sign = Some('+'); width += 1; + } + + let mut prefixed = false; + if self.alternate() { + prefixed = true; width += prefix.chars().count(); + } + + // Writes the sign if it exists, and then the prefix if it was requested + let write_prefix = |f: &mut Formatter| { + if let Some(c) = sign { + f.buf.write_str(unsafe { + str::from_utf8_unchecked(c.encode_utf8().as_slice()) + })?; + } + if prefixed { f.buf.write_str(prefix) } + else { Ok(()) } + }; + + // The `width` field is more of a `min-width` parameter at this point. + match self.width { + // If there's no minimum length requirements then we can just + // write the bytes. + None => { + write_prefix(self)?; self.buf.write_str(buf) + } + // Check if we're over the minimum width, if so then we can also + // just write the bytes. + Some(min) if width >= min => { + write_prefix(self)?; self.buf.write_str(buf) + } + // The sign and prefix goes before the padding if the fill character + // is zero + Some(min) if self.sign_aware_zero_pad() => { + self.fill = '0'; + write_prefix(self)?; + self.with_padding(min - width, rt::v1::Alignment::Right, |f| { + f.buf.write_str(buf) + }) + } + // Otherwise, the sign and prefix goes after the padding + Some(min) => { + self.with_padding(min - width, rt::v1::Alignment::Right, |f| { + write_prefix(f)?; f.buf.write_str(buf) + }) + } + } + } + + /// This function takes a string slice and emits it to the internal buffer + /// after applying the relevant formatting flags specified. The flags + /// recognized for generic strings are: + /// + /// * width - the minimum width of what to emit + /// * fill/align - what to emit and where to emit it if the string + /// provided needs to be padded + /// * precision - the maximum length to emit, the string is truncated if it + /// is longer than this length + /// + /// Notably this function ignored the `flag` parameters + #[stable(feature = "rust1", since = "1.0.0")] + pub fn pad(&mut self, s: &str) -> Result { + // Make sure there's a fast path up front + if self.width.is_none() && self.precision.is_none() { + return self.buf.write_str(s); + } + // The `precision` field can be interpreted as a `max-width` for the + // string being formatted + if let Some(max) = self.precision { + // If there's a maximum width and our string is longer than + // that, then we must always have truncation. This is the only + // case where the maximum length will matter. + if let Some((i, _)) = s.char_indices().skip(max).next() { + return self.buf.write_str(&s[..i]) + } + } + // The `width` field is more of a `min-width` parameter at this point. + match self.width { + // If we're under the maximum length, and there's no minimum length + // requirements, then we can just emit the string + None => self.buf.write_str(s), + // If we're under the maximum width, check if we're over the minimum + // width, if so it's as easy as just emitting the string. + Some(width) if s.chars().count() >= width => { + self.buf.write_str(s) + } + // If we're under both the maximum and the minimum width, then fill + // up the minimum width with the specified string + some alignment. + Some(width) => { + let align = rt::v1::Alignment::Left; + self.with_padding(width - s.chars().count(), align, |me| { + me.buf.write_str(s) + }) + } + } + } + + /// Runs a callback, emitting the correct padding either before or + /// afterwards depending on whether right or left alignment is requested. + fn with_padding<F>(&mut self, padding: usize, default: rt::v1::Alignment, + f: F) -> Result + where F: FnOnce(&mut Formatter) -> Result, + { + use char::CharExt; + let align = match self.align { + rt::v1::Alignment::Unknown => default, + _ => self.align + }; + + let (pre_pad, post_pad) = match align { + rt::v1::Alignment::Left => (0, padding), + rt::v1::Alignment::Right | + rt::v1::Alignment::Unknown => (padding, 0), + rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2), + }; + + let fill = self.fill.encode_utf8(); + let fill = unsafe { + str::from_utf8_unchecked(fill.as_slice()) + }; + + for _ in 0..pre_pad { + self.buf.write_str(fill)?; + } + + f(self)?; + + for _ in 0..post_pad { + self.buf.write_str(fill)?; + } + + Ok(()) + } + + /// Takes the formatted parts and applies the padding. + /// Assumes that the caller already has rendered the parts with required precision, + /// so that `self.precision` can be ignored. + fn pad_formatted_parts(&mut self, formatted: &flt2dec::Formatted) -> Result { + if let Some(mut width) = self.width { + // for the sign-aware zero padding, we render the sign first and + // behave as if we had no sign from the beginning. + let mut formatted = formatted.clone(); + let mut align = self.align; + let old_fill = self.fill; + if self.sign_aware_zero_pad() { + // a sign always goes first + let sign = unsafe { str::from_utf8_unchecked(formatted.sign) }; + self.buf.write_str(sign)?; + + // remove the sign from the formatted parts + formatted.sign = b""; + width = if width < sign.len() { 0 } else { width - sign.len() }; + align = rt::v1::Alignment::Right; + self.fill = '0'; + } + + // remaining parts go through the ordinary padding process. + let len = formatted.len(); + let ret = if width <= len { // no padding + self.write_formatted_parts(&formatted) + } else { + self.with_padding(width - len, align, |f| { + f.write_formatted_parts(&formatted) + }) + }; + self.fill = old_fill; + ret + } else { + // this is the common case and we take a shortcut + self.write_formatted_parts(formatted) + } + } + + fn write_formatted_parts(&mut self, formatted: &flt2dec::Formatted) -> Result { + fn write_bytes(buf: &mut Write, s: &[u8]) -> Result { + buf.write_str(unsafe { str::from_utf8_unchecked(s) }) + } + + if !formatted.sign.is_empty() { + write_bytes(self.buf, formatted.sign)?; + } + for part in formatted.parts { + match *part { + flt2dec::Part::Zero(mut nzeroes) => { + const ZEROES: &'static str = // 64 zeroes + "0000000000000000000000000000000000000000000000000000000000000000"; + while nzeroes > ZEROES.len() { + self.buf.write_str(ZEROES)?; + nzeroes -= ZEROES.len(); + } + if nzeroes > 0 { + self.buf.write_str(&ZEROES[..nzeroes])?; + } + } + flt2dec::Part::Num(mut v) => { + let mut s = [0; 5]; + let len = part.len(); + for c in s[..len].iter_mut().rev() { + *c = b'0' + (v % 10) as u8; + v /= 10; + } + write_bytes(self.buf, &s[..len])?; + } + flt2dec::Part::Copy(buf) => { + write_bytes(self.buf, buf)?; + } + } + } + Ok(()) + } + + /// Writes some data to the underlying buffer contained within this + /// formatter. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn write_str(&mut self, data: &str) -> Result { + self.buf.write_str(data) + } + + /// Writes some formatted information into this instance + #[stable(feature = "rust1", since = "1.0.0")] + pub fn write_fmt(&mut self, fmt: Arguments) -> Result { + write(self.buf, fmt) + } + + /// Flags for formatting (packed version of rt::Flag) + #[stable(feature = "rust1", since = "1.0.0")] + pub fn flags(&self) -> u32 { self.flags } + + /// Character used as 'fill' whenever there is alignment + #[stable(feature = "fmt_flags", since = "1.5.0")] + pub fn fill(&self) -> char { self.fill } + + /// Flag indicating what form of alignment was requested + #[unstable(feature = "fmt_flags_align", reason = "method was just created", + issue = "27726")] + pub fn align(&self) -> Alignment { + match self.align { + rt::v1::Alignment::Left => Alignment::Left, + rt::v1::Alignment::Right => Alignment::Right, + rt::v1::Alignment::Center => Alignment::Center, + rt::v1::Alignment::Unknown => Alignment::Unknown, + } + } + + /// Optionally specified integer width that the output should be + #[stable(feature = "fmt_flags", since = "1.5.0")] + pub fn width(&self) -> Option<usize> { self.width } + + /// Optionally specified precision for numeric types + #[stable(feature = "fmt_flags", since = "1.5.0")] + pub fn precision(&self) -> Option<usize> { self.precision } + + /// Determines if the `+` flag was specified. + #[stable(feature = "fmt_flags", since = "1.5.0")] + pub fn sign_plus(&self) -> bool { self.flags & (1 << FlagV1::SignPlus as u32) != 0 } + + /// Determines if the `-` flag was specified. + #[stable(feature = "fmt_flags", since = "1.5.0")] + pub fn sign_minus(&self) -> bool { self.flags & (1 << FlagV1::SignMinus as u32) != 0 } + + /// Determines if the `#` flag was specified. + #[stable(feature = "fmt_flags", since = "1.5.0")] + pub fn alternate(&self) -> bool { self.flags & (1 << FlagV1::Alternate as u32) != 0 } + + /// Determines if the `0` flag was specified. + #[stable(feature = "fmt_flags", since = "1.5.0")] + pub fn sign_aware_zero_pad(&self) -> bool { + self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0 + } + + /// Creates a `DebugStruct` builder designed to assist with creation of + /// `fmt::Debug` implementations for structs. + /// + /// # Examples + /// + /// ```rust + /// use std::fmt; + /// + /// struct Foo { + /// bar: i32, + /// baz: String, + /// } + /// + /// impl fmt::Debug for Foo { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// fmt.debug_struct("Foo") + /// .field("bar", &self.bar) + /// .field("baz", &self.baz) + /// .finish() + /// } + /// } + /// + /// // prints "Foo { bar: 10, baz: "Hello World" }" + /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }); + /// ``` + #[stable(feature = "debug_builders", since = "1.2.0")] + #[inline] + pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> { + builders::debug_struct_new(self, name) + } + + /// Creates a `DebugTuple` builder designed to assist with creation of + /// `fmt::Debug` implementations for tuple structs. + /// + /// # Examples + /// + /// ```rust + /// use std::fmt; + /// + /// struct Foo(i32, String); + /// + /// impl fmt::Debug for Foo { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// fmt.debug_tuple("Foo") + /// .field(&self.0) + /// .field(&self.1) + /// .finish() + /// } + /// } + /// + /// // prints "Foo(10, "Hello World")" + /// println!("{:?}", Foo(10, "Hello World".to_string())); + /// ``` + #[stable(feature = "debug_builders", since = "1.2.0")] + #[inline] + pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> { + builders::debug_tuple_new(self, name) + } + + /// Creates a `DebugList` builder designed to assist with creation of + /// `fmt::Debug` implementations for list-like structures. + /// + /// # Examples + /// + /// ```rust + /// use std::fmt; + /// + /// struct Foo(Vec<i32>); + /// + /// impl fmt::Debug for Foo { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// fmt.debug_list().entries(self.0.iter()).finish() + /// } + /// } + /// + /// // prints "[10, 11]" + /// println!("{:?}", Foo(vec![10, 11])); + /// ``` + #[stable(feature = "debug_builders", since = "1.2.0")] + #[inline] + pub fn debug_list<'b>(&'b mut self) -> DebugList<'b, 'a> { + builders::debug_list_new(self) + } + + /// Creates a `DebugSet` builder designed to assist with creation of + /// `fmt::Debug` implementations for set-like structures. + /// + /// # Examples + /// + /// ```rust + /// use std::fmt; + /// + /// struct Foo(Vec<i32>); + /// + /// impl fmt::Debug for Foo { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// fmt.debug_set().entries(self.0.iter()).finish() + /// } + /// } + /// + /// // prints "{10, 11}" + /// println!("{:?}", Foo(vec![10, 11])); + /// ``` + #[stable(feature = "debug_builders", since = "1.2.0")] + #[inline] + pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> { + builders::debug_set_new(self) + } + + /// Creates a `DebugMap` builder designed to assist with creation of + /// `fmt::Debug` implementations for map-like structures. + /// + /// # Examples + /// + /// ```rust + /// use std::fmt; + /// + /// struct Foo(Vec<(String, i32)>); + /// + /// impl fmt::Debug for Foo { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// fmt.debug_map().entries(self.0.iter().map(|&(ref k, ref v)| (k, v))).finish() + /// } + /// } + /// + /// // prints "{"A": 10, "B": 11}" + /// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])); + /// ``` + #[stable(feature = "debug_builders", since = "1.2.0")] + #[inline] + pub fn debug_map<'b>(&'b mut self) -> DebugMap<'b, 'a> { + builders::debug_map_new(self) + } +} + +#[stable(since = "1.2.0", feature = "formatter_write")] +impl<'a> Write for Formatter<'a> { + fn write_str(&mut self, s: &str) -> Result { + self.buf.write_str(s) + } + + fn write_char(&mut self, c: char) -> Result { + self.buf.write_char(c) + } + + fn write_fmt(&mut self, args: Arguments) -> Result { + write(self.buf, args) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Display for Error { + fn fmt(&self, f: &mut Formatter) -> Result { + Display::fmt("an error occurred when formatting an argument", f) + } +} + +// Implementations of the core formatting traits + +macro_rules! fmt_refs { + ($($tr:ident),*) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + $tr> $tr for &'a T { + fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } + } + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + $tr> $tr for &'a mut T { + fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } + } + )* + } +} + +fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } + +#[stable(feature = "rust1", since = "1.0.0")] +impl Debug for bool { + fn fmt(&self, f: &mut Formatter) -> Result { + Display::fmt(self, f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Display for bool { + fn fmt(&self, f: &mut Formatter) -> Result { + Display::fmt(if *self { "true" } else { "false" }, f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Debug for str { + fn fmt(&self, f: &mut Formatter) -> Result { + f.write_char('"')?; + let mut from = 0; + for (i, c) in self.char_indices() { + let esc = c.escape_default(); + // If char needs escaping, flush backlog so far and write, else skip + if esc.size_hint() != (1, Some(1)) { + f.write_str(&self[from..i])?; + for c in esc { + f.write_char(c)?; + } + from = i + c.len_utf8(); + } + } + f.write_str(&self[from..])?; + f.write_char('"') + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Display for str { + fn fmt(&self, f: &mut Formatter) -> Result { + f.pad(self) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Debug for char { + fn fmt(&self, f: &mut Formatter) -> Result { + f.write_char('\'')?; + for c in self.escape_default() { + f.write_char(c)? + } + f.write_char('\'') + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Display for char { + fn fmt(&self, f: &mut Formatter) -> Result { + if f.width.is_none() && f.precision.is_none() { + f.write_char(*self) + } else { + f.pad(unsafe { + str::from_utf8_unchecked(self.encode_utf8().as_slice()) + }) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Pointer for *const T { + fn fmt(&self, f: &mut Formatter) -> Result { + let old_width = f.width; + let old_flags = f.flags; + + // The alternate flag is already treated by LowerHex as being special- + // it denotes whether to prefix with 0x. We use it to work out whether + // or not to zero extend, and then unconditionally set it to get the + // prefix. + if f.alternate() { + f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32); + + if let None = f.width { + f.width = Some(((mem::size_of::<usize>() * 8) / 4) + 2); + } + } + f.flags |= 1 << (FlagV1::Alternate as u32); + + let ret = LowerHex::fmt(&(*self as *const () as usize), f); + + f.width = old_width; + f.flags = old_flags; + + ret + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Pointer for *mut T { + fn fmt(&self, f: &mut Formatter) -> Result { + Pointer::fmt(&(*self as *const T), f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Pointer for &'a T { + fn fmt(&self, f: &mut Formatter) -> Result { + Pointer::fmt(&(*self as *const T), f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Pointer for &'a mut T { + fn fmt(&self, f: &mut Formatter) -> Result { + Pointer::fmt(&(&**self as *const T), f) + } +} + +// Common code of floating point Debug and Display. +fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T, negative_zero: bool) -> Result + where T: flt2dec::DecodableFloat +{ + let force_sign = fmt.sign_plus(); + let sign = match (force_sign, negative_zero) { + (false, false) => flt2dec::Sign::Minus, + (false, true) => flt2dec::Sign::MinusRaw, + (true, false) => flt2dec::Sign::MinusPlus, + (true, true) => flt2dec::Sign::MinusPlusRaw, + }; + + let mut buf = [0; 1024]; // enough for f32 and f64 + let mut parts = [flt2dec::Part::Zero(0); 16]; + let formatted = if let Some(precision) = fmt.precision { + flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign, + precision, false, &mut buf, &mut parts) + } else { + flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign, + 0, false, &mut buf, &mut parts) + }; + fmt.pad_formatted_parts(&formatted) +} + +// Common code of floating point LowerExp and UpperExp. +fn float_to_exponential_common<T>(fmt: &mut Formatter, num: &T, upper: bool) -> Result + where T: flt2dec::DecodableFloat +{ + let force_sign = fmt.sign_plus(); + let sign = match force_sign { + false => flt2dec::Sign::Minus, + true => flt2dec::Sign::MinusPlus, + }; + + let mut buf = [0; 1024]; // enough for f32 and f64 + let mut parts = [flt2dec::Part::Zero(0); 16]; + let formatted = if let Some(precision) = fmt.precision { + // 1 integral digit + `precision` fractional digits = `precision + 1` total digits + flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign, + precision + 1, upper, &mut buf, &mut parts) + } else { + flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign, + (0, 0), upper, &mut buf, &mut parts) + }; + fmt.pad_formatted_parts(&formatted) +} + +macro_rules! floating { ($ty:ident) => { + + #[stable(feature = "rust1", since = "1.0.0")] + impl Debug for $ty { + fn fmt(&self, fmt: &mut Formatter) -> Result { + float_to_decimal_common(fmt, self, true) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Display for $ty { + fn fmt(&self, fmt: &mut Formatter) -> Result { + float_to_decimal_common(fmt, self, false) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl LowerExp for $ty { + fn fmt(&self, fmt: &mut Formatter) -> Result { + float_to_exponential_common(fmt, self, false) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl UpperExp for $ty { + fn fmt(&self, fmt: &mut Formatter) -> Result { + float_to_exponential_common(fmt, self, true) + } + } +} } +floating! { f32 } +floating! { f64 } + +// Implementation of Display/Debug for various core types + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> Debug for *const T { + fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> Debug for *mut T { + fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } +} + +macro_rules! peel { + ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* }) +} + +macro_rules! tuple { + () => (); + ( $($name:ident,)+ ) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($name:Debug),*> Debug for ($($name,)*) { + #[allow(non_snake_case, unused_assignments, deprecated)] + fn fmt(&self, f: &mut Formatter) -> Result { + let mut builder = f.debug_tuple(""); + let ($(ref $name,)*) = *self; + $( + builder.field($name); + )* + + builder.finish() + } + } + peel! { $($name,)* } + ) +} + +tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: Debug> Debug for [T] { + fn fmt(&self, f: &mut Formatter) -> Result { + f.debug_list().entries(self.iter()).finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Debug for () { + fn fmt(&self, f: &mut Formatter) -> Result { + f.pad("()") + } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Debug for PhantomData<T> { + fn fmt(&self, f: &mut Formatter) -> Result { + f.pad("PhantomData") + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: Copy + Debug> Debug for Cell<T> { + fn fmt(&self, f: &mut Formatter) -> Result { + f.debug_struct("Cell") + .field("value", &self.get()) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized + Debug> Debug for RefCell<T> { + fn fmt(&self, f: &mut Formatter) -> Result { + match self.borrow_state() { + BorrowState::Unused | BorrowState::Reading => { + f.debug_struct("RefCell") + .field("value", &self.borrow()) + .finish() + } + BorrowState::Writing => { + f.debug_struct("RefCell") + .field("value", &"<borrowed>") + .finish() + } + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'b, T: ?Sized + Debug> Debug for Ref<'b, T> { + fn fmt(&self, f: &mut Formatter) -> Result { + Debug::fmt(&**self, f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'b, T: ?Sized + Debug> Debug for RefMut<'b, T> { + fn fmt(&self, f: &mut Formatter) -> Result { + Debug::fmt(&*(self.deref()), f) + } +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<T: ?Sized + Debug> Debug for UnsafeCell<T> { + fn fmt(&self, f: &mut Formatter) -> Result { + f.pad("UnsafeCell") + } +} + +// If you expected tests to be here, look instead at the run-pass/ifmt.rs test, +// it's a lot easier than creating all of the rt::Piece structures here. diff --git a/libcore/fmt/num.rs b/libcore/fmt/num.rs new file mode 100644 index 0000000..a944c99 --- /dev/null +++ b/libcore/fmt/num.rs @@ -0,0 +1,262 @@ +// 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. + +//! Integer and floating-point number formatting + +#![allow(deprecated)] + +// FIXME: #6220 Implement floating point formatting + +use prelude::v1::*; + +use fmt; +use num::Zero; +use ops::{Div, Rem, Sub}; +use str; +use slice; +use ptr; +use mem; + +#[doc(hidden)] +trait Int: Zero + PartialEq + PartialOrd + Div<Output=Self> + Rem<Output=Self> + + Sub<Output=Self> + Copy { + fn from_u8(u: u8) -> Self; + fn to_u8(&self) -> u8; + fn to_u32(&self) -> u32; + fn to_u64(&self) -> u64; +} + +macro_rules! doit { + ($($t:ident)*) => ($(impl Int for $t { + fn from_u8(u: u8) -> $t { u as $t } + fn to_u8(&self) -> u8 { *self as u8 } + fn to_u32(&self) -> u32 { *self as u32 } + fn to_u64(&self) -> u64 { *self as u64 } + })*) +} +doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } + +/// A type that represents a specific radix +#[doc(hidden)] +trait GenericRadix { + /// The number of digits. + fn base(&self) -> u8; + + /// A radix-specific prefix string. + fn prefix(&self) -> &'static str { + "" + } + + /// Converts an integer to corresponding radix digit. + fn digit(&self, x: u8) -> u8; + + /// Format an integer using the radix using a formatter. + fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result { + // The radix can be as low as 2, so we need a buffer of at least 64 + // characters for a base 2 number. + let zero = T::zero(); + let is_nonnegative = x >= zero; + let mut buf = [0; 64]; + let mut curr = buf.len(); + let base = T::from_u8(self.base()); + if is_nonnegative { + // Accumulate each digit of the number from the least significant + // to the most significant figure. + for byte in buf.iter_mut().rev() { + let n = x % base; // Get the current place value. + x = x / base; // Deaccumulate the number. + *byte = self.digit(n.to_u8()); // Store the digit in the buffer. + curr -= 1; + if x == zero { + // No more digits left to accumulate. + break + }; + } + } else { + // Do the same as above, but accounting for two's complement. + for byte in buf.iter_mut().rev() { + let n = zero - (x % base); // Get the current place value. + x = x / base; // Deaccumulate the number. + *byte = self.digit(n.to_u8()); // Store the digit in the buffer. + curr -= 1; + if x == zero { + // No more digits left to accumulate. + break + }; + } + } + let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) }; + f.pad_integral(is_nonnegative, self.prefix(), buf) + } +} + +/// A binary (base 2) radix +#[derive(Clone, PartialEq)] +struct Binary; + +/// An octal (base 8) radix +#[derive(Clone, PartialEq)] +struct Octal; + +/// A decimal (base 10) radix +#[derive(Clone, PartialEq)] +struct Decimal; + +/// A hexadecimal (base 16) radix, formatted with lower-case characters +#[derive(Clone, PartialEq)] +struct LowerHex; + +/// A hexadecimal (base 16) radix, formatted with upper-case characters +#[derive(Clone, PartialEq)] +struct UpperHex; + +macro_rules! radix { + ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => { + impl GenericRadix for $T { + fn base(&self) -> u8 { $base } + fn prefix(&self) -> &'static str { $prefix } + fn digit(&self, x: u8) -> u8 { + match x { + $($x => $conv,)+ + x => panic!("number not in the range 0..{}: {}", self.base() - 1, x), + } + } + } + } +} + +radix! { Binary, 2, "0b", x @ 0 ... 2 => b'0' + x } +radix! { Octal, 8, "0o", x @ 0 ... 7 => b'0' + x } +radix! { Decimal, 10, "", x @ 0 ... 9 => b'0' + x } +radix! { LowerHex, 16, "0x", x @ 0 ... 9 => b'0' + x, + x @ 10 ... 15 => b'a' + (x - 10) } +radix! { UpperHex, 16, "0x", x @ 0 ... 9 => b'0' + x, + x @ 10 ... 15 => b'A' + (x - 10) } + +macro_rules! int_base { + ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl fmt::$Trait for $T { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + $Radix.fmt_int(*self as $U, f) + } + } + } +} + +macro_rules! debug { + ($T:ident) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl fmt::Debug for $T { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } + } + } +} + +macro_rules! integer { + ($Int:ident, $Uint:ident) => { + int_base! { Binary for $Int as $Uint -> Binary } + int_base! { Octal for $Int as $Uint -> Octal } + int_base! { LowerHex for $Int as $Uint -> LowerHex } + int_base! { UpperHex for $Int as $Uint -> UpperHex } + debug! { $Int } + + int_base! { Binary for $Uint as $Uint -> Binary } + int_base! { Octal for $Uint as $Uint -> Octal } + int_base! { LowerHex for $Uint as $Uint -> LowerHex } + int_base! { UpperHex for $Uint as $Uint -> UpperHex } + debug! { $Uint } + } +} +integer! { isize, usize } +integer! { i8, u8 } +integer! { i16, u16 } +integer! { i32, u32 } +integer! { i64, u64 } + +const DEC_DIGITS_LUT: &'static[u8] = + b"0001020304050607080910111213141516171819\ + 2021222324252627282930313233343536373839\ + 4041424344454647484950515253545556575859\ + 6061626364656667686970717273747576777879\ + 8081828384858687888990919293949596979899"; + +macro_rules! impl_Display { + ($($t:ident),*: $conv_fn:ident) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl fmt::Display for $t { + #[allow(unused_comparisons)] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let is_nonnegative = *self >= 0; + let mut n = if is_nonnegative { + self.$conv_fn() + } else { + // convert the negative num to positive by summing 1 to it's 2 complement + (!self.$conv_fn()).wrapping_add(1) + }; + let mut buf: [u8; 20] = unsafe { mem::uninitialized() }; + let mut curr = buf.len() as isize; + let buf_ptr = buf.as_mut_ptr(); + let lut_ptr = DEC_DIGITS_LUT.as_ptr(); + + unsafe { + // eagerly decode 4 characters at a time + if <$t>::max_value() as u64 >= 10000 { + while n >= 10000 { + let rem = (n % 10000) as isize; + n /= 10000; + + let d1 = (rem / 100) << 1; + let d2 = (rem % 100) << 1; + curr -= 4; + ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); + ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2); + } + } + + // if we reach here numbers are <= 9999, so at most 4 chars long + let mut n = n as isize; // possibly reduce 64bit math + + // decode 2 more chars, if > 2 chars + if n >= 100 { + let d1 = (n % 100) << 1; + n /= 100; + curr -= 2; + ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); + } + + // decode last 1 or 2 chars + if n < 10 { + curr -= 1; + *buf_ptr.offset(curr) = (n as u8) + 48; + } else { + let d1 = n << 1; + curr -= 2; + ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); + } + } + + let buf_slice = unsafe { + str::from_utf8_unchecked( + slice::from_raw_parts(buf_ptr.offset(curr), buf.len() - curr as usize)) + }; + f.pad_integral(is_nonnegative, "", buf_slice) + } + })*); +} + +impl_Display!(i8, u8, i16, u16, i32, u32: to_u32); +impl_Display!(i64, u64: to_u64); +#[cfg(target_pointer_width = "32")] +impl_Display!(isize, usize: to_u32); +#[cfg(target_pointer_width = "64")] +impl_Display!(isize, usize: to_u64); diff --git a/libcore/fmt/rt/v1.rs b/libcore/fmt/rt/v1.rs new file mode 100644 index 0000000..6b31e04 --- /dev/null +++ b/libcore/fmt/rt/v1.rs @@ -0,0 +1,58 @@ +// Copyright 2013 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. + +//! This is an internal module used by the ifmt! runtime. These structures are +//! emitted to static arrays to precompile format strings ahead of time. +//! +//! These definitions are similar to their `ct` equivalents, but differ in that +//! these can be statically allocated and are slightly optimized for the runtime +#![allow(missing_debug_implementations)] + +#[derive(Copy, Clone)] +pub struct Argument { + pub position: Position, + pub format: FormatSpec, +} + +#[derive(Copy, Clone)] +pub struct FormatSpec { + pub fill: char, + pub align: Alignment, + pub flags: u32, + pub precision: Count, + pub width: Count, +} + +/// Possible alignments that can be requested as part of a formatting directive. +#[derive(Copy, Clone, PartialEq)] +pub enum Alignment { + /// Indication that contents should be left-aligned. + Left, + /// Indication that contents should be right-aligned. + Right, + /// Indication that contents should be center-aligned. + Center, + /// No alignment was requested. + Unknown, +} + +#[derive(Copy, Clone)] +pub enum Count { + Is(usize), + Param(usize), + NextParam, + Implied, +} + +#[derive(Copy, Clone)] +pub enum Position { + Next, + At(usize), +} diff --git a/libcore/hash/mod.rs b/libcore/hash/mod.rs new file mode 100644 index 0000000..4d0fed9 --- /dev/null +++ b/libcore/hash/mod.rs @@ -0,0 +1,380 @@ +// Copyright 2012-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. + +//! Generic hashing support. +//! +//! This module provides a generic way to compute the hash of a value. The +//! simplest way to make a type hashable is to use `#[derive(Hash)]`: +//! +//! # Examples +//! +//! ```rust +//! use std::hash::{Hash, SipHasher, Hasher}; +//! +//! #[derive(Hash)] +//! struct Person { +//! id: u32, +//! name: String, +//! phone: u64, +//! } +//! +//! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 }; +//! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 }; +//! +//! assert!(hash(&person1) != hash(&person2)); +//! +//! fn hash<T: Hash>(t: &T) -> u64 { +//! let mut s = SipHasher::new(); +//! t.hash(&mut s); +//! s.finish() +//! } +//! ``` +//! +//! If you need more control over how a value is hashed, you need to implement +//! the trait `Hash`: +//! +//! ```rust +//! use std::hash::{Hash, Hasher, SipHasher}; +//! +//! struct Person { +//! id: u32, +//! # #[allow(dead_code)] +//! name: String, +//! phone: u64, +//! } +//! +//! impl Hash for Person { +//! fn hash<H: Hasher>(&self, state: &mut H) { +//! self.id.hash(state); +//! self.phone.hash(state); +//! } +//! } +//! +//! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 }; +//! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 }; +//! +//! assert_eq!(hash(&person1), hash(&person2)); +//! +//! fn hash<T: Hash>(t: &T) -> u64 { +//! let mut s = SipHasher::new(); +//! t.hash(&mut s); +//! s.finish() +//! } +//! ``` + +#![stable(feature = "rust1", since = "1.0.0")] + +use prelude::v1::*; + +use fmt; +use marker; +use mem; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::sip::SipHasher; + +mod sip; + +/// A hashable type. +/// +/// The `H` type parameter is an abstract hash state that is used by the `Hash` +/// to compute the hash. +/// +/// If you are also implementing `Eq`, there is an additional property that +/// is important: +/// +/// ```text +/// k1 == k2 -> hash(k1) == hash(k2) +/// ``` +/// +/// In other words, if two keys are equal, their hashes should also be equal. +/// `HashMap` and `HashSet` both rely on this behavior. +/// +/// This trait can be used with `#[derive]`. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Hash { + /// Feeds this value into the state given, updating the hasher as necessary. + #[stable(feature = "rust1", since = "1.0.0")] + fn hash<H: Hasher>(&self, state: &mut H); + + /// Feeds a slice of this type into the state provided. + #[stable(feature = "hash_slice", since = "1.3.0")] + fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) + where Self: Sized + { + for piece in data { + piece.hash(state); + } + } +} + +/// A trait which represents the ability to hash an arbitrary stream of bytes. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Hasher { + /// Completes a round of hashing, producing the output hash generated. + #[stable(feature = "rust1", since = "1.0.0")] + fn finish(&self) -> u64; + + /// Writes some data into this `Hasher` + #[stable(feature = "rust1", since = "1.0.0")] + fn write(&mut self, bytes: &[u8]); + + /// Write a single `u8` into this hasher + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_u8(&mut self, i: u8) { + self.write(&[i]) + } + /// Write a single `u16` into this hasher. + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_u16(&mut self, i: u16) { + self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) }) + } + /// Write a single `u32` into this hasher. + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_u32(&mut self, i: u32) { + self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) }) + } + /// Write a single `u64` into this hasher. + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_u64(&mut self, i: u64) { + self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) }) + } + /// Write a single `usize` into this hasher. + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_usize(&mut self, i: usize) { + let bytes = unsafe { + ::slice::from_raw_parts(&i as *const usize as *const u8, mem::size_of::<usize>()) + }; + self.write(bytes); + } + + /// Write a single `i8` into this hasher. + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_i8(&mut self, i: i8) { + self.write_u8(i as u8) + } + /// Write a single `i16` into this hasher. + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_i16(&mut self, i: i16) { + self.write_u16(i as u16) + } + /// Write a single `i32` into this hasher. + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_i32(&mut self, i: i32) { + self.write_u32(i as u32) + } + /// Write a single `i64` into this hasher. + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_i64(&mut self, i: i64) { + self.write_u64(i as u64) + } + /// Write a single `isize` into this hasher. + #[inline] + #[stable(feature = "hasher_write", since = "1.3.0")] + fn write_isize(&mut self, i: isize) { + self.write_usize(i as usize) + } +} + +/// A `BuildHasher` is typically used as a factory for instances of `Hasher` +/// which a `HashMap` can then use to hash keys independently. +/// +/// Note that for each instance of `BuildHasher`, the created hashers should be +/// identical. That is, if the same stream of bytes is fed into each hasher, the +/// same output will also be generated. +#[stable(since = "1.7.0", feature = "build_hasher")] +pub trait BuildHasher { + /// Type of the hasher that will be created. + #[stable(since = "1.7.0", feature = "build_hasher")] + type Hasher: Hasher; + + /// Creates a new hasher. + #[stable(since = "1.7.0", feature = "build_hasher")] + fn build_hasher(&self) -> Self::Hasher; +} + +/// A structure which implements `BuildHasher` for all `Hasher` types which also +/// implement `Default`. +/// +/// This struct is 0-sized and does not need construction. +#[stable(since = "1.7.0", feature = "build_hasher")] +pub struct BuildHasherDefault<H>(marker::PhantomData<H>); + +#[stable(since = "1.9.0", feature = "core_impl_debug")] +impl<H> fmt::Debug for BuildHasherDefault<H> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("BuildHasherDefault") + } +} + +#[stable(since = "1.7.0", feature = "build_hasher")] +impl<H: Default + Hasher> BuildHasher for BuildHasherDefault<H> { + type Hasher = H; + + fn build_hasher(&self) -> H { + H::default() + } +} + +#[stable(since = "1.7.0", feature = "build_hasher")] +impl<H> Clone for BuildHasherDefault<H> { + fn clone(&self) -> BuildHasherDefault<H> { + BuildHasherDefault(marker::PhantomData) + } +} + +#[stable(since = "1.7.0", feature = "build_hasher")] +impl<H> Default for BuildHasherDefault<H> { + fn default() -> BuildHasherDefault<H> { + BuildHasherDefault(marker::PhantomData) + } +} + +////////////////////////////////////////////////////////////////////////////// + +mod impls { + use prelude::v1::*; + + use mem; + use slice; + use super::*; + + macro_rules! impl_write { + ($(($ty:ident, $meth:ident),)*) => {$( + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for $ty { + fn hash<H: Hasher>(&self, state: &mut H) { + state.$meth(*self) + } + + fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) { + let newlen = data.len() * mem::size_of::<$ty>(); + let ptr = data.as_ptr() as *const u8; + state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) + } + } + )*} + } + + impl_write! { + (u8, write_u8), + (u16, write_u16), + (u32, write_u32), + (u64, write_u64), + (usize, write_usize), + (i8, write_i8), + (i16, write_i16), + (i32, write_i32), + (i64, write_i64), + (isize, write_isize), + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for bool { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_u8(*self as u8) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for char { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_u32(*self as u32) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for str { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write(self.as_bytes()); + state.write_u8(0xff) + } + } + + macro_rules! impl_hash_tuple { + () => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for () { + fn hash<H: Hasher>(&self, _state: &mut H) {} + } + ); + + ( $($name:ident)+) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($name: Hash),*> Hash for ($($name,)*) { + #[allow(non_snake_case)] + fn hash<S: Hasher>(&self, state: &mut S) { + let ($(ref $name,)*) = *self; + $($name.hash(state);)* + } + } + ); + } + + impl_hash_tuple! {} + impl_hash_tuple! { A } + impl_hash_tuple! { A B } + impl_hash_tuple! { A B C } + impl_hash_tuple! { A B C D } + impl_hash_tuple! { A B C D E } + impl_hash_tuple! { A B C D E F } + impl_hash_tuple! { A B C D E F G } + impl_hash_tuple! { A B C D E F G H } + impl_hash_tuple! { A B C D E F G H I } + impl_hash_tuple! { A B C D E F G H I J } + impl_hash_tuple! { A B C D E F G H I J K } + impl_hash_tuple! { A B C D E F G H I J K L } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T: Hash> Hash for [T] { + fn hash<H: Hasher>(&self, state: &mut H) { + self.len().hash(state); + Hash::hash_slice(self, state) + } + } + + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a T { + fn hash<H: Hasher>(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a mut T { + fn hash<H: Hasher>(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T> Hash for *const T { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T> Hash for *mut T { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_usize(*self as usize) + } + } +} diff --git a/libcore/hash/sip.rs b/libcore/hash/sip.rs new file mode 100644 index 0000000..fd1dab7 --- /dev/null +++ b/libcore/hash/sip.rs @@ -0,0 +1,239 @@ +// Copyright 2012-2015 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. + +//! An implementation of SipHash 2-4. + +use prelude::v1::*; + +use ptr; +use super::Hasher; + +/// An implementation of SipHash 2-4. +/// +/// See: https://131002.net/siphash/ +/// +/// This is currently the default hashing function used by standard library +/// (eg. `collections::HashMap` uses it by default). +/// +/// SipHash is a general-purpose hashing function: it runs at a good +/// speed (competitive with Spooky and City) and permits strong _keyed_ +/// hashing. This lets you key your hashtables from a strong RNG, such as +/// [`rand::os::OsRng`](https://doc.rust-lang.org/rand/rand/os/struct.OsRng.html). +/// +/// Although the SipHash algorithm is considered to be generally strong, +/// it is not intended for cryptographic purposes. As such, all +/// cryptographic uses of this implementation are _strongly discouraged_. +#[derive(Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct SipHasher { + k0: u64, + k1: u64, + length: usize, // how many bytes we've processed + // v0, v2 and v1, v3 show up in pairs in the algorithm, + // and simd implementations of SipHash will use vectors + // of v02 and v13. By placing them in this order in the struct, + // the compiler can pick up on just a few simd optimizations by itself. + v0: u64, // hash state + v2: u64, + v1: u64, + v3: u64, + tail: u64, // unprocessed bytes le + ntail: usize, // how many bytes in tail are valid +} + +// sadly, these macro definitions can't appear later, +// because they're needed in the following defs; +// this design could be improved. + +macro_rules! u8to64_le { + ($buf:expr, $i:expr) => + ($buf[0+$i] as u64 | + ($buf[1+$i] as u64) << 8 | + ($buf[2+$i] as u64) << 16 | + ($buf[3+$i] as u64) << 24 | + ($buf[4+$i] as u64) << 32 | + ($buf[5+$i] as u64) << 40 | + ($buf[6+$i] as u64) << 48 | + ($buf[7+$i] as u64) << 56); + ($buf:expr, $i:expr, $len:expr) => + ({ + let mut t = 0; + let mut out = 0; + while t < $len { + out |= ($buf[t+$i] as u64) << t*8; + t += 1; + } + out + }); +} + +/// Load a full u64 word from a byte stream, in LE order. Use +/// `copy_nonoverlapping` to let the compiler generate the most efficient way +/// to load u64 from a possibly unaligned address. +/// +/// Unsafe because: unchecked indexing at i..i+8 +#[inline] +unsafe fn load_u64_le(buf: &[u8], i: usize) -> u64 { + debug_assert!(i + 8 <= buf.len()); + let mut data = 0u64; + ptr::copy_nonoverlapping(buf.get_unchecked(i), &mut data as *mut _ as *mut u8, 8); + data.to_le() +} + +macro_rules! rotl { + ($x:expr, $b:expr) => + (($x << $b) | ($x >> (64_i32.wrapping_sub($b)))) +} + +macro_rules! compress { + ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => + ({ + $v0 = $v0.wrapping_add($v1); $v1 = rotl!($v1, 13); $v1 ^= $v0; + $v0 = rotl!($v0, 32); + $v2 = $v2.wrapping_add($v3); $v3 = rotl!($v3, 16); $v3 ^= $v2; + $v0 = $v0.wrapping_add($v3); $v3 = rotl!($v3, 21); $v3 ^= $v0; + $v2 = $v2.wrapping_add($v1); $v1 = rotl!($v1, 17); $v1 ^= $v2; + $v2 = rotl!($v2, 32); + }) +} + +impl SipHasher { + /// Creates a new `SipHasher` with the two initial keys set to 0. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new() -> SipHasher { + SipHasher::new_with_keys(0, 0) + } + + /// Creates a `SipHasher` that is keyed off the provided keys. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher { + let mut state = SipHasher { + k0: key0, + k1: key1, + length: 0, + v0: 0, + v1: 0, + v2: 0, + v3: 0, + tail: 0, + ntail: 0, + }; + state.reset(); + state + } + + #[inline] + fn reset(&mut self) { + self.length = 0; + self.v0 = self.k0 ^ 0x736f6d6570736575; + self.v1 = self.k1 ^ 0x646f72616e646f6d; + self.v2 = self.k0 ^ 0x6c7967656e657261; + self.v3 = self.k1 ^ 0x7465646279746573; + self.ntail = 0; + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Hasher for SipHasher { + #[inline] + fn write(&mut self, msg: &[u8]) { + let length = msg.len(); + self.length += length; + + let mut needed = 0; + + if self.ntail != 0 { + needed = 8 - self.ntail; + if length < needed { + self.tail |= u8to64_le!(msg, 0, length) << 8 * self.ntail; + self.ntail += length; + return + } + + let m = self.tail | u8to64_le!(msg, 0, needed) << 8 * self.ntail; + + self.v3 ^= m; + compress!(self.v0, self.v1, self.v2, self.v3); + compress!(self.v0, self.v1, self.v2, self.v3); + self.v0 ^= m; + + self.ntail = 0; + } + + // Buffered tail is now flushed, process new input. + let len = length - needed; + let left = len & 0x7; + + let mut i = needed; + while i < len - left { + let mi = unsafe { load_u64_le(msg, i) }; + + self.v3 ^= mi; + compress!(self.v0, self.v1, self.v2, self.v3); + compress!(self.v0, self.v1, self.v2, self.v3); + self.v0 ^= mi; + + i += 8; + } + + self.tail = u8to64_le!(msg, i, left); + self.ntail = left; + } + + #[inline] + fn finish(&self) -> u64 { + let mut v0 = self.v0; + let mut v1 = self.v1; + let mut v2 = self.v2; + let mut v3 = self.v3; + + let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail; + + v3 ^= b; + compress!(v0, v1, v2, v3); + compress!(v0, v1, v2, v3); + v0 ^= b; + + v2 ^= 0xff; + compress!(v0, v1, v2, v3); + compress!(v0, v1, v2, v3); + compress!(v0, v1, v2, v3); + compress!(v0, v1, v2, v3); + + v0 ^ v1 ^ v2 ^ v3 + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Clone for SipHasher { + #[inline] + fn clone(&self) -> SipHasher { + SipHasher { + k0: self.k0, + k1: self.k1, + length: self.length, + v0: self.v0, + v1: self.v1, + v2: self.v2, + v3: self.v3, + tail: self.tail, + ntail: self.ntail, + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for SipHasher { + fn default() -> SipHasher { + SipHasher::new() + } +} diff --git a/libcore/intrinsics.rs b/libcore/intrinsics.rs new file mode 100644 index 0000000..03bcf9c --- /dev/null +++ b/libcore/intrinsics.rs @@ -0,0 +1,623 @@ +// Copyright 2013 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. + +//! rustc compiler intrinsics. +//! +//! The corresponding definitions are in librustc_trans/trans/intrinsic.rs. +//! +//! # Volatiles +//! +//! The volatile intrinsics provide operations intended to act on I/O +//! memory, which are guaranteed to not be reordered by the compiler +//! across other volatile intrinsics. See the LLVM documentation on +//! [[volatile]]. +//! +//! [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses +//! +//! # Atomics +//! +//! The atomic intrinsics provide common atomic operations on machine +//! words, with multiple possible memory orderings. They obey the same +//! semantics as C++11. See the LLVM documentation on [[atomics]]. +//! +//! [atomics]: http://llvm.org/docs/Atomics.html +//! +//! A quick refresher on memory ordering: +//! +//! * Acquire - a barrier for acquiring a lock. Subsequent reads and writes +//! take place after the barrier. +//! * Release - a barrier for releasing a lock. Preceding reads and writes +//! take place before the barrier. +//! * Sequentially consistent - sequentially consistent operations are +//! guaranteed to happen in order. This is the standard mode for working +//! with atomic types and is equivalent to Java's `volatile`. + +#![unstable(feature = "core_intrinsics", + reason = "intrinsics are unlikely to ever be stabilized, instead \ + they should be used through stabilized interfaces \ + in the rest of the standard library", + issue = "0")] +#![allow(missing_docs)] + +use marker::Sized; + +extern "rust-intrinsic" { + + // NB: These intrinsics take raw pointers because they mutate aliased + // memory, which is not valid for either `&` or `&mut`. + + #[cfg(all(stage0, not(cargobuild)))] + pub fn atomic_cxchg<T>(dst: *mut T, old: T, src: T) -> T; + #[cfg(all(stage0, not(cargobuild)))] + pub fn atomic_cxchg_acq<T>(dst: *mut T, old: T, src: T) -> T; + #[cfg(all(stage0, not(cargobuild)))] + pub fn atomic_cxchg_rel<T>(dst: *mut T, old: T, src: T) -> T; + #[cfg(all(stage0, not(cargobuild)))] + pub fn atomic_cxchg_acqrel<T>(dst: *mut T, old: T, src: T) -> T; + #[cfg(all(stage0, not(cargobuild)))] + pub fn atomic_cxchg_relaxed<T>(dst: *mut T, old: T, src: T) -> T; + + #[cfg(any(not(stage0), cargobuild))] + pub fn atomic_cxchg<T>(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(any(not(stage0), cargobuild))] + pub fn atomic_cxchg_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(any(not(stage0), cargobuild))] + pub fn atomic_cxchg_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(any(not(stage0), cargobuild))] + pub fn atomic_cxchg_acqrel<T>(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(any(not(stage0), cargobuild))] + pub fn atomic_cxchg_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(any(not(stage0), cargobuild))] + pub fn atomic_cxchg_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(any(not(stage0), cargobuild))] + pub fn atomic_cxchg_failacq<T>(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(any(not(stage0), cargobuild))] + pub fn atomic_cxchg_acq_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(any(not(stage0), cargobuild))] + pub fn atomic_cxchg_acqrel_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + + pub fn atomic_cxchgweak<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_acqrel<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_failacq<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_acq_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_acqrel_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool); + + pub fn atomic_load<T>(src: *const T) -> T; + pub fn atomic_load_acq<T>(src: *const T) -> T; + pub fn atomic_load_relaxed<T>(src: *const T) -> T; + pub fn atomic_load_unordered<T>(src: *const T) -> T; + + pub fn atomic_store<T>(dst: *mut T, val: T); + pub fn atomic_store_rel<T>(dst: *mut T, val: T); + pub fn atomic_store_relaxed<T>(dst: *mut T, val: T); + pub fn atomic_store_unordered<T>(dst: *mut T, val: T); + + pub fn atomic_xchg<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xchg_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xchg_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xchg_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xchg_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_xadd<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xadd_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xadd_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xadd_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xadd_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_xsub<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xsub_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xsub_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xsub_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xsub_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_and<T>(dst: *mut T, src: T) -> T; + pub fn atomic_and_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_and_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_and_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_and_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_nand<T>(dst: *mut T, src: T) -> T; + pub fn atomic_nand_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_nand_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_nand_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_nand_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_or<T>(dst: *mut T, src: T) -> T; + pub fn atomic_or_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_or_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_or_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_or_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_xor<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xor_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xor_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xor_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_xor_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_max<T>(dst: *mut T, src: T) -> T; + pub fn atomic_max_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_max_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_max_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_max_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_min<T>(dst: *mut T, src: T) -> T; + pub fn atomic_min_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_min_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_min_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_min_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_umin<T>(dst: *mut T, src: T) -> T; + pub fn atomic_umin_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_umin_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_umin_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_umin_relaxed<T>(dst: *mut T, src: T) -> T; + + pub fn atomic_umax<T>(dst: *mut T, src: T) -> T; + pub fn atomic_umax_acq<T>(dst: *mut T, src: T) -> T; + pub fn atomic_umax_rel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_umax_acqrel<T>(dst: *mut T, src: T) -> T; + pub fn atomic_umax_relaxed<T>(dst: *mut T, src: T) -> T; +} + +extern "rust-intrinsic" { + + pub fn atomic_fence(); + pub fn atomic_fence_acq(); + pub fn atomic_fence_rel(); + pub fn atomic_fence_acqrel(); + + /// A compiler-only memory barrier. + /// + /// Memory accesses will never be reordered across this barrier by the + /// compiler, but no instructions will be emitted for it. This is + /// appropriate for operations on the same thread that may be preempted, + /// such as when interacting with signal handlers. + pub fn atomic_singlethreadfence(); + pub fn atomic_singlethreadfence_acq(); + pub fn atomic_singlethreadfence_rel(); + pub fn atomic_singlethreadfence_acqrel(); + + /// Aborts the execution of the process. + pub fn abort() -> !; + + /// Tells LLVM that this point in the code is not reachable, + /// enabling further optimizations. + /// + /// NB: This is very different from the `unreachable!()` macro! + pub fn unreachable() -> !; + + /// Informs the optimizer that a condition is always true. + /// If the condition is false, the behavior is undefined. + /// + /// No code is generated for this intrinsic, but the optimizer will try + /// to preserve it (and its condition) between passes, which may interfere + /// with optimization of surrounding code and reduce performance. It should + /// not be used if the invariant can be discovered by the optimizer on its + /// own, or if it does not enable any significant optimizations. + pub fn assume(b: bool); + + /// Executes a breakpoint trap, for inspection by a debugger. + pub fn breakpoint(); + + /// The size of a type in bytes. + /// + /// This is the exact number of bytes in memory taken up by a + /// value of the given type. In other words, a memset of this size + /// would *exactly* overwrite a value. When laid out in vectors + /// and structures there may be additional padding between + /// elements. + pub fn size_of<T>() -> usize; + + /// Moves a value to an uninitialized memory location. + /// + /// Drop glue is not run on the destination. + pub fn move_val_init<T>(dst: *mut T, src: T); + + pub fn min_align_of<T>() -> usize; + pub fn pref_align_of<T>() -> usize; + + pub fn size_of_val<T: ?Sized>(_: &T) -> usize; + pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize; + + /// Executes the destructor (if any) of the pointed-to value. + /// + /// This has two use cases: + /// + /// * It is *required* to use `drop_in_place` to drop unsized types like + /// trait objects, because they can't be read out onto the stack and + /// dropped normally. + /// + /// * It is friendlier to the optimizer to do this over `ptr::read` when + /// dropping manually allocated memory (e.g. when writing Box/Rc/Vec), + /// as the compiler doesn't need to prove that it's sound to elide the + /// copy. + /// + /// # Undefined Behavior + /// + /// This has all the same safety problems as `ptr::read` with respect to + /// invalid pointers, types, and double drops. + #[stable(feature = "drop_in_place", since = "1.8.0")] + pub fn drop_in_place<T: ?Sized>(to_drop: *mut T); + + /// Gets a static string slice containing the name of a type. + pub fn type_name<T: ?Sized>() -> &'static str; + + /// Gets an identifier which is globally unique to the specified type. This + /// function will return the same value for a type regardless of whichever + /// crate it is invoked in. + pub fn type_id<T: ?Sized + 'static>() -> u64; + + /// Creates a value initialized to so that its drop flag, + /// if any, says that it has been dropped. + /// + /// `init_dropped` is unsafe because it returns a datum with all + /// of its bytes set to the drop flag, which generally does not + /// correspond to a valid value. + /// + /// This intrinsic is likely to be deprecated in the future when + /// Rust moves to non-zeroing dynamic drop (and thus removes the + /// embedded drop flags that are being established by this + /// intrinsic). + pub fn init_dropped<T>() -> T; + + /// Creates a value initialized to zero. + /// + /// `init` is unsafe because it returns a zeroed-out datum, + /// which is unsafe unless T is `Copy`. Also, even if T is + /// `Copy`, an all-zero value may not correspond to any legitimate + /// state for the type in question. + pub fn init<T>() -> T; + + /// Creates an uninitialized value. + /// + /// `uninit` is unsafe because there is no guarantee of what its + /// contents are. In particular its drop-flag may be set to any + /// state, which means it may claim either dropped or + /// undropped. In the general case one must use `ptr::write` to + /// initialize memory previous set to the result of `uninit`. + pub fn uninit<T>() -> T; + + /// Moves a value out of scope without running drop glue. + pub fn forget<T>(_: T) -> (); + + /// Unsafely transforms a value of one type into a value of another type. + /// + /// Both types must have the same size. + /// + /// # Examples + /// + /// ``` + /// use std::mem; + /// + /// let array: &[u8] = unsafe { mem::transmute("Rust") }; + /// assert_eq!(array, [82, 117, 115, 116]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn transmute<T, U>(e: T) -> U; + + /// Gives the address for the return value of the enclosing function. + /// + /// Using this intrinsic in a function that does not use an out pointer + /// will trigger a compiler error. + pub fn return_address() -> *const u8; + + /// Returns `true` if the actual type given as `T` requires drop + /// glue; returns `false` if the actual type provided for `T` + /// implements `Copy`. + /// + /// If the actual type neither requires drop glue nor implements + /// `Copy`, then may return `true` or `false`. + pub fn needs_drop<T>() -> bool; + + /// Calculates the offset from a pointer. + /// + /// This is implemented as an intrinsic to avoid converting to and from an + /// integer, since the conversion would throw away aliasing information. + /// + /// # Safety + /// + /// Both the starting and resulting pointer must be either in bounds or one + /// byte past the end of an allocated object. If either pointer is out of + /// bounds or arithmetic overflow occurs then any further use of the + /// returned value will result in undefined behavior. + pub fn offset<T>(dst: *const T, offset: isize) -> *const T; + + /// Calculates the offset from a pointer, potentially wrapping. + /// + /// This is implemented as an intrinsic to avoid converting to and from an + /// integer, since the conversion inhibits certain optimizations. + /// + /// # Safety + /// + /// Unlike the `offset` intrinsic, this intrinsic does not restrict the + /// resulting pointer to point into or one byte past the end of an allocated + /// object, and it wraps with two's complement arithmetic. The resulting + /// value is not necessarily valid to be used to actually access memory. + pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T; + + /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source + /// and destination may *not* overlap. + /// + /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`. + /// + /// # Safety + /// + /// Beyond requiring that the program must be allowed to access both regions + /// of memory, it is Undefined Behavior for source and destination to + /// overlap. Care must also be taken with the ownership of `src` and + /// `dst`. This method semantically moves the values of `src` into `dst`. + /// However it does not drop the contents of `dst`, or prevent the contents + /// of `src` from being dropped or used. + /// + /// # Examples + /// + /// A safe swap function: + /// + /// ``` + /// use std::mem; + /// use std::ptr; + /// + /// # #[allow(dead_code)] + /// fn swap<T>(x: &mut T, y: &mut T) { + /// unsafe { + /// // Give ourselves some scratch space to work with + /// let mut t: T = mem::uninitialized(); + /// + /// // Perform the swap, `&mut` pointers never alias + /// ptr::copy_nonoverlapping(x, &mut t, 1); + /// ptr::copy_nonoverlapping(y, x, 1); + /// ptr::copy_nonoverlapping(&t, y, 1); + /// + /// // y and t now point to the same thing, but we need to completely forget `tmp` + /// // because it's no longer relevant. + /// mem::forget(t); + /// } + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize); + + /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source + /// and destination may overlap. + /// + /// `copy` is semantically equivalent to C's `memmove`. + /// + /// # Safety + /// + /// Care must be taken with the ownership of `src` and `dst`. + /// This method semantically moves the values of `src` into `dst`. + /// However it does not drop the contents of `dst`, or prevent the contents of `src` + /// from being dropped or used. + /// + /// # Examples + /// + /// Efficiently create a Rust vector from an unsafe buffer: + /// + /// ``` + /// use std::ptr; + /// + /// # #[allow(dead_code)] + /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> { + /// let mut dst = Vec::with_capacity(elts); + /// dst.set_len(elts); + /// ptr::copy(ptr, dst.as_mut_ptr(), elts); + /// dst + /// } + /// ``` + /// + #[stable(feature = "rust1", since = "1.0.0")] + pub fn copy<T>(src: *const T, dst: *mut T, count: usize); + + /// Invokes memset on the specified pointer, setting `count * size_of::<T>()` + /// bytes of memory starting at `dst` to `val`. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize); + + /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with + /// a size of `count` * `size_of::<T>()` and an alignment of + /// `min_align_of::<T>()` + /// + /// The volatile parameter is set to `true`, so it will not be optimized out. + pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, + count: usize); + /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with + /// a size of `count` * `size_of::<T>()` and an alignment of + /// `min_align_of::<T>()` + /// + /// The volatile parameter is set to `true`, so it will not be optimized out. + pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize); + /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a + /// size of `count` * `size_of::<T>()` and an alignment of + /// `min_align_of::<T>()`. + /// + /// The volatile parameter is set to `true`, so it will not be optimized out. + pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize); + + /// Perform a volatile load from the `src` pointer. + pub fn volatile_load<T>(src: *const T) -> T; + /// Perform a volatile store to the `dst` pointer. + pub fn volatile_store<T>(dst: *mut T, val: T); + + /// Returns the square root of an `f32` + pub fn sqrtf32(x: f32) -> f32; + /// Returns the square root of an `f64` + pub fn sqrtf64(x: f64) -> f64; + + /// Raises an `f32` to an integer power. + pub fn powif32(a: f32, x: i32) -> f32; + /// Raises an `f64` to an integer power. + pub fn powif64(a: f64, x: i32) -> f64; + + /// Returns the sine of an `f32`. + pub fn sinf32(x: f32) -> f32; + /// Returns the sine of an `f64`. + pub fn sinf64(x: f64) -> f64; + + /// Returns the cosine of an `f32`. + pub fn cosf32(x: f32) -> f32; + /// Returns the cosine of an `f64`. + pub fn cosf64(x: f64) -> f64; + + /// Raises an `f32` to an `f32` power. + pub fn powf32(a: f32, x: f32) -> f32; + /// Raises an `f64` to an `f64` power. + pub fn powf64(a: f64, x: f64) -> f64; + + /// Returns the exponential of an `f32`. + pub fn expf32(x: f32) -> f32; + /// Returns the exponential of an `f64`. + pub fn expf64(x: f64) -> f64; + + /// Returns 2 raised to the power of an `f32`. + pub fn exp2f32(x: f32) -> f32; + /// Returns 2 raised to the power of an `f64`. + pub fn exp2f64(x: f64) -> f64; + + /// Returns the natural logarithm of an `f32`. + pub fn logf32(x: f32) -> f32; + /// Returns the natural logarithm of an `f64`. + pub fn logf64(x: f64) -> f64; + + /// Returns the base 10 logarithm of an `f32`. + pub fn log10f32(x: f32) -> f32; + /// Returns the base 10 logarithm of an `f64`. + pub fn log10f64(x: f64) -> f64; + + /// Returns the base 2 logarithm of an `f32`. + pub fn log2f32(x: f32) -> f32; + /// Returns the base 2 logarithm of an `f64`. + pub fn log2f64(x: f64) -> f64; + + /// Returns `a * b + c` for `f32` values. + pub fn fmaf32(a: f32, b: f32, c: f32) -> f32; + /// Returns `a * b + c` for `f64` values. + pub fn fmaf64(a: f64, b: f64, c: f64) -> f64; + + /// Returns the absolute value of an `f32`. + pub fn fabsf32(x: f32) -> f32; + /// Returns the absolute value of an `f64`. + pub fn fabsf64(x: f64) -> f64; + + /// Copies the sign from `y` to `x` for `f32` values. + pub fn copysignf32(x: f32, y: f32) -> f32; + /// Copies the sign from `y` to `x` for `f64` values. + pub fn copysignf64(x: f64, y: f64) -> f64; + + /// Returns the largest integer less than or equal to an `f32`. + pub fn floorf32(x: f32) -> f32; + /// Returns the largest integer less than or equal to an `f64`. + pub fn floorf64(x: f64) -> f64; + + /// Returns the smallest integer greater than or equal to an `f32`. + pub fn ceilf32(x: f32) -> f32; + /// Returns the smallest integer greater than or equal to an `f64`. + pub fn ceilf64(x: f64) -> f64; + + /// Returns the integer part of an `f32`. + pub fn truncf32(x: f32) -> f32; + /// Returns the integer part of an `f64`. + pub fn truncf64(x: f64) -> f64; + + /// Returns the nearest integer to an `f32`. May raise an inexact floating-point exception + /// if the argument is not an integer. + pub fn rintf32(x: f32) -> f32; + /// Returns the nearest integer to an `f64`. May raise an inexact floating-point exception + /// if the argument is not an integer. + pub fn rintf64(x: f64) -> f64; + + /// Returns the nearest integer to an `f32`. + pub fn nearbyintf32(x: f32) -> f32; + /// Returns the nearest integer to an `f64`. + pub fn nearbyintf64(x: f64) -> f64; + + /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. + pub fn roundf32(x: f32) -> f32; + /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. + pub fn roundf64(x: f64) -> f64; + + /// Float addition that allows optimizations based on algebraic rules. + /// May assume inputs are finite. + #[cfg(not(stage0))] + pub fn fadd_fast<T>(a: T, b: T) -> T; + + /// Float subtraction that allows optimizations based on algebraic rules. + /// May assume inputs are finite. + #[cfg(not(stage0))] + pub fn fsub_fast<T>(a: T, b: T) -> T; + + /// Float multiplication that allows optimizations based on algebraic rules. + /// May assume inputs are finite. + #[cfg(not(stage0))] + pub fn fmul_fast<T>(a: T, b: T) -> T; + + /// Float division that allows optimizations based on algebraic rules. + /// May assume inputs are finite. + #[cfg(not(stage0))] + pub fn fdiv_fast<T>(a: T, b: T) -> T; + + /// Float remainder that allows optimizations based on algebraic rules. + /// May assume inputs are finite. + #[cfg(not(stage0))] + pub fn frem_fast<T>(a: T, b: T) -> T; + + + /// Returns the number of bits set in an integer type `T` + pub fn ctpop<T>(x: T) -> T; + + /// Returns the number of leading bits unset in an integer type `T` + pub fn ctlz<T>(x: T) -> T; + + /// Returns the number of trailing bits unset in an integer type `T` + pub fn cttz<T>(x: T) -> T; + + /// Reverses the bytes in an integer type `T`. + pub fn bswap<T>(x: T) -> T; + + /// Performs checked integer addition. + pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool); + + /// Performs checked integer subtraction + pub fn sub_with_overflow<T>(x: T, y: T) -> (T, bool); + + /// Performs checked integer multiplication + pub fn mul_with_overflow<T>(x: T, y: T) -> (T, bool); + + /// Performs an unchecked division, resulting in undefined behavior + /// where y = 0 or x = `T::min_value()` and y = -1 + pub fn unchecked_div<T>(x: T, y: T) -> T; + /// Returns the remainder of an unchecked division, resulting in + /// undefined behavior where y = 0 or x = `T::min_value()` and y = -1 + pub fn unchecked_rem<T>(x: T, y: T) -> T; + + /// Returns (a + b) mod 2^N, where N is the width of T in bits. + pub fn overflowing_add<T>(a: T, b: T) -> T; + /// Returns (a - b) mod 2^N, where N is the width of T in bits. + pub fn overflowing_sub<T>(a: T, b: T) -> T; + /// Returns (a * b) mod 2^N, where N is the width of T in bits. + pub fn overflowing_mul<T>(a: T, b: T) -> T; + + /// Returns the value of the discriminant for the variant in 'v', + /// cast to a `u64`; if `T` has no discriminant, returns 0. + pub fn discriminant_value<T>(v: &T) -> u64; + + /// Rust's "try catch" construct which invokes the function pointer `f` with + /// the data pointer `data`. + /// + /// The third pointer is a target-specific data pointer which is filled in + /// with the specifics of the exception that occurred. For examples on Unix + /// platforms this is a `*mut *mut T` which is filled in by the compiler and + /// on MSVC it's `*mut [usize; 2]`. For more information see the compiler's + /// source as well as std's catch implementation. + pub fn try(f: fn(*mut u8), data: *mut u8, local_ptr: *mut u8) -> i32; +} diff --git a/libcore/iter.rs b/libcore/iter.rs new file mode 100644 index 0000000..b4378a5 --- /dev/null +++ b/libcore/iter.rs @@ -0,0 +1,5007 @@ +// Copyright 2013-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. + +//! Composable external iteration. +//! +//! If you've found yourself with a collection of some kind, and needed to +//! perform an operation on the elements of said collection, you'll quickly run +//! into 'iterators'. Iterators are heavily used in idiomatic Rust code, so +//! it's worth becoming familiar with them. +//! +//! Before explaining more, let's talk about how this module is structured: +//! +//! # Organization +//! +//! This module is largely organized by type: +//! +//! * [Traits] are the core portion: these traits define what kind of iterators +//! exist and what you can do with them. The methods of these traits are worth +//! putting some extra study time into. +//! * [Functions] provide some helpful ways to create some basic iterators. +//! * [Structs] are often the return types of the various methods on this +//! module's traits. You'll usually want to look at the method that creates +//! the `struct`, rather than the `struct` itself. For more detail about why, +//! see '[Implementing Iterator](#implementing-iterator)'. +//! +//! [Traits]: #traits +//! [Functions]: #functions +//! [Structs]: #structs +//! +//! That's it! Let's dig into iterators. +//! +//! # Iterator +//! +//! The heart and soul of this module is the [`Iterator`] trait. The core of +//! [`Iterator`] looks like this: +//! +//! ``` +//! trait Iterator { +//! type Item; +//! fn next(&mut self) -> Option<Self::Item>; +//! } +//! ``` +//! +//! An iterator has a method, [`next()`], which when called, returns an +//! [`Option`]`<Item>`. [`next()`] will return `Some(Item)` as long as there +//! are elements, and once they've all been exhausted, will return `None` to +//! indicate that iteration is finished. Individual iterators may choose to +//! resume iteration, and so calling [`next()`] again may or may not eventually +//! start returning `Some(Item)` again at some point. +//! +//! [`Iterator`]'s full definition includes a number of other methods as well, +//! but they are default methods, built on top of [`next()`], and so you get +//! them for free. +//! +//! Iterators are also composable, and it's common to chain them together to do +//! more complex forms of processing. See the [Adapters](#adapters) section +//! below for more details. +//! +//! [`Iterator`]: trait.Iterator.html +//! [`next()`]: trait.Iterator.html#tymethod.next +//! [`Option`]: ../../std/option/enum.Option.html +//! +//! # The three forms of iteration +//! +//! There are three common methods which can create iterators from a collection: +//! +//! * `iter()`, which iterates over `&T`. +//! * `iter_mut()`, which iterates over `&mut T`. +//! * `into_iter()`, which iterates over `T`. +//! +//! Various things in the standard library may implement one or more of the +//! three, where appropriate. +//! +//! # Implementing Iterator +//! +//! Creating an iterator of your own involves two steps: creating a `struct` to +//! hold the iterator's state, and then `impl`ementing [`Iterator`] for that +//! `struct`. This is why there are so many `struct`s in this module: there is +//! one for each iterator and iterator adapter. +//! +//! Let's make an iterator named `Counter` which counts from `1` to `5`: +//! +//! ``` +//! // First, the struct: +//! +//! /// An iterator which counts from one to five +//! struct Counter { +//! count: usize, +//! } +//! +//! // we want our count to start at one, so let's add a new() method to help. +//! // This isn't strictly necessary, but is convenient. Note that we start +//! // `count` at zero, we'll see why in `next()`'s implementation below. +//! impl Counter { +//! fn new() -> Counter { +//! Counter { count: 0 } +//! } +//! } +//! +//! // Then, we implement `Iterator` for our `Counter`: +//! +//! impl Iterator for Counter { +//! // we will be counting with usize +//! type Item = usize; +//! +//! // next() is the only required method +//! fn next(&mut self) -> Option<usize> { +//! // increment our count. This is why we started at zero. +//! self.count += 1; +//! +//! // check to see if we've finished counting or not. +//! if self.count < 6 { +//! Some(self.count) +//! } else { +//! None +//! } +//! } +//! } +//! +//! // And now we can use it! +//! +//! let mut counter = Counter::new(); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! ``` +//! +//! This will print `1` through `5`, each on their own line. +//! +//! Calling `next()` this way gets repetitive. Rust has a construct which can +//! call `next()` on your iterator, until it reaches `None`. Let's go over that +//! next. +//! +//! # for Loops and IntoIterator +//! +//! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic +//! example of `for`: +//! +//! ``` +//! let values = vec![1, 2, 3, 4, 5]; +//! +//! for x in values { +//! println!("{}", x); +//! } +//! ``` +//! +//! This will print the numbers one through five, each on their own line. But +//! you'll notice something here: we never called anything on our vector to +//! produce an iterator. What gives? +//! +//! There's a trait in the standard library for converting something into an +//! iterator: [`IntoIterator`]. This trait has one method, [`into_iter()`], +//! which converts the thing implementing [`IntoIterator`] into an iterator. +//! Let's take a look at that `for` loop again, and what the compiler converts +//! it into: +//! +//! [`IntoIterator`]: trait.IntoIterator.html +//! [`into_iter()`]: trait.IntoIterator.html#tymethod.into_iter +//! +//! ``` +//! let values = vec![1, 2, 3, 4, 5]; +//! +//! for x in values { +//! println!("{}", x); +//! } +//! ``` +//! +//! Rust de-sugars this into: +//! +//! ``` +//! let values = vec![1, 2, 3, 4, 5]; +//! { +//! let result = match IntoIterator::into_iter(values) { +//! mut iter => loop { +//! match iter.next() { +//! Some(x) => { println!("{}", x); }, +//! None => break, +//! } +//! }, +//! }; +//! result +//! } +//! ``` +//! +//! First, we call `into_iter()` on the value. Then, we match on the iterator +//! that returns, calling [`next()`] over and over until we see a `None`. At +//! that point, we `break` out of the loop, and we're done iterating. +//! +//! There's one more subtle bit here: the standard library contains an +//! interesting implementation of [`IntoIterator`]: +//! +//! ```ignore +//! impl<I: Iterator> IntoIterator for I +//! ``` +//! +//! In other words, all [`Iterator`]s implement [`IntoIterator`], by just +//! returning themselves. This means two things: +//! +//! 1. If you're writing an [`Iterator`], you can use it with a `for` loop. +//! 2. If you're creating a collection, implementing [`IntoIterator`] for it +//! will allow your collection to be used with the `for` loop. +//! +//! # Adapters +//! +//! Functions which take an [`Iterator`] and return another [`Iterator`] are +//! often called 'iterator adapters', as they're a form of the 'adapter +//! pattern'. +//! +//! Common iterator adapters include [`map()`], [`take()`], and [`collect()`]. +//! For more, see their documentation. +//! +//! [`map()`]: trait.Iterator.html#method.map +//! [`take()`]: trait.Iterator.html#method.take +//! [`collect()`]: trait.Iterator.html#method.collect +//! +//! # Laziness +//! +//! Iterators (and iterator [adapters](#adapters)) are *lazy*. This means that +//! just creating an iterator doesn't _do_ a whole lot. Nothing really happens +//! until you call [`next()`]. This is sometimes a source of confusion when +//! creating an iterator solely for its side effects. For example, the [`map()`] +//! method calls a closure on each element it iterates over: +//! +//! ``` +//! # #![allow(unused_must_use)] +//! let v = vec![1, 2, 3, 4, 5]; +//! v.iter().map(|x| println!("{}", x)); +//! ``` +//! +//! This will not print any values, as we only created an iterator, rather than +//! using it. The compiler will warn us about this kind of behavior: +//! +//! ```text +//! warning: unused result which must be used: iterator adaptors are lazy and +//! do nothing unless consumed +//! ``` +//! +//! The idiomatic way to write a [`map()`] for its side effects is to use a +//! `for` loop instead: +//! +//! ``` +//! let v = vec![1, 2, 3, 4, 5]; +//! +//! for x in &v { +//! println!("{}", x); +//! } +//! ``` +//! +//! [`map()`]: trait.Iterator.html#method.map +//! +//! The two most common ways to evaluate an iterator are to use a `for` loop +//! like this, or using the [`collect()`] adapter to produce a new collection. +//! +//! [`collect()`]: trait.Iterator.html#method.collect +//! +//! # Infinity +//! +//! Iterators do not have to be finite. As an example, an open-ended range is +//! an infinite iterator: +//! +//! ``` +//! let numbers = 0..; +//! ``` +//! +//! It is common to use the [`take()`] iterator adapter to turn an infinite +//! iterator into a finite one: +//! +//! ``` +//! let numbers = 0..; +//! let five_numbers = numbers.take(5); +//! +//! for number in five_numbers { +//! println!("{}", number); +//! } +//! ``` +//! +//! This will print the numbers `0` through `4`, each on their own line. +//! +//! [`take()`]: trait.Iterator.html#method.take + +#![stable(feature = "rust1", since = "1.0.0")] + +use clone::Clone; +use cmp; +use cmp::{Ord, PartialOrd, PartialEq, Ordering}; +use default::Default; +use fmt; +use marker; +use mem; +use num::{Zero, One}; +use ops::{self, Add, Sub, FnMut, Mul}; +use option::Option::{self, Some, None}; +use marker::Sized; +use usize; + +fn _assert_is_object_safe(_: &Iterator<Item=()>) {} + +/// An interface for dealing with iterators. +/// +/// This is the main iterator trait. For more about the concept of iterators +/// generally, please see the [module-level documentation]. In particular, you +/// may want to know how to [implement `Iterator`][impl]. +/// +/// [module-level documentation]: index.html +/// [impl]: index.html#implementing-iterator +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \ + `.iter()` or a similar method"] +pub trait Iterator { + /// The type of the elements being iterated over. + #[stable(feature = "rust1", since = "1.0.0")] + type Item; + + /// Advances the iterator and returns the next value. + /// + /// Returns `None` when iteration is finished. Individual iterator + /// implementations may choose to resume iteration, and so calling `next()` + /// again may or may not eventually start returning `Some(Item)` again at some + /// point. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// // A call to next() returns the next value... + /// assert_eq!(Some(&1), iter.next()); + /// assert_eq!(Some(&2), iter.next()); + /// assert_eq!(Some(&3), iter.next()); + /// + /// // ... and then None once it's over. + /// assert_eq!(None, iter.next()); + /// + /// // More calls may or may not return None. Here, they always will. + /// assert_eq!(None, iter.next()); + /// assert_eq!(None, iter.next()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn next(&mut self) -> Option<Self::Item>; + + /// Returns the bounds on the remaining length of the iterator. + /// + /// Specifically, `size_hint()` returns a tuple where the first element + /// is the lower bound, and the second element is the upper bound. + /// + /// The second half of the tuple that is returned is an `Option<usize>`. A + /// `None` here means that either there is no known upper bound, or the + /// upper bound is larger than `usize`. + /// + /// # Implementation notes + /// + /// It is not enforced that an iterator implementation yields the declared + /// number of elements. A buggy iterator may yield less than the lower bound + /// or more than the upper bound of elements. + /// + /// `size_hint()` is primarily intended to be used for optimizations such as + /// reserving space for the elements of the iterator, but must not be + /// trusted to e.g. omit bounds checks in unsafe code. An incorrect + /// implementation of `size_hint()` should not lead to memory safety + /// violations. + /// + /// That said, the implementation should provide a correct estimation, + /// because otherwise it would be a violation of the trait's protocol. + /// + /// The default implementation returns `(0, None)` which is correct for any + /// iterator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// let iter = a.iter(); + /// + /// assert_eq!((3, Some(3)), iter.size_hint()); + /// ``` + /// + /// A more complex example: + /// + /// ``` + /// // The even numbers from zero to ten. + /// let iter = (0..10).filter(|x| x % 2 == 0); + /// + /// // We might iterate from zero to ten times. Knowing that it's five + /// // exactly wouldn't be possible without executing filter(). + /// assert_eq!((0, Some(10)), iter.size_hint()); + /// + /// // Let's add one five more numbers with chain() + /// let iter = (0..10).filter(|x| x % 2 == 0).chain(15..20); + /// + /// // now both bounds are increased by five + /// assert_eq!((5, Some(15)), iter.size_hint()); + /// ``` + /// + /// Returning `None` for an upper bound: + /// + /// ``` + /// // an infinite iterator has no upper bound + /// let iter = 0..; + /// + /// assert_eq!((0, None), iter.size_hint()); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn size_hint(&self) -> (usize, Option<usize>) { (0, None) } + + /// Consumes the iterator, counting the number of iterations and returning it. + /// + /// This method will evaluate the iterator until its [`next()`] returns + /// `None`. Once `None` is encountered, `count()` returns the number of + /// times it called [`next()`]. + /// + /// [`next()`]: #tymethod.next + /// + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so counting elements of + /// an iterator with more than `usize::MAX` elements either produces the + /// wrong result or panics. If debug assertions are enabled, a panic is + /// guaranteed. + /// + /// # Panics + /// + /// This function might panic if the iterator has more than `usize::MAX` + /// elements. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().count(), 3); + /// + /// let a = [1, 2, 3, 4, 5]; + /// assert_eq!(a.iter().count(), 5); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn count(self) -> usize where Self: Sized { + // Might overflow. + self.fold(0, |cnt, _| cnt + 1) + } + + /// Consumes the iterator, returning the last element. + /// + /// This method will evaluate the iterator until it returns `None`. While + /// doing so, it keeps track of the current element. After `None` is + /// returned, `last()` will then return the last element it saw. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().last(), Some(&3)); + /// + /// let a = [1, 2, 3, 4, 5]; + /// assert_eq!(a.iter().last(), Some(&5)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn last(self) -> Option<Self::Item> where Self: Sized { + let mut last = None; + for x in self { last = Some(x); } + last + } + + /// Consumes the `n` first elements of the iterator, then returns the + /// `next()` one. + /// + /// This method will evaluate the iterator `n` times, discarding those elements. + /// After it does so, it will call [`next()`] and return its value. + /// + /// [`next()`]: #tymethod.next + /// + /// Like most indexing operations, the count starts from zero, so `nth(0)` + /// returns the first value, `nth(1)` the second, and so on. + /// + /// `nth()` will return `None` if `n` is larger than the length of the + /// iterator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().nth(1), Some(&2)); + /// ``` + /// + /// Calling `nth()` multiple times doesn't rewind the iterator: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.nth(1), Some(&2)); + /// assert_eq!(iter.nth(1), None); + /// ``` + /// + /// Returning `None` if there are less than `n` elements: + /// + /// ``` + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().nth(10), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn nth(&mut self, mut n: usize) -> Option<Self::Item> where Self: Sized { + for x in self { + if n == 0 { return Some(x) } + n -= 1; + } + None + } + + /// Takes two iterators and creates a new iterator over both in sequence. + /// + /// `chain()` will return a new iterator which will first iterate over + /// values from the first iterator and then over values from the second + /// iterator. + /// + /// In other words, it links two iterators together, in a chain. 🔗 + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a1 = [1, 2, 3]; + /// let a2 = [4, 5, 6]; + /// + /// let mut iter = a1.iter().chain(a2.iter()); + /// + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(&4)); + /// assert_eq!(iter.next(), Some(&5)); + /// assert_eq!(iter.next(), Some(&6)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Since the argument to `chain()` uses [`IntoIterator`], we can pass + /// anything that can be converted into an [`Iterator`], not just an + /// [`Iterator`] itself. For example, slices (`&[T]`) implement + /// [`IntoIterator`], and so can be passed to `chain()` directly: + /// + /// [`IntoIterator`]: trait.IntoIterator.html + /// [`Iterator`]: trait.Iterator.html + /// + /// ``` + /// let s1 = &[1, 2, 3]; + /// let s2 = &[4, 5, 6]; + /// + /// let mut iter = s1.iter().chain(s2); + /// + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(&4)); + /// assert_eq!(iter.next(), Some(&5)); + /// assert_eq!(iter.next(), Some(&6)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where + Self: Sized, U: IntoIterator<Item=Self::Item>, + { + Chain{a: self, b: other.into_iter(), state: ChainState::Both} + } + + /// 'Zips up' two iterators into a single iterator of pairs. + /// + /// `zip()` returns a new iterator that will iterate over two other + /// iterators, returning a tuple where the first element comes from the + /// first iterator, and the second element comes from the second iterator. + /// + /// In other words, it zips two iterators together, into a single one. + /// + /// When either iterator returns `None`, all further calls to `next()` + /// will return `None`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a1 = [1, 2, 3]; + /// let a2 = [4, 5, 6]; + /// + /// let mut iter = a1.iter().zip(a2.iter()); + /// + /// assert_eq!(iter.next(), Some((&1, &4))); + /// assert_eq!(iter.next(), Some((&2, &5))); + /// assert_eq!(iter.next(), Some((&3, &6))); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Since the argument to `zip()` uses [`IntoIterator`], we can pass + /// anything that can be converted into an [`Iterator`], not just an + /// [`Iterator`] itself. For example, slices (`&[T]`) implement + /// [`IntoIterator`], and so can be passed to `zip()` directly: + /// + /// [`IntoIterator`]: trait.IntoIterator.html + /// [`Iterator`]: trait.Iterator.html + /// + /// ``` + /// let s1 = &[1, 2, 3]; + /// let s2 = &[4, 5, 6]; + /// + /// let mut iter = s1.iter().zip(s2); + /// + /// assert_eq!(iter.next(), Some((&1, &4))); + /// assert_eq!(iter.next(), Some((&2, &5))); + /// assert_eq!(iter.next(), Some((&3, &6))); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// `zip()` is often used to zip an infinite iterator to a finite one. + /// This works because the finite iterator will eventually return `None`, + /// ending the zipper. Zipping with `(0..)` can look a lot like [`enumerate()`]: + /// + /// ``` + /// let enumerate: Vec<_> = "foo".chars().enumerate().collect(); + /// + /// let zipper: Vec<_> = (0..).zip("foo".chars()).collect(); + /// + /// assert_eq!((0, 'f'), enumerate[0]); + /// assert_eq!((0, 'f'), zipper[0]); + /// + /// assert_eq!((1, 'o'), enumerate[1]); + /// assert_eq!((1, 'o'), zipper[1]); + /// + /// assert_eq!((2, 'o'), enumerate[2]); + /// assert_eq!((2, 'o'), zipper[2]); + /// ``` + /// + /// [`enumerate()`]: trait.Iterator.html#method.enumerate + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter> where + Self: Sized, U: IntoIterator + { + Zip{a: self, b: other.into_iter()} + } + + /// Takes a closure and creates an iterator which calls that closure on each + /// element. + /// + /// `map()` transforms one iterator into another, by means of its argument: + /// something that implements `FnMut`. It produces a new iterator which + /// calls this closure on each element of the original iterator. + /// + /// If you are good at thinking in types, you can think of `map()` like this: + /// If you have an iterator that gives you elements of some type `A`, and + /// you want an iterator of some other type `B`, you can use `map()`, + /// passing a closure that takes an `A` and returns a `B`. + /// + /// `map()` is conceptually similar to a [`for`] loop. However, as `map()` is + /// lazy, it is best used when you're already working with other iterators. + /// If you're doing some sort of looping for a side effect, it's considered + /// more idiomatic to use [`for`] than `map()`. + /// + /// [`for`]: ../../book/loops.html#for + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.into_iter().map(|x| 2 * x); + /// + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), Some(4)); + /// assert_eq!(iter.next(), Some(6)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// If you're doing some sort of side effect, prefer [`for`] to `map()`: + /// + /// ``` + /// # #![allow(unused_must_use)] + /// // don't do this: + /// (0..5).map(|x| println!("{}", x)); + /// + /// // it won't even execute, as it is lazy. Rust will warn you about this. + /// + /// // Instead, use for: + /// for x in 0..5 { + /// println!("{}", x); + /// } + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn map<B, F>(self, f: F) -> Map<Self, F> where + Self: Sized, F: FnMut(Self::Item) -> B, + { + Map{iter: self, f: f} + } + + /// Creates an iterator which uses a closure to determine if an element + /// should be yielded. + /// + /// The closure must return `true` or `false`. `filter()` creates an + /// iterator which calls this closure on each element. If the closure + /// returns `true`, then the element is returned. If the closure returns + /// `false`, it will try again, and call the closure on the next element, + /// seeing if it passes the test. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [0i32, 1, 2]; + /// + /// let mut iter = a.into_iter().filter(|x| x.is_positive()); + /// + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Because the closure passed to `filter()` takes a reference, and many + /// iterators iterate over references, this leads to a possibly confusing + /// situation, where the type of the closure is a double reference: + /// + /// ``` + /// let a = [0, 1, 2]; + /// + /// let mut iter = a.into_iter().filter(|x| **x > 1); // need two *s! + /// + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// It's common to instead use destructuring on the argument to strip away + /// one: + /// + /// ``` + /// let a = [0, 1, 2]; + /// + /// let mut iter = a.into_iter().filter(|&x| *x > 1); // both & and * + /// + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// or both: + /// + /// ``` + /// let a = [0, 1, 2]; + /// + /// let mut iter = a.into_iter().filter(|&&x| x > 1); // two &s + /// + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// of these layers. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn filter<P>(self, predicate: P) -> Filter<Self, P> where + Self: Sized, P: FnMut(&Self::Item) -> bool, + { + Filter{iter: self, predicate: predicate} + } + + /// Creates an iterator that both filters and maps. + /// + /// The closure must return an [`Option<T>`]. `filter_map()` creates an + /// iterator which calls this closure on each element. If the closure + /// returns `Some(element)`, then that element is returned. If the + /// closure returns `None`, it will try again, and call the closure on the + /// next element, seeing if it will return `Some`. + /// + /// [`Option<T>`]: ../../std/option/enum.Option.html + /// + /// Why `filter_map()` and not just [`filter()`].[`map()`]? The key is in this + /// part: + /// + /// [`filter()`]: #method.filter + /// [`map()`]: #method.map + /// + /// > If the closure returns `Some(element)`, then that element is returned. + /// + /// In other words, it removes the [`Option<T>`] layer automatically. If your + /// mapping is already returning an [`Option<T>`] and you want to skip over + /// `None`s, then `filter_map()` is much, much nicer to use. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = ["1", "2", "lol"]; + /// + /// let mut iter = a.iter().filter_map(|s| s.parse().ok()); + /// + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Here's the same example, but with [`filter()`] and [`map()`]: + /// + /// ``` + /// let a = ["1", "2", "lol"]; + /// + /// let mut iter = a.iter() + /// .map(|s| s.parse().ok()) + /// .filter(|s| s.is_some()); + /// + /// assert_eq!(iter.next(), Some(Some(1))); + /// assert_eq!(iter.next(), Some(Some(2))); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// There's an extra layer of `Some` in there. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where + Self: Sized, F: FnMut(Self::Item) -> Option<B>, + { + FilterMap { iter: self, f: f } + } + + /// Creates an iterator which gives the current iteration count as well as + /// the next value. + /// + /// The iterator returned yields pairs `(i, val)`, where `i` is the + /// current index of iteration and `val` is the value returned by the + /// iterator. + /// + /// `enumerate()` keeps its count as a [`usize`]. If you want to count by a + /// different sized integer, the [`zip()`] function provides similar + /// functionality. + /// + /// [`usize`]: ../../std/primitive.usize.html + /// [`zip()`]: #method.zip + /// + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so enumerating more than + /// [`usize::MAX`] elements either produces the wrong result or panics. If + /// debug assertions are enabled, a panic is guaranteed. + /// + /// [`usize::MAX`]: ../../std/usize/constant.MAX.html + /// + /// # Panics + /// + /// The returned iterator might panic if the to-be-returned index would + /// overflow a `usize`. + /// + /// # Examples + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().enumerate(); + /// + /// assert_eq!(iter.next(), Some((0, &1))); + /// assert_eq!(iter.next(), Some((1, &2))); + /// assert_eq!(iter.next(), Some((2, &3))); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn enumerate(self) -> Enumerate<Self> where Self: Sized { + Enumerate { iter: self, count: 0 } + } + + /// Creates an iterator which can look at the `next()` element without + /// consuming it. + /// + /// Adds a [`peek()`] method to an iterator. See its documentation for + /// more information. + /// + /// [`peek()`]: struct.Peekable.html#method.peek + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let xs = [1, 2, 3]; + /// + /// let mut iter = xs.iter().peekable(); + /// + /// // peek() lets us see into the future + /// assert_eq!(iter.peek(), Some(&&1)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// assert_eq!(iter.next(), Some(&2)); + /// + /// // we can peek() multiple times, the iterator won't advance + /// assert_eq!(iter.peek(), Some(&&3)); + /// assert_eq!(iter.peek(), Some(&&3)); + /// + /// assert_eq!(iter.next(), Some(&3)); + /// + /// // after the iterator is finished, so is peek() + /// assert_eq!(iter.peek(), None); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn peekable(self) -> Peekable<Self> where Self: Sized { + Peekable{iter: self, peeked: None} + } + + /// Creates an iterator that [`skip()`]s elements based on a predicate. + /// + /// [`skip()`]: #method.skip + /// + /// `skip_while()` takes a closure as an argument. It will call this + /// closure on each element of the iterator, and ignore elements + /// until it returns `false`. + /// + /// After `false` is returned, `skip_while()`'s job is over, and the + /// rest of the elements are yielded. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [-1i32, 0, 1]; + /// + /// let mut iter = a.into_iter().skip_while(|x| x.is_negative()); + /// + /// assert_eq!(iter.next(), Some(&0)); + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Because the closure passed to `skip_while()` takes a reference, and many + /// iterators iterate over references, this leads to a possibly confusing + /// situation, where the type of the closure is a double reference: + /// + /// ``` + /// let a = [-1, 0, 1]; + /// + /// let mut iter = a.into_iter().skip_while(|x| **x < 0); // need two *s! + /// + /// assert_eq!(iter.next(), Some(&0)); + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Stopping after an initial `false`: + /// + /// ``` + /// let a = [-1, 0, 1, -2]; + /// + /// let mut iter = a.into_iter().skip_while(|x| **x < 0); + /// + /// assert_eq!(iter.next(), Some(&0)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// // while this would have been false, since we already got a false, + /// // skip_while() isn't used any more + /// assert_eq!(iter.next(), Some(&-2)); + /// + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where + Self: Sized, P: FnMut(&Self::Item) -> bool, + { + SkipWhile{iter: self, flag: false, predicate: predicate} + } + + /// Creates an iterator that yields elements based on a predicate. + /// + /// `take_while()` takes a closure as an argument. It will call this + /// closure on each element of the iterator, and yield elements + /// while it returns `true`. + /// + /// After `false` is returned, `take_while()`'s job is over, and the + /// rest of the elements are ignored. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [-1i32, 0, 1]; + /// + /// let mut iter = a.into_iter().take_while(|x| x.is_negative()); + /// + /// assert_eq!(iter.next(), Some(&-1)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Because the closure passed to `take_while()` takes a reference, and many + /// iterators iterate over references, this leads to a possibly confusing + /// situation, where the type of the closure is a double reference: + /// + /// ``` + /// let a = [-1, 0, 1]; + /// + /// let mut iter = a.into_iter().take_while(|x| **x < 0); // need two *s! + /// + /// assert_eq!(iter.next(), Some(&-1)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Stopping after an initial `false`: + /// + /// ``` + /// let a = [-1, 0, 1, -2]; + /// + /// let mut iter = a.into_iter().take_while(|x| **x < 0); + /// + /// assert_eq!(iter.next(), Some(&-1)); + /// + /// // We have more elements that are less than zero, but since we already + /// // got a false, take_while() isn't used any more + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Because `take_while()` needs to look at the value in order to see if it + /// should be included or not, consuming iterators will see that it is + /// removed: + /// + /// ``` + /// let a = [1, 2, 3, 4]; + /// let mut iter = a.into_iter(); + /// + /// let result: Vec<i32> = iter.by_ref() + /// .take_while(|n| **n != 3) + /// .cloned() + /// .collect(); + /// + /// assert_eq!(result, &[1, 2]); + /// + /// let result: Vec<i32> = iter.cloned().collect(); + /// + /// assert_eq!(result, &[4]); + /// ``` + /// + /// The `3` is no longer there, because it was consumed in order to see if + /// the iteration should stop, but wasn't placed back into the iterator or + /// some similar thing. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where + Self: Sized, P: FnMut(&Self::Item) -> bool, + { + TakeWhile{iter: self, flag: false, predicate: predicate} + } + + /// Creates an iterator that skips the first `n` elements. + /// + /// After they have been consumed, the rest of the elements are yielded. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().skip(2); + /// + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn skip(self, n: usize) -> Skip<Self> where Self: Sized { + Skip{iter: self, n: n} + } + + /// Creates an iterator that yields its first `n` elements. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().take(2); + /// + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// `take()` is often used with an infinite iterator, to make it finite: + /// + /// ``` + /// let mut iter = (0..).take(3); + /// + /// assert_eq!(iter.next(), Some(0)); + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn take(self, n: usize) -> Take<Self> where Self: Sized, { + Take{iter: self, n: n} + } + + /// An iterator adaptor similar to [`fold()`] that holds internal state and + /// produces a new iterator. + /// + /// [`fold()`]: #method.fold + /// + /// `scan()` takes two arguments: an initial value which seeds the internal + /// state, and a closure with two arguments, the first being a mutable + /// reference to the internal state and the second an iterator element. + /// The closure can assign to the internal state to share state between + /// iterations. + /// + /// On iteration, the closure will be applied to each element of the + /// iterator and the return value from the closure, an [`Option`], is + /// yielded by the iterator. + /// + /// [`Option`]: ../../std/option/enum.Option.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().scan(1, |state, &x| { + /// // each iteration, we'll multiply the state by the element + /// *state = *state * x; + /// + /// // the value passed on to the next iteration + /// Some(*state) + /// }); + /// + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), Some(6)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> + where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option<B>, + { + Scan{iter: self, f: f, state: initial_state} + } + + /// Creates an iterator that works like map, but flattens nested structure. + /// + /// The [`map()`] adapter is very useful, but only when the closure + /// argument produces values. If it produces an iterator instead, there's + /// an extra layer of indirection. `flat_map()` will remove this extra layer + /// on its own. + /// + /// [`map()`]: #method.map + /// + /// Another way of thinking about `flat_map()`: [`map()`]'s closure returns + /// one item for each element, and `flat_map()`'s closure returns an + /// iterator for each element. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let words = ["alpha", "beta", "gamma"]; + /// + /// // chars() returns an iterator + /// let merged: String = words.iter() + /// .flat_map(|s| s.chars()) + /// .collect(); + /// assert_eq!(merged, "alphabetagamma"); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> + where Self: Sized, U: IntoIterator, F: FnMut(Self::Item) -> U, + { + FlatMap{iter: self, f: f, frontiter: None, backiter: None } + } + + /// Creates an iterator which ends after the first `None`. + /// + /// After an iterator returns `None`, future calls may or may not yield + /// `Some(T)` again. `fuse()` adapts an iterator, ensuring that after a + /// `None` is given, it will always return `None` forever. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // an iterator which alternates between Some and None + /// struct Alternate { + /// state: i32, + /// } + /// + /// impl Iterator for Alternate { + /// type Item = i32; + /// + /// fn next(&mut self) -> Option<i32> { + /// let val = self.state; + /// self.state = self.state + 1; + /// + /// // if it's even, Some(i32), else None + /// if val % 2 == 0 { + /// Some(val) + /// } else { + /// None + /// } + /// } + /// } + /// + /// let mut iter = Alternate { state: 0 }; + /// + /// // we can see our iterator going back and forth + /// assert_eq!(iter.next(), Some(0)); + /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), None); + /// + /// // however, once we fuse it... + /// let mut iter = iter.fuse(); + /// + /// assert_eq!(iter.next(), Some(4)); + /// assert_eq!(iter.next(), None); + /// + /// // it will always return None after the first time. + /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn fuse(self) -> Fuse<Self> where Self: Sized { + Fuse{iter: self, done: false} + } + + /// Do something with each element of an iterator, passing the value on. + /// + /// When using iterators, you'll often chain several of them together. + /// While working on such code, you might want to check out what's + /// happening at various parts in the pipeline. To do that, insert + /// a call to `inspect()`. + /// + /// It's much more common for `inspect()` to be used as a debugging tool + /// than to exist in your final code, but never say never. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 4, 2, 3]; + /// + /// // this iterator sequence is complex. + /// let sum = a.iter() + /// .cloned() + /// .filter(|&x| x % 2 == 0) + /// .fold(0, |sum, i| sum + i); + /// + /// println!("{}", sum); + /// + /// // let's add some inspect() calls to investigate what's happening + /// let sum = a.iter() + /// .cloned() + /// .inspect(|x| println!("about to filter: {}", x)) + /// .filter(|&x| x % 2 == 0) + /// .inspect(|x| println!("made it through filter: {}", x)) + /// .fold(0, |sum, i| sum + i); + /// + /// println!("{}", sum); + /// ``` + /// + /// This will print: + /// + /// ```text + /// about to filter: 1 + /// about to filter: 4 + /// made it through filter: 4 + /// about to filter: 2 + /// made it through filter: 2 + /// about to filter: 3 + /// 6 + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn inspect<F>(self, f: F) -> Inspect<Self, F> where + Self: Sized, F: FnMut(&Self::Item), + { + Inspect{iter: self, f: f} + } + + /// Borrows an iterator, rather than consuming it. + /// + /// This is useful to allow applying iterator adaptors while still + /// retaining ownership of the original iterator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let iter = a.into_iter(); + /// + /// let sum: i32 = iter.take(5) + /// .fold(0, |acc, &i| acc + i ); + /// + /// assert_eq!(sum, 6); + /// + /// // if we try to use iter again, it won't work. The following line + /// // gives "error: use of moved value: `iter` + /// // assert_eq!(iter.next(), None); + /// + /// // let's try that again + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.into_iter(); + /// + /// // instead, we add in a .by_ref() + /// let sum: i32 = iter.by_ref() + /// .take(2) + /// .fold(0, |acc, &i| acc + i ); + /// + /// assert_eq!(sum, 3); + /// + /// // now this is just fine: + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn by_ref(&mut self) -> &mut Self where Self: Sized { self } + + /// Transforms an iterator into a collection. + /// + /// `collect()` can take anything iterable, and turn it into a relevant + /// collection. This is one of the more powerful methods in the standard + /// library, used in a variety of contexts. + /// + /// The most basic pattern in which `collect()` is used is to turn one + /// collection into another. You take a collection, call `iter()` on it, + /// do a bunch of transformations, and then `collect()` at the end. + /// + /// One of the keys to `collect()`'s power is that many things you might + /// not think of as 'collections' actually are. For example, a [`String`] + /// is a collection of [`char`]s. And a collection of [`Result<T, E>`] can + /// be thought of as single `Result<Collection<T>, E>`. See the examples + /// below for more. + /// + /// [`String`]: ../../std/string/struct.String.html + /// [`Result<T, E>`]: ../../std/result/enum.Result.html + /// [`char`]: ../../std/primitive.char.html + /// + /// Because `collect()` is so general, it can cause problems with type + /// inference. As such, `collect()` is one of the few times you'll see + /// the syntax affectionately known as the 'turbofish': `::<>`. This + /// helps the inference algorithm understand specifically which collection + /// you're trying to collect into. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let doubled: Vec<i32> = a.iter() + /// .map(|&x| x * 2) + /// .collect(); + /// + /// assert_eq!(vec![2, 4, 6], doubled); + /// ``` + /// + /// Note that we needed the `: Vec<i32>` on the left-hand side. This is because + /// we could collect into, for example, a [`VecDeque<T>`] instead: + /// + /// [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html + /// + /// ``` + /// use std::collections::VecDeque; + /// + /// let a = [1, 2, 3]; + /// + /// let doubled: VecDeque<i32> = a.iter() + /// .map(|&x| x * 2) + /// .collect(); + /// + /// assert_eq!(2, doubled[0]); + /// assert_eq!(4, doubled[1]); + /// assert_eq!(6, doubled[2]); + /// ``` + /// + /// Using the 'turbofish' instead of annotating `doubled`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let doubled = a.iter() + /// .map(|&x| x * 2) + /// .collect::<Vec<i32>>(); + /// + /// assert_eq!(vec![2, 4, 6], doubled); + /// ``` + /// + /// Because `collect()` cares about what you're collecting into, you can + /// still use a partial type hint, `_`, with the turbofish: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let doubled = a.iter() + /// .map(|&x| x * 2) + /// .collect::<Vec<_>>(); + /// + /// assert_eq!(vec![2, 4, 6], doubled); + /// ``` + /// + /// Using `collect()` to make a [`String`]: + /// + /// ``` + /// let chars = ['g', 'd', 'k', 'k', 'n']; + /// + /// let hello: String = chars.iter() + /// .map(|&x| x as u8) + /// .map(|x| (x + 1) as char) + /// .collect(); + /// + /// assert_eq!("hello", hello); + /// ``` + /// + /// If you have a list of [`Result<T, E>`]s, you can use `collect()` to + /// see if any of them failed: + /// + /// ``` + /// let results = [Ok(1), Err("nope"), Ok(3), Err("bad")]; + /// + /// let result: Result<Vec<_>, &str> = results.iter().cloned().collect(); + /// + /// // gives us the first error + /// assert_eq!(Err("nope"), result); + /// + /// let results = [Ok(1), Ok(3)]; + /// + /// let result: Result<Vec<_>, &str> = results.iter().cloned().collect(); + /// + /// // gives us the list of answers + /// assert_eq!(Ok(vec![1, 3]), result); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized { + FromIterator::from_iter(self) + } + + /// Consumes an iterator, creating two collections from it. + /// + /// The predicate passed to `partition()` can return `true`, or `false`. + /// `partition()` returns a pair, all of the elements for which it returned + /// `true`, and all of the elements for which it returned `false`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let (even, odd): (Vec<i32>, Vec<i32>) = a.into_iter() + /// .partition(|&n| n % 2 == 0); + /// + /// assert_eq!(even, vec![2]); + /// assert_eq!(odd, vec![1, 3]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn partition<B, F>(self, mut f: F) -> (B, B) where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool + { + let mut left: B = Default::default(); + let mut right: B = Default::default(); + + for x in self { + if f(&x) { + left.extend(Some(x)) + } else { + right.extend(Some(x)) + } + } + + (left, right) + } + + /// An iterator adaptor that applies a function, producing a single, final value. + /// + /// `fold()` takes two arguments: an initial value, and a closure with two + /// arguments: an 'accumulator', and an element. The closure returns the value that + /// the accumulator should have for the next iteration. + /// + /// The initial value is the value the accumulator will have on the first + /// call. + /// + /// After applying this closure to every element of the iterator, `fold()` + /// returns the accumulator. + /// + /// This operation is sometimes called 'reduce' or 'inject'. + /// + /// Folding is useful whenever you have a collection of something, and want + /// to produce a single value from it. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// // the sum of all of the elements of a + /// let sum = a.iter() + /// .fold(0, |acc, &x| acc + x); + /// + /// assert_eq!(sum, 6); + /// ``` + /// + /// Let's walk through each step of the iteration here: + /// + /// | element | acc | x | result | + /// |---------|-----|---|--------| + /// | | 0 | | | + /// | 1 | 0 | 1 | 1 | + /// | 2 | 1 | 2 | 3 | + /// | 3 | 3 | 3 | 6 | + /// + /// And so, our final result, `6`. + /// + /// It's common for people who haven't used iterators a lot to + /// use a `for` loop with a list of things to build up a result. Those + /// can be turned into `fold()`s: + /// + /// ``` + /// let numbers = [1, 2, 3, 4, 5]; + /// + /// let mut result = 0; + /// + /// // for loop: + /// for i in &numbers { + /// result = result + i; + /// } + /// + /// // fold: + /// let result2 = numbers.iter().fold(0, |acc, &x| acc + x); + /// + /// // they're the same + /// assert_eq!(result, result2); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn fold<B, F>(self, init: B, mut f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + let mut accum = init; + for x in self { + accum = f(accum, x); + } + accum + } + + /// Tests if every element of the iterator matches a predicate. + /// + /// `all()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, and if they all return + /// `true`, then so does `all()`. If any of them return `false`, it + /// returns `false`. + /// + /// `all()` is short-circuiting; in other words, it will stop processing + /// as soon as it finds a `false`, given that no matter what else happens, + /// the result will also be `false`. + /// + /// An empty iterator returns `true`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert!(a.iter().all(|&x| x > 0)); + /// + /// assert!(!a.iter().all(|&x| x > 2)); + /// ``` + /// + /// Stopping at the first `false`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert!(!iter.all(|&x| x != 2)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn all<F>(&mut self, mut f: F) -> bool where + Self: Sized, F: FnMut(Self::Item) -> bool + { + for x in self { + if !f(x) { + return false; + } + } + true + } + + /// Tests if any element of the iterator matches a predicate. + /// + /// `any()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, and if any of them return + /// `true`, then so does `any()`. If they all return `false`, it + /// returns `false`. + /// + /// `any()` is short-circuiting; in other words, it will stop processing + /// as soon as it finds a `true`, given that no matter what else happens, + /// the result will also be `true`. + /// + /// An empty iterator returns `false`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert!(a.iter().any(|&x| x > 0)); + /// + /// assert!(!a.iter().any(|&x| x > 5)); + /// ``` + /// + /// Stopping at the first `true`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert!(iter.any(|&x| x != 2)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&2)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn any<F>(&mut self, mut f: F) -> bool where + Self: Sized, + F: FnMut(Self::Item) -> bool + { + for x in self { + if f(x) { + return true; + } + } + false + } + + /// Searches for an element of an iterator that satisfies a predicate. + /// + /// `find()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, and if any of them return + /// `true`, then `find()` returns `Some(element)`. If they all return + /// `false`, it returns `None`. + /// + /// `find()` is short-circuiting; in other words, it will stop processing + /// as soon as the closure returns `true`. + /// + /// Because `find()` takes a reference, and many iterators iterate over + /// references, this leads to a possibly confusing situation where the + /// argument is a double reference. You can see this effect in the + /// examples below, with `&&x`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().find(|&&x| x == 2), Some(&2)); + /// + /// assert_eq!(a.iter().find(|&&x| x == 5), None); + /// ``` + /// + /// Stopping at the first `true`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.find(|&&x| x == 2), Some(&2)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where + Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + for x in self { + if predicate(&x) { return Some(x) } + } + None + } + + /// Searches for an element in an iterator, returning its index. + /// + /// `position()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, and if one of them + /// returns `true`, then `position()` returns `Some(index)`. If all of + /// them return `false`, it returns `None`. + /// + /// `position()` is short-circuiting; in other words, it will stop + /// processing as soon as it finds a `true`. + /// + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so if there are more + /// than `usize::MAX` non-matching elements, it either produces the wrong + /// result or panics. If debug assertions are enabled, a panic is + /// guaranteed. + /// + /// # Panics + /// + /// This function might panic if the iterator has more than `usize::MAX` + /// non-matching elements. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().position(|&x| x == 2), Some(1)); + /// + /// assert_eq!(a.iter().position(|&x| x == 5), None); + /// ``` + /// + /// Stopping at the first `true`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.position(|&x| x == 2), Some(1)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn position<P>(&mut self, mut predicate: P) -> Option<usize> where + Self: Sized, + P: FnMut(Self::Item) -> bool, + { + // `enumerate` might overflow. + for (i, x) in self.enumerate() { + if predicate(x) { + return Some(i); + } + } + None + } + + /// Searches for an element in an iterator from the right, returning its + /// index. + /// + /// `rposition()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, starting from the end, + /// and if one of them returns `true`, then `rposition()` returns + /// `Some(index)`. If all of them return `false`, it returns `None`. + /// + /// `rposition()` is short-circuiting; in other words, it will stop + /// processing as soon as it finds a `true`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().rposition(|&x| x == 3), Some(2)); + /// + /// assert_eq!(a.iter().rposition(|&x| x == 5), None); + /// ``` + /// + /// Stopping at the first `true`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.rposition(|&x| x == 2), Some(1)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&1)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn rposition<P>(&mut self, mut predicate: P) -> Option<usize> where + P: FnMut(Self::Item) -> bool, + Self: Sized + ExactSizeIterator + DoubleEndedIterator + { + let mut i = self.len(); + + while let Some(v) = self.next_back() { + if predicate(v) { + return Some(i - 1); + } + // No need for an overflow check here, because `ExactSizeIterator` + // implies that the number of elements fits into a `usize`. + i -= 1; + } + None + } + + /// Returns the maximum element of an iterator. + /// + /// If the two elements are equally maximum, the latest element is + /// returned. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().max(), Some(&3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn max(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord + { + select_fold1(self, + |_| (), + // switch to y even if it is only equal, to preserve + // stability. + |_, x, _, y| *x <= *y) + .map(|(_, x)| x) + } + + /// Returns the minimum element of an iterator. + /// + /// If the two elements are equally minimum, the first element is + /// returned. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().min(), Some(&1)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn min(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord + { + select_fold1(self, + |_| (), + // only switch to y if it is strictly smaller, to + // preserve stability. + |_, x, _, y| *x > *y) + .map(|(_, x)| x) + } + + /// Returns the element that gives the maximum value from the + /// specified function. + /// + /// Returns the rightmost element if the comparison determines two elements + /// to be equally maximum. + /// + /// # Examples + /// + /// ``` + /// let a = [-3_i32, 0, 1, 5, -10]; + /// assert_eq!(*a.iter().max_by_key(|x| x.abs()).unwrap(), -10); + /// ``` + #[inline] + #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] + fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item> + where Self: Sized, F: FnMut(&Self::Item) -> B, + { + select_fold1(self, + f, + // switch to y even if it is only equal, to preserve + // stability. + |x_p, _, y_p, _| x_p <= y_p) + .map(|(_, x)| x) + } + + /// Returns the element that gives the minimum value from the + /// specified function. + /// + /// Returns the latest element if the comparison determines two elements + /// to be equally minimum. + /// + /// # Examples + /// + /// ``` + /// let a = [-3_i32, 0, 1, 5, -10]; + /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0); + /// ``` + #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] + fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item> + where Self: Sized, F: FnMut(&Self::Item) -> B, + { + select_fold1(self, + f, + // only switch to y if it is strictly smaller, to + // preserve stability. + |x_p, _, y_p, _| x_p > y_p) + .map(|(_, x)| x) + } + + /// Reverses an iterator's direction. + /// + /// Usually, iterators iterate from left to right. After using `rev()`, + /// an iterator will instead iterate from right to left. + /// + /// This is only possible if the iterator has an end, so `rev()` only + /// works on [`DoubleEndedIterator`]s. + /// + /// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html + /// + /// # Examples + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().rev(); + /// + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedIterator { + Rev{iter: self} + } + + /// Converts an iterator of pairs into a pair of containers. + /// + /// `unzip()` consumes an entire iterator of pairs, producing two + /// collections: one from the left elements of the pairs, and one + /// from the right elements. + /// + /// This function is, in some sense, the opposite of [`zip()`]. + /// + /// [`zip()`]: #method.zip + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [(1, 2), (3, 4)]; + /// + /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip(); + /// + /// assert_eq!(left, [1, 3]); + /// assert_eq!(right, [2, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item=(A, B)>, + { + struct SizeHint<A>(usize, Option<usize>, marker::PhantomData<A>); + impl<A> Iterator for SizeHint<A> { + type Item = A; + + fn next(&mut self) -> Option<A> { None } + fn size_hint(&self) -> (usize, Option<usize>) { + (self.0, self.1) + } + } + + let (lo, hi) = self.size_hint(); + let mut ts: FromA = Default::default(); + let mut us: FromB = Default::default(); + + ts.extend(SizeHint(lo, hi, marker::PhantomData)); + us.extend(SizeHint(lo, hi, marker::PhantomData)); + + for (t, u) in self { + ts.extend(Some(t)); + us.extend(Some(u)); + } + + (ts, us) + } + + /// Creates an iterator which `clone()`s all of its elements. + /// + /// This is useful when you have an iterator over `&T`, but you need an + /// iterator over `T`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let v_cloned: Vec<_> = a.iter().cloned().collect(); + /// + /// // cloned is the same as .map(|&x| x), for integers + /// let v_map: Vec<_> = a.iter().map(|&x| x).collect(); + /// + /// assert_eq!(v_cloned, vec![1, 2, 3]); + /// assert_eq!(v_map, vec![1, 2, 3]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn cloned<'a, T: 'a>(self) -> Cloned<Self> + where Self: Sized + Iterator<Item=&'a T>, T: Clone + { + Cloned { it: self } + } + + /// Repeats an iterator endlessly. + /// + /// Instead of stopping at `None`, the iterator will instead start again, + /// from the beginning. After iterating again, it will start at the + /// beginning again. And again. And again. Forever. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut it = a.iter().cycle(); + /// + /// assert_eq!(it.next(), Some(&1)); + /// assert_eq!(it.next(), Some(&2)); + /// assert_eq!(it.next(), Some(&3)); + /// assert_eq!(it.next(), Some(&1)); + /// assert_eq!(it.next(), Some(&2)); + /// assert_eq!(it.next(), Some(&3)); + /// assert_eq!(it.next(), Some(&1)); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + fn cycle(self) -> Cycle<Self> where Self: Sized + Clone { + Cycle{orig: self.clone(), iter: self} + } + + /// Sums the elements of an iterator. + /// + /// Takes each element, adds them together, and returns the result. + /// + /// An empty iterator returns the zero value of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(iter_arith)] + /// + /// let a = [1, 2, 3]; + /// let sum: i32 = a.iter().sum(); + /// + /// assert_eq!(sum, 6); + /// ``` + #[unstable(feature = "iter_arith", reason = "bounds recently changed", + issue = "27739")] + fn sum<S>(self) -> S where + S: Add<Self::Item, Output=S> + Zero, + Self: Sized, + { + self.fold(Zero::zero(), |s, e| s + e) + } + + /// Iterates over the entire iterator, multiplying all the elements + /// + /// An empty iterator returns the one value of the type. + /// + /// # Examples + /// + /// ``` + /// #![feature(iter_arith)] + /// + /// fn factorial(n: u32) -> u32 { + /// (1..).take_while(|&i| i <= n).product() + /// } + /// assert_eq!(factorial(0), 1); + /// assert_eq!(factorial(1), 1); + /// assert_eq!(factorial(5), 120); + /// ``` + #[unstable(feature="iter_arith", reason = "bounds recently changed", + issue = "27739")] + fn product<P>(self) -> P where + P: Mul<Self::Item, Output=P> + One, + Self: Sized, + { + self.fold(One::one(), |p, e| p * e) + } + + /// Lexicographically compares the elements of this `Iterator` with those + /// of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn cmp<I>(mut self, other: I) -> Ordering where + I: IntoIterator<Item = Self::Item>, + Self::Item: Ord, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return Ordering::Equal, + (None, _ ) => return Ordering::Less, + (_ , None) => return Ordering::Greater, + (Some(x), Some(y)) => match x.cmp(&y) { + Ordering::Equal => (), + non_eq => return non_eq, + }, + } + } + } + + /// Lexicographically compares the elements of this `Iterator` with those + /// of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn partial_cmp<I>(mut self, other: I) -> Option<Ordering> where + I: IntoIterator, + Self::Item: PartialOrd<I::Item>, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return Some(Ordering::Equal), + (None, _ ) => return Some(Ordering::Less), + (_ , None) => return Some(Ordering::Greater), + (Some(x), Some(y)) => match x.partial_cmp(&y) { + Some(Ordering::Equal) => (), + non_eq => return non_eq, + }, + } + } + } + + /// Determines if the elements of this `Iterator` are equal to those of + /// another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn eq<I>(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialEq<I::Item>, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return true, + (None, _) | (_, None) => return false, + (Some(x), Some(y)) => if x != y { return false }, + } + } + } + + /// Determines if the elements of this `Iterator` are unequal to those of + /// another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn ne<I>(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialEq<I::Item>, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return false, + (None, _) | (_, None) => return true, + (Some(x), Some(y)) => if x.ne(&y) { return true }, + } + } + } + + /// Determines if the elements of this `Iterator` are lexicographically + /// less than those of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn lt<I>(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialOrd<I::Item>, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return false, + (None, _ ) => return true, + (_ , None) => return false, + (Some(x), Some(y)) => { + match x.partial_cmp(&y) { + Some(Ordering::Less) => return true, + Some(Ordering::Equal) => {} + Some(Ordering::Greater) => return false, + None => return false, + } + }, + } + } + } + + /// Determines if the elements of this `Iterator` are lexicographically + /// less or equal to those of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn le<I>(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialOrd<I::Item>, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return true, + (None, _ ) => return true, + (_ , None) => return false, + (Some(x), Some(y)) => { + match x.partial_cmp(&y) { + Some(Ordering::Less) => return true, + Some(Ordering::Equal) => {} + Some(Ordering::Greater) => return false, + None => return false, + } + }, + } + } + } + + /// Determines if the elements of this `Iterator` are lexicographically + /// greater than those of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn gt<I>(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialOrd<I::Item>, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return false, + (None, _ ) => return false, + (_ , None) => return true, + (Some(x), Some(y)) => { + match x.partial_cmp(&y) { + Some(Ordering::Less) => return false, + Some(Ordering::Equal) => {} + Some(Ordering::Greater) => return true, + None => return false, + } + } + } + } + } + + /// Determines if the elements of this `Iterator` are lexicographically + /// greater than or equal to those of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn ge<I>(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialOrd<I::Item>, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return true, + (None, _ ) => return false, + (_ , None) => return true, + (Some(x), Some(y)) => { + match x.partial_cmp(&y) { + Some(Ordering::Less) => return false, + Some(Ordering::Equal) => {} + Some(Ordering::Greater) => return true, + None => return false, + } + }, + } + } + } +} + +/// Select an element from an iterator based on the given projection +/// and "comparison" function. +/// +/// This is an idiosyncratic helper to try to factor out the +/// commonalities of {max,min}{,_by}. In particular, this avoids +/// having to implement optimizations several times. +#[inline] +fn select_fold1<I,B, FProj, FCmp>(mut it: I, + mut f_proj: FProj, + mut f_cmp: FCmp) -> Option<(B, I::Item)> + where I: Iterator, + FProj: FnMut(&I::Item) -> B, + FCmp: FnMut(&B, &I::Item, &B, &I::Item) -> bool +{ + // start with the first element as our selection. This avoids + // having to use `Option`s inside the loop, translating to a + // sizeable performance gain (6x in one case). + it.next().map(|mut sel| { + let mut sel_p = f_proj(&sel); + + for x in it { + let x_p = f_proj(&x); + if f_cmp(&sel_p, &sel, &x_p, &x) { + sel = x; + sel_p = x_p; + } + } + (sel_p, sel) + }) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I { + type Item = I::Item; + fn next(&mut self) -> Option<I::Item> { (**self).next() } + fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() } +} + +/// Conversion from an `Iterator`. +/// +/// By implementing `FromIterator` for a type, you define how it will be +/// created from an iterator. This is common for types which describe a +/// collection of some kind. +/// +/// `FromIterator`'s [`from_iter()`] is rarely called explicitly, and is instead +/// used through [`Iterator`]'s [`collect()`] method. See [`collect()`]'s +/// documentation for more examples. +/// +/// [`from_iter()`]: #tymethod.from_iter +/// [`Iterator`]: trait.Iterator.html +/// [`collect()`]: trait.Iterator.html#method.collect +/// +/// See also: [`IntoIterator`]. +/// +/// [`IntoIterator`]: trait.IntoIterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter::FromIterator; +/// +/// let five_fives = std::iter::repeat(5).take(5); +/// +/// let v = Vec::from_iter(five_fives); +/// +/// assert_eq!(v, vec![5, 5, 5, 5, 5]); +/// ``` +/// +/// Using [`collect()`] to implicitly use `FromIterator`: +/// +/// ``` +/// let five_fives = std::iter::repeat(5).take(5); +/// +/// let v: Vec<i32> = five_fives.collect(); +/// +/// assert_eq!(v, vec![5, 5, 5, 5, 5]); +/// ``` +/// +/// Implementing `FromIterator` for your type: +/// +/// ``` +/// use std::iter::FromIterator; +/// +/// // A sample collection, that's just a wrapper over Vec<T> +/// #[derive(Debug)] +/// struct MyCollection(Vec<i32>); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // and we'll implement FromIterator +/// impl FromIterator<i32> for MyCollection { +/// fn from_iter<I: IntoIterator<Item=i32>>(iter: I) -> Self { +/// let mut c = MyCollection::new(); +/// +/// for i in iter { +/// c.add(i); +/// } +/// +/// c +/// } +/// } +/// +/// // Now we can make a new iterator... +/// let iter = (0..5).into_iter(); +/// +/// // ... and make a MyCollection out of it +/// let c = MyCollection::from_iter(iter); +/// +/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); +/// +/// // collect works too! +/// +/// let iter = (0..5).into_iter(); +/// let c: MyCollection = iter.collect(); +/// +/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \ + built from an iterator over elements of type `{A}`"] +pub trait FromIterator<A>: Sized { + /// Creates a value from an iterator. + /// + /// See the [module-level documentation] for more. + /// + /// [module-level documentation]: trait.FromIterator.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::iter::FromIterator; + /// + /// let five_fives = std::iter::repeat(5).take(5); + /// + /// let v = Vec::from_iter(five_fives); + /// + /// assert_eq!(v, vec![5, 5, 5, 5, 5]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn from_iter<T: IntoIterator<Item=A>>(iter: T) -> Self; +} + +/// Conversion into an `Iterator`. +/// +/// By implementing `IntoIterator` for a type, you define how it will be +/// converted to an iterator. This is common for types which describe a +/// collection of some kind. +/// +/// One benefit of implementing `IntoIterator` is that your type will [work +/// with Rust's `for` loop syntax](index.html#for-loops-and-intoiterator). +/// +/// See also: [`FromIterator`]. +/// +/// [`FromIterator`]: trait.FromIterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// let v = vec![1, 2, 3]; +/// +/// let mut iter = v.into_iter(); +/// +/// let n = iter.next(); +/// assert_eq!(Some(1), n); +/// +/// let n = iter.next(); +/// assert_eq!(Some(2), n); +/// +/// let n = iter.next(); +/// assert_eq!(Some(3), n); +/// +/// let n = iter.next(); +/// assert_eq!(None, n); +/// ``` +/// +/// Implementing `IntoIterator` for your type: +/// +/// ``` +/// // A sample collection, that's just a wrapper over Vec<T> +/// #[derive(Debug)] +/// struct MyCollection(Vec<i32>); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // and we'll implement IntoIterator +/// impl IntoIterator for MyCollection { +/// type Item = i32; +/// type IntoIter = ::std::vec::IntoIter<i32>; +/// +/// fn into_iter(self) -> Self::IntoIter { +/// self.0.into_iter() +/// } +/// } +/// +/// // Now we can make a new collection... +/// let mut c = MyCollection::new(); +/// +/// // ... add some stuff to it ... +/// c.add(0); +/// c.add(1); +/// c.add(2); +/// +/// // ... and then turn it into an Iterator: +/// for (i, n) in c.into_iter().enumerate() { +/// assert_eq!(i as i32, n); +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait IntoIterator { + /// The type of the elements being iterated over. + #[stable(feature = "rust1", since = "1.0.0")] + type Item; + + /// Which kind of iterator are we turning this into? + #[stable(feature = "rust1", since = "1.0.0")] + type IntoIter: Iterator<Item=Self::Item>; + + /// Creates an iterator from a value. + /// + /// See the [module-level documentation] for more. + /// + /// [module-level documentation]: trait.IntoIterator.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let v = vec![1, 2, 3]; + /// + /// let mut iter = v.into_iter(); + /// + /// let n = iter.next(); + /// assert_eq!(Some(1), n); + /// + /// let n = iter.next(); + /// assert_eq!(Some(2), n); + /// + /// let n = iter.next(); + /// assert_eq!(Some(3), n); + /// + /// let n = iter.next(); + /// assert_eq!(None, n); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn into_iter(self) -> Self::IntoIter; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: Iterator> IntoIterator for I { + type Item = I::Item; + type IntoIter = I; + + fn into_iter(self) -> I { + self + } +} + +/// Extend a collection with the contents of an iterator. +/// +/// Iterators produce a series of values, and collections can also be thought +/// of as a series of values. The `Extend` trait bridges this gap, allowing you +/// to extend a collection by including the contents of that iterator. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // You can extend a String with some chars: +/// let mut message = String::from("The first three letters are: "); +/// +/// message.extend(&['a', 'b', 'c']); +/// +/// assert_eq!("abc", &message[29..32]); +/// ``` +/// +/// Implementing `Extend`: +/// +/// ``` +/// // A sample collection, that's just a wrapper over Vec<T> +/// #[derive(Debug)] +/// struct MyCollection(Vec<i32>); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // since MyCollection has a list of i32s, we implement Extend for i32 +/// impl Extend<i32> for MyCollection { +/// +/// // This is a bit simpler with the concrete type signature: we can call +/// // extend on anything which can be turned into an Iterator which gives +/// // us i32s. Because we need i32s to put into MyCollection. +/// fn extend<T: IntoIterator<Item=i32>>(&mut self, iter: T) { +/// +/// // The implementation is very straightforward: loop through the +/// // iterator, and add() each element to ourselves. +/// for elem in iter { +/// self.add(elem); +/// } +/// } +/// } +/// +/// let mut c = MyCollection::new(); +/// +/// c.add(5); +/// c.add(6); +/// c.add(7); +/// +/// // let's extend our collection with three more numbers +/// c.extend(vec![1, 2, 3]); +/// +/// // we've added these elements onto the end +/// assert_eq!("MyCollection([5, 6, 7, 1, 2, 3])", format!("{:?}", c)); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Extend<A> { + /// Extends a collection with the contents of an iterator. + /// + /// As this is the only method for this trait, the [trait-level] docs + /// contain more details. + /// + /// [trait-level]: trait.Extend.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // You can extend a String with some chars: + /// let mut message = String::from("abc"); + /// + /// message.extend(['d', 'e', 'f'].iter()); + /// + /// assert_eq!("abcdef", &message); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T); +} + +/// An iterator able to yield elements from both ends. +/// +/// Something that implements `DoubleEndedIterator` has one extra capability +/// over something that implements [`Iterator`]: the ability to also take +/// `Item`s from the back, as well as the front. +/// +/// It is important to note that both back and forth work on the same range, +/// and do not cross: iteration is over when they meet in the middle. +/// +/// In a similar fashion to the [`Iterator`] protocol, once a +/// `DoubleEndedIterator` returns `None` from a `next_back()`, calling it again +/// may or may not ever return `Some` again. `next()` and `next_back()` are +/// interchangable for this purpose. +/// +/// [`Iterator`]: trait.Iterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// let numbers = vec![1, 2, 3]; +/// +/// let mut iter = numbers.iter(); +/// +/// assert_eq!(Some(&1), iter.next()); +/// assert_eq!(Some(&3), iter.next_back()); +/// assert_eq!(Some(&2), iter.next_back()); +/// assert_eq!(None, iter.next()); +/// assert_eq!(None, iter.next_back()); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait DoubleEndedIterator: Iterator { + /// An iterator able to yield elements from both ends. + /// + /// As this is the only method for this trait, the [trait-level] docs + /// contain more details. + /// + /// [trait-level]: trait.DoubleEndedIterator.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let numbers = vec![1, 2, 3]; + /// + /// let mut iter = numbers.iter(); + /// + /// assert_eq!(Some(&1), iter.next()); + /// assert_eq!(Some(&3), iter.next_back()); + /// assert_eq!(Some(&2), iter.next_back()); + /// assert_eq!(None, iter.next()); + /// assert_eq!(None, iter.next_back()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn next_back(&mut self) -> Option<Self::Item>; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I { + fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() } +} + +/// An iterator that knows its exact length. +/// +/// Many [`Iterator`]s don't know how many times they will iterate, but some do. +/// If an iterator knows how many times it can iterate, providing access to +/// that information can be useful. For example, if you want to iterate +/// backwards, a good start is to know where the end is. +/// +/// When implementing an `ExactSizeIterator`, You must also implement +/// [`Iterator`]. When doing so, the implementation of [`size_hint()`] *must* +/// return the exact size of the iterator. +/// +/// [`Iterator`]: trait.Iterator.html +/// [`size_hint()`]: trait.Iterator.html#method.size_hint +/// +/// The [`len()`] method has a default implementation, so you usually shouldn't +/// implement it. However, you may be able to provide a more performant +/// implementation than the default, so overriding it in this case makes sense. +/// +/// [`len()`]: #method.len +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // a finite range knows exactly how many times it will iterate +/// let five = 0..5; +/// +/// assert_eq!(5, five.len()); +/// ``` +/// +/// In the [module level docs][moddocs], we implemented an [`Iterator`], +/// `Counter`. Let's implement `ExactSizeIterator` for it as well: +/// +/// [moddocs]: index.html +/// +/// ``` +/// # struct Counter { +/// # count: usize, +/// # } +/// # impl Counter { +/// # fn new() -> Counter { +/// # Counter { count: 0 } +/// # } +/// # } +/// # impl Iterator for Counter { +/// # type Item = usize; +/// # fn next(&mut self) -> Option<usize> { +/// # self.count += 1; +/// # if self.count < 6 { +/// # Some(self.count) +/// # } else { +/// # None +/// # } +/// # } +/// # } +/// impl ExactSizeIterator for Counter { +/// // We already have the number of iterations, so we can use it directly. +/// fn len(&self) -> usize { +/// self.count +/// } +/// } +/// +/// // And now we can use it! +/// +/// let counter = Counter::new(); +/// +/// assert_eq!(0, counter.len()); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait ExactSizeIterator: Iterator { + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + /// Returns the exact number of times the iterator will iterate. + /// + /// This method has a default implementation, so you usually should not + /// implement it directly. However, if you can provide a more efficient + /// implementation, you can do so. See the [trait-level] docs for an + /// example. + /// + /// This function has the same safety guarantees as the [`size_hint()`] + /// function. + /// + /// [trait-level]: trait.ExactSizeIterator.html + /// [`size_hint()`]: trait.Iterator.html#method.size_hint + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // a finite range knows exactly how many times it will iterate + /// let five = 0..5; + /// + /// assert_eq!(5, five.len()); + /// ``` + fn len(&self) -> usize { + let (lower, upper) = self.size_hint(); + // Note: This assertion is overly defensive, but it checks the invariant + // guaranteed by the trait. If this trait were rust-internal, + // we could use debug_assert!; assert_eq! will check all Rust user + // implementations too. + assert_eq!(upper, Some(lower)); + lower + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I: ExactSizeIterator + ?Sized> ExactSizeIterator for &'a mut I {} + +// All adaptors that preserve the size of the wrapped iterator are fine +// Adaptors that may overflow in `size_hint` are not, i.e. `Chain`. +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> ExactSizeIterator for Enumerate<I> where I: ExactSizeIterator {} +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F> where + F: FnMut(&I::Item), +{} +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> ExactSizeIterator for Rev<I> + where I: ExactSizeIterator + DoubleEndedIterator {} +#[stable(feature = "rust1", since = "1.0.0")] +impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F> where + F: FnMut(I::Item) -> B, +{} +#[stable(feature = "rust1", since = "1.0.0")] +impl<A, B> ExactSizeIterator for Zip<A, B> + where A: ExactSizeIterator, B: ExactSizeIterator {} + +/// An double-ended iterator with the direction inverted. +/// +/// This `struct` is created by the [`rev()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`rev()`]: trait.Iterator.html#method.rev +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Rev<T> { + iter: T +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> Iterator for Rev<I> where I: DoubleEndedIterator { + type Item = <I as Iterator>::Item; + + #[inline] + fn next(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next_back() } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator { + #[inline] + fn next_back(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next() } +} + +/// An iterator that clones the elements of an underlying iterator. +/// +/// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`cloned()`]: trait.Iterator.html#method.cloned +/// [`Iterator`]: trait.Iterator.html +#[stable(feature = "iter_cloned", since = "1.1.0")] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[derive(Clone, Debug)] +pub struct Cloned<I> { + it: I, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I, T: 'a> Iterator for Cloned<I> + where I: Iterator<Item=&'a T>, T: Clone +{ + type Item = T; + + fn next(&mut self) -> Option<T> { + self.it.next().cloned() + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.it.size_hint() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I> + where I: DoubleEndedIterator<Item=&'a T>, T: Clone +{ + fn next_back(&mut self) -> Option<T> { + self.it.next_back().cloned() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I> + where I: ExactSizeIterator<Item=&'a T>, T: Clone +{} + +/// An iterator that repeats endlessly. +/// +/// This `struct` is created by the [`cycle()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`cycle()`]: trait.Iterator.html#method.cycle +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Cycle<I> { + orig: I, + iter: I, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> Iterator for Cycle<I> where I: Clone + Iterator { + type Item = <I as Iterator>::Item; + + #[inline] + fn next(&mut self) -> Option<<I as Iterator>::Item> { + match self.iter.next() { + None => { self.iter = self.orig.clone(); self.iter.next() } + y => y + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + // the cycle iterator is either empty or infinite + match self.orig.size_hint() { + sz @ (0, Some(0)) => sz, + (0, _) => (0, None), + _ => (usize::MAX, None) + } + } +} + +/// An iterator that strings two iterators together. +/// +/// This `struct` is created by the [`chain()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`chain()`]: trait.Iterator.html#method.chain +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Chain<A, B> { + a: A, + b: B, + state: ChainState, +} + +// The iterator protocol specifies that iteration ends with the return value +// `None` from `.next()` (or `.next_back()`) and it is unspecified what +// further calls return. The chain adaptor must account for this since it uses +// two subiterators. +// +// It uses three states: +// +// - Both: `a` and `b` are remaining +// - Front: `a` remaining +// - Back: `b` remaining +// +// The fourth state (neither iterator is remaining) only occurs after Chain has +// returned None once, so we don't need to store this state. +#[derive(Clone, Debug)] +enum ChainState { + // both front and back iterator are remaining + Both, + // only front is remaining + Front, + // only back is remaining + Back, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A, B> Iterator for Chain<A, B> where + A: Iterator, + B: Iterator<Item = A::Item> +{ + type Item = A::Item; + + #[inline] + fn next(&mut self) -> Option<A::Item> { + match self.state { + ChainState::Both => match self.a.next() { + elt @ Some(..) => elt, + None => { + self.state = ChainState::Back; + self.b.next() + } + }, + ChainState::Front => self.a.next(), + ChainState::Back => self.b.next(), + } + } + + #[inline] + fn count(self) -> usize { + match self.state { + ChainState::Both => self.a.count() + self.b.count(), + ChainState::Front => self.a.count(), + ChainState::Back => self.b.count(), + } + } + + #[inline] + fn nth(&mut self, mut n: usize) -> Option<A::Item> { + match self.state { + ChainState::Both | ChainState::Front => { + for x in self.a.by_ref() { + if n == 0 { + return Some(x) + } + n -= 1; + } + if let ChainState::Both = self.state { + self.state = ChainState::Back; + } + } + ChainState::Back => {} + } + if let ChainState::Back = self.state { + self.b.nth(n) + } else { + None + } + } + + #[inline] + fn last(self) -> Option<A::Item> { + match self.state { + ChainState::Both => { + // Must exhaust a before b. + let a_last = self.a.last(); + let b_last = self.b.last(); + b_last.or(a_last) + }, + ChainState::Front => self.a.last(), + ChainState::Back => self.b.last() + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = a_lower.saturating_add(b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => x.checked_add(y), + _ => None + }; + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A, B> DoubleEndedIterator for Chain<A, B> where + A: DoubleEndedIterator, + B: DoubleEndedIterator<Item=A::Item>, +{ + #[inline] + fn next_back(&mut self) -> Option<A::Item> { + match self.state { + ChainState::Both => match self.b.next_back() { + elt @ Some(..) => elt, + None => { + self.state = ChainState::Front; + self.a.next_back() + } + }, + ChainState::Front => self.a.next_back(), + ChainState::Back => self.b.next_back(), + } + } +} + +/// An iterator that iterates two other iterators simultaneously. +/// +/// This `struct` is created by the [`zip()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`zip()`]: trait.Iterator.html#method.zip +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Zip<A, B> { + a: A, + b: B +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A, B> Iterator for Zip<A, B> where A: Iterator, B: Iterator +{ + type Item = (A::Item, B::Item); + + #[inline] + fn next(&mut self) -> Option<(A::Item, B::Item)> { + self.a.next().and_then(|x| { + self.b.next().and_then(|y| { + Some((x, y)) + }) + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = cmp::min(a_lower, b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => Some(cmp::min(x,y)), + (Some(x), None) => Some(x), + (None, Some(y)) => Some(y), + (None, None) => None + }; + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A, B> DoubleEndedIterator for Zip<A, B> where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator, +{ + #[inline] + fn next_back(&mut self) -> Option<(A::Item, B::Item)> { + let a_sz = self.a.len(); + let b_sz = self.b.len(); + if a_sz != b_sz { + // Adjust a, b to equal length + if a_sz > b_sz { + for _ in 0..a_sz - b_sz { self.a.next_back(); } + } else { + for _ in 0..b_sz - a_sz { self.b.next_back(); } + } + } + match (self.a.next_back(), self.b.next_back()) { + (Some(x), Some(y)) => Some((x, y)), + (None, None) => None, + _ => unreachable!(), + } + } +} + +/// An iterator that maps the values of `iter` with `f`. +/// +/// This `struct` is created by the [`map()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`map()`]: trait.Iterator.html#method.map +/// [`Iterator`]: trait.Iterator.html +/// +/// # Notes about side effects +/// +/// The [`map()`] iterator implements [`DoubleEndedIterator`], meaning that +/// you can also [`map()`] backwards: +/// +/// ```rust +/// let v: Vec<i32> = vec![1, 2, 3].into_iter().rev().map(|x| x + 1).collect(); +/// +/// assert_eq!(v, [4, 3, 2]); +/// ``` +/// +/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html +/// +/// But if your closure has state, iterating backwards may act in a way you do +/// not expect. Let's go through an example. First, in the forward direction: +/// +/// ```rust +/// let mut c = 0; +/// +/// for pair in vec!['a', 'b', 'c'].into_iter() +/// .map(|letter| { c += 1; (letter, c) }) { +/// println!("{:?}", pair); +/// } +/// ``` +/// +/// This will print "('a', 1), ('b', 2), ('c', 3)". +/// +/// Now consider this twist where we add a call to `rev`. This version will +/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed, +/// but the values of the counter still go in order. This is because `map()` is +/// still being called lazilly on each item, but we are popping items off the +/// back of the vector now, instead of shifting them from the front. +/// +/// ```rust +/// let mut c = 0; +/// +/// for pair in vec!['a', 'b', 'c'].into_iter() +/// .map(|letter| { c += 1; (letter, c) }) +/// .rev() { +/// println!("{:?}", pair); +/// } +/// ``` +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Map<I, F> { + iter: I, + f: F, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<I: fmt::Debug, F> fmt::Debug for Map<I, F> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Map") + .field("iter", &self.iter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B { + type Item = B; + + #[inline] + fn next(&mut self) -> Option<B> { + self.iter.next().map(&mut self.f) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where + F: FnMut(I::Item) -> B, +{ + #[inline] + fn next_back(&mut self) -> Option<B> { + self.iter.next_back().map(&mut self.f) + } +} + +/// An iterator that filters the elements of `iter` with `predicate`. +/// +/// This `struct` is created by the [`filter()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter()`]: trait.Iterator.html#method.filter +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Filter<I, P> { + iter: I, + predicate: P, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Filter") + .field("iter", &self.iter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option<I::Item> { + for x in self.iter.by_ref() { + if (self.predicate)(&x) { + return Some(x); + } + } + None + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P> + where P: FnMut(&I::Item) -> bool, +{ + #[inline] + fn next_back(&mut self) -> Option<I::Item> { + for x in self.iter.by_ref().rev() { + if (self.predicate)(&x) { + return Some(x); + } + } + None + } +} + +/// An iterator that uses `f` to both filter and map elements from `iter`. +/// +/// This `struct` is created by the [`filter_map()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter_map()`]: trait.Iterator.html#method.filter_map +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct FilterMap<I, F> { + iter: I, + f: F, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<I: fmt::Debug, F> fmt::Debug for FilterMap<I, F> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("FilterMap") + .field("iter", &self.iter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<B, I: Iterator, F> Iterator for FilterMap<I, F> + where F: FnMut(I::Item) -> Option<B>, +{ + type Item = B; + + #[inline] + fn next(&mut self) -> Option<B> { + for x in self.iter.by_ref() { + if let Some(y) = (self.f)(x) { + return Some(y); + } + } + None + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F> + where F: FnMut(I::Item) -> Option<B>, +{ + #[inline] + fn next_back(&mut self) -> Option<B> { + for x in self.iter.by_ref().rev() { + if let Some(y) = (self.f)(x) { + return Some(y); + } + } + None + } +} + +/// An iterator that yields the current count and the element during iteration. +/// +/// This `struct` is created by the [`enumerate()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`enumerate()`]: trait.Iterator.html#method.enumerate +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Enumerate<I> { + iter: I, + count: usize, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> Iterator for Enumerate<I> where I: Iterator { + type Item = (usize, <I as Iterator>::Item); + + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so enumerating more than + /// `usize::MAX` elements either produces the wrong result or panics. If + /// debug assertions are enabled, a panic is guaranteed. + /// + /// # Panics + /// + /// Might panic if the index of the element overflows a `usize`. + #[inline] + fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> { + self.iter.next().map(|a| { + let ret = (self.count, a); + // Possible undefined overflow. + self.count += 1; + ret + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> { + self.iter.nth(n).map(|a| { + let i = self.count + n; + self.count = i + 1; + (i, a) + }) + } + + #[inline] + fn count(self) -> usize { + self.iter.count() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> DoubleEndedIterator for Enumerate<I> where + I: ExactSizeIterator + DoubleEndedIterator +{ + #[inline] + fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> { + self.iter.next_back().map(|a| { + let len = self.iter.len(); + // Can safely add, `ExactSizeIterator` promises that the number of + // elements fits into a `usize`. + (self.count + len, a) + }) + } +} + +/// An iterator with a `peek()` that returns an optional reference to the next +/// element. +/// +/// This `struct` is created by the [`peekable()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`peekable()`]: trait.Iterator.html#method.peekable +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Peekable<I: Iterator> { + iter: I, + peeked: Option<I::Item>, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: Iterator> Iterator for Peekable<I> { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option<I::Item> { + match self.peeked { + Some(_) => self.peeked.take(), + None => self.iter.next(), + } + } + + #[inline] + fn count(self) -> usize { + (if self.peeked.is_some() { 1 } else { 0 }) + self.iter.count() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<I::Item> { + match self.peeked { + Some(_) if n == 0 => self.peeked.take(), + Some(_) => { + self.peeked = None; + self.iter.nth(n-1) + }, + None => self.iter.nth(n) + } + } + + #[inline] + fn last(self) -> Option<I::Item> { + self.iter.last().or(self.peeked) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (lo, hi) = self.iter.size_hint(); + if self.peeked.is_some() { + let lo = lo.saturating_add(1); + let hi = hi.and_then(|x| x.checked_add(1)); + (lo, hi) + } else { + (lo, hi) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {} + +impl<I: Iterator> Peekable<I> { + /// Returns a reference to the next() value without advancing the iterator. + /// + /// The `peek()` method will return the value that a call to [`next()`] would + /// return, but does not advance the iterator. Like [`next()`], if there is + /// a value, it's wrapped in a `Some(T)`, but if the iterator is over, it + /// will return `None`. + /// + /// [`next()`]: trait.Iterator.html#tymethod.next + /// + /// Because `peek()` returns reference, and many iterators iterate over + /// references, this leads to a possibly confusing situation where the + /// return value is a double reference. You can see this effect in the + /// examples below, with `&&i32`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let xs = [1, 2, 3]; + /// + /// let mut iter = xs.iter().peekable(); + /// + /// // peek() lets us see into the future + /// assert_eq!(iter.peek(), Some(&&1)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// assert_eq!(iter.next(), Some(&2)); + /// + /// // we can peek() multiple times, the iterator won't advance + /// assert_eq!(iter.peek(), Some(&&3)); + /// assert_eq!(iter.peek(), Some(&&3)); + /// + /// assert_eq!(iter.next(), Some(&3)); + /// + /// // after the iterator is finished, so is peek() + /// assert_eq!(iter.peek(), None); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn peek(&mut self) -> Option<&I::Item> { + if self.peeked.is_none() { + self.peeked = self.iter.next(); + } + match self.peeked { + Some(ref value) => Some(value), + None => None, + } + } + + /// Checks if the iterator has finished iterating. + /// + /// Returns `true` if there are no more elements in the iterator, and + /// `false` if there are. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(peekable_is_empty)] + /// + /// let xs = [1, 2, 3]; + /// + /// let mut iter = xs.iter().peekable(); + /// + /// // there are still elements to iterate over + /// assert_eq!(iter.is_empty(), false); + /// + /// // let's consume the iterator + /// iter.next(); + /// iter.next(); + /// iter.next(); + /// + /// assert_eq!(iter.is_empty(), true); + /// ``` + #[unstable(feature = "peekable_is_empty", issue = "32111")] + #[inline] + pub fn is_empty(&mut self) -> bool { + self.peek().is_none() + } +} + +/// An iterator that rejects elements while `predicate` is true. +/// +/// This `struct` is created by the [`skip_while()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`skip_while()`]: trait.Iterator.html#method.skip_while +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct SkipWhile<I, P> { + iter: I, + flag: bool, + predicate: P, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<I: fmt::Debug, P> fmt::Debug for SkipWhile<I, P> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SkipWhile") + .field("iter", &self.iter) + .field("flag", &self.flag) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: Iterator, P> Iterator for SkipWhile<I, P> + where P: FnMut(&I::Item) -> bool +{ + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option<I::Item> { + for x in self.iter.by_ref() { + if self.flag || !(self.predicate)(&x) { + self.flag = true; + return Some(x); + } + } + None + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +/// An iterator that only accepts elements while `predicate` is true. +/// +/// This `struct` is created by the [`take_while()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`take_while()`]: trait.Iterator.html#method.take_while +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct TakeWhile<I, P> { + iter: I, + flag: bool, + predicate: P, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<I: fmt::Debug, P> fmt::Debug for TakeWhile<I, P> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("TakeWhile") + .field("iter", &self.iter) + .field("flag", &self.flag) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: Iterator, P> Iterator for TakeWhile<I, P> + where P: FnMut(&I::Item) -> bool +{ + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option<I::Item> { + if self.flag { + None + } else { + self.iter.next().and_then(|x| { + if (self.predicate)(&x) { + Some(x) + } else { + self.flag = true; + None + } + }) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +/// An iterator that skips over `n` elements of `iter`. +/// +/// This `struct` is created by the [`skip()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`skip()`]: trait.Iterator.html#method.skip +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Skip<I> { + iter: I, + n: usize +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> Iterator for Skip<I> where I: Iterator { + type Item = <I as Iterator>::Item; + + #[inline] + fn next(&mut self) -> Option<I::Item> { + if self.n == 0 { + self.iter.next() + } else { + let old_n = self.n; + self.n = 0; + self.iter.nth(old_n) + } + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<I::Item> { + // Can't just add n + self.n due to overflow. + if self.n == 0 { + self.iter.nth(n) + } else { + let to_skip = self.n; + self.n = 0; + // nth(n) skips n+1 + if self.iter.nth(to_skip-1).is_none() { + return None; + } + self.iter.nth(n) + } + } + + #[inline] + fn count(self) -> usize { + self.iter.count().saturating_sub(self.n) + } + + #[inline] + fn last(mut self) -> Option<I::Item> { + if self.n == 0 { + self.iter.last() + } else { + let next = self.next(); + if next.is_some() { + // recurse. n should be 0. + self.last().or(next) + } else { + None + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (lower, upper) = self.iter.size_hint(); + + let lower = lower.saturating_sub(self.n); + let upper = upper.map(|x| x.saturating_sub(self.n)); + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> ExactSizeIterator for Skip<I> where I: ExactSizeIterator {} + +#[stable(feature = "double_ended_skip_iterator", since = "1.8.0")] +impl<I> DoubleEndedIterator for Skip<I> where I: DoubleEndedIterator + ExactSizeIterator { + fn next_back(&mut self) -> Option<Self::Item> { + if self.len() > 0 { + self.iter.next_back() + } else { + None + } + } +} + +/// An iterator that only iterates over the first `n` iterations of `iter`. +/// +/// This `struct` is created by the [`take()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`take()`]: trait.Iterator.html#method.take +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Take<I> { + iter: I, + n: usize +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> Iterator for Take<I> where I: Iterator{ + type Item = <I as Iterator>::Item; + + #[inline] + fn next(&mut self) -> Option<<I as Iterator>::Item> { + if self.n != 0 { + self.n -= 1; + self.iter.next() + } else { + None + } + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<I::Item> { + if self.n > n { + self.n -= n + 1; + self.iter.nth(n) + } else { + if self.n > 0 { + self.iter.nth(self.n - 1); + self.n = 0; + } + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (lower, upper) = self.iter.size_hint(); + + let lower = cmp::min(lower, self.n); + + let upper = match upper { + Some(x) if x < self.n => Some(x), + _ => Some(self.n) + }; + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {} + + +/// An iterator to maintain state while iterating another iterator. +/// +/// This `struct` is created by the [`scan()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`scan()`]: trait.Iterator.html#method.scan +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Scan<I, St, F> { + iter: I, + f: F, + state: St, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<I: fmt::Debug, St: fmt::Debug, F> fmt::Debug for Scan<I, St, F> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Scan") + .field("iter", &self.iter) + .field("state", &self.state) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<B, I, St, F> Iterator for Scan<I, St, F> where + I: Iterator, + F: FnMut(&mut St, I::Item) -> Option<B>, +{ + type Item = B; + + #[inline] + fn next(&mut self) -> Option<B> { + self.iter.next().and_then(|a| (self.f)(&mut self.state, a)) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the scan function + } +} + +/// An iterator that maps each element to an iterator, and yields the elements +/// of the produced iterators. +/// +/// This `struct` is created by the [`flat_map()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`flat_map()`]: trait.Iterator.html#method.flat_map +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct FlatMap<I, U: IntoIterator, F> { + iter: I, + f: F, + frontiter: Option<U::IntoIter>, + backiter: Option<U::IntoIter>, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<I: fmt::Debug, U: IntoIterator, F> fmt::Debug for FlatMap<I, U, F> + where U::IntoIter: fmt::Debug +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("FlatMap") + .field("iter", &self.iter) + .field("frontiter", &self.frontiter) + .field("backiter", &self.backiter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F> + where F: FnMut(I::Item) -> U, +{ + type Item = U::Item; + + #[inline] + fn next(&mut self) -> Option<U::Item> { + loop { + if let Some(ref mut inner) = self.frontiter { + if let Some(x) = inner.by_ref().next() { + return Some(x) + } + } + match self.iter.next().map(&mut self.f) { + None => return self.backiter.as_mut().and_then(|it| it.next()), + next => self.frontiter = next.map(IntoIterator::into_iter), + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); + let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); + let lo = flo.saturating_add(blo); + match (self.iter.size_hint(), fhi, bhi) { + ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)), + _ => (lo, None) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F> where + F: FnMut(I::Item) -> U, + U: IntoIterator, + U::IntoIter: DoubleEndedIterator +{ + #[inline] + fn next_back(&mut self) -> Option<U::Item> { + loop { + if let Some(ref mut inner) = self.backiter { + if let Some(y) = inner.next_back() { + return Some(y) + } + } + match self.iter.next_back().map(&mut self.f) { + None => return self.frontiter.as_mut().and_then(|it| it.next_back()), + next => self.backiter = next.map(IntoIterator::into_iter), + } + } + } +} + +/// An iterator that yields `None` forever after the underlying iterator +/// yields `None` once. +/// +/// This `struct` is created by the [`fuse()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`fuse()`]: trait.Iterator.html#method.fuse +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Fuse<I> { + iter: I, + done: bool +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> Iterator for Fuse<I> where I: Iterator { + type Item = <I as Iterator>::Item; + + #[inline] + fn next(&mut self) -> Option<<I as Iterator>::Item> { + if self.done { + None + } else { + let next = self.iter.next(); + self.done = next.is_none(); + next + } + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<I::Item> { + if self.done { + None + } else { + let nth = self.iter.nth(n); + self.done = nth.is_none(); + nth + } + } + + #[inline] + fn last(self) -> Option<I::Item> { + if self.done { + None + } else { + self.iter.last() + } + } + + #[inline] + fn count(self) -> usize { + if self.done { + 0 + } else { + self.iter.count() + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + if self.done { + (0, Some(0)) + } else { + self.iter.size_hint() + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator { + #[inline] + fn next_back(&mut self) -> Option<<I as Iterator>::Item> { + if self.done { + None + } else { + let next = self.iter.next_back(); + self.done = next.is_none(); + next + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> ExactSizeIterator for Fuse<I> where I: ExactSizeIterator {} + +/// An iterator that calls a function with a reference to each element before +/// yielding it. +/// +/// This `struct` is created by the [`inspect()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`inspect()`]: trait.Iterator.html#method.inspect +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Inspect<I, F> { + iter: I, + f: F, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<I: fmt::Debug, F> fmt::Debug for Inspect<I, F> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Inspect") + .field("iter", &self.iter) + .finish() + } +} + +impl<I: Iterator, F> Inspect<I, F> where F: FnMut(&I::Item) { + #[inline] + fn do_inspect(&mut self, elt: Option<I::Item>) -> Option<I::Item> { + if let Some(ref a) = elt { + (self.f)(a); + } + + elt + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: Iterator, F> Iterator for Inspect<I, F> where F: FnMut(&I::Item) { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option<I::Item> { + let next = self.iter.next(); + self.do_inspect(next) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F> + where F: FnMut(&I::Item), +{ + #[inline] + fn next_back(&mut self) -> Option<I::Item> { + let next = self.iter.next_back(); + self.do_inspect(next) + } +} + +/// Objects that can be stepped over in both directions. +/// +/// The `steps_between` function provides a way to efficiently compare +/// two `Step` objects. +#[unstable(feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "27741")] +pub trait Step: PartialOrd + Sized { + /// Steps `self` if possible. + fn step(&self, by: &Self) -> Option<Self>; + + /// Returns the number of steps between two step objects. The count is + /// inclusive of `start` and exclusive of `end`. + /// + /// Returns `None` if it is not possible to calculate `steps_between` + /// without overflow. + fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>; +} + +macro_rules! step_impl_unsigned { + ($($t:ty)*) => ($( + #[unstable(feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "27741")] + impl Step for $t { + #[inline] + fn step(&self, by: &$t) -> Option<$t> { + (*self).checked_add(*by) + } + #[inline] + #[allow(trivial_numeric_casts)] + fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> { + if *by == 0 { return None; } + if *start < *end { + // Note: We assume $t <= usize here + let diff = (*end - *start) as usize; + let by = *by as usize; + if diff % by > 0 { + Some(diff / by + 1) + } else { + Some(diff / by) + } + } else { + Some(0) + } + } + } + )*) +} +macro_rules! step_impl_signed { + ($($t:ty)*) => ($( + #[unstable(feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "27741")] + impl Step for $t { + #[inline] + fn step(&self, by: &$t) -> Option<$t> { + (*self).checked_add(*by) + } + #[inline] + #[allow(trivial_numeric_casts)] + fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> { + if *by == 0 { return None; } + let diff: usize; + let by_u: usize; + if *by > 0 { + if *start >= *end { + return Some(0); + } + // Note: We assume $t <= isize here + // Use .wrapping_sub and cast to usize to compute the + // difference that may not fit inside the range of isize. + diff = (*end as isize).wrapping_sub(*start as isize) as usize; + by_u = *by as usize; + } else { + if *start <= *end { + return Some(0); + } + diff = (*start as isize).wrapping_sub(*end as isize) as usize; + by_u = (*by as isize).wrapping_mul(-1) as usize; + } + if diff % by_u > 0 { + Some(diff / by_u + 1) + } else { + Some(diff / by_u) + } + } + } + )*) +} + +macro_rules! step_impl_no_between { + ($($t:ty)*) => ($( + #[unstable(feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "27741")] + impl Step for $t { + #[inline] + fn step(&self, by: &$t) -> Option<$t> { + (*self).checked_add(*by) + } + #[inline] + fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option<usize> { + None + } + } + )*) +} + +step_impl_unsigned!(usize u8 u16 u32); +step_impl_signed!(isize i8 i16 i32); +#[cfg(target_pointer_width = "64")] +step_impl_unsigned!(u64); +#[cfg(target_pointer_width = "64")] +step_impl_signed!(i64); +// If the target pointer width is not 64-bits, we +// assume here that it is less than 64-bits. +#[cfg(not(target_pointer_width = "64"))] +step_impl_no_between!(u64 i64); + +/// An adapter for stepping range iterators by a custom amount. +/// +/// The resulting iterator handles overflow by stopping. The `A` +/// parameter is the type being iterated over, while `R` is the range +/// type (usually one of `std::ops::{Range, RangeFrom, RangeInclusive}`. +#[derive(Clone, Debug)] +#[unstable(feature = "step_by", reason = "recent addition", + issue = "27741")] +pub struct StepBy<A, R> { + step_by: A, + range: R, +} + +impl<A: Step> ops::RangeFrom<A> { + /// Creates an iterator starting at the same point, but stepping by + /// the given amount at each iteration. + /// + /// # Examples + /// + /// ``` + /// # #![feature(step_by)] + /// + /// for i in (0u8..).step_by(2).take(10) { + /// println!("{}", i); + /// } + /// ``` + /// + /// This prints the first ten even natural integers (0 to 18). + #[unstable(feature = "step_by", reason = "recent addition", + issue = "27741")] + pub fn step_by(self, by: A) -> StepBy<A, Self> { + StepBy { + step_by: by, + range: self + } + } +} + +impl<A: Step> ops::Range<A> { + /// Creates an iterator with the same range, but stepping by the + /// given amount at each iteration. + /// + /// The resulting iterator handles overflow by stopping. + /// + /// # Examples + /// + /// ``` + /// #![feature(step_by)] + /// + /// for i in (0..10).step_by(2) { + /// println!("{}", i); + /// } + /// ``` + /// + /// This prints: + /// + /// ```text + /// 0 + /// 2 + /// 4 + /// 6 + /// 8 + /// ``` + #[unstable(feature = "step_by", reason = "recent addition", + issue = "27741")] + pub fn step_by(self, by: A) -> StepBy<A, Self> { + StepBy { + step_by: by, + range: self + } + } +} + +impl<A: Step> ops::RangeInclusive<A> { + /// Creates an iterator with the same range, but stepping by the + /// given amount at each iteration. + /// + /// The resulting iterator handles overflow by stopping. + /// + /// # Examples + /// + /// ``` + /// #![feature(step_by, inclusive_range_syntax)] + /// + /// for i in (0...10).step_by(2) { + /// println!("{}", i); + /// } + /// ``` + /// + /// This prints: + /// + /// ```text + /// 0 + /// 2 + /// 4 + /// 6 + /// 8 + /// 10 + /// ``` + #[unstable(feature = "step_by", reason = "recent addition", + issue = "27741")] + pub fn step_by(self, by: A) -> StepBy<A, Self> { + StepBy { + step_by: by, + range: self + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A> Iterator for StepBy<A, ops::RangeFrom<A>> where + A: Clone, + for<'a> &'a A: Add<&'a A, Output = A> +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + let mut n = &self.range.start + &self.step_by; + mem::swap(&mut n, &mut self.range.start); + Some(n) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + (usize::MAX, None) // Too bad we can't specify an infinite lower bound + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::Range<A>> { + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + let rev = self.step_by < A::zero(); + if (rev && self.range.start > self.range.end) || + (!rev && self.range.start < self.range.end) + { + match self.range.start.step(&self.step_by) { + Some(mut n) => { + mem::swap(&mut self.range.start, &mut n); + Some(n) + }, + None => { + let mut n = self.range.end.clone(); + mem::swap(&mut self.range.start, &mut n); + Some(n) + } + } + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + match Step::steps_between(&self.range.start, + &self.range.end, + &self.step_by) { + Some(hint) => (hint, Some(hint)), + None => (0, None) + } + } +} + +#[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] +impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> { + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + use ops::RangeInclusive::*; + + // this function has a sort of odd structure due to borrowck issues + // we may need to replace self.range, so borrows of start and end need to end early + + let (finishing, n) = match self.range { + Empty { .. } => return None, // empty iterators yield no values + + NonEmpty { ref mut start, ref mut end } => { + let zero = A::zero(); + let rev = self.step_by < zero; + + // march start towards (maybe past!) end and yield the old value + if (rev && start >= end) || + (!rev && start <= end) + { + match start.step(&self.step_by) { + Some(mut n) => { + mem::swap(start, &mut n); + (None, Some(n)) // yield old value, remain non-empty + }, + None => { + let mut n = end.clone(); + mem::swap(start, &mut n); + (None, Some(n)) // yield old value, remain non-empty + } + } + } else { + // found range in inconsistent state (start at or past end), so become empty + (Some(mem::replace(end, zero)), None) + } + } + }; + + // turn into an empty iterator if we've reached the end + if let Some(end) = finishing { + self.range = Empty { at: end }; + } + + n + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + use ops::RangeInclusive::*; + + match self.range { + Empty { .. } => (0, Some(0)), + + NonEmpty { ref start, ref end } => + match Step::steps_between(start, + end, + &self.step_by) { + Some(hint) => (hint.saturating_add(1), hint.checked_add(1)), + None => (0, None) + } + } + } +} + +macro_rules! range_exact_iter_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl ExactSizeIterator for ops::Range<$t> { } + + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ExactSizeIterator for ops::RangeInclusive<$t> { } + )*) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A: Step + One> Iterator for ops::Range<A> where + for<'a> &'a A: Add<&'a A, Output = A> +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + if self.start < self.end { + let mut n = &self.start + &A::one(); + mem::swap(&mut n, &mut self.start); + Some(n) + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + match Step::steps_between(&self.start, &self.end, &A::one()) { + Some(hint) => (hint, Some(hint)), + None => (0, None) + } + } +} + +// Ranges of u64 and i64 are excluded because they cannot guarantee having +// a length <= usize::MAX, which is required by ExactSizeIterator. +range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32); + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where + for<'a> &'a A: Add<&'a A, Output = A>, + for<'a> &'a A: Sub<&'a A, Output = A> +{ + #[inline] + fn next_back(&mut self) -> Option<A> { + if self.start < self.end { + self.end = &self.end - &A::one(); + Some(self.end.clone()) + } else { + None + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A: Step + One> Iterator for ops::RangeFrom<A> where + for<'a> &'a A: Add<&'a A, Output = A> +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + let mut n = &self.start + &A::one(); + mem::swap(&mut n, &mut self.start); + Some(n) + } +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<A: Step + One> Iterator for ops::RangeInclusive<A> where + for<'a> &'a A: Add<&'a A, Output = A> +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + use ops::RangeInclusive::*; + + // this function has a sort of odd structure due to borrowck issues + // we may need to replace self, so borrows of self.start and self.end need to end early + + let (finishing, n) = match *self { + Empty { .. } => (None, None), // empty iterators yield no values + + NonEmpty { ref mut start, ref mut end } => { + if start == end { + (Some(mem::replace(end, A::one())), Some(mem::replace(start, A::one()))) + } else if start < end { + let one = A::one(); + let mut n = &*start + &one; + mem::swap(&mut n, start); + + // if the iterator is done iterating, it will change from NonEmpty to Empty + // to avoid unnecessary drops or clones, we'll reuse either start or end + // (they are equal now, so it doesn't matter which) + // to pull out end, we need to swap something back in -- use the previously + // created A::one() as a dummy value + + (if n == *end { Some(mem::replace(end, one)) } else { None }, + // ^ are we done yet? + Some(n)) // < the value to output + } else { + (Some(mem::replace(start, A::one())), None) + } + } + }; + + // turn into an empty iterator if this is the last value + if let Some(end) = finishing { + *self = Empty { at: end }; + } + + n + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + use ops::RangeInclusive::*; + + match *self { + Empty { .. } => (0, Some(0)), + + NonEmpty { ref start, ref end } => + match Step::steps_between(start, end, &A::one()) { + Some(hint) => (hint.saturating_add(1), hint.checked_add(1)), + None => (0, None), + } + } + } +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<A: Step + One> DoubleEndedIterator for ops::RangeInclusive<A> where + for<'a> &'a A: Add<&'a A, Output = A>, + for<'a> &'a A: Sub<&'a A, Output = A> +{ + #[inline] + fn next_back(&mut self) -> Option<A> { + use ops::RangeInclusive::*; + + // see Iterator::next for comments + + let (finishing, n) = match *self { + Empty { .. } => return None, + + NonEmpty { ref mut start, ref mut end } => { + if start == end { + (Some(mem::replace(start, A::one())), Some(mem::replace(end, A::one()))) + } else if start < end { + let one = A::one(); + let mut n = &*end - &one; + mem::swap(&mut n, end); + + (if n == *start { Some(mem::replace(start, one)) } else { None }, + Some(n)) + } else { + (Some(mem::replace(end, A::one())), None) + } + } + }; + + if let Some(start) = finishing { + *self = Empty { at: start }; + } + + n + } +} + +/// An iterator that repeats an element endlessly. +/// +/// This `struct` is created by the [`repeat()`] function. See its documentation for more. +/// +/// [`repeat()`]: fn.repeat.html +#[derive(Clone, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Repeat<A> { + element: A +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A: Clone> Iterator for Repeat<A> { + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { Some(self.element.clone()) } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A: Clone> DoubleEndedIterator for Repeat<A> { + #[inline] + fn next_back(&mut self) -> Option<A> { Some(self.element.clone()) } +} + +/// Creates a new iterator that endlessly repeats a single element. +/// +/// The `repeat()` function repeats a single value over and over and over and +/// over and over and 🔁. +/// +/// Infinite iterators like `repeat()` are often used with adapters like +/// [`take()`], in order to make them finite. +/// +/// [`take()`]: trait.Iterator.html#method.take +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter; +/// +/// // the number four 4ever: +/// let mut fours = iter::repeat(4); +/// +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// +/// // yup, still four +/// assert_eq!(Some(4), fours.next()); +/// ``` +/// +/// Going finite with [`take()`]: +/// +/// ``` +/// use std::iter; +/// +/// // that last example was too many fours. Let's only have four fours. +/// let mut four_fours = iter::repeat(4).take(4); +/// +/// assert_eq!(Some(4), four_fours.next()); +/// assert_eq!(Some(4), four_fours.next()); +/// assert_eq!(Some(4), four_fours.next()); +/// assert_eq!(Some(4), four_fours.next()); +/// +/// // ... and now we're done +/// assert_eq!(None, four_fours.next()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn repeat<T: Clone>(elt: T) -> Repeat<T> { + Repeat{element: elt} +} + +/// An iterator that yields nothing. +/// +/// This `struct` is created by the [`empty()`] function. See its documentation for more. +/// +/// [`empty()`]: fn.empty.html +#[stable(feature = "iter_empty", since = "1.2.0")] +pub struct Empty<T>(marker::PhantomData<T>); + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<T> fmt::Debug for Empty<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("Empty") + } +} + +#[stable(feature = "iter_empty", since = "1.2.0")] +impl<T> Iterator for Empty<T> { + type Item = T; + + fn next(&mut self) -> Option<T> { + None + } + + fn size_hint(&self) -> (usize, Option<usize>){ + (0, Some(0)) + } +} + +#[stable(feature = "iter_empty", since = "1.2.0")] +impl<T> DoubleEndedIterator for Empty<T> { + fn next_back(&mut self) -> Option<T> { + None + } +} + +#[stable(feature = "iter_empty", since = "1.2.0")] +impl<T> ExactSizeIterator for Empty<T> { + fn len(&self) -> usize { + 0 + } +} + +// not #[derive] because that adds a Clone bound on T, +// which isn't necessary. +#[stable(feature = "iter_empty", since = "1.2.0")] +impl<T> Clone for Empty<T> { + fn clone(&self) -> Empty<T> { + Empty(marker::PhantomData) + } +} + +// not #[derive] because that adds a Default bound on T, +// which isn't necessary. +#[stable(feature = "iter_empty", since = "1.2.0")] +impl<T> Default for Empty<T> { + fn default() -> Empty<T> { + Empty(marker::PhantomData) + } +} + +/// Creates an iterator that yields nothing. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter; +/// +/// // this could have been an iterator over i32, but alas, it's just not. +/// let mut nope = iter::empty::<i32>(); +/// +/// assert_eq!(None, nope.next()); +/// ``` +#[stable(feature = "iter_empty", since = "1.2.0")] +pub fn empty<T>() -> Empty<T> { + Empty(marker::PhantomData) +} + +/// An iterator that yields an element exactly once. +/// +/// This `struct` is created by the [`once()`] function. See its documentation for more. +/// +/// [`once()`]: fn.once.html +#[derive(Clone, Debug)] +#[stable(feature = "iter_once", since = "1.2.0")] +pub struct Once<T> { + inner: ::option::IntoIter<T> +} + +#[stable(feature = "iter_once", since = "1.2.0")] +impl<T> Iterator for Once<T> { + type Item = T; + + fn next(&mut self) -> Option<T> { + self.inner.next() + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.inner.size_hint() + } +} + +#[stable(feature = "iter_once", since = "1.2.0")] +impl<T> DoubleEndedIterator for Once<T> { + fn next_back(&mut self) -> Option<T> { + self.inner.next_back() + } +} + +#[stable(feature = "iter_once", since = "1.2.0")] +impl<T> ExactSizeIterator for Once<T> { + fn len(&self) -> usize { + self.inner.len() + } +} + +/// Creates an iterator that yields an element exactly once. +/// +/// This is commonly used to adapt a single value into a [`chain()`] of other +/// kinds of iteration. Maybe you have an iterator that covers almost +/// everything, but you need an extra special case. Maybe you have a function +/// which works on iterators, but you only need to process one value. +/// +/// [`chain()`]: trait.Iterator.html#method.chain +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter; +/// +/// // one is the loneliest number +/// let mut one = iter::once(1); +/// +/// assert_eq!(Some(1), one.next()); +/// +/// // just one, that's all we get +/// assert_eq!(None, one.next()); +/// ``` +/// +/// Chaining together with another iterator. Let's say that we want to iterate +/// over each file of the `.foo` directory, but also a configuration file, +/// `.foorc`: +/// +/// ```no_run +/// use std::iter; +/// use std::fs; +/// use std::path::PathBuf; +/// +/// let dirs = fs::read_dir(".foo").unwrap(); +/// +/// // we need to convert from an iterator of DirEntry-s to an iterator of +/// // PathBufs, so we use map +/// let dirs = dirs.map(|file| file.unwrap().path()); +/// +/// // now, our iterator just for our config file +/// let config = iter::once(PathBuf::from(".foorc")); +/// +/// // chain the two iterators together into one big iterator +/// let files = dirs.chain(config); +/// +/// // this will give us all of the files in .foo as well as .foorc +/// for f in files { +/// println!("{:?}", f); +/// } +/// ``` +#[stable(feature = "iter_once", since = "1.2.0")] +pub fn once<T>(value: T) -> Once<T> { + Once { inner: Some(value).into_iter() } +} diff --git a/libcore/lib.rs b/libcore/lib.rs new file mode 100644 index 0000000..fa5e905 --- /dev/null +++ b/libcore/lib.rs @@ -0,0 +1,156 @@ +// 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. + +//! # The Rust Core Library +//! +//! The Rust Core Library is the dependency-free[^free] foundation of [The +//! Rust Standard Library](../std/index.html). It is the portable glue +//! between the language and its libraries, defining the intrinsic and +//! primitive building blocks of all Rust code. It links to no +//! upstream libraries, no system libraries, and no libc. +//! +//! [^free]: Strictly speaking, there are some symbols which are needed but +//! they aren't always necessary. +//! +//! The core library is *minimal*: it isn't even aware of heap allocation, +//! nor does it provide concurrency or I/O. These things require +//! platform integration, and this library is platform-agnostic. +//! +//! # How to use the core library +//! +// FIXME: Fill me in with more detail when the interface settles +//! This library is built on the assumption of a few existing symbols: +//! +//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are +//! often generated by LLVM. Additionally, this library can make explicit +//! calls to these functions. Their signatures are the same as found in C. +//! These functions are often provided by the system libc, but can also be +//! provided by the [rlibc crate](https://crates.io/crates/rlibc). +//! +//! * `rust_begin_unwind` - This function takes three arguments, a +//! `fmt::Arguments`, a `&str`, and a `u32`. These three arguments dictate +//! the panic message, the file at which panic was invoked, and the line. +//! It is up to consumers of this core library to define this panic +//! function; it is only required to never return. + +// Since libcore defines many fundamental lang items, all tests live in a +// separate crate, libcoretest, to avoid bizarre issues. + +#![crate_name = "core"] +#![stable(feature = "core", since = "1.6.0")] +#![crate_type = "rlib"] +#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", + issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", + test(no_crate_inject, attr(deny(warnings))), + test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] + +#![no_core] +#![deny(missing_docs)] +#![deny(missing_debug_implementations)] +#![cfg_attr(not(stage0), deny(warnings))] + +#![feature(allow_internal_unstable)] +#![feature(associated_type_defaults)] +#![feature(concat_idents)] +#![feature(const_fn)] +#![feature(custom_attribute)] +#![feature(fundamental)] +#![feature(inclusive_range_syntax)] +#![feature(intrinsics)] +#![feature(lang_items)] +#![feature(no_core)] +#![feature(on_unimplemented)] +#![feature(optin_builtin_traits)] +#![feature(reflect)] +#![feature(unwind_attributes)] +#![feature(repr_simd, platform_intrinsics)] +#![feature(rustc_attrs)] +#![feature(specialization)] +#![feature(staged_api)] +#![feature(unboxed_closures)] +#![feature(question_mark)] + +#[macro_use] +mod macros; + +#[path = "num/float_macros.rs"] +#[macro_use] +mod float_macros; + +#[path = "num/int_macros.rs"] +#[macro_use] +mod int_macros; + +#[path = "num/uint_macros.rs"] +#[macro_use] +mod uint_macros; + +#[path = "num/isize.rs"] pub mod isize; +#[path = "num/i8.rs"] pub mod i8; +#[path = "num/i16.rs"] pub mod i16; +#[path = "num/i32.rs"] pub mod i32; +#[path = "num/i64.rs"] pub mod i64; + +#[path = "num/usize.rs"] pub mod usize; +#[path = "num/u8.rs"] pub mod u8; +#[path = "num/u16.rs"] pub mod u16; +#[path = "num/u32.rs"] pub mod u32; +#[path = "num/u64.rs"] pub mod u64; + +#[path = "num/f32.rs"] pub mod f32; +#[path = "num/f64.rs"] pub mod f64; + +#[macro_use] +pub mod num; + +/* The libcore prelude, not as all-encompassing as the libstd prelude */ + +pub mod prelude; + +/* Core modules for ownership management */ + +pub mod intrinsics; +pub mod mem; +pub mod nonzero; +pub mod ptr; + +/* Core language traits */ + +pub mod marker; +pub mod ops; +pub mod cmp; +pub mod clone; +pub mod default; +pub mod convert; +pub mod borrow; + +/* Core types and methods on primitives */ + +pub mod any; +pub mod array; +pub mod sync; +pub mod cell; +pub mod char; +pub mod panicking; +pub mod iter; +pub mod option; +pub mod raw; +pub mod result; + +pub mod slice; +pub mod str; +pub mod hash; +pub mod fmt; + +// note: does not need to be public +mod tuple; diff --git a/libcore/macros.rs b/libcore/macros.rs new file mode 100644 index 0000000..f923668 --- /dev/null +++ b/libcore/macros.rs @@ -0,0 +1,366 @@ +// 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. + +/// Entry point of thread panic, for details, see std::macros +#[macro_export] +#[allow_internal_unstable] +#[stable(feature = "core", since = "1.6.0")] +macro_rules! panic { + () => ( + panic!("explicit panic") + ); + ($msg:expr) => ({ + static _MSG_FILE_LINE: (&'static str, &'static str, u32) = ($msg, file!(), line!()); + $crate::panicking::panic(&_MSG_FILE_LINE) + }); + ($fmt:expr, $($arg:tt)*) => ({ + // The leading _'s are to avoid dead code warnings if this is + // used inside a dead function. Just `#[allow(dead_code)]` is + // insufficient, since the user may have + // `#[forbid(dead_code)]` and which cannot be overridden. + static _FILE_LINE: (&'static str, u32) = (file!(), line!()); + $crate::panicking::panic_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE) + }); +} + +/// Ensure that a boolean expression is `true` at runtime. +/// +/// This will invoke the `panic!` macro if the provided expression cannot be +/// evaluated to `true` at runtime. +/// +/// This macro has a second version, where a custom panic message can be provided. +/// +/// # Examples +/// +/// ``` +/// // the panic message for these assertions is the stringified value of the +/// // expression given. +/// assert!(true); +/// +/// fn some_computation() -> bool { true } // a very simple function +/// +/// assert!(some_computation()); +/// +/// // assert with a custom message +/// let x = true; +/// assert!(x, "x wasn't true!"); +/// +/// let a = 3; let b = 27; +/// assert!(a + b == 30, "a = {}, b = {}", a, b); +/// ``` +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +macro_rules! assert { + ($cond:expr) => ( + if !$cond { + panic!(concat!("assertion failed: ", stringify!($cond))) + } + ); + ($cond:expr, $($arg:tt)+) => ( + if !$cond { + panic!($($arg)+) + } + ); +} + +/// Asserts that two expressions are equal to each other. +/// +/// On panic, this macro will print the values of the expressions with their +/// debug representations. +/// +/// # Examples +/// +/// ``` +/// let a = 3; +/// let b = 1 + 2; +/// assert_eq!(a, b); +/// ``` +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +macro_rules! assert_eq { + ($left:expr , $right:expr) => ({ + match (&($left), &($right)) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + panic!("assertion failed: `(left == right)` \ + (left: `{:?}`, right: `{:?}`)", left_val, right_val) + } + } + } + }) +} + +/// Ensure that a boolean expression is `true` at runtime. +/// +/// This will invoke the `panic!` macro if the provided expression cannot be +/// evaluated to `true` at runtime. +/// +/// Like `assert!`, this macro also has a second version, where a custom panic +/// message can be provided. +/// +/// Unlike `assert!`, `debug_assert!` statements are only enabled in non +/// optimized builds by default. An optimized build will omit all +/// `debug_assert!` statements unless `-C debug-assertions` is passed to the +/// compiler. This makes `debug_assert!` useful for checks that are too +/// expensive to be present in a release build but may be helpful during +/// development. +/// +/// # Examples +/// +/// ``` +/// // the panic message for these assertions is the stringified value of the +/// // expression given. +/// debug_assert!(true); +/// +/// fn some_expensive_computation() -> bool { true } // a very simple function +/// debug_assert!(some_expensive_computation()); +/// +/// // assert with a custom message +/// let x = true; +/// debug_assert!(x, "x wasn't true!"); +/// +/// let a = 3; let b = 27; +/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b); +/// ``` +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +macro_rules! debug_assert { + ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); }) +} + +/// Asserts that two expressions are equal to each other. +/// +/// On panic, this macro will print the values of the expressions with their +/// debug representations. +/// +/// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non +/// optimized builds by default. An optimized build will omit all +/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the +/// compiler. This makes `debug_assert_eq!` useful for checks that are too +/// expensive to be present in a release build but may be helpful during +/// development. +/// +/// # Examples +/// +/// ``` +/// let a = 3; +/// let b = 1 + 2; +/// debug_assert_eq!(a, b); +/// ``` +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +macro_rules! debug_assert_eq { + ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); }) +} + +/// Helper macro for unwrapping `Result` values while returning early with an +/// error if the value of the expression is `Err`. Can only be used in +/// functions that return `Result` because of the early return of `Err` that +/// it provides. +/// +/// # Examples +/// +/// ``` +/// use std::io; +/// use std::fs::File; +/// use std::io::prelude::*; +/// +/// fn write_to_file_using_try() -> Result<(), io::Error> { +/// let mut file = try!(File::create("my_best_friends.txt")); +/// try!(file.write_all(b"This is a list of my best friends.")); +/// println!("I wrote to the file"); +/// Ok(()) +/// } +/// // This is equivalent to: +/// fn write_to_file_using_match() -> Result<(), io::Error> { +/// let mut file = try!(File::create("my_best_friends.txt")); +/// match file.write_all(b"This is a list of my best friends.") { +/// Ok(_) => (), +/// Err(e) => return Err(e), +/// } +/// println!("I wrote to the file"); +/// Ok(()) +/// } +/// ``` +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +macro_rules! try { + ($expr:expr) => (match $expr { + $crate::result::Result::Ok(val) => val, + $crate::result::Result::Err(err) => { + return $crate::result::Result::Err($crate::convert::From::from(err)) + } + }) +} + +/// Use the `format!` syntax to write data into a buffer. +/// +/// This macro is typically used with a buffer of `&mut `[`Write`][write]. +/// +/// See [`std::fmt`][fmt] for more information on format syntax. +/// +/// [fmt]: ../std/fmt/index.html +/// [write]: ../std/io/trait.Write.html +/// +/// # Examples +/// +/// ``` +/// use std::io::Write; +/// +/// let mut w = Vec::new(); +/// write!(&mut w, "test").unwrap(); +/// write!(&mut w, "formatted {}", "arguments").unwrap(); +/// +/// assert_eq!(w, b"testformatted arguments"); +/// ``` +#[macro_export] +#[stable(feature = "core", since = "1.6.0")] +macro_rules! write { + ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*))) +} + +/// Use the `format!` syntax to write data into a buffer, appending a newline. +/// +/// This macro is typically used with a buffer of `&mut `[`Write`][write]. +/// +/// See [`std::fmt`][fmt] for more information on format syntax. +/// +/// [fmt]: ../std/fmt/index.html +/// [write]: ../std/io/trait.Write.html +/// +/// # Examples +/// +/// ``` +/// use std::io::Write; +/// +/// let mut w = Vec::new(); +/// writeln!(&mut w, "test").unwrap(); +/// writeln!(&mut w, "formatted {}", "arguments").unwrap(); +/// +/// assert_eq!(&w[..], "test\nformatted arguments\n".as_bytes()); +/// ``` +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +macro_rules! writeln { + ($dst:expr, $fmt:expr) => ( + write!($dst, concat!($fmt, "\n")) + ); + ($dst:expr, $fmt:expr, $($arg:tt)*) => ( + write!($dst, concat!($fmt, "\n"), $($arg)*) + ); +} + +/// A utility macro for indicating unreachable code. +/// +/// This is useful any time that the compiler can't determine that some code is unreachable. For +/// example: +/// +/// * Match arms with guard conditions. +/// * Loops that dynamically terminate. +/// * Iterators that dynamically terminate. +/// +/// # Panics +/// +/// This will always panic. +/// +/// # Examples +/// +/// Match arms: +/// +/// ``` +/// # #[allow(dead_code)] +/// fn foo(x: Option<i32>) { +/// match x { +/// Some(n) if n >= 0 => println!("Some(Non-negative)"), +/// Some(n) if n < 0 => println!("Some(Negative)"), +/// Some(_) => unreachable!(), // compile error if commented out +/// None => println!("None") +/// } +/// } +/// ``` +/// +/// Iterators: +/// +/// ``` +/// # #[allow(dead_code)] +/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3 +/// for i in 0.. { +/// if 3*i < i { panic!("u32 overflow"); } +/// if x < 3*i { return i-1; } +/// } +/// unreachable!(); +/// } +/// ``` +#[macro_export] +#[stable(feature = "core", since = "1.6.0")] +macro_rules! unreachable { + () => ({ + panic!("internal error: entered unreachable code") + }); + ($msg:expr) => ({ + unreachable!("{}", $msg) + }); + ($fmt:expr, $($arg:tt)*) => ({ + panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*) + }); +} + +/// A standardized placeholder for marking unfinished code. It panics with the +/// message `"not yet implemented"` when executed. +/// +/// This can be useful if you are prototyping and are just looking to have your +/// code typecheck, or if you're implementing a trait that requires multiple +/// methods, and you're only planning on using one of them. +/// +/// # Examples +/// +/// Here's an example of some in-progress code. We have a trait `Foo`: +/// +/// ``` +/// trait Foo { +/// fn bar(&self); +/// fn baz(&self); +/// } +/// ``` +/// +/// We want to implement `Foo` on one of our types, but we also want to work on +/// just `bar()` first. In order for our code to compile, we need to implement +/// `baz()`, so we can use `unimplemented!`: +/// +/// ``` +/// # trait Foo { +/// # fn bar(&self); +/// # fn baz(&self); +/// # } +/// struct MyStruct; +/// +/// impl Foo for MyStruct { +/// fn bar(&self) { +/// // implementation goes here +/// } +/// +/// fn baz(&self) { +/// // let's not worry about implementing baz() for now +/// unimplemented!(); +/// } +/// } +/// +/// fn main() { +/// let s = MyStruct; +/// s.bar(); +/// +/// // we aren't even using baz() yet, so this is fine. +/// } +/// ``` +#[macro_export] +#[stable(feature = "core", since = "1.6.0")] +macro_rules! unimplemented { + () => (panic!("not yet implemented")) +} diff --git a/libcore/marker.rs b/libcore/marker.rs new file mode 100644 index 0000000..1ed2a21 --- /dev/null +++ b/libcore/marker.rs @@ -0,0 +1,463 @@ +// Copyright 2012-2015 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. + +//! Primitive traits and marker types representing basic 'kinds' of types. +//! +//! Rust types can be classified in various useful ways according to +//! intrinsic properties of the type. These classifications, often called +//! 'kinds', are represented as traits. + +#![stable(feature = "rust1", since = "1.0.0")] + +use clone::Clone; +use cmp; +use default::Default; +use option::Option; +use hash::Hash; +use hash::Hasher; + +/// Types that can be transferred across thread boundaries. +/// +/// This trait is automatically derived when the compiler determines it's appropriate. +#[stable(feature = "rust1", since = "1.0.0")] +#[lang = "send"] +#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] +pub unsafe trait Send { + // empty. +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Send for .. { } + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> !Send for *const T { } +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> !Send for *mut T { } + +/// Types with a constant size known at compile-time. +/// +/// All type parameters which can be bounded have an implicit bound of `Sized`. The special syntax +/// `?Sized` can be used to remove this bound if it is not appropriate. +/// +/// ``` +/// # #![allow(dead_code)] +/// struct Foo<T>(T); +/// struct Bar<T: ?Sized>(T); +/// +/// // struct FooUse(Foo<[i32]>); // error: Sized is not implemented for [i32] +/// struct BarUse(Bar<[i32]>); // OK +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +#[lang = "sized"] +#[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] +#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable +pub trait Sized { + // Empty. +} + +/// Types that can be "unsized" to a dynamically sized type. +#[unstable(feature = "unsize", issue = "27732")] +#[lang="unsize"] +pub trait Unsize<T: ?Sized> { + // Empty. +} + +/// Types that can be copied by simply copying bits (i.e. `memcpy`). +/// +/// By default, variable bindings have 'move semantics.' In other +/// words: +/// +/// ``` +/// #[derive(Debug)] +/// struct Foo; +/// +/// let x = Foo; +/// +/// let y = x; +/// +/// // `x` has moved into `y`, and so cannot be used +/// +/// // println!("{:?}", x); // error: use of moved value +/// ``` +/// +/// However, if a type implements `Copy`, it instead has 'copy semantics': +/// +/// ``` +/// // we can just derive a `Copy` implementation +/// #[derive(Debug, Copy, Clone)] +/// struct Foo; +/// +/// let x = Foo; +/// +/// let y = x; +/// +/// // `y` is a copy of `x` +/// +/// println!("{:?}", x); // A-OK! +/// ``` +/// +/// It's important to note that in these two examples, the only difference is if you are allowed to +/// access `x` after the assignment: a move is also a bitwise copy under the hood. +/// +/// ## When can my type be `Copy`? +/// +/// A type can implement `Copy` if all of its components implement `Copy`. For example, this +/// `struct` can be `Copy`: +/// +/// ``` +/// # #[allow(dead_code)] +/// struct Point { +/// x: i32, +/// y: i32, +/// } +/// ``` +/// +/// A `struct` can be `Copy`, and `i32` is `Copy`, so therefore, `Point` is eligible to be `Copy`. +/// +/// ``` +/// # #![allow(dead_code)] +/// # struct Point; +/// struct PointList { +/// points: Vec<Point>, +/// } +/// ``` +/// +/// The `PointList` `struct` cannot implement `Copy`, because `Vec<T>` is not `Copy`. If we +/// attempt to derive a `Copy` implementation, we'll get an error: +/// +/// ```text +/// the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy` +/// ``` +/// +/// ## How can I implement `Copy`? +/// +/// There are two ways to implement `Copy` on your type: +/// +/// ``` +/// #[derive(Copy, Clone)] +/// struct MyStruct; +/// ``` +/// +/// and +/// +/// ``` +/// struct MyStruct; +/// impl Copy for MyStruct {} +/// impl Clone for MyStruct { fn clone(&self) -> MyStruct { *self } } +/// ``` +/// +/// There is a small difference between the two: the `derive` strategy will also place a `Copy` +/// bound on type parameters, which isn't always desired. +/// +/// ## When can my type _not_ be `Copy`? +/// +/// Some types can't be copied safely. For example, copying `&mut T` would create an aliased +/// mutable reference, and copying `String` would result in two attempts to free the same buffer. +/// +/// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's +/// managing some resource besides its own `size_of::<T>()` bytes. +/// +/// ## When should my type be `Copy`? +/// +/// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing +/// to consider though: if you think your type may _not_ be able to implement `Copy` in the future, +/// then it might be prudent to not implement `Copy`. This is because removing `Copy` is a breaking +/// change: that second example would fail to compile if we made `Foo` non-`Copy`. +/// +/// # Derivable +/// +/// This trait can be used with `#[derive]`. +#[stable(feature = "rust1", since = "1.0.0")] +#[lang = "copy"] +pub trait Copy : Clone { + // Empty. +} + +/// Types that can be safely shared between threads when aliased. +/// +/// The precise definition is: a type `T` is `Sync` if `&T` is +/// thread-safe. In other words, there is no possibility of data races +/// when passing `&T` references between threads. +/// +/// As one would expect, primitive types like `u8` and `f64` are all +/// `Sync`, and so are simple aggregate types containing them (like +/// tuples, structs and enums). More instances of basic `Sync` types +/// include "immutable" types like `&T` and those with simple +/// inherited mutability, such as `Box<T>`, `Vec<T>` and most other +/// collection types. (Generic parameters need to be `Sync` for their +/// container to be `Sync`.) +/// +/// A somewhat surprising consequence of the definition is `&mut T` is +/// `Sync` (if `T` is `Sync`) even though it seems that it might +/// provide unsynchronized mutation. The trick is a mutable reference +/// stored in an aliasable reference (that is, `& &mut T`) becomes +/// read-only, as if it were a `& &T`, hence there is no risk of a data +/// race. +/// +/// Types that are not `Sync` are those that have "interior +/// mutability" in a non-thread-safe way, such as `Cell` and `RefCell` +/// in `std::cell`. These types allow for mutation of their contents +/// even when in an immutable, aliasable slot, e.g. the contents of +/// `&Cell<T>` can be `.set`, and do not ensure data races are +/// impossible, hence they cannot be `Sync`. A higher level example +/// of a non-`Sync` type is the reference counted pointer +/// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new +/// reference, which modifies the reference counts in a non-atomic +/// way. +/// +/// For cases when one does need thread-safe interior mutability, +/// types like the atomics in `std::sync` and `Mutex` & `RWLock` in +/// the `sync` crate do ensure that any mutation cannot cause data +/// races. Hence these types are `Sync`. +/// +/// Any types with interior mutability must also use the `std::cell::UnsafeCell` +/// wrapper around the value(s) which can be mutated when behind a `&` +/// reference; not doing this is undefined behavior (for example, +/// `transmute`-ing from `&T` to `&mut T` is invalid). +/// +/// This trait is automatically derived when the compiler determines it's appropriate. +#[stable(feature = "rust1", since = "1.0.0")] +#[lang = "sync"] +#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] +pub unsafe trait Sync { + // Empty +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Sync for .. { } + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> !Sync for *const T { } +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> !Sync for *mut T { } + +macro_rules! impls{ + ($t: ident) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:?Sized> Hash for $t<T> { + #[inline] + fn hash<H: Hasher>(&self, _: &mut H) { + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:?Sized> cmp::PartialEq for $t<T> { + fn eq(&self, _other: &$t<T>) -> bool { + true + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:?Sized> cmp::Eq for $t<T> { + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:?Sized> cmp::PartialOrd for $t<T> { + fn partial_cmp(&self, _other: &$t<T>) -> Option<cmp::Ordering> { + Option::Some(cmp::Ordering::Equal) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:?Sized> cmp::Ord for $t<T> { + fn cmp(&self, _other: &$t<T>) -> cmp::Ordering { + cmp::Ordering::Equal + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:?Sized> Copy for $t<T> { } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:?Sized> Clone for $t<T> { + fn clone(&self) -> $t<T> { + $t + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T:?Sized> Default for $t<T> { + fn default() -> $t<T> { + $t + } + } + ) +} + +/// `PhantomData<T>` allows you to describe that a type acts as if it stores a value of type `T`, +/// even though it does not. This allows you to inform the compiler about certain safety properties +/// of your code. +/// +/// For a more in-depth explanation of how to use `PhantomData<T>`, please see [the Nomicon]. +/// +/// [the Nomicon]: ../../nomicon/phantom-data.html +/// +/// # A ghastly note 👻👻👻 +/// +/// Though they both have scary names, `PhantomData<T>` and 'phantom types' are related, but not +/// identical. Phantom types are a more general concept that don't require `PhantomData<T>` to +/// implement, but `PhantomData<T>` is the most common way to implement them in a correct manner. +/// +/// # Examples +/// +/// ## Unused lifetime parameter +/// +/// Perhaps the most common time that `PhantomData` is required is +/// with a struct that has an unused lifetime parameter, typically as +/// part of some unsafe code. For example, here is a struct `Slice` +/// that has two pointers of type `*const T`, presumably pointing into +/// an array somewhere: +/// +/// ```ignore +/// struct Slice<'a, T> { +/// start: *const T, +/// end: *const T, +/// } +/// ``` +/// +/// The intention is that the underlying data is only valid for the +/// lifetime `'a`, so `Slice` should not outlive `'a`. However, this +/// intent is not expressed in the code, since there are no uses of +/// the lifetime `'a` and hence it is not clear what data it applies +/// to. We can correct this by telling the compiler to act *as if* the +/// `Slice` struct contained a borrowed reference `&'a T`: +/// +/// ``` +/// use std::marker::PhantomData; +/// +/// # #[allow(dead_code)] +/// struct Slice<'a, T: 'a> { +/// start: *const T, +/// end: *const T, +/// phantom: PhantomData<&'a T> +/// } +/// ``` +/// +/// This also in turn requires that we annotate `T:'a`, indicating +/// that `T` is a type that can be borrowed for the lifetime `'a`. +/// +/// ## Unused type parameters +/// +/// It sometimes happens that there are unused type parameters that +/// indicate what type of data a struct is "tied" to, even though that +/// data is not actually found in the struct itself. Here is an +/// example where this arises when handling external resources over a +/// foreign function interface. `PhantomData<T>` can prevent +/// mismatches by enforcing types in the method implementations: +/// +/// ``` +/// # #![allow(dead_code)] +/// # trait ResType { fn foo(&self); } +/// # struct ParamType; +/// # mod foreign_lib { +/// # pub fn new(_: usize) -> *mut () { 42 as *mut () } +/// # pub fn do_stuff(_: *mut (), _: usize) {} +/// # } +/// # fn convert_params(_: ParamType) -> usize { 42 } +/// use std::marker::PhantomData; +/// use std::mem; +/// +/// struct ExternalResource<R> { +/// resource_handle: *mut (), +/// resource_type: PhantomData<R>, +/// } +/// +/// impl<R: ResType> ExternalResource<R> { +/// fn new() -> ExternalResource<R> { +/// let size_of_res = mem::size_of::<R>(); +/// ExternalResource { +/// resource_handle: foreign_lib::new(size_of_res), +/// resource_type: PhantomData, +/// } +/// } +/// +/// fn do_stuff(&self, param: ParamType) { +/// let foreign_params = convert_params(param); +/// foreign_lib::do_stuff(self.resource_handle, foreign_params); +/// } +/// } +/// ``` +/// +/// ## Indicating ownership +/// +/// Adding a field of type `PhantomData<T>` also indicates that your +/// struct owns data of type `T`. This in turn implies that when your +/// struct is dropped, it may in turn drop one or more instances of +/// the type `T`, though that may not be apparent from the other +/// structure of the type itself. This is commonly necessary if the +/// structure is using a raw pointer like `*mut T` whose referent +/// may be dropped when the type is dropped, as a `*mut T` is +/// otherwise not treated as owned. +/// +/// If your struct does not in fact *own* the data of type `T`, it is +/// better to use a reference type, like `PhantomData<&'a T>` +/// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so +/// as not to indicate ownership. +#[lang = "phantom_data"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct PhantomData<T:?Sized>; + +impls! { PhantomData } + +mod impls { + use super::{Send, Sync, Sized}; + + #[stable(feature = "rust1", since = "1.0.0")] + unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {} + #[stable(feature = "rust1", since = "1.0.0")] + unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {} +} + +/// Types that can be reflected over. +/// +/// This trait is implemented for all types. Its purpose is to ensure +/// that when you write a generic function that will employ +/// reflection, that must be reflected (no pun intended) in the +/// generic bounds of that function. Here is an example: +/// +/// ``` +/// #![feature(reflect_marker)] +/// use std::marker::Reflect; +/// use std::any::Any; +/// +/// # #[allow(dead_code)] +/// fn foo<T: Reflect + 'static>(x: &T) { +/// let any: &Any = x; +/// if any.is::<u32>() { println!("u32"); } +/// } +/// ``` +/// +/// Without the declaration `T: Reflect`, `foo` would not type check +/// (note: as a matter of style, it would be preferable to write +/// `T: Any`, because `T: Any` implies `T: Reflect` and `T: 'static`, but +/// we use `Reflect` here to show how it works). The `Reflect` bound +/// thus serves to alert `foo`'s caller to the fact that `foo` may +/// behave differently depending on whether `T = u32` or not. In +/// particular, thanks to the `Reflect` bound, callers know that a +/// function declared like `fn bar<T>(...)` will always act in +/// precisely the same way no matter what type `T` is supplied, +/// because there are no bounds declared on `T`. (The ability for a +/// caller to reason about what a function may do based solely on what +/// generic bounds are declared is often called the ["parametricity +/// property"][1].) +/// +/// [1]: http://en.wikipedia.org/wiki/Parametricity +#[rustc_reflect_like] +#[unstable(feature = "reflect_marker", + reason = "requires RFC and more experience", + issue = "27749")] +#[rustc_on_unimplemented = "`{Self}` does not implement `Any`; \ + ensure all type parameters are bounded by `Any`"] +pub trait Reflect {} + +#[unstable(feature = "reflect_marker", + reason = "requires RFC and more experience", + issue = "27749")] +impl Reflect for .. { } diff --git a/libcore/mem.rs b/libcore/mem.rs new file mode 100644 index 0000000..2c648d1 --- /dev/null +++ b/libcore/mem.rs @@ -0,0 +1,598 @@ +// Copyright 2012-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. + +//! Basic functions for dealing with memory. +//! +//! This module contains functions for querying the size and alignment of +//! types, initializing and manipulating memory. + +#![stable(feature = "rust1", since = "1.0.0")] + +use marker::Sized; +use intrinsics; +use ptr; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::transmute; + +/// Leaks a value into the void, consuming ownership and never running its +/// destructor. +/// +/// This function will take ownership of its argument, but is distinct from the +/// `mem::drop` function in that it **does not run the destructor**, leaking the +/// value and any resources that it owns. +/// +/// There's only a few reasons to use this function. They mainly come +/// up in unsafe code or FFI code. +/// +/// * You have an uninitialized value, perhaps for performance reasons, and +/// need to prevent the destructor from running on it. +/// * You have two copies of a value (like when writing something like +/// [`mem::swap`][swap]), but need the destructor to only run once to +/// prevent a double `free`. +/// * Transferring resources across [FFI][ffi] boundaries. +/// +/// [swap]: fn.swap.html +/// [ffi]: ../../book/ffi.html +/// +/// # Safety +/// +/// This function is not marked as `unsafe` as Rust does not guarantee that the +/// `Drop` implementation for a value will always run. Note, however, that +/// leaking resources such as memory or I/O objects is likely not desired, so +/// this function is only recommended for specialized use cases. +/// +/// The safety of this function implies that when writing `unsafe` code +/// yourself care must be taken when leveraging a destructor that is required to +/// run to preserve memory safety. There are known situations where the +/// destructor may not run (such as if ownership of the object with the +/// destructor is returned) which must be taken into account. +/// +/// # Other forms of Leakage +/// +/// It's important to point out that this function is not the only method by +/// which a value can be leaked in safe Rust code. Other known sources of +/// leakage are: +/// +/// * `Rc` and `Arc` cycles +/// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally) +/// * Panicking destructors are likely to leak local resources +/// +/// # Example +/// +/// Leak some heap memory by never deallocating it: +/// +/// ```rust +/// use std::mem; +/// +/// let heap_memory = Box::new(3); +/// mem::forget(heap_memory); +/// ``` +/// +/// Leak an I/O object, never closing the file: +/// +/// ```rust,no_run +/// use std::mem; +/// use std::fs::File; +/// +/// let file = File::open("foo.txt").unwrap(); +/// mem::forget(file); +/// ``` +/// +/// The `mem::swap` function uses `mem::forget` to good effect: +/// +/// ```rust +/// use std::mem; +/// use std::ptr; +/// +/// # #[allow(dead_code)] +/// fn swap<T>(x: &mut T, y: &mut T) { +/// unsafe { +/// // Give ourselves some scratch space to work with +/// let mut t: T = mem::uninitialized(); +/// +/// // Perform the swap, `&mut` pointers never alias +/// ptr::copy_nonoverlapping(&*x, &mut t, 1); +/// ptr::copy_nonoverlapping(&*y, x, 1); +/// ptr::copy_nonoverlapping(&t, y, 1); +/// +/// // y and t now point to the same thing, but we need to completely +/// // forget `t` because we do not want to run the destructor for `T` +/// // on its value, which is still owned somewhere outside this function. +/// mem::forget(t); +/// } +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub fn forget<T>(t: T) { + unsafe { intrinsics::forget(t) } +} + +/// Returns the size of a type in bytes. +/// +/// # Examples +/// +/// ``` +/// use std::mem; +/// +/// assert_eq!(4, mem::size_of::<i32>()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn size_of<T>() -> usize { + unsafe { intrinsics::size_of::<T>() } +} + +/// Returns the size of the given value in bytes. +/// +/// # Examples +/// +/// ``` +/// use std::mem; +/// +/// assert_eq!(4, mem::size_of_val(&5i32)); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn size_of_val<T: ?Sized>(val: &T) -> usize { + unsafe { intrinsics::size_of_val(val) } +} + +/// Returns the ABI-required minimum alignment of a type +/// +/// This is the alignment used for struct fields. It may be smaller than the preferred alignment. +/// +/// # Examples +/// +/// ``` +/// # #![allow(deprecated)] +/// use std::mem; +/// +/// assert_eq!(4, mem::min_align_of::<i32>()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_deprecated(reason = "use `align_of` instead", since = "1.2.0")] +pub fn min_align_of<T>() -> usize { + unsafe { intrinsics::min_align_of::<T>() } +} + +/// Returns the ABI-required minimum alignment of the type of the value that `val` points to +/// +/// # Examples +/// +/// ``` +/// # #![allow(deprecated)] +/// use std::mem; +/// +/// assert_eq!(4, mem::min_align_of_val(&5i32)); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_deprecated(reason = "use `align_of_val` instead", since = "1.2.0")] +pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize { + unsafe { intrinsics::min_align_of_val(val) } +} + +/// Returns the alignment in memory for a type. +/// +/// This is the alignment used for struct fields. It may be smaller than the preferred alignment. +/// +/// # Examples +/// +/// ``` +/// use std::mem; +/// +/// assert_eq!(4, mem::align_of::<i32>()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn align_of<T>() -> usize { + unsafe { intrinsics::min_align_of::<T>() } +} + +/// Returns the ABI-required minimum alignment of the type of the value that `val` points to +/// +/// # Examples +/// +/// ``` +/// use std::mem; +/// +/// assert_eq!(4, mem::align_of_val(&5i32)); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn align_of_val<T: ?Sized>(val: &T) -> usize { + unsafe { intrinsics::min_align_of_val(val) } +} + +/// Creates a value initialized to zero. +/// +/// This function is similar to allocating space for a local variable and zeroing it out (an unsafe +/// operation). +/// +/// Care must be taken when using this function, if the type `T` has a destructor and the value +/// falls out of scope (due to unwinding or returning) before being initialized, then the +/// destructor will run on zeroed data, likely leading to crashes. +/// +/// This is useful for FFI functions sometimes, but should generally be avoided. +/// +/// # Examples +/// +/// ``` +/// use std::mem; +/// +/// let x: i32 = unsafe { mem::zeroed() }; +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn zeroed<T>() -> T { + intrinsics::init() +} + +/// Creates a value initialized to an unspecified series of bytes. +/// +/// The byte sequence usually indicates that the value at the memory +/// in question has been dropped. Thus, *if* T carries a drop flag, +/// any associated destructor will not be run when the value falls out +/// of scope. +/// +/// Some code at one time used the `zeroed` function above to +/// accomplish this goal. +/// +/// This function is expected to be deprecated with the transition +/// to non-zeroing drop. +#[inline] +#[unstable(feature = "filling_drop", issue = "5016")] +pub unsafe fn dropped<T>() -> T { + #[inline(always)] + unsafe fn dropped_impl<T>() -> T { intrinsics::init_dropped() } + + dropped_impl() +} + +/// Bypasses Rust's normal memory-initialization checks by pretending to +/// produce a value of type T, while doing nothing at all. +/// +/// **This is incredibly dangerous, and should not be done lightly. Deeply +/// consider initializing your memory with a default value instead.** +/// +/// This is useful for FFI functions and initializing arrays sometimes, +/// but should generally be avoided. +/// +/// # Undefined Behavior +/// +/// It is Undefined Behavior to read uninitialized memory. Even just an +/// uninitialized boolean. For instance, if you branch on the value of such +/// a boolean your program may take one, both, or neither of the branches. +/// +/// Note that this often also includes *writing* to the uninitialized value. +/// Rust believes the value is initialized, and will therefore try to Drop +/// the uninitialized value and its fields if you try to overwrite the memory +/// in a normal manner. The only way to safely initialize an arbitrary +/// uninitialized value is with one of the `ptr` functions: `write`, `copy`, or +/// `copy_nonoverlapping`. This isn't necessary if `T` is a primitive +/// or otherwise only contains types that don't implement Drop. +/// +/// If this value *does* need some kind of Drop, it must be initialized before +/// it goes out of scope (and therefore would be dropped). Note that this +/// includes a `panic` occurring and unwinding the stack suddenly. +/// +/// # Examples +/// +/// Here's how to safely initialize an array of `Vec`s. +/// +/// ``` +/// use std::mem; +/// use std::ptr; +/// +/// // Only declare the array. This safely leaves it +/// // uninitialized in a way that Rust will track for us. +/// // However we can't initialize it element-by-element +/// // safely, and we can't use the `[value; 1000]` +/// // constructor because it only works with `Copy` data. +/// let mut data: [Vec<u32>; 1000]; +/// +/// unsafe { +/// // So we need to do this to initialize it. +/// data = mem::uninitialized(); +/// +/// // DANGER ZONE: if anything panics or otherwise +/// // incorrectly reads the array here, we will have +/// // Undefined Behavior. +/// +/// // It's ok to mutably iterate the data, since this +/// // doesn't involve reading it at all. +/// // (ptr and len are statically known for arrays) +/// for elem in &mut data[..] { +/// // *elem = Vec::new() would try to drop the +/// // uninitialized memory at `elem` -- bad! +/// // +/// // Vec::new doesn't allocate or do really +/// // anything. It's only safe to call here +/// // because we know it won't panic. +/// ptr::write(elem, Vec::new()); +/// } +/// +/// // SAFE ZONE: everything is initialized. +/// } +/// +/// println!("{:?}", &data[0]); +/// ``` +/// +/// This example emphasizes exactly how delicate and dangerous doing this is. +/// Note that the `vec!` macro *does* let you initialize every element with a +/// value that is only `Clone`, so the following is semantically equivalent and +/// vastly less dangerous, as long as you can live with an extra heap +/// allocation: +/// +/// ``` +/// let data: Vec<Vec<u32>> = vec![Vec::new(); 1000]; +/// println!("{:?}", &data[0]); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn uninitialized<T>() -> T { + intrinsics::uninit() +} + +/// Swap the values at two mutable locations of the same type, without deinitializing or copying +/// either one. +/// +/// # Examples +/// +/// ``` +/// use std::mem; +/// +/// let x = &mut 5; +/// let y = &mut 42; +/// +/// mem::swap(x, y); +/// +/// assert_eq!(42, *x); +/// assert_eq!(5, *y); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn swap<T>(x: &mut T, y: &mut T) { + unsafe { + // Give ourselves some scratch space to work with + let mut t: T = uninitialized(); + + // Perform the swap, `&mut` pointers never alias + ptr::copy_nonoverlapping(&*x, &mut t, 1); + ptr::copy_nonoverlapping(&*y, x, 1); + ptr::copy_nonoverlapping(&t, y, 1); + + // y and t now point to the same thing, but we need to completely + // forget `t` because we do not want to run the destructor for `T` + // on its value, which is still owned somewhere outside this function. + forget(t); + } +} + +/// Replaces the value at a mutable location with a new one, returning the old value, without +/// deinitializing or copying either one. +/// +/// This is primarily used for transferring and swapping ownership of a value in a mutable +/// location. +/// +/// # Examples +/// +/// A simple example: +/// +/// ``` +/// use std::mem; +/// +/// let mut v: Vec<i32> = Vec::new(); +/// +/// mem::replace(&mut v, Vec::new()); +/// ``` +/// +/// This function allows consumption of one field of a struct by replacing it with another value. +/// The normal approach doesn't always work: +/// +/// ```rust,ignore +/// struct Buffer<T> { buf: Vec<T> } +/// +/// impl<T> Buffer<T> { +/// fn get_and_reset(&mut self) -> Vec<T> { +/// // error: cannot move out of dereference of `&mut`-pointer +/// let buf = self.buf; +/// self.buf = Vec::new(); +/// buf +/// } +/// } +/// ``` +/// +/// Note that `T` does not necessarily implement `Clone`, so it can't even clone and reset +/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from +/// `self`, allowing it to be returned: +/// +/// ``` +/// # #![allow(dead_code)] +/// use std::mem; +/// # struct Buffer<T> { buf: Vec<T> } +/// impl<T> Buffer<T> { +/// fn get_and_reset(&mut self) -> Vec<T> { +/// mem::replace(&mut self.buf, Vec::new()) +/// } +/// } +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn replace<T>(dest: &mut T, mut src: T) -> T { + swap(dest, &mut src); + src +} + +/// Disposes of a value. +/// +/// While this does call the argument's implementation of `Drop`, it will not +/// release any borrows, as borrows are based on lexical scope. +/// +/// This effectively does nothing for +/// [types which implement `Copy`](../../book/ownership.html#copy-types), +/// e.g. integers. Such values are copied and _then_ moved into the function, +/// so the value persists after this function call. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// let v = vec![1, 2, 3]; +/// +/// drop(v); // explicitly drop the vector +/// ``` +/// +/// Borrows are based on lexical scope, so this produces an error: +/// +/// ```ignore +/// let mut v = vec![1, 2, 3]; +/// let x = &v[0]; +/// +/// drop(x); // explicitly drop the reference, but the borrow still exists +/// +/// v.push(4); // error: cannot borrow `v` as mutable because it is also +/// // borrowed as immutable +/// ``` +/// +/// An inner scope is needed to fix this: +/// +/// ``` +/// let mut v = vec![1, 2, 3]; +/// +/// { +/// let x = &v[0]; +/// +/// drop(x); // this is now redundant, as `x` is going out of scope anyway +/// } +/// +/// v.push(4); // no problems +/// ``` +/// +/// Since `RefCell` enforces the borrow rules at runtime, `drop()` can +/// seemingly release a borrow of one: +/// +/// ``` +/// use std::cell::RefCell; +/// +/// let x = RefCell::new(1); +/// +/// let mut mutable_borrow = x.borrow_mut(); +/// *mutable_borrow = 1; +/// +/// drop(mutable_borrow); // relinquish the mutable borrow on this slot +/// +/// let borrow = x.borrow(); +/// println!("{}", *borrow); +/// ``` +/// +/// Integers and other types implementing `Copy` are unaffected by `drop()` +/// +/// ``` +/// #[derive(Copy, Clone)] +/// struct Foo(u8); +/// +/// let x = 1; +/// let y = Foo(2); +/// drop(x); // a copy of `x` is moved and dropped +/// drop(y); // a copy of `y` is moved and dropped +/// +/// println!("x: {}, y: {}", x, y.0); // still available +/// ``` +/// +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn drop<T>(_x: T) { } + +macro_rules! repeat_u8_as_u32 { + ($name:expr) => { (($name as u32) << 24 | + ($name as u32) << 16 | + ($name as u32) << 8 | + ($name as u32)) } +} +macro_rules! repeat_u8_as_u64 { + ($name:expr) => { ((repeat_u8_as_u32!($name) as u64) << 32 | + (repeat_u8_as_u32!($name) as u64)) } +} + +// NOTE: Keep synchronized with values used in librustc_trans::trans::adt. +// +// In particular, the POST_DROP_U8 marker must never equal the +// DTOR_NEEDED_U8 marker. +// +// For a while pnkfelix was using 0xc1 here. +// But having the sign bit set is a pain, so 0x1d is probably better. +// +// And of course, 0x00 brings back the old world of zero'ing on drop. +#[unstable(feature = "filling_drop", issue = "5016")] +#[allow(missing_docs)] +pub const POST_DROP_U8: u8 = 0x1d; +#[unstable(feature = "filling_drop", issue = "5016")] +#[allow(missing_docs)] +pub const POST_DROP_U32: u32 = repeat_u8_as_u32!(POST_DROP_U8); +#[unstable(feature = "filling_drop", issue = "5016")] +#[allow(missing_docs)] +pub const POST_DROP_U64: u64 = repeat_u8_as_u64!(POST_DROP_U8); + +#[cfg(target_pointer_width = "32")] +#[unstable(feature = "filling_drop", issue = "5016")] +#[allow(missing_docs)] +pub const POST_DROP_USIZE: usize = POST_DROP_U32 as usize; +#[cfg(target_pointer_width = "64")] +#[unstable(feature = "filling_drop", issue = "5016")] +#[allow(missing_docs)] +pub const POST_DROP_USIZE: usize = POST_DROP_U64 as usize; + +/// Interprets `src` as `&U`, and then reads `src` without moving the contained +/// value. +/// +/// This function will unsafely assume the pointer `src` is valid for +/// `sizeof(U)` bytes by transmuting `&T` to `&U` and then reading the `&U`. It +/// will also unsafely create a copy of the contained value instead of moving +/// out of `src`. +/// +/// It is not a compile-time error if `T` and `U` have different sizes, but it +/// is highly encouraged to only invoke this function where `T` and `U` have the +/// same size. This function triggers undefined behavior if `U` is larger than +/// `T`. +/// +/// # Examples +/// +/// ``` +/// use std::mem; +/// +/// #[repr(packed)] +/// struct Foo { +/// bar: u8, +/// } +/// +/// let foo_slice = [10u8]; +/// +/// unsafe { +/// // Copy the data from 'foo_slice' and treat it as a 'Foo' +/// let mut foo_struct: Foo = mem::transmute_copy(&foo_slice); +/// assert_eq!(foo_struct.bar, 10); +/// +/// // Modify the copied data +/// foo_struct.bar = 20; +/// assert_eq!(foo_struct.bar, 20); +/// } +/// +/// // The contents of 'foo_slice' should not have changed +/// assert_eq!(foo_slice, [10]); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn transmute_copy<T, U>(src: &T) -> U { + ptr::read(src as *const T as *const U) +} diff --git a/libcore/nonzero.rs b/libcore/nonzero.rs new file mode 100644 index 0000000..92bbc4e --- /dev/null +++ b/libcore/nonzero.rs @@ -0,0 +1,60 @@ +// Copyright 2012-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. + +//! Exposes the NonZero lang item which provides optimization hints. +#![unstable(feature = "nonzero", + reason = "needs an RFC to flesh out the design", + issue = "27730")] + +use marker::Sized; +use ops::{CoerceUnsized, Deref}; + +/// Unsafe trait to indicate what types are usable with the NonZero struct +pub unsafe trait Zeroable {} + +unsafe impl<T:?Sized> Zeroable for *const T {} +unsafe impl<T:?Sized> Zeroable for *mut T {} +unsafe impl Zeroable for isize {} +unsafe impl Zeroable for usize {} +unsafe impl Zeroable for i8 {} +unsafe impl Zeroable for u8 {} +unsafe impl Zeroable for i16 {} +unsafe impl Zeroable for u16 {} +unsafe impl Zeroable for i32 {} +unsafe impl Zeroable for u32 {} +unsafe impl Zeroable for i64 {} +unsafe impl Zeroable for u64 {} + +/// A wrapper type for raw pointers and integers that will never be +/// NULL or 0 that might allow certain optimizations. +#[lang = "non_zero"] +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] +pub struct NonZero<T: Zeroable>(T); + +impl<T: Zeroable> NonZero<T> { + /// Creates an instance of NonZero with the provided value. + /// You must indeed ensure that the value is actually "non-zero". + #[inline(always)] + pub const unsafe fn new(inner: T) -> NonZero<T> { + NonZero(inner) + } +} + +impl<T: Zeroable> Deref for NonZero<T> { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + let NonZero(ref inner) = *self; + inner + } +} + +impl<T: Zeroable+CoerceUnsized<U>, U: Zeroable> CoerceUnsized<NonZero<U>> for NonZero<T> {} diff --git a/libcore/num/bignum.rs b/libcore/num/bignum.rs new file mode 100644 index 0000000..66c6deb --- /dev/null +++ b/libcore/num/bignum.rs @@ -0,0 +1,499 @@ +// Copyright 2015 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. + +//! Custom arbitrary-precision number (bignum) implementation. +//! +//! This is designed to avoid the heap allocation at expense of stack memory. +//! The most used bignum type, `Big32x40`, is limited by 32 × 40 = 1,280 bits +//! and will take at most 160 bytes of stack memory. This is more than enough +//! for round-tripping all possible finite `f64` values. +//! +//! In principle it is possible to have multiple bignum types for different +//! inputs, but we don't do so to avoid the code bloat. Each bignum is still +//! tracked for the actual usages, so it normally doesn't matter. + +// This module is only for dec2flt and flt2dec, and only public because of libcoretest. +// It is not intended to ever be stabilized. +#![doc(hidden)] +#![unstable(feature = "core_private_bignum", + reason = "internal routines only exposed for testing", + issue = "0")] +#![macro_use] + +use prelude::v1::*; + +use mem; +use intrinsics; + +/// Arithmetic operations required by bignums. +pub trait FullOps { + /// Returns `(carry', v')` such that `carry' * 2^W + v' = self + other + carry`, + /// where `W` is the number of bits in `Self`. + fn full_add(self, other: Self, carry: bool) -> (bool /*carry*/, Self); + + /// Returns `(carry', v')` such that `carry' * 2^W + v' = self * other + carry`, + /// where `W` is the number of bits in `Self`. + fn full_mul(self, other: Self, carry: Self) -> (Self /*carry*/, Self); + + /// Returns `(carry', v')` such that `carry' * 2^W + v' = self * other + other2 + carry`, + /// where `W` is the number of bits in `Self`. + fn full_mul_add(self, other: Self, other2: Self, carry: Self) -> (Self /*carry*/, Self); + + /// Returns `(quo, rem)` such that `borrow * 2^W + self = quo * other + rem` + /// and `0 <= rem < other`, where `W` is the number of bits in `Self`. + fn full_div_rem(self, other: Self, borrow: Self) -> (Self /*quotient*/, Self /*remainder*/); +} + +macro_rules! impl_full_ops { + ($($ty:ty: add($addfn:path), mul/div($bigty:ident);)*) => ( + $( + impl FullOps for $ty { + fn full_add(self, other: $ty, carry: bool) -> (bool, $ty) { + // this cannot overflow, the output is between 0 and 2*2^nbits - 1 + // FIXME will LLVM optimize this into ADC or similar??? + let (v, carry1) = unsafe { intrinsics::add_with_overflow(self, other) }; + let (v, carry2) = unsafe { + intrinsics::add_with_overflow(v, if carry {1} else {0}) + }; + (carry1 || carry2, v) + } + + fn full_mul(self, other: $ty, carry: $ty) -> ($ty, $ty) { + // this cannot overflow, the output is between 0 and 2^nbits * (2^nbits - 1) + let nbits = mem::size_of::<$ty>() * 8; + let v = (self as $bigty) * (other as $bigty) + (carry as $bigty); + ((v >> nbits) as $ty, v as $ty) + } + + fn full_mul_add(self, other: $ty, other2: $ty, carry: $ty) -> ($ty, $ty) { + // this cannot overflow, the output is between 0 and 2^(2*nbits) - 1 + let nbits = mem::size_of::<$ty>() * 8; + let v = (self as $bigty) * (other as $bigty) + (other2 as $bigty) + + (carry as $bigty); + ((v >> nbits) as $ty, v as $ty) + } + + fn full_div_rem(self, other: $ty, borrow: $ty) -> ($ty, $ty) { + debug_assert!(borrow < other); + // this cannot overflow, the dividend is between 0 and other * 2^nbits - 1 + let nbits = mem::size_of::<$ty>() * 8; + let lhs = ((borrow as $bigty) << nbits) | (self as $bigty); + let rhs = other as $bigty; + ((lhs / rhs) as $ty, (lhs % rhs) as $ty) + } + } + )* + ) +} + +impl_full_ops! { + u8: add(intrinsics::u8_add_with_overflow), mul/div(u16); + u16: add(intrinsics::u16_add_with_overflow), mul/div(u32); + u32: add(intrinsics::u32_add_with_overflow), mul/div(u64); +// u64: add(intrinsics::u64_add_with_overflow), mul/div(u128); // see RFC #521 for enabling this. +} + +/// Table of powers of 5 representable in digits. Specifically, the largest {u8, u16, u32} value +/// that's a power of five, plus the corresponding exponent. Used in `mul_pow5`. +const SMALL_POW5: [(u64, usize); 3] = [ + (125, 3), + (15625, 6), + (1_220_703_125, 13), +]; + +macro_rules! define_bignum { + ($name:ident: type=$ty:ty, n=$n:expr) => ( + /// Stack-allocated arbitrary-precision (up to certain limit) integer. + /// + /// This is backed by a fixed-size array of given type ("digit"). + /// While the array is not very large (normally some hundred bytes), + /// copying it recklessly may result in the performance hit. + /// Thus this is intentionally not `Copy`. + /// + /// All operations available to bignums panic in the case of over/underflows. + /// The caller is responsible to use large enough bignum types. + pub struct $name { + /// One plus the offset to the maximum "digit" in use. + /// This does not decrease, so be aware of the computation order. + /// `base[size..]` should be zero. + size: usize, + /// Digits. `[a, b, c, ...]` represents `a + b*2^W + c*2^(2W) + ...` + /// where `W` is the number of bits in the digit type. + base: [$ty; $n] + } + + impl $name { + /// Makes a bignum from one digit. + pub fn from_small(v: $ty) -> $name { + let mut base = [0; $n]; + base[0] = v; + $name { size: 1, base: base } + } + + /// Makes a bignum from `u64` value. + pub fn from_u64(mut v: u64) -> $name { + use mem; + + let mut base = [0; $n]; + let mut sz = 0; + while v > 0 { + base[sz] = v as $ty; + v >>= mem::size_of::<$ty>() * 8; + sz += 1; + } + $name { size: sz, base: base } + } + + /// Return the internal digits as a slice `[a, b, c, ...]` such that the numeric + /// value is `a + b * 2^W + c * 2^(2W) + ...` where `W` is the number of bits in + /// the digit type. + pub fn digits(&self) -> &[$ty] { + &self.base[..self.size] + } + + /// Return the `i`-th bit where bit 0 is the least significant one. + /// In other words, the bit with weight `2^i`. + pub fn get_bit(&self, i: usize) -> u8 { + use mem; + + let digitbits = mem::size_of::<$ty>() * 8; + let d = i / digitbits; + let b = i % digitbits; + ((self.base[d] >> b) & 1) as u8 + } + + /// Returns true if the bignum is zero. + pub fn is_zero(&self) -> bool { + self.digits().iter().all(|&v| v == 0) + } + + /// Returns the number of bits necessary to represent this value. Note that zero + /// is considered to need 0 bits. + pub fn bit_length(&self) -> usize { + use mem; + + // Skip over the most significant digits which are zero. + let digits = self.digits(); + let zeros = digits.iter().rev().take_while(|&&x| x == 0).count(); + let end = digits.len() - zeros; + let nonzero = &digits[..end]; + + if nonzero.is_empty() { + // There are no non-zero digits, i.e. the number is zero. + return 0; + } + // This could be optimized with leading_zeros() and bit shifts, but that's + // probably not worth the hassle. + let digitbits = mem::size_of::<$ty>()* 8; + let mut i = nonzero.len() * digitbits - 1; + while self.get_bit(i) == 0 { + i -= 1; + } + i + 1 + } + + /// Adds `other` to itself and returns its own mutable reference. + pub fn add<'a>(&'a mut self, other: &$name) -> &'a mut $name { + use cmp; + use num::bignum::FullOps; + + let mut sz = cmp::max(self.size, other.size); + let mut carry = false; + for (a, b) in self.base[..sz].iter_mut().zip(&other.base[..sz]) { + let (c, v) = (*a).full_add(*b, carry); + *a = v; + carry = c; + } + if carry { + self.base[sz] = 1; + sz += 1; + } + self.size = sz; + self + } + + pub fn add_small(&mut self, other: $ty) -> &mut $name { + use num::bignum::FullOps; + + let (mut carry, v) = self.base[0].full_add(other, false); + self.base[0] = v; + let mut i = 1; + while carry { + let (c, v) = self.base[i].full_add(0, carry); + self.base[i] = v; + carry = c; + i += 1; + } + if i > self.size { + self.size = i; + } + self + } + + /// Subtracts `other` from itself and returns its own mutable reference. + pub fn sub<'a>(&'a mut self, other: &$name) -> &'a mut $name { + use cmp; + use num::bignum::FullOps; + + let sz = cmp::max(self.size, other.size); + let mut noborrow = true; + for (a, b) in self.base[..sz].iter_mut().zip(&other.base[..sz]) { + let (c, v) = (*a).full_add(!*b, noborrow); + *a = v; + noborrow = c; + } + assert!(noborrow); + self.size = sz; + self + } + + /// Multiplies itself by a digit-sized `other` and returns its own + /// mutable reference. + pub fn mul_small(&mut self, other: $ty) -> &mut $name { + use num::bignum::FullOps; + + let mut sz = self.size; + let mut carry = 0; + for a in &mut self.base[..sz] { + let (c, v) = (*a).full_mul(other, carry); + *a = v; + carry = c; + } + if carry > 0 { + self.base[sz] = carry; + sz += 1; + } + self.size = sz; + self + } + + /// Multiplies itself by `2^bits` and returns its own mutable reference. + pub fn mul_pow2(&mut self, bits: usize) -> &mut $name { + use mem; + + let digitbits = mem::size_of::<$ty>() * 8; + let digits = bits / digitbits; + let bits = bits % digitbits; + + assert!(digits < $n); + debug_assert!(self.base[$n-digits..].iter().all(|&v| v == 0)); + debug_assert!(bits == 0 || (self.base[$n-digits-1] >> (digitbits - bits)) == 0); + + // shift by `digits * digitbits` bits + for i in (0..self.size).rev() { + self.base[i+digits] = self.base[i]; + } + for i in 0..digits { + self.base[i] = 0; + } + + // shift by `bits` bits + let mut sz = self.size + digits; + if bits > 0 { + let last = sz; + let overflow = self.base[last-1] >> (digitbits - bits); + if overflow > 0 { + self.base[last] = overflow; + sz += 1; + } + for i in (digits+1..last).rev() { + self.base[i] = (self.base[i] << bits) | + (self.base[i-1] >> (digitbits - bits)); + } + self.base[digits] <<= bits; + // self.base[..digits] is zero, no need to shift + } + + self.size = sz; + self + } + + /// Multiplies itself by `5^e` and returns its own mutable reference. + pub fn mul_pow5(&mut self, mut e: usize) -> &mut $name { + use mem; + use num::bignum::SMALL_POW5; + + // There are exactly n trailing zeros on 2^n, and the only relevant digit sizes + // are consecutive powers of two, so this is well suited index for the table. + let table_index = mem::size_of::<$ty>().trailing_zeros() as usize; + let (small_power, small_e) = SMALL_POW5[table_index]; + let small_power = small_power as $ty; + + // Multiply with the largest single-digit power as long as possible ... + while e >= small_e { + self.mul_small(small_power); + e -= small_e; + } + + // ... then finish off the remainder. + let mut rest_power = 1; + for _ in 0..e { + rest_power *= 5; + } + self.mul_small(rest_power); + + self + } + + + /// Multiplies itself by a number described by `other[0] + other[1] * 2^W + + /// other[2] * 2^(2W) + ...` (where `W` is the number of bits in the digit type) + /// and returns its own mutable reference. + pub fn mul_digits<'a>(&'a mut self, other: &[$ty]) -> &'a mut $name { + // the internal routine. works best when aa.len() <= bb.len(). + fn mul_inner(ret: &mut [$ty; $n], aa: &[$ty], bb: &[$ty]) -> usize { + use num::bignum::FullOps; + + let mut retsz = 0; + for (i, &a) in aa.iter().enumerate() { + if a == 0 { continue; } + let mut sz = bb.len(); + let mut carry = 0; + for (j, &b) in bb.iter().enumerate() { + let (c, v) = a.full_mul_add(b, ret[i + j], carry); + ret[i + j] = v; + carry = c; + } + if carry > 0 { + ret[i + sz] = carry; + sz += 1; + } + if retsz < i + sz { + retsz = i + sz; + } + } + retsz + } + + let mut ret = [0; $n]; + let retsz = if self.size < other.len() { + mul_inner(&mut ret, &self.digits(), other) + } else { + mul_inner(&mut ret, other, &self.digits()) + }; + self.base = ret; + self.size = retsz; + self + } + + /// Divides itself by a digit-sized `other` and returns its own + /// mutable reference *and* the remainder. + pub fn div_rem_small(&mut self, other: $ty) -> (&mut $name, $ty) { + use num::bignum::FullOps; + + assert!(other > 0); + + let sz = self.size; + let mut borrow = 0; + for a in self.base[..sz].iter_mut().rev() { + let (q, r) = (*a).full_div_rem(other, borrow); + *a = q; + borrow = r; + } + (self, borrow) + } + + /// Divide self by another bignum, overwriting `q` with the quotient and `r` with the + /// remainder. + pub fn div_rem(&self, d: &$name, q: &mut $name, r: &mut $name) { + use mem; + + // Stupid slow base-2 long division taken from + // https://en.wikipedia.org/wiki/Division_algorithm + // FIXME use a greater base ($ty) for the long division. + assert!(!d.is_zero()); + let digitbits = mem::size_of::<$ty>() * 8; + for digit in &mut q.base[..] { + *digit = 0; + } + for digit in &mut r.base[..] { + *digit = 0; + } + r.size = d.size; + q.size = 1; + let mut q_is_zero = true; + let end = self.bit_length(); + for i in (0..end).rev() { + r.mul_pow2(1); + r.base[0] |= self.get_bit(i) as $ty; + if &*r >= d { + r.sub(d); + // Set bit `i` of q to 1. + let digit_idx = i / digitbits; + let bit_idx = i % digitbits; + if q_is_zero { + q.size = digit_idx + 1; + q_is_zero = false; + } + q.base[digit_idx] |= 1 << bit_idx; + } + } + debug_assert!(q.base[q.size..].iter().all(|&d| d == 0)); + debug_assert!(r.base[r.size..].iter().all(|&d| d == 0)); + } + } + + impl ::cmp::PartialEq for $name { + fn eq(&self, other: &$name) -> bool { self.base[..] == other.base[..] } + } + + impl ::cmp::Eq for $name { + } + + impl ::cmp::PartialOrd for $name { + fn partial_cmp(&self, other: &$name) -> ::option::Option<::cmp::Ordering> { + ::option::Option::Some(self.cmp(other)) + } + } + + impl ::cmp::Ord for $name { + fn cmp(&self, other: &$name) -> ::cmp::Ordering { + use cmp::max; + let sz = max(self.size, other.size); + let lhs = self.base[..sz].iter().cloned().rev(); + let rhs = other.base[..sz].iter().cloned().rev(); + lhs.cmp(rhs) + } + } + + impl ::clone::Clone for $name { + fn clone(&self) -> $name { + $name { size: self.size, base: self.base } + } + } + + impl ::fmt::Debug for $name { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + use mem; + + let sz = if self.size < 1 {1} else {self.size}; + let digitlen = mem::size_of::<$ty>() * 2; + + try!(write!(f, "{:#x}", self.base[sz-1])); + for &v in self.base[..sz-1].iter().rev() { + try!(write!(f, "_{:01$x}", v, digitlen)); + } + ::result::Result::Ok(()) + } + } + ) +} + +/// The digit type for `Big32x40`. +pub type Digit32 = u32; + +define_bignum!(Big32x40: type=Digit32, n=40); + +// this one is used for testing only. +#[doc(hidden)] +pub mod tests { + use prelude::v1::*; + define_bignum!(Big8x3: type=u8, n=3); +} diff --git a/libcore/num/dec2flt/algorithm.rs b/libcore/num/dec2flt/algorithm.rs new file mode 100644 index 0000000..e33c281 --- /dev/null +++ b/libcore/num/dec2flt/algorithm.rs @@ -0,0 +1,357 @@ +// Copyright 2015 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. + +//! The various algorithms from the paper. + +use prelude::v1::*; +use cmp::min; +use cmp::Ordering::{Less, Equal, Greater}; +use num::diy_float::Fp; +use num::dec2flt::table; +use num::dec2flt::rawfp::{self, Unpacked, RawFloat, fp_to_float, next_float, prev_float}; +use num::dec2flt::num::{self, Big}; + +/// Number of significand bits in Fp +const P: u32 = 64; + +// We simply store the best approximation for *all* exponents, so the variable "h" and the +// associated conditions can be omitted. This trades performance for a couple kilobytes of space. + +fn power_of_ten(e: i16) -> Fp { + assert!(e >= table::MIN_E); + let i = e - table::MIN_E; + let sig = table::POWERS.0[i as usize]; + let exp = table::POWERS.1[i as usize]; + Fp { f: sig, e: exp } +} + +/// The fast path of Bellerophon using machine-sized integers and floats. +/// +/// This is extracted into a separate function so that it can be attempted before constructing +/// a bignum. +/// +/// The fast path crucially depends on arithmetic being correctly rounded, so on x86 +/// without SSE or SSE2 it will be **wrong** (as in, off by one ULP occasionally), because the x87 +/// FPU stack will round to 80 bit first before rounding to 64/32 bit. However, as such hardware +/// is extremely rare nowadays and in fact all in-tree target triples assume an SSE2-capable +/// microarchitecture, there is little incentive to deal with that. There's a test that will fail +/// when SSE or SSE2 is disabled, so people building their own non-SSE copy will get a heads up. +/// +/// FIXME: It would nevertheless be nice if we had a good way to detect and deal with x87. +pub fn fast_path<T: RawFloat>(integral: &[u8], fractional: &[u8], e: i64) -> Option<T> { + let num_digits = integral.len() + fractional.len(); + // log_10(f64::max_sig) ~ 15.95. We compare the exact value to max_sig near the end, + // this is just a quick, cheap rejection (and also frees the rest of the code from + // worrying about underflow). + if num_digits > 16 { + return None; + } + if e.abs() >= T::ceil_log5_of_max_sig() as i64 { + return None; + } + let f = num::from_str_unchecked(integral.iter().chain(fractional.iter())); + if f > T::max_sig() { + return None; + } + // The case e < 0 cannot be folded into the other branch. Negative powers result in + // a repeating fractional part in binary, which are rounded, which causes real + // (and occasioally quite significant!) errors in the final result. + if e >= 0 { + Some(T::from_int(f) * T::short_fast_pow10(e as usize)) + } else { + Some(T::from_int(f) / T::short_fast_pow10(e.abs() as usize)) + } +} + +/// Algorithm Bellerophon is trivial code justified by non-trivial numeric analysis. +/// +/// It rounds ``f`` to a float with 64 bit significand and multiplies it by the best approximation +/// of `10^e` (in the same floating point format). This is often enough to get the correct result. +/// However, when the result is close to halfway between two adjecent (ordinary) floats, the +/// compound rounding error from multiplying two approximation means the result may be off by a +/// few bits. When this happens, the iterative Algorithm R fixes things up. +/// +/// The hand-wavy "close to halfway" is made precise by the numeric analysis in the paper. +/// In the words of Clinger: +/// +/// > Slop, expressed in units of the least significant bit, is an inclusive bound for the error +/// > accumulated during the floating point calculation of the approximation to f * 10^e. (Slop is +/// > not a bound for the true error, but bounds the difference between the approximation z and +/// > the best possible approximation that uses p bits of significand.) +pub fn bellerophon<T: RawFloat>(f: &Big, e: i16) -> T { + let slop; + if f <= &Big::from_u64(T::max_sig()) { + // The cases abs(e) < log5(2^N) are in fast_path() + slop = if e >= 0 { 0 } else { 3 }; + } else { + slop = if e >= 0 { 1 } else { 4 }; + } + let z = rawfp::big_to_fp(f).mul(&power_of_ten(e)).normalize(); + let exp_p_n = 1 << (P - T::sig_bits() as u32); + let lowbits: i64 = (z.f % exp_p_n) as i64; + // Is the slop large enough to make a difference when + // rounding to n bits? + if (lowbits - exp_p_n as i64 / 2).abs() <= slop { + algorithm_r(f, e, fp_to_float(z)) + } else { + fp_to_float(z) + } +} + +/// An iterative algorithm that improves a floating point approximation of `f * 10^e`. +/// +/// Each iteration gets one unit in the last place closer, which of course takes terribly long to +/// converge if `z0` is even mildly off. Luckily, when used as fallback for Bellerophon, the +/// starting approximation is off by at most one ULP. +fn algorithm_r<T: RawFloat>(f: &Big, e: i16, z0: T) -> T { + let mut z = z0; + loop { + let raw = z.unpack(); + let (m, k) = (raw.sig, raw.k); + let mut x = f.clone(); + let mut y = Big::from_u64(m); + + // Find positive integers `x`, `y` such that `x / y` is exactly `(f * 10^e) / (m * 2^k)`. + // This not only avoids dealing with the signs of `e` and `k`, we also eliminate the + // power of two common to `10^e` and `2^k` to make the numbers smaller. + make_ratio(&mut x, &mut y, e, k); + + let m_digits = [(m & 0xFF_FF_FF_FF) as u32, (m >> 32) as u32]; + // This is written a bit awkwardly because our bignums don't support + // negative numbers, so we use the absolute value + sign information. + // The multiplication with m_digits can't overflow. If `x` or `y` are large enough that + // we need to worry about overflow, then they are also large enough that `make_ratio` has + // reduced the fraction by a factor of 2^64 or more. + let (d2, d_negative) = if x >= y { + // Don't need x any more, save a clone(). + x.sub(&y).mul_pow2(1).mul_digits(&m_digits); + (x, false) + } else { + // Still need y - make a copy. + let mut y = y.clone(); + y.sub(&x).mul_pow2(1).mul_digits(&m_digits); + (y, true) + }; + + if d2 < y { + let mut d2_double = d2; + d2_double.mul_pow2(1); + if m == T::min_sig() && d_negative && d2_double > y { + z = prev_float(z); + } else { + return z; + } + } else if d2 == y { + if m % 2 == 0 { + if m == T::min_sig() && d_negative { + z = prev_float(z); + } else { + return z; + } + } else if d_negative { + z = prev_float(z); + } else { + z = next_float(z); + } + } else if d_negative { + z = prev_float(z); + } else { + z = next_float(z); + } + } +} + +/// Given `x = f` and `y = m` where `f` represent input decimal digits as usual and `m` is the +/// significand of a floating point approximation, make the ratio `x / y` equal to +/// `(f * 10^e) / (m * 2^k)`, possibly reduced by a power of two both have in common. +fn make_ratio(x: &mut Big, y: &mut Big, e: i16, k: i16) { + let (e_abs, k_abs) = (e.abs() as usize, k.abs() as usize); + if e >= 0 { + if k >= 0 { + // x = f * 10^e, y = m * 2^k, except that we reduce the fraction by some power of two. + let common = min(e_abs, k_abs); + x.mul_pow5(e_abs).mul_pow2(e_abs - common); + y.mul_pow2(k_abs - common); + } else { + // x = f * 10^e * 2^abs(k), y = m + // This can't overflow because it requires positive `e` and negative `k`, which can + // only happen for values extremely close to 1, which means that `e` and `k` will be + // comparatively tiny. + x.mul_pow5(e_abs).mul_pow2(e_abs + k_abs); + } + } else { + if k >= 0 { + // x = f, y = m * 10^abs(e) * 2^k + // This can't overflow either, see above. + y.mul_pow5(e_abs).mul_pow2(k_abs + e_abs); + } else { + // x = f * 2^abs(k), y = m * 10^abs(e), again reducing by a common power of two. + let common = min(e_abs, k_abs); + x.mul_pow2(k_abs - common); + y.mul_pow5(e_abs).mul_pow2(e_abs - common); + } + } +} + +/// Conceptually, Algorithm M is the simplest way to convert a decimal to a float. +/// +/// We form a ratio that is equal to `f * 10^e`, then throwing in powers of two until it gives +/// a valid float significand. The binary exponent `k` is the number of times we multiplied +/// numerator or denominator by two, i.e., at all times `f * 10^e` equals `(u / v) * 2^k`. +/// When we have found out significand, we only need to round by inspecting the remainder of the +/// division, which is done in helper functions further below. +/// +/// This algorithm is super slow, even with the optimization described in `quick_start()`. +/// However, it's the simplest of the algorithms to adapt for overflow, underflow, and subnormal +/// results. This implementation takes over when Bellerophon and Algorithm R are overwhelmed. +/// Detecting underflow and overflow is easy: The ratio still isn't an in-range significand, +/// yet the minimum/maximum exponent has been reached. In the case of overflow, we simply return +/// infinity. +/// +/// Handling underflow and subnormals is trickier. One big problem is that, with the minimum +/// exponent, the ratio might still be too large for a significand. See underflow() for details. +pub fn algorithm_m<T: RawFloat>(f: &Big, e: i16) -> T { + let mut u; + let mut v; + let e_abs = e.abs() as usize; + let mut k = 0; + if e < 0 { + u = f.clone(); + v = Big::from_small(1); + v.mul_pow5(e_abs).mul_pow2(e_abs); + } else { + // FIXME possible optimization: generalize big_to_fp so that we can do the equivalent of + // fp_to_float(big_to_fp(u)) here, only without the double rounding. + u = f.clone(); + u.mul_pow5(e_abs).mul_pow2(e_abs); + v = Big::from_small(1); + } + quick_start::<T>(&mut u, &mut v, &mut k); + let mut rem = Big::from_small(0); + let mut x = Big::from_small(0); + let min_sig = Big::from_u64(T::min_sig()); + let max_sig = Big::from_u64(T::max_sig()); + loop { + u.div_rem(&v, &mut x, &mut rem); + if k == T::min_exp_int() { + // We have to stop at the minimum exponent, if we wait until `k < T::min_exp_int()`, + // then we'd be off by a factor of two. Unfortunately this means we have to special- + // case normal numbers with the minimum exponent. + // FIXME find a more elegant formulation, but run the `tiny-pow10` test to make sure + // that it's actually correct! + if x >= min_sig && x <= max_sig { + break; + } + return underflow(x, v, rem); + } + if k > T::max_exp_int() { + return T::infinity(); + } + if x < min_sig { + u.mul_pow2(1); + k -= 1; + } else if x > max_sig { + v.mul_pow2(1); + k += 1; + } else { + break; + } + } + let q = num::to_u64(&x); + let z = rawfp::encode_normal(Unpacked::new(q, k)); + round_by_remainder(v, rem, q, z) +} + +/// Skip over most AlgorithmM iterations by checking the bit length. +fn quick_start<T: RawFloat>(u: &mut Big, v: &mut Big, k: &mut i16) { + // The bit length is an estimate of the base two logarithm, and log(u / v) = log(u) - log(v). + // The estimate is off by at most 1, but always an under-estimate, so the error on log(u) + // and log(v) are of the same sign and cancel out (if both are large). Therefore the error + // for log(u / v) is at most one as well. + // The target ratio is one where u/v is in an in-range significand. Thus our termination + // condition is log2(u / v) being the significand bits, plus/minus one. + // FIXME Looking at the second bit could improve the estimate and avoid some more divisions. + let target_ratio = T::sig_bits() as i16; + let log2_u = u.bit_length() as i16; + let log2_v = v.bit_length() as i16; + let mut u_shift: i16 = 0; + let mut v_shift: i16 = 0; + assert!(*k == 0); + loop { + if *k == T::min_exp_int() { + // Underflow or subnormal. Leave it to the main function. + break; + } + if *k == T::max_exp_int() { + // Overflow. Leave it to the main function. + break; + } + let log2_ratio = (log2_u + u_shift) - (log2_v + v_shift); + if log2_ratio < target_ratio - 1 { + u_shift += 1; + *k -= 1; + } else if log2_ratio > target_ratio + 1 { + v_shift += 1; + *k += 1; + } else { + break; + } + } + u.mul_pow2(u_shift as usize); + v.mul_pow2(v_shift as usize); +} + +fn underflow<T: RawFloat>(x: Big, v: Big, rem: Big) -> T { + if x < Big::from_u64(T::min_sig()) { + let q = num::to_u64(&x); + let z = rawfp::encode_subnormal(q); + return round_by_remainder(v, rem, q, z); + } + // Ratio isn't an in-range significand with the minimum exponent, so we need to round off + // excess bits and adjust the exponent accordingly. The real value now looks like this: + // + // x lsb + // /--------------\/ + // 1010101010101010.10101010101010 * 2^k + // \-----/\-------/ \------------/ + // q trunc. (represented by rem) + // + // Therefore, when the rounded-off bits are != 0.5 ULP, they decide the rounding + // on their own. When they are equal and the remainder is non-zero, the value still + // needs to be rounded up. Only when the rounded off bits are 1/2 and the remainer + // is zero, we have a half-to-even situation. + let bits = x.bit_length(); + let lsb = bits - T::sig_bits() as usize; + let q = num::get_bits(&x, lsb, bits); + let k = T::min_exp_int() + lsb as i16; + let z = rawfp::encode_normal(Unpacked::new(q, k)); + let q_even = q % 2 == 0; + match num::compare_with_half_ulp(&x, lsb) { + Greater => next_float(z), + Less => z, + Equal if rem.is_zero() && q_even => z, + Equal => next_float(z), + } +} + +/// Ordinary round-to-even, obfuscated by having to round based on the remainder of a division. +fn round_by_remainder<T: RawFloat>(v: Big, r: Big, q: u64, z: T) -> T { + let mut v_minus_r = v; + v_minus_r.sub(&r); + if r < v_minus_r { + z + } else if r > v_minus_r { + next_float(z) + } else if q % 2 == 0 { + z + } else { + next_float(z) + } +} diff --git a/libcore/num/dec2flt/mod.rs b/libcore/num/dec2flt/mod.rs new file mode 100644 index 0000000..022bd84 --- /dev/null +++ b/libcore/num/dec2flt/mod.rs @@ -0,0 +1,332 @@ +// Copyright 2015 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. + +//! Converting decimal strings into IEEE 754 binary floating point numbers. +//! +//! # Problem statement +//! +//! We are given a decimal string such as `12.34e56`. This string consists of integral (`12`), +//! fractional (`45`), and exponent (`56`) parts. All parts are optional and interpreted as zero +//! when missing. +//! +//! We seek the IEEE 754 floating point number that is closest to the exact value of the decimal +//! string. It is well-known that many decimal strings do not have terminating representations in +//! base two, so we round to 0.5 units in the last place (in other words, as well as possible). +//! Ties, decimal values exactly half-way between two consecutive floats, are resolved with the +//! half-to-even strategy, also known as banker's rounding. +//! +//! Needless to say, this is quite hard, both in terms of implementation complexity and in terms +//! of CPU cycles taken. +//! +//! # Implementation +//! +//! First, we ignore signs. Or rather, we remove it at the very beginning of the conversion +//! process and re-apply it at the very end. This is correct in all edge cases since IEEE +//! floats are symmetric around zero, negating one simply flips the first bit. +//! +//! Then we remove the decimal point by adjusting the exponent: Conceptually, `12.34e56` turns +//! into `1234e54`, which we describe with a positive integer `f = 1234` and an integer `e = 54`. +//! The `(f, e)` representation is used by almost all code past the parsing stage. +//! +//! We then try a long chain of progressively more general and expensive special cases using +//! machine-sized integers and small, fixed-sized floating point numbers (first `f32`/`f64`, then +//! a type with 64 bit significand, `Fp`). When all these fail, we bite the bullet and resort to a +//! simple but very slow algorithm that involved computing `f * 10^e` fully and doing an iterative +//! search for the best approximation. +//! +//! Primarily, this module and its children implement the algorithms described in: +//! "How to Read Floating Point Numbers Accurately" by William D. Clinger, +//! available online: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.4152 +//! +//! In addition, there are numerous helper functions that are used in the paper but not available +//! in Rust (or at least in core). Our version is additionally complicated by the need to handle +//! overflow and underflow and the desire to handle subnormal numbers. Bellerophon and +//! Algorithm R have trouble with overflow, subnormals, and underflow. We conservatively switch to +//! Algorithm M (with the modifications described in section 8 of the paper) well before the +//! inputs get into the critical region. +//! +//! Another aspect that needs attention is the ``RawFloat`` trait by which almost all functions +//! are parametrized. One might think that it's enough to parse to `f64` and cast the result to +//! `f32`. Unfortunately this is not the world we live in, and this has nothing to do with using +//! base two or half-to-even rounding. +//! +//! Consider for example two types `d2` and `d4` representing a decimal type with two decimal +//! digits and four decimal digits each and take "0.01499" as input. Let's use half-up rounding. +//! Going directly to two decimal digits gives `0.01`, but if we round to four digits first, +//! we get `0.0150`, which is then rounded up to `0.02`. The same principle applies to other +//! operations as well, if you want 0.5 ULP accuracy you need to do *everything* in full precision +//! and round *exactly once, at the end*, by considering all truncated bits at once. +//! +//! FIXME Although some code duplication is necessary, perhaps parts of the code could be shuffled +//! around such that less code is duplicated. Large parts of the algorithms are independent of the +//! float type to output, or only needs access to a few constants, which could be passed in as +//! parameters. +//! +//! # Other +//! +//! The conversion should *never* panic. There are assertions and explicit panics in the code, +//! but they should never be triggered and only serve as internal sanity checks. Any panics should +//! be considered a bug. +//! +//! There are unit tests but they are woefully inadequate at ensuring correctness, they only cover +//! a small percentage of possible errors. Far more extensive tests are located in the directory +//! `src/etc/test-float-parse` as a Python script. +//! +//! A note on integer overflow: Many parts of this file perform arithmetic with the decimal +//! exponent `e`. Primarily, we shift the decimal point around: Before the first decimal digit, +//! after the last decimal digit, and so on. This could overflow if done carelessly. We rely on +//! the parsing submodule to only hand out sufficiently small exponents, where "sufficient" means +//! "such that the exponent +/- the number of decimal digits fits into a 64 bit integer". +//! Larger exponents are accepted, but we don't do arithmetic with them, they are immediately +//! turned into {positive,negative} {zero,infinity}. + +#![doc(hidden)] +#![unstable(feature = "dec2flt", + reason = "internal routines only exposed for testing", + issue = "0")] + +use prelude::v1::*; +use fmt; +use str::FromStr; + +use self::parse::{parse_decimal, Decimal, Sign, ParseResult}; +use self::num::digits_to_big; +use self::rawfp::RawFloat; + +mod algorithm; +mod table; +mod num; +// These two have their own tests. +pub mod rawfp; +pub mod parse; + +macro_rules! from_str_float_impl { + ($t:ty) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl FromStr for $t { + type Err = ParseFloatError; + + /// Converts a string in base 10 to a float. + /// Accepts an optional decimal exponent. + /// + /// This function accepts strings such as + /// + /// * '3.14' + /// * '-3.14' + /// * '2.5E10', or equivalently, '2.5e10' + /// * '2.5E-10' + /// * '.' (understood as 0) + /// * '5.' + /// * '.5', or, equivalently, '0.5' + /// * 'inf', '-inf', 'NaN' + /// + /// Leading and trailing whitespace represent an error. + /// + /// # Arguments + /// + /// * src - A string + /// + /// # Return value + /// + /// `Err(ParseFloatError)` if the string did not represent a valid + /// number. Otherwise, `Ok(n)` where `n` is the floating-point + /// number represented by `src`. + #[inline] + fn from_str(src: &str) -> Result<Self, ParseFloatError> { + dec2flt(src) + } + } + } +} +from_str_float_impl!(f32); +from_str_float_impl!(f64); + +/// An error which can be returned when parsing a float. +/// +/// This error is used as the error type for the [`FromStr`] implementation +/// for [`f32`] and [`f64`]. +/// +/// [`FromStr`]: ../str/trait.FromStr.html +/// [`f32`]: ../../std/primitive.f32.html +/// [`f64`]: ../../std/primitive.f64.html +#[derive(Debug, Clone, PartialEq)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct ParseFloatError { + kind: FloatErrorKind +} + +#[derive(Debug, Clone, PartialEq)] +enum FloatErrorKind { + Empty, + Invalid, +} + +impl ParseFloatError { + #[unstable(feature = "int_error_internals", + reason = "available through Error trait and this method should \ + not be exposed publicly", + issue = "0")] + #[doc(hidden)] + pub fn __description(&self) -> &str { + match self.kind { + FloatErrorKind::Empty => "cannot parse float from empty string", + FloatErrorKind::Invalid => "invalid float literal", + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Display for ParseFloatError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.__description().fmt(f) + } +} + +fn pfe_empty() -> ParseFloatError { + ParseFloatError { kind: FloatErrorKind::Empty } +} + +fn pfe_invalid() -> ParseFloatError { + ParseFloatError { kind: FloatErrorKind::Invalid } +} + +/// Split decimal string into sign and the rest, without inspecting or validating the rest. +fn extract_sign(s: &str) -> (Sign, &str) { + match s.as_bytes()[0] { + b'+' => (Sign::Positive, &s[1..]), + b'-' => (Sign::Negative, &s[1..]), + // If the string is invalid, we never use the sign, so we don't need to validate here. + _ => (Sign::Positive, s), + } +} + +/// Convert a decimal string into a floating point number. +fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> { + if s.is_empty() { + return Err(pfe_empty()) + } + let (sign, s) = extract_sign(s); + let flt = match parse_decimal(s) { + ParseResult::Valid(decimal) => convert(decimal)?, + ParseResult::ShortcutToInf => T::infinity(), + ParseResult::ShortcutToZero => T::zero(), + ParseResult::Invalid => match s { + "inf" => T::infinity(), + "NaN" => T::nan(), + _ => { return Err(pfe_invalid()); } + } + }; + + match sign { + Sign::Positive => Ok(flt), + Sign::Negative => Ok(-flt), + } +} + +/// The main workhorse for the decimal-to-float conversion: Orchestrate all the preprocessing +/// and figure out which algorithm should do the actual conversion. +fn convert<T: RawFloat>(mut decimal: Decimal) -> Result<T, ParseFloatError> { + simplify(&mut decimal); + if let Some(x) = trivial_cases(&decimal) { + return Ok(x); + } + // Remove/shift out the decimal point. + let e = decimal.exp - decimal.fractional.len() as i64; + if let Some(x) = algorithm::fast_path(decimal.integral, decimal.fractional, e) { + return Ok(x); + } + // Big32x40 is limited to 1280 bits, which translates to about 385 decimal digits. + // If we exceed this, we'll crash, so we error out before getting too close (within 10^10). + let upper_bound = bound_intermediate_digits(&decimal, e); + if upper_bound > 375 { + return Err(pfe_invalid()); + } + let f = digits_to_big(decimal.integral, decimal.fractional); + + // Now the exponent certainly fits in 16 bit, which is used throughout the main algorithms. + let e = e as i16; + // FIXME These bounds are rather conservative. A more careful analysis of the failure modes + // of Bellerophon could allow using it in more cases for a massive speed up. + let exponent_in_range = table::MIN_E <= e && e <= table::MAX_E; + let value_in_range = upper_bound <= T::max_normal_digits() as u64; + if exponent_in_range && value_in_range { + Ok(algorithm::bellerophon(&f, e)) + } else { + Ok(algorithm::algorithm_m(&f, e)) + } +} + +// As written, this optimizes badly (see #27130, though it refers to an old version of the code). +// `inline(always)` is a workaround for that. There are only two call sites overall and it doesn't +// make code size worse. + +/// Strip zeros where possible, even when this requires changing the exponent +#[inline(always)] +fn simplify(decimal: &mut Decimal) { + let is_zero = &|&&d: &&u8| -> bool { d == b'0' }; + // Trimming these zeros does not change anything but may enable the fast path (< 15 digits). + let leading_zeros = decimal.integral.iter().take_while(is_zero).count(); + decimal.integral = &decimal.integral[leading_zeros..]; + let trailing_zeros = decimal.fractional.iter().rev().take_while(is_zero).count(); + let end = decimal.fractional.len() - trailing_zeros; + decimal.fractional = &decimal.fractional[..end]; + // Simplify numbers of the form 0.0...x and x...0.0, adjusting the exponent accordingly. + // This may not always be a win (possibly pushes some numbers out of the fast path), but it + // simplifies other parts significantly (notably, approximating the magnitude of the value). + if decimal.integral.is_empty() { + let leading_zeros = decimal.fractional.iter().take_while(is_zero).count(); + decimal.fractional = &decimal.fractional[leading_zeros..]; + decimal.exp -= leading_zeros as i64; + } else if decimal.fractional.is_empty() { + let trailing_zeros = decimal.integral.iter().rev().take_while(is_zero).count(); + let end = decimal.integral.len() - trailing_zeros; + decimal.integral = &decimal.integral[..end]; + decimal.exp += trailing_zeros as i64; + } +} + +/// Quick and dirty upper bound on the size (log10) of the largest value that Algorithm R and +/// Algorithm M will compute while working on the given decimal. +fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 { + // We don't need to worry too much about overflow here thanks to trivial_cases() and the + // parser, which filter out the most extreme inputs for us. + let f_len: u64 = decimal.integral.len() as u64 + decimal.fractional.len() as u64; + if e >= 0 { + // In the case e >= 0, both algorithms compute about `f * 10^e`. Algorithm R proceeds to + // do some complicated calculations with this but we can ignore that for the upper bound + // because it also reduces the fraction beforehand, so we have plenty of buffer there. + f_len + (e as u64) + } else { + // If e < 0, Algorithm R does roughly the same thing, but Algorithm M differs: + // It tries to find a positive number k such that `f << k / 10^e` is an in-range + // significand. This will result in about `2^53 * f * 10^e` < `10^17 * f * 10^e`. + // One input that triggers this is 0.33...33 (375 x 3). + f_len + (e.abs() as u64) + 17 + } +} + +/// Detect obvious overflows and underflows without even looking at the decimal digits. +fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> { + // There were zeros but they were stripped by simplify() + if decimal.integral.is_empty() && decimal.fractional.is_empty() { + return Some(T::zero()); + } + // This is a crude approximation of ceil(log10(the real value)). We don't need to worry too + // much about overflow here because the input length is tiny (at least compared to 2^64) and + // the parser already handles exponents whose absolute value is greater than 10^18 + // (which is still 10^19 short of 2^64). + let max_place = decimal.exp + decimal.integral.len() as i64; + if max_place > T::inf_cutoff() { + return Some(T::infinity()); + } else if max_place < T::zero_cutoff() { + return Some(T::zero()); + } + None +} diff --git a/libcore/num/dec2flt/num.rs b/libcore/num/dec2flt/num.rs new file mode 100644 index 0000000..81e7856 --- /dev/null +++ b/libcore/num/dec2flt/num.rs @@ -0,0 +1,94 @@ +// Copyright 2015 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. + +//! Utility functions for bignums that don't make too much sense to turn into methods. + +// FIXME This module's name is a bit unfortunate, since other modules also import `core::num`. + +use prelude::v1::*; +use cmp::Ordering::{self, Less, Equal, Greater}; + +pub use num::bignum::Big32x40 as Big; + +/// Test whether truncating all bits less significant than `ones_place` introduces +/// a relative error less, equal, or greater than 0.5 ULP. +pub fn compare_with_half_ulp(f: &Big, ones_place: usize) -> Ordering { + if ones_place == 0 { + return Less; + } + let half_bit = ones_place - 1; + if f.get_bit(half_bit) == 0 { + // < 0.5 ULP + return Less; + } + // If all remaining bits are zero, it's = 0.5 ULP, otherwise > 0.5 + // If there are no more bits (half_bit == 0), the below also correctly returns Equal. + for i in 0..half_bit { + if f.get_bit(i) == 1 { + return Greater; + } + } + Equal +} + +/// Convert an ASCII string containing only decimal digits to a `u64`. +/// +/// Does not perform checks for overflow or invalid characters, so if the caller is not careful, +/// the result is bogus and can panic (though it won't be `unsafe`). Additionally, empty strings +/// are treated as zero. This function exists because +/// +/// 1. using `FromStr` on `&[u8]` requires `from_utf8_unchecked`, which is bad, and +/// 2. piecing together the results of `integral.parse()` and `fractional.parse()` is +/// more complicated than this entire function. +pub fn from_str_unchecked<'a, T>(bytes: T) -> u64 where T : IntoIterator<Item=&'a u8> { + let mut result = 0; + for &c in bytes { + result = result * 10 + (c - b'0') as u64; + } + result +} + +/// Convert a string of ASCII digits into a bignum. +/// +/// Like `from_str_unchecked`, this function relies on the parser to weed out non-digits. +pub fn digits_to_big(integral: &[u8], fractional: &[u8]) -> Big { + let mut f = Big::from_small(0); + for &c in integral.iter().chain(fractional) { + let n = (c - b'0') as u32; + f.mul_small(10); + f.add_small(n); + } + f +} + +/// Unwraps a bignum into a 64 bit integer. Panics if the number is too large. +pub fn to_u64(x: &Big) -> u64 { + assert!(x.bit_length() < 64); + let d = x.digits(); + if d.len() < 2 { + d[0] as u64 + } else { + (d[1] as u64) << 32 | d[0] as u64 + } +} + + +/// Extract a range of bits. + +/// Index 0 is the least significant bit and the range is half-open as usual. +/// Panics if asked to extract more bits than fit into the return type. +pub fn get_bits(x: &Big, start: usize, end: usize) -> u64 { + assert!(end - start <= 64); + let mut result: u64 = 0; + for i in (start..end).rev() { + result = result << 1 | x.get_bit(i) as u64; + } + result +} diff --git a/libcore/num/dec2flt/parse.rs b/libcore/num/dec2flt/parse.rs new file mode 100644 index 0000000..fce1c25 --- /dev/null +++ b/libcore/num/dec2flt/parse.rs @@ -0,0 +1,134 @@ +// Copyright 2015 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. + +//! Validating and decomposing a decimal string of the form: +//! +//! `(digits | digits? '.'? digits?) (('e' | 'E') ('+' | '-')? digits)?` +//! +//! In other words, standard floating-point syntax, with two exceptions: No sign, and no +//! handling of "inf" and "NaN". These are handled by the driver function (super::dec2flt). +//! +//! Although recognizing valid inputs is relatively easy, this module also has to reject the +//! countless invalid variations, never panic, and perform numerous checks that the other +//! modules rely on to not panic (or overflow) in turn. +//! To make matters worse, all that happens in a single pass over the input. +//! So, be careful when modifying anything, and double-check with the other modules. +use prelude::v1::*; +use super::num; +use self::ParseResult::{Valid, ShortcutToInf, ShortcutToZero, Invalid}; + +#[derive(Debug)] +pub enum Sign { + Positive, + Negative, +} + +#[derive(Debug, PartialEq, Eq)] +/// The interesting parts of a decimal string. +pub struct Decimal<'a> { + pub integral: &'a [u8], + pub fractional: &'a [u8], + /// The decimal exponent, guaranteed to have fewer than 18 decimal digits. + pub exp: i64, +} + +impl<'a> Decimal<'a> { + pub fn new(integral: &'a [u8], fractional: &'a [u8], exp: i64) -> Decimal<'a> { + Decimal { integral: integral, fractional: fractional, exp: exp } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub enum ParseResult<'a> { + Valid(Decimal<'a>), + ShortcutToInf, + ShortcutToZero, + Invalid, +} + +/// Check if the input string is a valid floating point number and if so, locate the integral +/// part, the fractional part, and the exponent in it. Does not handle signs. +pub fn parse_decimal(s: &str) -> ParseResult { + if s.is_empty() { + return Invalid; + } + + let s = s.as_bytes(); + let (integral, s) = eat_digits(s); + + match s.first() { + None => Valid(Decimal::new(integral, b"", 0)), + Some(&b'e') | Some(&b'E') => { + if integral.is_empty() { + return Invalid; // No digits before 'e' + } + + parse_exp(integral, b"", &s[1..]) + } + Some(&b'.') => { + let (fractional, s) = eat_digits(&s[1..]); + if integral.is_empty() && fractional.is_empty() && s.is_empty() { + return Invalid; + } + + match s.first() { + None => Valid(Decimal::new(integral, fractional, 0)), + Some(&b'e') | Some(&b'E') => parse_exp(integral, fractional, &s[1..]), + _ => Invalid, // Trailing junk after fractional part + } + } + _ => Invalid, // Trailing junk after first digit string + } +} + +/// Carve off decimal digits up to the first non-digit character. +fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) { + let mut i = 0; + while i < s.len() && b'0' <= s[i] && s[i] <= b'9' { + i += 1; + } + (&s[..i], &s[i..]) +} + +/// Exponent extraction and error checking. +fn parse_exp<'a>(integral: &'a [u8], fractional: &'a [u8], rest: &'a [u8]) -> ParseResult<'a> { + let (sign, rest) = match rest.first() { + Some(&b'-') => (Sign::Negative, &rest[1..]), + Some(&b'+') => (Sign::Positive, &rest[1..]), + _ => (Sign::Positive, rest), + }; + let (mut number, trailing) = eat_digits(rest); + if !trailing.is_empty() { + return Invalid; // Trailing junk after exponent + } + if number.is_empty() { + return Invalid; // Empty exponent + } + // At this point, we certainly have a valid string of digits. It may be too long to put into + // an `i64`, but if it's that huge, the input is certainly zero or infinity. Since each zero + // in the decimal digits only adjusts the exponent by +/- 1, at exp = 10^18 the input would + // have to be 17 exabyte (!) of zeros to get even remotely close to being finite. + // This is not exactly a use case we need to cater to. + while number.first() == Some(&b'0') { + number = &number[1..]; + } + if number.len() >= 18 { + return match sign { + Sign::Positive => ShortcutToInf, + Sign::Negative => ShortcutToZero, + }; + } + let abs_exp = num::from_str_unchecked(number); + let e = match sign { + Sign::Positive => abs_exp as i64, + Sign::Negative => -(abs_exp as i64), + }; + Valid(Decimal::new(integral, fractional, e)) +} diff --git a/libcore/num/dec2flt/rawfp.rs b/libcore/num/dec2flt/rawfp.rs new file mode 100644 index 0000000..2099c6a --- /dev/null +++ b/libcore/num/dec2flt/rawfp.rs @@ -0,0 +1,368 @@ +// Copyright 2015 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. + +//! Bit fiddling on positive IEEE 754 floats. Negative numbers aren't and needn't be handled. +//! Normal floating point numbers have a canonical representation as (frac, exp) such that the +//! value is 2^exp * (1 + sum(frac[N-i] / 2^i)) where N is the number of bits. Subnormals are +//! slightly different and weird, but the same principle applies. +//! +//! Here, however, we represent them as (sig, k) with f positive, such that the value is f * 2^e. +//! Besides making the "hidden bit" explicit, this changes the exponent by the so-called +//! mantissa shift. +//! +//! Put another way, normally floats are written as (1) but here they are written as (2): +//! +//! 1. `1.101100...11 * 2^m` +//! 2. `1101100...11 * 2^n` +//! +//! We call (1) the **fractional representation** and (2) the **integral representation**. +//! +//! Many functions in this module only handle normal numbers. The dec2flt routines conservatively +//! take the universally-correct slow path (Algorithm M) for very small and very large numbers. +//! That algorithm needs only next_float() which does handle subnormals and zeros. +use prelude::v1::*; +use u32; +use cmp::Ordering::{Less, Equal, Greater}; +use ops::{Mul, Div, Neg}; +use fmt::{Debug, LowerExp}; +use mem::transmute; +use num::diy_float::Fp; +use num::FpCategory::{Infinite, Zero, Subnormal, Normal, Nan}; +use num::Float; +use num::dec2flt::num::{self, Big}; +use num::dec2flt::table; + +#[derive(Copy, Clone, Debug)] +pub struct Unpacked { + pub sig: u64, + pub k: i16, +} + +impl Unpacked { + pub fn new(sig: u64, k: i16) -> Self { + Unpacked { sig: sig, k: k } + } +} + +/// A helper trait to avoid duplicating basically all the conversion code for `f32` and `f64`. +/// +/// See the parent module's doc comment for why this is necessary. +/// +/// Should **never ever** be implemented for other types or be used outside the dec2flt module. +/// Inherits from `Float` because there is some overlap, but all the reused methods are trivial. +/// The "methods" (pseudo-constants) with default implementation should not be overriden. +pub trait RawFloat : Float + Copy + Debug + LowerExp + + Mul<Output=Self> + Div<Output=Self> + Neg<Output=Self> +{ + /// Get the raw binary representation of the float. + fn transmute(self) -> u64; + + /// Transmute the raw binary representation into a float. + fn from_bits(bits: u64) -> Self; + + /// Decode the float. + fn unpack(self) -> Unpacked; + + /// Cast from a small integer that can be represented exactly. Panic if the integer can't be + /// represented, the other code in this module makes sure to never let that happen. + fn from_int(x: u64) -> Self; + + /// Get the value 10^e from a pre-computed table. Panics for e >= ceil_log5_of_max_sig(). + fn short_fast_pow10(e: usize) -> Self; + + // FIXME Everything that follows should be associated constants, but taking the value of an + // associated constant from a type parameter does not work (yet?) + // A possible workaround is having a `FloatInfo` struct for all the constants, but so far + // the methods aren't painful enough to rewrite. + + /// What the name says. It's easier to hard code than juggling intrinsics and + /// hoping LLVM constant folds it. + fn ceil_log5_of_max_sig() -> i16; + + // A conservative bound on the decimal digits of inputs that can't produce overflow or zero or + /// subnormals. Probably the decimal exponent of the maximum normal value, hence the name. + fn max_normal_digits() -> usize; + + /// When the most significant decimal digit has a place value greater than this, the number + /// is certainly rounded to infinity. + fn inf_cutoff() -> i64; + + /// When the most significant decimal digit has a place value less than this, the number + /// is certainly rounded to zero. + fn zero_cutoff() -> i64; + + /// The number of bits in the exponent. + fn exp_bits() -> u8; + + /// The number of bits in the singificand, *including* the hidden bit. + fn sig_bits() -> u8; + + /// The number of bits in the singificand, *excluding* the hidden bit. + fn explicit_sig_bits() -> u8 { + Self::sig_bits() - 1 + } + + /// The maximum legal exponent in fractional representation. + fn max_exp() -> i16 { + (1 << (Self::exp_bits() - 1)) - 1 + } + + /// The minimum legal exponent in fractional representation, excluding subnormals. + fn min_exp() -> i16 { + -Self::max_exp() + 1 + } + + /// `MAX_EXP` for integral representation, i.e., with the shift applied. + fn max_exp_int() -> i16 { + Self::max_exp() - (Self::sig_bits() as i16 - 1) + } + + /// `MAX_EXP` encoded (i.e., with offset bias) + fn max_encoded_exp() -> i16 { + (1 << Self::exp_bits()) - 1 + } + + /// `MIN_EXP` for integral representation, i.e., with the shift applied. + fn min_exp_int() -> i16 { + Self::min_exp() - (Self::sig_bits() as i16 - 1) + } + + /// The maximum normalized singificand in integral representation. + fn max_sig() -> u64 { + (1 << Self::sig_bits()) - 1 + } + + /// The minimal normalized significand in integral representation. + fn min_sig() -> u64 { + 1 << (Self::sig_bits() - 1) + } +} + +impl RawFloat for f32 { + fn sig_bits() -> u8 { + 24 + } + + fn exp_bits() -> u8 { + 8 + } + + fn ceil_log5_of_max_sig() -> i16 { + 11 + } + + fn transmute(self) -> u64 { + let bits: u32 = unsafe { transmute(self) }; + bits as u64 + } + + fn from_bits(bits: u64) -> f32 { + assert!(bits < u32::MAX as u64, "f32::from_bits: too many bits"); + unsafe { transmute(bits as u32) } + } + + fn unpack(self) -> Unpacked { + let (sig, exp, _sig) = self.integer_decode(); + Unpacked::new(sig, exp) + } + + fn from_int(x: u64) -> f32 { + // rkruppe is uncertain whether `as` rounds correctly on all platforms. + debug_assert!(x as f32 == fp_to_float(Fp { f: x, e: 0 })); + x as f32 + } + + fn short_fast_pow10(e: usize) -> Self { + table::F32_SHORT_POWERS[e] + } + + fn max_normal_digits() -> usize { + 35 + } + + fn inf_cutoff() -> i64 { + 40 + } + + fn zero_cutoff() -> i64 { + -48 + } +} + + +impl RawFloat for f64 { + fn sig_bits() -> u8 { + 53 + } + + fn exp_bits() -> u8 { + 11 + } + + fn ceil_log5_of_max_sig() -> i16 { + 23 + } + + fn transmute(self) -> u64 { + let bits: u64 = unsafe { transmute(self) }; + bits + } + + fn from_bits(bits: u64) -> f64 { + unsafe { transmute(bits) } + } + + fn unpack(self) -> Unpacked { + let (sig, exp, _sig) = self.integer_decode(); + Unpacked::new(sig, exp) + } + + fn from_int(x: u64) -> f64 { + // rkruppe is uncertain whether `as` rounds correctly on all platforms. + debug_assert!(x as f64 == fp_to_float(Fp { f: x, e: 0 })); + x as f64 + } + + fn short_fast_pow10(e: usize) -> Self { + table::F64_SHORT_POWERS[e] + } + + fn max_normal_digits() -> usize { + 305 + } + + fn inf_cutoff() -> i64 { + 310 + } + + fn zero_cutoff() -> i64 { + -326 + } + +} + +/// Convert an Fp to the closest f64. Only handles number that fit into a normalized f64. +pub fn fp_to_float<T: RawFloat>(x: Fp) -> T { + let x = x.normalize(); + // x.f is 64 bit, so x.e has a mantissa shift of 63 + let e = x.e + 63; + if e > T::max_exp() { + panic!("fp_to_float: exponent {} too large", e) + } else if e > T::min_exp() { + encode_normal(round_normal::<T>(x)) + } else { + panic!("fp_to_float: exponent {} too small", e) + } +} + +/// Round the 64-bit significand to 53 bit with half-to-even. Does not handle exponent overflow. +pub fn round_normal<T: RawFloat>(x: Fp) -> Unpacked { + let excess = 64 - T::sig_bits() as i16; + let half: u64 = 1 << (excess - 1); + let (q, rem) = (x.f >> excess, x.f & ((1 << excess) - 1)); + assert_eq!(q << excess | rem, x.f); + // Adjust mantissa shift + let k = x.e + excess; + if rem < half { + Unpacked::new(q, k) + } else if rem == half && (q % 2) == 0 { + Unpacked::new(q, k) + } else if q == T::max_sig() { + Unpacked::new(T::min_sig(), k + 1) + } else { + Unpacked::new(q + 1, k) + } +} + +/// Inverse of `RawFloat::unpack()` for normalized numbers. +/// Panics if the significand or exponent are not valid for normalized numbers. +pub fn encode_normal<T: RawFloat>(x: Unpacked) -> T { + debug_assert!(T::min_sig() <= x.sig && x.sig <= T::max_sig(), + "encode_normal: significand not normalized"); + // Remove the hidden bit + let sig_enc = x.sig & !(1 << T::explicit_sig_bits()); + // Adjust the exponent for exponent bias and mantissa shift + let k_enc = x.k + T::max_exp() + T::explicit_sig_bits() as i16; + debug_assert!(k_enc != 0 && k_enc < T::max_encoded_exp(), + "encode_normal: exponent out of range"); + // Leave sign bit at 0 ("+"), our numbers are all positive + let bits = (k_enc as u64) << T::explicit_sig_bits() | sig_enc; + T::from_bits(bits) +} + +/// Construct the subnormal. A mantissa of 0 is allowed and constructs zero. +pub fn encode_subnormal<T: RawFloat>(significand: u64) -> T { + assert!(significand < T::min_sig(), "encode_subnormal: not actually subnormal"); + // Encoded exponent is 0, the sign bit is 0, so we just have to reinterpret the bits. + T::from_bits(significand) +} + +/// Approximate a bignum with an Fp. Rounds within 0.5 ULP with half-to-even. +pub fn big_to_fp(f: &Big) -> Fp { + let end = f.bit_length(); + assert!(end != 0, "big_to_fp: unexpectedly, input is zero"); + let start = end.saturating_sub(64); + let leading = num::get_bits(f, start, end); + // We cut off all bits prior to the index `start`, i.e., we effectively right-shift by + // an amount of `start`, so this is also the exponent we need. + let e = start as i16; + let rounded_down = Fp { f: leading, e: e }.normalize(); + // Round (half-to-even) depending on the truncated bits. + match num::compare_with_half_ulp(f, start) { + Less => rounded_down, + Equal if leading % 2 == 0 => rounded_down, + Equal | Greater => match leading.checked_add(1) { + Some(f) => Fp { f: f, e: e }.normalize(), + None => Fp { f: 1 << 63, e: e + 1 }, + } + } +} + +/// Find the largest floating point number strictly smaller than the argument. +/// Does not handle subnormals, zero, or exponent underflow. +pub fn prev_float<T: RawFloat>(x: T) -> T { + match x.classify() { + Infinite => panic!("prev_float: argument is infinite"), + Nan => panic!("prev_float: argument is NaN"), + Subnormal => panic!("prev_float: argument is subnormal"), + Zero => panic!("prev_float: argument is zero"), + Normal => { + let Unpacked { sig, k } = x.unpack(); + if sig == T::min_sig() { + encode_normal(Unpacked::new(T::max_sig(), k - 1)) + } else { + encode_normal(Unpacked::new(sig - 1, k)) + } + } + } +} + +// Find the smallest floating point number strictly larger than the argument. +// This operation is saturating, i.e. next_float(inf) == inf. +// Unlike most code in this module, this function does handle zero, subnormals, and infinities. +// However, like all other code here, it does not deal with NaN and negative numbers. +pub fn next_float<T: RawFloat>(x: T) -> T { + match x.classify() { + Nan => panic!("next_float: argument is NaN"), + Infinite => T::infinity(), + // This seems too good to be true, but it works. + // 0.0 is encoded as the all-zero word. Subnormals are 0x000m...m where m is the mantissa. + // In particular, the smallest subnormal is 0x0...01 and the largest is 0x000F...F. + // The smallest normal number is 0x0010...0, so this corner case works as well. + // If the increment overflows the mantissa, the carry bit increments the exponent as we + // want, and the mantissa bits become zero. Because of the hidden bit convention, this + // too is exactly what we want! + // Finally, f64::MAX + 1 = 7eff...f + 1 = 7ff0...0 = f64::INFINITY. + Zero | Subnormal | Normal => { + let bits: u64 = x.transmute(); + T::from_bits(bits + 1) + } + } +} diff --git a/libcore/num/dec2flt/table.rs b/libcore/num/dec2flt/table.rs new file mode 100644 index 0000000..cb8c943 --- /dev/null +++ b/libcore/num/dec2flt/table.rs @@ -0,0 +1,1281 @@ +// Copyright 2015 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. + +//! Tables of approximations of powers of ten. +//! DO NOT MODIFY: Generated by `src/etc/dec2flt_table.py` + +pub const MIN_E: i16 = -305; +pub const MAX_E: i16 = 305; + +pub const POWERS: ([u64; 611], [i16; 611]) = ([ + 0xe0b62e2929aba83c, + 0x8c71dcd9ba0b4926, + 0xaf8e5410288e1b6f, + 0xdb71e91432b1a24b, + 0x892731ac9faf056f, + 0xab70fe17c79ac6ca, + 0xd64d3d9db981787d, + 0x85f0468293f0eb4e, + 0xa76c582338ed2622, + 0xd1476e2c07286faa, + 0x82cca4db847945ca, + 0xa37fce126597973d, + 0xcc5fc196fefd7d0c, + 0xff77b1fcbebcdc4f, + 0x9faacf3df73609b1, + 0xc795830d75038c1e, + 0xf97ae3d0d2446f25, + 0x9becce62836ac577, + 0xc2e801fb244576d5, + 0xf3a20279ed56d48a, + 0x9845418c345644d7, + 0xbe5691ef416bd60c, + 0xedec366b11c6cb8f, + 0x94b3a202eb1c3f39, + 0xb9e08a83a5e34f08, + 0xe858ad248f5c22ca, + 0x91376c36d99995be, + 0xb58547448ffffb2e, + 0xe2e69915b3fff9f9, + 0x8dd01fad907ffc3c, + 0xb1442798f49ffb4b, + 0xdd95317f31c7fa1d, + 0x8a7d3eef7f1cfc52, + 0xad1c8eab5ee43b67, + 0xd863b256369d4a41, + 0x873e4f75e2224e68, + 0xa90de3535aaae202, + 0xd3515c2831559a83, + 0x8412d9991ed58092, + 0xa5178fff668ae0b6, + 0xce5d73ff402d98e4, + 0x80fa687f881c7f8e, + 0xa139029f6a239f72, + 0xc987434744ac874f, + 0xfbe9141915d7a922, + 0x9d71ac8fada6c9b5, + 0xc4ce17b399107c23, + 0xf6019da07f549b2b, + 0x99c102844f94e0fb, + 0xc0314325637a193a, + 0xf03d93eebc589f88, + 0x96267c7535b763b5, + 0xbbb01b9283253ca3, + 0xea9c227723ee8bcb, + 0x92a1958a7675175f, + 0xb749faed14125d37, + 0xe51c79a85916f485, + 0x8f31cc0937ae58d3, + 0xb2fe3f0b8599ef08, + 0xdfbdcece67006ac9, + 0x8bd6a141006042be, + 0xaecc49914078536d, + 0xda7f5bf590966849, + 0x888f99797a5e012d, + 0xaab37fd7d8f58179, + 0xd5605fcdcf32e1d7, + 0x855c3be0a17fcd26, + 0xa6b34ad8c9dfc070, + 0xd0601d8efc57b08c, + 0x823c12795db6ce57, + 0xa2cb1717b52481ed, + 0xcb7ddcdda26da269, + 0xfe5d54150b090b03, + 0x9efa548d26e5a6e2, + 0xc6b8e9b0709f109a, + 0xf867241c8cc6d4c1, + 0x9b407691d7fc44f8, + 0xc21094364dfb5637, + 0xf294b943e17a2bc4, + 0x979cf3ca6cec5b5b, + 0xbd8430bd08277231, + 0xece53cec4a314ebe, + 0x940f4613ae5ed137, + 0xb913179899f68584, + 0xe757dd7ec07426e5, + 0x9096ea6f3848984f, + 0xb4bca50b065abe63, + 0xe1ebce4dc7f16dfc, + 0x8d3360f09cf6e4bd, + 0xb080392cc4349ded, + 0xdca04777f541c568, + 0x89e42caaf9491b61, + 0xac5d37d5b79b6239, + 0xd77485cb25823ac7, + 0x86a8d39ef77164bd, + 0xa8530886b54dbdec, + 0xd267caa862a12d67, + 0x8380dea93da4bc60, + 0xa46116538d0deb78, + 0xcd795be870516656, + 0x806bd9714632dff6, + 0xa086cfcd97bf97f4, + 0xc8a883c0fdaf7df0, + 0xfad2a4b13d1b5d6c, + 0x9cc3a6eec6311a64, + 0xc3f490aa77bd60fd, + 0xf4f1b4d515acb93c, + 0x991711052d8bf3c5, + 0xbf5cd54678eef0b7, + 0xef340a98172aace5, + 0x9580869f0e7aac0f, + 0xbae0a846d2195713, + 0xe998d258869facd7, + 0x91ff83775423cc06, + 0xb67f6455292cbf08, + 0xe41f3d6a7377eeca, + 0x8e938662882af53e, + 0xb23867fb2a35b28e, + 0xdec681f9f4c31f31, + 0x8b3c113c38f9f37f, + 0xae0b158b4738705f, + 0xd98ddaee19068c76, + 0x87f8a8d4cfa417ca, + 0xa9f6d30a038d1dbc, + 0xd47487cc8470652b, + 0x84c8d4dfd2c63f3b, + 0xa5fb0a17c777cf0a, + 0xcf79cc9db955c2cc, + 0x81ac1fe293d599c0, + 0xa21727db38cb0030, + 0xca9cf1d206fdc03c, + 0xfd442e4688bd304b, + 0x9e4a9cec15763e2f, + 0xc5dd44271ad3cdba, + 0xf7549530e188c129, + 0x9a94dd3e8cf578ba, + 0xc13a148e3032d6e8, + 0xf18899b1bc3f8ca2, + 0x96f5600f15a7b7e5, + 0xbcb2b812db11a5de, + 0xebdf661791d60f56, + 0x936b9fcebb25c996, + 0xb84687c269ef3bfb, + 0xe65829b3046b0afa, + 0x8ff71a0fe2c2e6dc, + 0xb3f4e093db73a093, + 0xe0f218b8d25088b8, + 0x8c974f7383725573, + 0xafbd2350644eead0, + 0xdbac6c247d62a584, + 0x894bc396ce5da772, + 0xab9eb47c81f5114f, + 0xd686619ba27255a3, + 0x8613fd0145877586, + 0xa798fc4196e952e7, + 0xd17f3b51fca3a7a1, + 0x82ef85133de648c5, + 0xa3ab66580d5fdaf6, + 0xcc963fee10b7d1b3, + 0xffbbcfe994e5c620, + 0x9fd561f1fd0f9bd4, + 0xc7caba6e7c5382c9, + 0xf9bd690a1b68637b, + 0x9c1661a651213e2d, + 0xc31bfa0fe5698db8, + 0xf3e2f893dec3f126, + 0x986ddb5c6b3a76b8, + 0xbe89523386091466, + 0xee2ba6c0678b597f, + 0x94db483840b717f0, + 0xba121a4650e4ddec, + 0xe896a0d7e51e1566, + 0x915e2486ef32cd60, + 0xb5b5ada8aaff80b8, + 0xe3231912d5bf60e6, + 0x8df5efabc5979c90, + 0xb1736b96b6fd83b4, + 0xddd0467c64bce4a1, + 0x8aa22c0dbef60ee4, + 0xad4ab7112eb3929e, + 0xd89d64d57a607745, + 0x87625f056c7c4a8b, + 0xa93af6c6c79b5d2e, + 0xd389b47879823479, + 0x843610cb4bf160cc, + 0xa54394fe1eedb8ff, + 0xce947a3da6a9273e, + 0x811ccc668829b887, + 0xa163ff802a3426a9, + 0xc9bcff6034c13053, + 0xfc2c3f3841f17c68, + 0x9d9ba7832936edc1, + 0xc5029163f384a931, + 0xf64335bcf065d37d, + 0x99ea0196163fa42e, + 0xc06481fb9bcf8d3a, + 0xf07da27a82c37088, + 0x964e858c91ba2655, + 0xbbe226efb628afeb, + 0xeadab0aba3b2dbe5, + 0x92c8ae6b464fc96f, + 0xb77ada0617e3bbcb, + 0xe55990879ddcaabe, + 0x8f57fa54c2a9eab7, + 0xb32df8e9f3546564, + 0xdff9772470297ebd, + 0x8bfbea76c619ef36, + 0xaefae51477a06b04, + 0xdab99e59958885c5, + 0x88b402f7fd75539b, + 0xaae103b5fcd2a882, + 0xd59944a37c0752a2, + 0x857fcae62d8493a5, + 0xa6dfbd9fb8e5b88f, + 0xd097ad07a71f26b2, + 0x825ecc24c8737830, + 0xa2f67f2dfa90563b, + 0xcbb41ef979346bca, + 0xfea126b7d78186bd, + 0x9f24b832e6b0f436, + 0xc6ede63fa05d3144, + 0xf8a95fcf88747d94, + 0x9b69dbe1b548ce7d, + 0xc24452da229b021c, + 0xf2d56790ab41c2a3, + 0x97c560ba6b0919a6, + 0xbdb6b8e905cb600f, + 0xed246723473e3813, + 0x9436c0760c86e30c, + 0xb94470938fa89bcf, + 0xe7958cb87392c2c3, + 0x90bd77f3483bb9ba, + 0xb4ecd5f01a4aa828, + 0xe2280b6c20dd5232, + 0x8d590723948a535f, + 0xb0af48ec79ace837, + 0xdcdb1b2798182245, + 0x8a08f0f8bf0f156b, + 0xac8b2d36eed2dac6, + 0xd7adf884aa879177, + 0x86ccbb52ea94baeb, + 0xa87fea27a539e9a5, + 0xd29fe4b18e88640f, + 0x83a3eeeef9153e89, + 0xa48ceaaab75a8e2b, + 0xcdb02555653131b6, + 0x808e17555f3ebf12, + 0xa0b19d2ab70e6ed6, + 0xc8de047564d20a8c, + 0xfb158592be068d2f, + 0x9ced737bb6c4183d, + 0xc428d05aa4751e4d, + 0xf53304714d9265e0, + 0x993fe2c6d07b7fac, + 0xbf8fdb78849a5f97, + 0xef73d256a5c0f77d, + 0x95a8637627989aae, + 0xbb127c53b17ec159, + 0xe9d71b689dde71b0, + 0x9226712162ab070e, + 0xb6b00d69bb55c8d1, + 0xe45c10c42a2b3b06, + 0x8eb98a7a9a5b04e3, + 0xb267ed1940f1c61c, + 0xdf01e85f912e37a3, + 0x8b61313bbabce2c6, + 0xae397d8aa96c1b78, + 0xd9c7dced53c72256, + 0x881cea14545c7575, + 0xaa242499697392d3, + 0xd4ad2dbfc3d07788, + 0x84ec3c97da624ab5, + 0xa6274bbdd0fadd62, + 0xcfb11ead453994ba, + 0x81ceb32c4b43fcf5, + 0xa2425ff75e14fc32, + 0xcad2f7f5359a3b3e, + 0xfd87b5f28300ca0e, + 0x9e74d1b791e07e48, + 0xc612062576589ddb, + 0xf79687aed3eec551, + 0x9abe14cd44753b53, + 0xc16d9a0095928a27, + 0xf1c90080baf72cb1, + 0x971da05074da7bef, + 0xbce5086492111aeb, + 0xec1e4a7db69561a5, + 0x9392ee8e921d5d07, + 0xb877aa3236a4b449, + 0xe69594bec44de15b, + 0x901d7cf73ab0acd9, + 0xb424dc35095cd80f, + 0xe12e13424bb40e13, + 0x8cbccc096f5088cc, + 0xafebff0bcb24aaff, + 0xdbe6fecebdedd5bf, + 0x89705f4136b4a597, + 0xabcc77118461cefd, + 0xd6bf94d5e57a42bc, + 0x8637bd05af6c69b6, + 0xa7c5ac471b478423, + 0xd1b71758e219652c, + 0x83126e978d4fdf3b, + 0xa3d70a3d70a3d70a, + 0xcccccccccccccccd, + 0x8000000000000000, + 0xa000000000000000, + 0xc800000000000000, + 0xfa00000000000000, + 0x9c40000000000000, + 0xc350000000000000, + 0xf424000000000000, + 0x9896800000000000, + 0xbebc200000000000, + 0xee6b280000000000, + 0x9502f90000000000, + 0xba43b74000000000, + 0xe8d4a51000000000, + 0x9184e72a00000000, + 0xb5e620f480000000, + 0xe35fa931a0000000, + 0x8e1bc9bf04000000, + 0xb1a2bc2ec5000000, + 0xde0b6b3a76400000, + 0x8ac7230489e80000, + 0xad78ebc5ac620000, + 0xd8d726b7177a8000, + 0x878678326eac9000, + 0xa968163f0a57b400, + 0xd3c21bcecceda100, + 0x84595161401484a0, + 0xa56fa5b99019a5c8, + 0xcecb8f27f4200f3a, + 0x813f3978f8940984, + 0xa18f07d736b90be5, + 0xc9f2c9cd04674edf, + 0xfc6f7c4045812296, + 0x9dc5ada82b70b59e, + 0xc5371912364ce305, + 0xf684df56c3e01bc7, + 0x9a130b963a6c115c, + 0xc097ce7bc90715b3, + 0xf0bdc21abb48db20, + 0x96769950b50d88f4, + 0xbc143fa4e250eb31, + 0xeb194f8e1ae525fd, + 0x92efd1b8d0cf37be, + 0xb7abc627050305ae, + 0xe596b7b0c643c719, + 0x8f7e32ce7bea5c70, + 0xb35dbf821ae4f38c, + 0xe0352f62a19e306f, + 0x8c213d9da502de45, + 0xaf298d050e4395d7, + 0xdaf3f04651d47b4c, + 0x88d8762bf324cd10, + 0xab0e93b6efee0054, + 0xd5d238a4abe98068, + 0x85a36366eb71f041, + 0xa70c3c40a64e6c52, + 0xd0cf4b50cfe20766, + 0x82818f1281ed44a0, + 0xa321f2d7226895c8, + 0xcbea6f8ceb02bb3a, + 0xfee50b7025c36a08, + 0x9f4f2726179a2245, + 0xc722f0ef9d80aad6, + 0xf8ebad2b84e0d58c, + 0x9b934c3b330c8577, + 0xc2781f49ffcfa6d5, + 0xf316271c7fc3908b, + 0x97edd871cfda3a57, + 0xbde94e8e43d0c8ec, + 0xed63a231d4c4fb27, + 0x945e455f24fb1cf9, + 0xb975d6b6ee39e437, + 0xe7d34c64a9c85d44, + 0x90e40fbeea1d3a4b, + 0xb51d13aea4a488dd, + 0xe264589a4dcdab15, + 0x8d7eb76070a08aed, + 0xb0de65388cc8ada8, + 0xdd15fe86affad912, + 0x8a2dbf142dfcc7ab, + 0xacb92ed9397bf996, + 0xd7e77a8f87daf7fc, + 0x86f0ac99b4e8dafd, + 0xa8acd7c0222311bd, + 0xd2d80db02aabd62c, + 0x83c7088e1aab65db, + 0xa4b8cab1a1563f52, + 0xcde6fd5e09abcf27, + 0x80b05e5ac60b6178, + 0xa0dc75f1778e39d6, + 0xc913936dd571c84c, + 0xfb5878494ace3a5f, + 0x9d174b2dcec0e47b, + 0xc45d1df942711d9a, + 0xf5746577930d6501, + 0x9968bf6abbe85f20, + 0xbfc2ef456ae276e9, + 0xefb3ab16c59b14a3, + 0x95d04aee3b80ece6, + 0xbb445da9ca61281f, + 0xea1575143cf97227, + 0x924d692ca61be758, + 0xb6e0c377cfa2e12e, + 0xe498f455c38b997a, + 0x8edf98b59a373fec, + 0xb2977ee300c50fe7, + 0xdf3d5e9bc0f653e1, + 0x8b865b215899f46d, + 0xae67f1e9aec07188, + 0xda01ee641a708dea, + 0x884134fe908658b2, + 0xaa51823e34a7eedf, + 0xd4e5e2cdc1d1ea96, + 0x850fadc09923329e, + 0xa6539930bf6bff46, + 0xcfe87f7cef46ff17, + 0x81f14fae158c5f6e, + 0xa26da3999aef774a, + 0xcb090c8001ab551c, + 0xfdcb4fa002162a63, + 0x9e9f11c4014dda7e, + 0xc646d63501a1511e, + 0xf7d88bc24209a565, + 0x9ae757596946075f, + 0xc1a12d2fc3978937, + 0xf209787bb47d6b85, + 0x9745eb4d50ce6333, + 0xbd176620a501fc00, + 0xec5d3fa8ce427b00, + 0x93ba47c980e98ce0, + 0xb8a8d9bbe123f018, + 0xe6d3102ad96cec1e, + 0x9043ea1ac7e41393, + 0xb454e4a179dd1877, + 0xe16a1dc9d8545e95, + 0x8ce2529e2734bb1d, + 0xb01ae745b101e9e4, + 0xdc21a1171d42645d, + 0x899504ae72497eba, + 0xabfa45da0edbde69, + 0xd6f8d7509292d603, + 0x865b86925b9bc5c2, + 0xa7f26836f282b733, + 0xd1ef0244af2364ff, + 0x8335616aed761f1f, + 0xa402b9c5a8d3a6e7, + 0xcd036837130890a1, + 0x802221226be55a65, + 0xa02aa96b06deb0fe, + 0xc83553c5c8965d3d, + 0xfa42a8b73abbf48d, + 0x9c69a97284b578d8, + 0xc38413cf25e2d70e, + 0xf46518c2ef5b8cd1, + 0x98bf2f79d5993803, + 0xbeeefb584aff8604, + 0xeeaaba2e5dbf6785, + 0x952ab45cfa97a0b3, + 0xba756174393d88e0, + 0xe912b9d1478ceb17, + 0x91abb422ccb812ef, + 0xb616a12b7fe617aa, + 0xe39c49765fdf9d95, + 0x8e41ade9fbebc27d, + 0xb1d219647ae6b31c, + 0xde469fbd99a05fe3, + 0x8aec23d680043bee, + 0xada72ccc20054aea, + 0xd910f7ff28069da4, + 0x87aa9aff79042287, + 0xa99541bf57452b28, + 0xd3fa922f2d1675f2, + 0x847c9b5d7c2e09b7, + 0xa59bc234db398c25, + 0xcf02b2c21207ef2f, + 0x8161afb94b44f57d, + 0xa1ba1ba79e1632dc, + 0xca28a291859bbf93, + 0xfcb2cb35e702af78, + 0x9defbf01b061adab, + 0xc56baec21c7a1916, + 0xf6c69a72a3989f5c, + 0x9a3c2087a63f6399, + 0xc0cb28a98fcf3c80, + 0xf0fdf2d3f3c30b9f, + 0x969eb7c47859e744, + 0xbc4665b596706115, + 0xeb57ff22fc0c795a, + 0x9316ff75dd87cbd8, + 0xb7dcbf5354e9bece, + 0xe5d3ef282a242e82, + 0x8fa475791a569d11, + 0xb38d92d760ec4455, + 0xe070f78d3927556b, + 0x8c469ab843b89563, + 0xaf58416654a6babb, + 0xdb2e51bfe9d0696a, + 0x88fcf317f22241e2, + 0xab3c2fddeeaad25b, + 0xd60b3bd56a5586f2, + 0x85c7056562757457, + 0xa738c6bebb12d16d, + 0xd106f86e69d785c8, + 0x82a45b450226b39d, + 0xa34d721642b06084, + 0xcc20ce9bd35c78a5, + 0xff290242c83396ce, + 0x9f79a169bd203e41, + 0xc75809c42c684dd1, + 0xf92e0c3537826146, + 0x9bbcc7a142b17ccc, + 0xc2abf989935ddbfe, + 0xf356f7ebf83552fe, + 0x98165af37b2153df, + 0xbe1bf1b059e9a8d6, + 0xeda2ee1c7064130c, + 0x9485d4d1c63e8be8, + 0xb9a74a0637ce2ee1, + 0xe8111c87c5c1ba9a, + 0x910ab1d4db9914a0, + 0xb54d5e4a127f59c8, + 0xe2a0b5dc971f303a, + 0x8da471a9de737e24, + 0xb10d8e1456105dad, + 0xdd50f1996b947519, + 0x8a5296ffe33cc930, + 0xace73cbfdc0bfb7b, + 0xd8210befd30efa5a, + 0x8714a775e3e95c78, + 0xa8d9d1535ce3b396, + 0xd31045a8341ca07c, + 0x83ea2b892091e44e, + 0xa4e4b66b68b65d61, + 0xce1de40642e3f4b9, + 0x80d2ae83e9ce78f4, + 0xa1075a24e4421731, + 0xc94930ae1d529cfd, + 0xfb9b7cd9a4a7443c, + 0x9d412e0806e88aa6, + 0xc491798a08a2ad4f, + 0xf5b5d7ec8acb58a3, + 0x9991a6f3d6bf1766, + 0xbff610b0cc6edd3f, + 0xeff394dcff8a948f, + 0x95f83d0a1fb69cd9, + 0xbb764c4ca7a44410, + 0xea53df5fd18d5514, + 0x92746b9be2f8552c, + 0xb7118682dbb66a77, + 0xe4d5e82392a40515, + 0x8f05b1163ba6832d, + 0xb2c71d5bca9023f8, + 0xdf78e4b2bd342cf7, + 0x8bab8eefb6409c1a, + 0xae9672aba3d0c321, + 0xda3c0f568cc4f3e9, + 0x8865899617fb1871, + 0xaa7eebfb9df9de8e, + 0xd51ea6fa85785631, + 0x8533285c936b35df, + 0xa67ff273b8460357, + 0xd01fef10a657842c, + 0x8213f56a67f6b29c, + 0xa298f2c501f45f43, + 0xcb3f2f7642717713, + 0xfe0efb53d30dd4d8, + 0x9ec95d1463e8a507, + 0xc67bb4597ce2ce49, + 0xf81aa16fdc1b81db, + 0x9b10a4e5e9913129, + 0xc1d4ce1f63f57d73, + 0xf24a01a73cf2dcd0, + 0x976e41088617ca02, + 0xbd49d14aa79dbc82, + 0xec9c459d51852ba3, + 0x93e1ab8252f33b46, + 0xb8da1662e7b00a17, + 0xe7109bfba19c0c9d, + 0x906a617d450187e2, + 0xb484f9dc9641e9db, + 0xe1a63853bbd26451, + 0x8d07e33455637eb3, + 0xb049dc016abc5e60, + 0xdc5c5301c56b75f7, + 0x89b9b3e11b6329bb, + 0xac2820d9623bf429, + 0xd732290fbacaf134, + 0x867f59a9d4bed6c0, + 0xa81f301449ee8c70, + 0xd226fc195c6a2f8c, + 0x83585d8fd9c25db8, + 0xa42e74f3d032f526, + 0xcd3a1230c43fb26f, + 0x80444b5e7aa7cf85, + 0xa0555e361951c367, + 0xc86ab5c39fa63441, + 0xfa856334878fc151, + 0x9c935e00d4b9d8d2, + 0xc3b8358109e84f07, + 0xf4a642e14c6262c9, + 0x98e7e9cccfbd7dbe, + 0xbf21e44003acdd2d, + 0xeeea5d5004981478, + 0x95527a5202df0ccb, + 0xbaa718e68396cffe, + 0xe950df20247c83fd, + 0x91d28b7416cdd27e, +], [ + -1077, + -1073, + -1070, + -1067, + -1063, + -1060, + -1057, + -1053, + -1050, + -1047, + -1043, + -1040, + -1037, + -1034, + -1030, + -1027, + -1024, + -1020, + -1017, + -1014, + -1010, + -1007, + -1004, + -1000, + -997, + -994, + -990, + -987, + -984, + -980, + -977, + -974, + -970, + -967, + -964, + -960, + -957, + -954, + -950, + -947, + -944, + -940, + -937, + -934, + -931, + -927, + -924, + -921, + -917, + -914, + -911, + -907, + -904, + -901, + -897, + -894, + -891, + -887, + -884, + -881, + -877, + -874, + -871, + -867, + -864, + -861, + -857, + -854, + -851, + -847, + -844, + -841, + -838, + -834, + -831, + -828, + -824, + -821, + -818, + -814, + -811, + -808, + -804, + -801, + -798, + -794, + -791, + -788, + -784, + -781, + -778, + -774, + -771, + -768, + -764, + -761, + -758, + -754, + -751, + -748, + -744, + -741, + -738, + -735, + -731, + -728, + -725, + -721, + -718, + -715, + -711, + -708, + -705, + -701, + -698, + -695, + -691, + -688, + -685, + -681, + -678, + -675, + -671, + -668, + -665, + -661, + -658, + -655, + -651, + -648, + -645, + -642, + -638, + -635, + -632, + -628, + -625, + -622, + -618, + -615, + -612, + -608, + -605, + -602, + -598, + -595, + -592, + -588, + -585, + -582, + -578, + -575, + -572, + -568, + -565, + -562, + -558, + -555, + -552, + -549, + -545, + -542, + -539, + -535, + -532, + -529, + -525, + -522, + -519, + -515, + -512, + -509, + -505, + -502, + -499, + -495, + -492, + -489, + -485, + -482, + -479, + -475, + -472, + -469, + -465, + -462, + -459, + -455, + -452, + -449, + -446, + -442, + -439, + -436, + -432, + -429, + -426, + -422, + -419, + -416, + -412, + -409, + -406, + -402, + -399, + -396, + -392, + -389, + -386, + -382, + -379, + -376, + -372, + -369, + -366, + -362, + -359, + -356, + -353, + -349, + -346, + -343, + -339, + -336, + -333, + -329, + -326, + -323, + -319, + -316, + -313, + -309, + -306, + -303, + -299, + -296, + -293, + -289, + -286, + -283, + -279, + -276, + -273, + -269, + -266, + -263, + -259, + -256, + -253, + -250, + -246, + -243, + -240, + -236, + -233, + -230, + -226, + -223, + -220, + -216, + -213, + -210, + -206, + -203, + -200, + -196, + -193, + -190, + -186, + -183, + -180, + -176, + -173, + -170, + -166, + -163, + -160, + -157, + -153, + -150, + -147, + -143, + -140, + -137, + -133, + -130, + -127, + -123, + -120, + -117, + -113, + -110, + -107, + -103, + -100, + -97, + -93, + -90, + -87, + -83, + -80, + -77, + -73, + -70, + -67, + -63, + -60, + -57, + -54, + -50, + -47, + -44, + -40, + -37, + -34, + -30, + -27, + -24, + -20, + -17, + -14, + -10, + -7, + -4, + 0, + 3, + 6, + 10, + 13, + 16, + 20, + 23, + 26, + 30, + 33, + 36, + 39, + 43, + 46, + 49, + 53, + 56, + 59, + 63, + 66, + 69, + 73, + 76, + 79, + 83, + 86, + 89, + 93, + 96, + 99, + 103, + 106, + 109, + 113, + 116, + 119, + 123, + 126, + 129, + 132, + 136, + 139, + 142, + 146, + 149, + 152, + 156, + 159, + 162, + 166, + 169, + 172, + 176, + 179, + 182, + 186, + 189, + 192, + 196, + 199, + 202, + 206, + 209, + 212, + 216, + 219, + 222, + 226, + 229, + 232, + 235, + 239, + 242, + 245, + 249, + 252, + 255, + 259, + 262, + 265, + 269, + 272, + 275, + 279, + 282, + 285, + 289, + 292, + 295, + 299, + 302, + 305, + 309, + 312, + 315, + 319, + 322, + 325, + 328, + 332, + 335, + 338, + 342, + 345, + 348, + 352, + 355, + 358, + 362, + 365, + 368, + 372, + 375, + 378, + 382, + 385, + 388, + 392, + 395, + 398, + 402, + 405, + 408, + 412, + 415, + 418, + 422, + 425, + 428, + 431, + 435, + 438, + 441, + 445, + 448, + 451, + 455, + 458, + 461, + 465, + 468, + 471, + 475, + 478, + 481, + 485, + 488, + 491, + 495, + 498, + 501, + 505, + 508, + 511, + 515, + 518, + 521, + 524, + 528, + 531, + 534, + 538, + 541, + 544, + 548, + 551, + 554, + 558, + 561, + 564, + 568, + 571, + 574, + 578, + 581, + 584, + 588, + 591, + 594, + 598, + 601, + 604, + 608, + 611, + 614, + 617, + 621, + 624, + 627, + 631, + 634, + 637, + 641, + 644, + 647, + 651, + 654, + 657, + 661, + 664, + 667, + 671, + 674, + 677, + 681, + 684, + 687, + 691, + 694, + 697, + 701, + 704, + 707, + 711, + 714, + 717, + 720, + 724, + 727, + 730, + 734, + 737, + 740, + 744, + 747, + 750, + 754, + 757, + 760, + 764, + 767, + 770, + 774, + 777, + 780, + 784, + 787, + 790, + 794, + 797, + 800, + 804, + 807, + 810, + 813, + 817, + 820, + 823, + 827, + 830, + 833, + 837, + 840, + 843, + 847, + 850, + 853, + 857, + 860, + 863, + 867, + 870, + 873, + 877, + 880, + 883, + 887, + 890, + 893, + 897, + 900, + 903, + 907, + 910, + 913, + 916, + 920, + 923, + 926, + 930, + 933, + 936, + 940, + 943, + 946, + 950, +]); + +pub const F32_SHORT_POWERS: [f32; 11] = [ + 1e0, + 1e1, + 1e2, + 1e3, + 1e4, + 1e5, + 1e6, + 1e7, + 1e8, + 1e9, + 1e10, +]; + +pub const F64_SHORT_POWERS: [f64; 23] = [ + 1e0, + 1e1, + 1e2, + 1e3, + 1e4, + 1e5, + 1e6, + 1e7, + 1e8, + 1e9, + 1e10, + 1e11, + 1e12, + 1e13, + 1e14, + 1e15, + 1e16, + 1e17, + 1e18, + 1e19, + 1e20, + 1e21, + 1e22, +]; diff --git a/libcore/num/diy_float.rs b/libcore/num/diy_float.rs new file mode 100644 index 0000000..7c369ee --- /dev/null +++ b/libcore/num/diy_float.rs @@ -0,0 +1,71 @@ +// Copyright 2015 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. + +//! Extended precision "soft float", for internal use only. + +// This module is only for dec2flt and flt2dec, and only public because of libcoretest. +// It is not intended to ever be stabilized. +#![doc(hidden)] +#![unstable(feature = "core_private_diy_float", + reason = "internal routines only exposed for testing", + issue = "0")] + +/// A custom 64-bit floating point type, representing `f * 2^e`. +#[derive(Copy, Clone, Debug)] +#[doc(hidden)] +pub struct Fp { + /// The integer mantissa. + pub f: u64, + /// The exponent in base 2. + pub e: i16, +} + +impl Fp { + /// Returns a correctly rounded product of itself and `other`. + pub fn mul(&self, other: &Fp) -> Fp { + const MASK: u64 = 0xffffffff; + let a = self.f >> 32; + let b = self.f & MASK; + let c = other.f >> 32; + let d = other.f & MASK; + let ac = a * c; + let bc = b * c; + let ad = a * d; + let bd = b * d; + let tmp = (bd >> 32) + (ad & MASK) + (bc & MASK) + (1 << 31) /* round */; + let f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); + let e = self.e + other.e + 64; + Fp { f: f, e: e } + } + + /// Normalizes itself so that the resulting mantissa is at least `2^63`. + pub fn normalize(&self) -> Fp { + let mut f = self.f; + let mut e = self.e; + if f >> (64 - 32) == 0 { f <<= 32; e -= 32; } + if f >> (64 - 16) == 0 { f <<= 16; e -= 16; } + if f >> (64 - 8) == 0 { f <<= 8; e -= 8; } + if f >> (64 - 4) == 0 { f <<= 4; e -= 4; } + if f >> (64 - 2) == 0 { f <<= 2; e -= 2; } + if f >> (64 - 1) == 0 { f <<= 1; e -= 1; } + debug_assert!(f >= (1 >> 63)); + Fp { f: f, e: e } + } + + /// Normalizes itself to have the shared exponent. + /// It can only decrease the exponent (and thus increase the mantissa). + pub fn normalize_to(&self, e: i16) -> Fp { + let edelta = self.e - e; + assert!(edelta >= 0); + let edelta = edelta as usize; + assert_eq!(self.f << edelta >> edelta, self.f); + Fp { f: self.f << edelta, e: e } + } +} diff --git a/libcore/num/f32.rs b/libcore/num/f32.rs new file mode 100644 index 0000000..c24eaa3 --- /dev/null +++ b/libcore/num/f32.rs @@ -0,0 +1,272 @@ +// Copyright 2012-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. + +//! Operations and constants for 32-bits floats (`f32` type) + +// FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353 +#![allow(overflowing_literals)] + +#![stable(feature = "rust1", since = "1.0.0")] + +use intrinsics; +use mem; +use num::Float; +use num::FpCategory as Fp; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const RADIX: u32 = 2; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MANTISSA_DIGITS: u32 = 24; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const DIGITS: u32 = 6; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const EPSILON: f32 = 1.19209290e-07_f32; + +/// Smallest finite f32 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MIN: f32 = -3.40282347e+38_f32; +/// Smallest positive, normalized f32 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32; +/// Largest finite f32 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MAX: f32 = 3.40282347e+38_f32; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MIN_EXP: i32 = -125; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MAX_EXP: i32 = 128; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MIN_10_EXP: i32 = -37; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MAX_10_EXP: i32 = 38; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const NAN: f32 = 0.0_f32/0.0_f32; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const INFINITY: f32 = 1.0_f32/0.0_f32; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const NEG_INFINITY: f32 = -1.0_f32/0.0_f32; + +/// Basic mathematical constants. +#[stable(feature = "rust1", since = "1.0.0")] +pub mod consts { + // FIXME: replace with mathematical constants from cmath. + + /// Archimedes' constant + #[stable(feature = "rust1", since = "1.0.0")] + pub const PI: f32 = 3.14159265358979323846264338327950288_f32; + + /// pi/2.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32; + + /// pi/3.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32; + + /// pi/4.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32; + + /// pi/6.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32; + + /// pi/8.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32; + + /// 1.0/pi + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32; + + /// 2.0/pi + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32; + + /// 2.0/sqrt(pi) + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_2_SQRT_PI: f32 = 1.12837916709551257389615890312154517_f32; + + /// sqrt(2.0) + #[stable(feature = "rust1", since = "1.0.0")] + pub const SQRT_2: f32 = 1.41421356237309504880168872420969808_f32; + + /// 1.0/sqrt(2.0) + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_1_SQRT_2: f32 = 0.707106781186547524400844362104849039_f32; + + /// Euler's number + #[stable(feature = "rust1", since = "1.0.0")] + pub const E: f32 = 2.71828182845904523536028747135266250_f32; + + /// log2(e) + #[stable(feature = "rust1", since = "1.0.0")] + pub const LOG2_E: f32 = 1.44269504088896340735992468100189214_f32; + + /// log10(e) + #[stable(feature = "rust1", since = "1.0.0")] + pub const LOG10_E: f32 = 0.434294481903251827651128918916605082_f32; + + /// ln(2.0) + #[stable(feature = "rust1", since = "1.0.0")] + pub const LN_2: f32 = 0.693147180559945309417232121458176568_f32; + + /// ln(10.0) + #[stable(feature = "rust1", since = "1.0.0")] + pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32; +} + +#[unstable(feature = "core_float", + reason = "stable interface is via `impl f{32,64}` in later crates", + issue = "32110")] +impl Float for f32 { + #[inline] + fn nan() -> f32 { NAN } + + #[inline] + fn infinity() -> f32 { INFINITY } + + #[inline] + fn neg_infinity() -> f32 { NEG_INFINITY } + + #[inline] + fn zero() -> f32 { 0.0 } + + #[inline] + fn neg_zero() -> f32 { -0.0 } + + #[inline] + fn one() -> f32 { 1.0 } + + /// Returns `true` if the number is NaN. + #[inline] + fn is_nan(self) -> bool { self != self } + + /// Returns `true` if the number is infinite. + #[inline] + fn is_infinite(self) -> bool { + self == Float::infinity() || self == Float::neg_infinity() + } + + /// Returns `true` if the number is neither infinite or NaN. + #[inline] + fn is_finite(self) -> bool { + !(self.is_nan() || self.is_infinite()) + } + + /// Returns `true` if the number is neither zero, infinite, subnormal or NaN. + #[inline] + fn is_normal(self) -> bool { + self.classify() == Fp::Normal + } + + /// Returns the floating point category of the number. If only one property + /// is going to be tested, it is generally faster to use the specific + /// predicate instead. + fn classify(self) -> Fp { + const EXP_MASK: u32 = 0x7f800000; + const MAN_MASK: u32 = 0x007fffff; + + let bits: u32 = unsafe { mem::transmute(self) }; + match (bits & MAN_MASK, bits & EXP_MASK) { + (0, 0) => Fp::Zero, + (_, 0) => Fp::Subnormal, + (0, EXP_MASK) => Fp::Infinite, + (_, EXP_MASK) => Fp::Nan, + _ => Fp::Normal, + } + } + + /// Returns the mantissa, exponent and sign as integers. + fn integer_decode(self) -> (u64, i16, i8) { + let bits: u32 = unsafe { mem::transmute(self) }; + let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 }; + let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; + let mantissa = if exponent == 0 { + (bits & 0x7fffff) << 1 + } else { + (bits & 0x7fffff) | 0x800000 + }; + // Exponent bias + mantissa shift + exponent -= 127 + 23; + (mantissa as u64, exponent, sign) + } + + /// Computes the absolute value of `self`. Returns `Float::nan()` if the + /// number is `Float::nan()`. + #[inline] + fn abs(self) -> f32 { + unsafe { intrinsics::fabsf32(self) } + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` + /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` + /// - `Float::nan()` if the number is `Float::nan()` + #[inline] + fn signum(self) -> f32 { + if self.is_nan() { + Float::nan() + } else { + unsafe { intrinsics::copysignf32(1.0, self) } + } + } + + /// Returns `true` if `self` is positive, including `+0.0` and + /// `Float::infinity()`. + #[inline] + fn is_sign_positive(self) -> bool { + self > 0.0 || (1.0 / self) == Float::infinity() + } + + /// Returns `true` if `self` is negative, including `-0.0` and + /// `Float::neg_infinity()`. + #[inline] + fn is_sign_negative(self) -> bool { + self < 0.0 || (1.0 / self) == Float::neg_infinity() + } + + /// Returns the reciprocal (multiplicative inverse) of the number. + #[inline] + fn recip(self) -> f32 { 1.0 / self } + + #[inline] + fn powi(self, n: i32) -> f32 { + unsafe { intrinsics::powif32(self, n) } + } + + /// Converts to degrees, assuming the number is in radians. + #[inline] + fn to_degrees(self) -> f32 { self * (180.0f32 / consts::PI) } + + /// Converts to radians, assuming the number is in degrees. + #[inline] + fn to_radians(self) -> f32 { + let value: f32 = consts::PI; + self * (value / 180.0f32) + } +} diff --git a/libcore/num/f64.rs b/libcore/num/f64.rs new file mode 100644 index 0000000..beeee80 --- /dev/null +++ b/libcore/num/f64.rs @@ -0,0 +1,272 @@ +// Copyright 2012-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. + +//! Operations and constants for 64-bits floats (`f64` type) + +// FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353 +#![allow(overflowing_literals)] + +#![stable(feature = "rust1", since = "1.0.0")] + +use intrinsics; +use mem; +use num::FpCategory as Fp; +use num::Float; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const RADIX: u32 = 2; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MANTISSA_DIGITS: u32 = 53; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const DIGITS: u32 = 15; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const EPSILON: f64 = 2.2204460492503131e-16_f64; + +/// Smallest finite f64 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MIN: f64 = -1.7976931348623157e+308_f64; +/// Smallest positive, normalized f64 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MIN_POSITIVE: f64 = 2.2250738585072014e-308_f64; +/// Largest finite f64 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MAX: f64 = 1.7976931348623157e+308_f64; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MIN_EXP: i32 = -1021; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MAX_EXP: i32 = 1024; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MIN_10_EXP: i32 = -307; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MAX_10_EXP: i32 = 308; + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const NAN: f64 = 0.0_f64/0.0_f64; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const INFINITY: f64 = 1.0_f64/0.0_f64; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const NEG_INFINITY: f64 = -1.0_f64/0.0_f64; + +/// Basic mathematical constants. +#[stable(feature = "rust1", since = "1.0.0")] +pub mod consts { + // FIXME: replace with mathematical constants from cmath. + + /// Archimedes' constant + #[stable(feature = "rust1", since = "1.0.0")] + pub const PI: f64 = 3.14159265358979323846264338327950288_f64; + + /// pi/2.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64; + + /// pi/3.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_3: f64 = 1.04719755119659774615421446109316763_f64; + + /// pi/4.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64; + + /// pi/6.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_6: f64 = 0.52359877559829887307710723054658381_f64; + + /// pi/8.0 + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_PI_8: f64 = 0.39269908169872415480783042290993786_f64; + + /// 1.0/pi + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64; + + /// 2.0/pi + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64; + + /// 2.0/sqrt(pi) + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_2_SQRT_PI: f64 = 1.12837916709551257389615890312154517_f64; + + /// sqrt(2.0) + #[stable(feature = "rust1", since = "1.0.0")] + pub const SQRT_2: f64 = 1.41421356237309504880168872420969808_f64; + + /// 1.0/sqrt(2.0) + #[stable(feature = "rust1", since = "1.0.0")] + pub const FRAC_1_SQRT_2: f64 = 0.707106781186547524400844362104849039_f64; + + /// Euler's number + #[stable(feature = "rust1", since = "1.0.0")] + pub const E: f64 = 2.71828182845904523536028747135266250_f64; + + /// log2(e) + #[stable(feature = "rust1", since = "1.0.0")] + pub const LOG2_E: f64 = 1.44269504088896340735992468100189214_f64; + + /// log10(e) + #[stable(feature = "rust1", since = "1.0.0")] + pub const LOG10_E: f64 = 0.434294481903251827651128918916605082_f64; + + /// ln(2.0) + #[stable(feature = "rust1", since = "1.0.0")] + pub const LN_2: f64 = 0.693147180559945309417232121458176568_f64; + + /// ln(10.0) + #[stable(feature = "rust1", since = "1.0.0")] + pub const LN_10: f64 = 2.30258509299404568401799145468436421_f64; +} + +#[unstable(feature = "core_float", + reason = "stable interface is via `impl f{32,64}` in later crates", + issue = "32110")] +impl Float for f64 { + #[inline] + fn nan() -> f64 { NAN } + + #[inline] + fn infinity() -> f64 { INFINITY } + + #[inline] + fn neg_infinity() -> f64 { NEG_INFINITY } + + #[inline] + fn zero() -> f64 { 0.0 } + + #[inline] + fn neg_zero() -> f64 { -0.0 } + + #[inline] + fn one() -> f64 { 1.0 } + + /// Returns `true` if the number is NaN. + #[inline] + fn is_nan(self) -> bool { self != self } + + /// Returns `true` if the number is infinite. + #[inline] + fn is_infinite(self) -> bool { + self == Float::infinity() || self == Float::neg_infinity() + } + + /// Returns `true` if the number is neither infinite or NaN. + #[inline] + fn is_finite(self) -> bool { + !(self.is_nan() || self.is_infinite()) + } + + /// Returns `true` if the number is neither zero, infinite, subnormal or NaN. + #[inline] + fn is_normal(self) -> bool { + self.classify() == Fp::Normal + } + + /// Returns the floating point category of the number. If only one property + /// is going to be tested, it is generally faster to use the specific + /// predicate instead. + fn classify(self) -> Fp { + const EXP_MASK: u64 = 0x7ff0000000000000; + const MAN_MASK: u64 = 0x000fffffffffffff; + + let bits: u64 = unsafe { mem::transmute(self) }; + match (bits & MAN_MASK, bits & EXP_MASK) { + (0, 0) => Fp::Zero, + (_, 0) => Fp::Subnormal, + (0, EXP_MASK) => Fp::Infinite, + (_, EXP_MASK) => Fp::Nan, + _ => Fp::Normal, + } + } + + /// Returns the mantissa, exponent and sign as integers. + fn integer_decode(self) -> (u64, i16, i8) { + let bits: u64 = unsafe { mem::transmute(self) }; + let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; + let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; + let mantissa = if exponent == 0 { + (bits & 0xfffffffffffff) << 1 + } else { + (bits & 0xfffffffffffff) | 0x10000000000000 + }; + // Exponent bias + mantissa shift + exponent -= 1023 + 52; + (mantissa, exponent, sign) + } + + /// Computes the absolute value of `self`. Returns `Float::nan()` if the + /// number is `Float::nan()`. + #[inline] + fn abs(self) -> f64 { + unsafe { intrinsics::fabsf64(self) } + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` + /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` + /// - `Float::nan()` if the number is `Float::nan()` + #[inline] + fn signum(self) -> f64 { + if self.is_nan() { + Float::nan() + } else { + unsafe { intrinsics::copysignf64(1.0, self) } + } + } + + /// Returns `true` if `self` is positive, including `+0.0` and + /// `Float::infinity()`. + #[inline] + fn is_sign_positive(self) -> bool { + self > 0.0 || (1.0 / self) == Float::infinity() + } + + /// Returns `true` if `self` is negative, including `-0.0` and + /// `Float::neg_infinity()`. + #[inline] + fn is_sign_negative(self) -> bool { + self < 0.0 || (1.0 / self) == Float::neg_infinity() + } + + /// Returns the reciprocal (multiplicative inverse) of the number. + #[inline] + fn recip(self) -> f64 { 1.0 / self } + + #[inline] + fn powi(self, n: i32) -> f64 { + unsafe { intrinsics::powif64(self, n) } + } + + /// Converts to degrees, assuming the number is in radians. + #[inline] + fn to_degrees(self) -> f64 { self * (180.0f64 / consts::PI) } + + /// Converts to radians, assuming the number is in degrees. + #[inline] + fn to_radians(self) -> f64 { + let value: f64 = consts::PI; + self * (value / 180.0) + } +} diff --git a/libcore/num/float_macros.rs b/libcore/num/float_macros.rs new file mode 100644 index 0000000..b3adef5 --- /dev/null +++ b/libcore/num/float_macros.rs @@ -0,0 +1,20 @@ +// 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. + +#![doc(hidden)] + +macro_rules! assert_approx_eq { + ($a:expr, $b:expr) => ({ + use num::Float; + let (a, b) = (&$a, &$b); + assert!((*a - *b).abs() < 1.0e-6, + "{} is not approximately equal to {}", *a, *b); + }) +} diff --git a/libcore/num/flt2dec/decoder.rs b/libcore/num/flt2dec/decoder.rs new file mode 100644 index 0000000..6265691 --- /dev/null +++ b/libcore/num/flt2dec/decoder.rs @@ -0,0 +1,100 @@ +// Copyright 2015 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. + +//! Decodes a floating-point value into individual parts and error ranges. + +use prelude::v1::*; + +use {f32, f64}; +use num::{Float, FpCategory}; + +/// Decoded unsigned finite value, such that: +/// +/// - The original value equals to `mant * 2^exp`. +/// +/// - Any number from `(mant - minus) * 2^exp` to `(mant + plus) * 2^exp` will +/// round to the original value. The range is inclusive only when +/// `inclusive` is true. +#[derive(Copy, Clone, Debug, PartialEq)] +pub struct Decoded { + /// The scaled mantissa. + pub mant: u64, + /// The lower error range. + pub minus: u64, + /// The upper error range. + pub plus: u64, + /// The shared exponent in base 2. + pub exp: i16, + /// True when the error range is inclusive. + /// + /// In IEEE 754, this is true when the original mantissa was even. + pub inclusive: bool, +} + +/// Decoded unsigned value. +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum FullDecoded { + /// Not-a-number. + Nan, + /// Infinities, either positive or negative. + Infinite, + /// Zero, either positive or negative. + Zero, + /// Finite numbers with further decoded fields. + Finite(Decoded), +} + +/// A floating point type which can be `decode`d. +pub trait DecodableFloat: Float + Copy { + /// The minimum positive normalized value. + fn min_pos_norm_value() -> Self; +} + +impl DecodableFloat for f32 { + fn min_pos_norm_value() -> Self { f32::MIN_POSITIVE } +} + +impl DecodableFloat for f64 { + fn min_pos_norm_value() -> Self { f64::MIN_POSITIVE } +} + +/// Returns a sign (true when negative) and `FullDecoded` value +/// from given floating point number. +pub fn decode<T: DecodableFloat>(v: T) -> (/*negative?*/ bool, FullDecoded) { + let (mant, exp, sign) = v.integer_decode(); + let even = (mant & 1) == 0; + let decoded = match v.classify() { + FpCategory::Nan => FullDecoded::Nan, + FpCategory::Infinite => FullDecoded::Infinite, + FpCategory::Zero => FullDecoded::Zero, + FpCategory::Subnormal => { + // neighbors: (mant - 2, exp) -- (mant, exp) -- (mant + 2, exp) + // Float::integer_decode always preserves the exponent, + // so the mantissa is scaled for subnormals. + FullDecoded::Finite(Decoded { mant: mant, minus: 1, plus: 1, + exp: exp, inclusive: even }) + } + FpCategory::Normal => { + let minnorm = <T as DecodableFloat>::min_pos_norm_value().integer_decode(); + if mant == minnorm.0 { + // neighbors: (maxmant, exp - 1) -- (minnormmant, exp) -- (minnormmant + 1, exp) + // where maxmant = minnormmant * 2 - 1 + FullDecoded::Finite(Decoded { mant: mant << 2, minus: 1, plus: 2, + exp: exp - 2, inclusive: even }) + } else { + // neighbors: (mant - 1, exp) -- (mant, exp) -- (mant + 1, exp) + FullDecoded::Finite(Decoded { mant: mant << 1, minus: 1, plus: 1, + exp: exp - 1, inclusive: even }) + } + } + }; + (sign < 0, decoded) +} + diff --git a/libcore/num/flt2dec/estimator.rs b/libcore/num/flt2dec/estimator.rs new file mode 100644 index 0000000..d42e05a --- /dev/null +++ b/libcore/num/flt2dec/estimator.rs @@ -0,0 +1,25 @@ +// Copyright 2015 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. + +//! The exponent estimator. + +/// Finds `k_0` such that `10^(k_0-1) < mant * 2^exp <= 10^(k_0+1)`. +/// +/// This is used to approximate `k = ceil(log_10 (mant * 2^exp))`; +/// the true `k` is either `k_0` or `k_0+1`. +#[doc(hidden)] +pub fn estimate_scaling_factor(mant: u64, exp: i16) -> i16 { + // 2^(nbits-1) < mant <= 2^nbits if mant > 0 + let nbits = 64 - (mant - 1).leading_zeros() as i64; + // 1292913986 = floor(2^32 * log_10 2) + // therefore this always underestimates (or is exact), but not much. + (((nbits + exp as i64) * 1292913986) >> 32) as i16 +} + diff --git a/libcore/num/flt2dec/mod.rs b/libcore/num/flt2dec/mod.rs new file mode 100644 index 0000000..b549f33 --- /dev/null +++ b/libcore/num/flt2dec/mod.rs @@ -0,0 +1,662 @@ +// Copyright 2015 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. + +/*! + +Floating-point number to decimal conversion routines. + +# Problem statement + +We are given the floating-point number `v = f * 2^e` with an integer `f`, +and its bounds `minus` and `plus` such that any number between `v - minus` and +`v + plus` will be rounded to `v`. For the simplicity we assume that +this range is exclusive. Then we would like to get the unique decimal +representation `V = 0.d[0..n-1] * 10^k` such that: + +- `d[0]` is non-zero. + +- It's correctly rounded when parsed back: `v - minus < V < v + plus`. + Furthermore it is shortest such one, i.e. there is no representation + with less than `n` digits that is correctly rounded. + +- It's closest to the original value: `abs(V - v) <= 10^(k-n) / 2`. Note that + there might be two representations satisfying this uniqueness requirement, + in which case some tie-breaking mechanism is used. + +We will call this mode of operation as to the *shortest* mode. This mode is used +when there is no additional constraint, and can be thought as a "natural" mode +as it matches the ordinary intuition (it at least prints `0.1f32` as "0.1"). + +We have two more modes of operation closely related to each other. In these modes +we are given either the number of significant digits `n` or the last-digit +limitation `limit` (which determines the actual `n`), and we would like to get +the representation `V = 0.d[0..n-1] * 10^k` such that: + +- `d[0]` is non-zero, unless `n` was zero in which case only `k` is returned. + +- It's closest to the original value: `abs(V - v) <= 10^(k-n) / 2`. Again, + there might be some tie-breaking mechanism. + +When `limit` is given but not `n`, we set `n` such that `k - n = limit` +so that the last digit `d[n-1]` is scaled by `10^(k-n) = 10^limit`. +If such `n` is negative, we clip it to zero so that we will only get `k`. +We are also limited by the supplied buffer. This limitation is used to print +the number up to given number of fractional digits without knowing +the correct `k` beforehand. + +We will call the mode of operation requiring `n` as to the *exact* mode, +and one requiring `limit` as to the *fixed* mode. The exact mode is a subset of +the fixed mode: the sufficiently large last-digit limitation will eventually fill +the supplied buffer and let the algorithm to return. + +# Implementation overview + +It is easy to get the floating point printing correct but slow (Russ Cox has +[demonstrated](http://research.swtch.com/ftoa) how it's easy), or incorrect but +fast (naïve division and modulo). But it is surprisingly hard to print +floating point numbers correctly *and* efficiently. + +There are two classes of algorithms widely known to be correct. + +- The "Dragon" family of algorithm is first described by Guy L. Steele Jr. and + Jon L. White. They rely on the fixed-size big integer for their correctness. + A slight improvement was found later, which is posthumously described by + Robert G. Burger and R. Kent Dybvig. David Gay's `dtoa.c` routine is + a popular implementation of this strategy. + +- The "Grisu" family of algorithm is first described by Florian Loitsch. + They use very cheap integer-only procedure to determine the close-to-correct + representation which is at least guaranteed to be shortest. The variant, + Grisu3, actively detects if the resulting representation is incorrect. + +We implement both algorithms with necessary tweaks to suit our requirements. +In particular, published literatures are short of the actual implementation +difficulties like how to avoid arithmetic overflows. Each implementation, +available in `strategy::dragon` and `strategy::grisu` respectively, +extensively describes all necessary justifications and many proofs for them. +(It is still difficult to follow though. You have been warned.) + +Both implementations expose two public functions: + +- `format_shortest(decoded, buf)`, which always needs at least + `MAX_SIG_DIGITS` digits of buffer. Implements the shortest mode. + +- `format_exact(decoded, buf, limit)`, which accepts as small as + one digit of buffer. Implements exact and fixed modes. + +They try to fill the `u8` buffer with digits and returns the number of digits +written and the exponent `k`. They are total for all finite `f32` and `f64` +inputs (Grisu internally falls back to Dragon if necessary). + +The rendered digits are formatted into the actual string form with +four functions: + +- `to_shortest_str` prints the shortest representation, which can be padded by + zeroes to make *at least* given number of fractional digits. + +- `to_shortest_exp_str` prints the shortest representation, which can be + padded by zeroes when its exponent is in the specified ranges, + or can be printed in the exponential form such as `1.23e45`. + +- `to_exact_exp_str` prints the exact representation with given number of + digits in the exponential form. + +- `to_exact_fixed_str` prints the fixed representation with *exactly* + given number of fractional digits. + +They all return a slice of preallocated `Part` array, which corresponds to +the individual part of strings: a fixed string, a part of rendered digits, +a number of zeroes or a small (`u16`) number. The caller is expected to +provide a large enough buffer and `Part` array, and to assemble the final +string from resulting `Part`s itself. + +All algorithms and formatting functions are accompanied by extensive tests +in `coretest::num::flt2dec` module. It also shows how to use individual +functions. + +*/ + +// while this is extensively documented, this is in principle private which is +// only made public for testing. do not expose us. +#![doc(hidden)] +#![unstable(feature = "flt2dec", + reason = "internal routines only exposed for testing", + issue = "0")] + +use prelude::v1::*; +use i16; +pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded}; + +pub mod estimator; +pub mod decoder; + +/// Digit-generation algorithms. +pub mod strategy { + pub mod dragon; + pub mod grisu; +} + +/// The minimum size of buffer necessary for the shortest mode. +/// +/// It is a bit non-trivial to derive, but this is one plus the maximal number of +/// significant decimal digits from formatting algorithms with the shortest result. +/// The exact formula is `ceil(# bits in mantissa * log_10 2 + 1)`. +pub const MAX_SIG_DIGITS: usize = 17; + +/// When `d[..n]` contains decimal digits, increase the last digit and propagate carry. +/// Returns a next digit when it causes the length change. +#[doc(hidden)] +pub fn round_up(d: &mut [u8], n: usize) -> Option<u8> { + match d[..n].iter().rposition(|&c| c != b'9') { + Some(i) => { // d[i+1..n] is all nines + d[i] += 1; + for j in i+1..n { d[j] = b'0'; } + None + } + None if n > 0 => { // 999..999 rounds to 1000..000 with an increased exponent + d[0] = b'1'; + for j in 1..n { d[j] = b'0'; } + Some(b'0') + } + None => { // an empty buffer rounds up (a bit strange but reasonable) + Some(b'1') + } + } +} + +/// Formatted parts. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Part<'a> { + /// Given number of zero digits. + Zero(usize), + /// A literal number up to 5 digits. + Num(u16), + /// A verbatim copy of given bytes. + Copy(&'a [u8]), +} + +impl<'a> Part<'a> { + /// Returns the exact byte length of given part. + pub fn len(&self) -> usize { + match *self { + Part::Zero(nzeroes) => nzeroes, + Part::Num(v) => if v < 1_000 { if v < 10 { 1 } else if v < 100 { 2 } else { 3 } } + else { if v < 10_000 { 4 } else { 5 } }, + Part::Copy(buf) => buf.len(), + } + } + + /// Writes a part into the supplied buffer. + /// Returns the number of written bytes, or `None` if the buffer is not enough. + /// (It may still leave partially written bytes in the buffer; do not rely on that.) + pub fn write(&self, out: &mut [u8]) -> Option<usize> { + let len = self.len(); + if out.len() >= len { + match *self { + Part::Zero(nzeroes) => { + for c in &mut out[..nzeroes] { *c = b'0'; } + } + Part::Num(mut v) => { + for c in out[..len].iter_mut().rev() { + *c = b'0' + (v % 10) as u8; + v /= 10; + } + } + Part::Copy(buf) => { + out[..buf.len()].copy_from_slice(buf); + } + } + Some(len) + } else { + None + } + } +} + +/// Formatted result containing one or more parts. +/// This can be written to the byte buffer or converted to the allocated string. +#[allow(missing_debug_implementations)] +#[derive(Clone)] +pub struct Formatted<'a> { + /// A byte slice representing a sign, either `""`, `"-"` or `"+"`. + pub sign: &'static [u8], + /// Formatted parts to be rendered after a sign and optional zero padding. + pub parts: &'a [Part<'a>], +} + +impl<'a> Formatted<'a> { + /// Returns the exact byte length of combined formatted result. + pub fn len(&self) -> usize { + let mut len = self.sign.len(); + for part in self.parts { + len += part.len(); + } + len + } + + /// Writes all formatted parts into the supplied buffer. + /// Returns the number of written bytes, or `None` if the buffer is not enough. + /// (It may still leave partially written bytes in the buffer; do not rely on that.) + pub fn write(&self, out: &mut [u8]) -> Option<usize> { + if out.len() < self.sign.len() { return None; } + out[..self.sign.len()].copy_from_slice(self.sign); + + let mut written = self.sign.len(); + for part in self.parts { + match part.write(&mut out[written..]) { + Some(len) => { written += len; } + None => { return None; } + } + } + Some(written) + } +} + +/// Formats given decimal digits `0.<...buf...> * 10^exp` into the decimal form +/// with at least given number of fractional digits. The result is stored to +/// the supplied parts array and a slice of written parts is returned. +/// +/// `frac_digits` can be less than the number of actual fractional digits in `buf`; +/// it will be ignored and full digits will be printed. It is only used to print +/// additional zeroes after rendered digits. Thus `frac_digits` of 0 means that +/// it will only print given digits and nothing else. +fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize, + parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] { + assert!(!buf.is_empty()); + assert!(buf[0] > b'0'); + assert!(parts.len() >= 4); + + // if there is the restriction on the last digit position, `buf` is assumed to be + // left-padded with the virtual zeroes. the number of virtual zeroes, `nzeroes`, + // equals to `max(0, exp + frac_digits - buf.len())`, so that the position of + // the last digit `exp - buf.len() - nzeroes` is no more than `-frac_digits`: + // + // |<-virtual->| + // |<---- buf ---->| zeroes | exp + // 0. 1 2 3 4 5 6 7 8 9 _ _ _ _ _ _ x 10 + // | | | + // 10^exp 10^(exp-buf.len()) 10^(exp-buf.len()-nzeroes) + // + // `nzeroes` is individually calculated for each case in order to avoid overflow. + + if exp <= 0 { + // the decimal point is before rendered digits: [0.][000...000][1234][____] + let minus_exp = -(exp as i32) as usize; + parts[0] = Part::Copy(b"0."); + parts[1] = Part::Zero(minus_exp); + parts[2] = Part::Copy(buf); + if frac_digits > buf.len() && frac_digits - buf.len() > minus_exp { + parts[3] = Part::Zero((frac_digits - buf.len()) - minus_exp); + &parts[..4] + } else { + &parts[..3] + } + } else { + let exp = exp as usize; + if exp < buf.len() { + // the decimal point is inside rendered digits: [12][.][34][____] + parts[0] = Part::Copy(&buf[..exp]); + parts[1] = Part::Copy(b"."); + parts[2] = Part::Copy(&buf[exp..]); + if frac_digits > buf.len() - exp { + parts[3] = Part::Zero(frac_digits - (buf.len() - exp)); + &parts[..4] + } else { + &parts[..3] + } + } else { + // the decimal point is after rendered digits: [1234][____0000] or [1234][__][.][__]. + parts[0] = Part::Copy(buf); + parts[1] = Part::Zero(exp - buf.len()); + if frac_digits > 0 { + parts[2] = Part::Copy(b"."); + parts[3] = Part::Zero(frac_digits); + &parts[..4] + } else { + &parts[..2] + } + } + } +} + +/// Formats given decimal digits `0.<...buf...> * 10^exp` into the exponential form +/// with at least given number of significant digits. When `upper` is true, +/// the exponent will be prefixed by `E`; otherwise that's `e`. The result is +/// stored to the supplied parts array and a slice of written parts is returned. +/// +/// `min_digits` can be less than the number of actual significant digits in `buf`; +/// it will be ignored and full digits will be printed. It is only used to print +/// additional zeroes after rendered digits. Thus `min_digits` of 0 means that +/// it will only print given digits and nothing else. +fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool, + parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] { + assert!(!buf.is_empty()); + assert!(buf[0] > b'0'); + assert!(parts.len() >= 6); + + let mut n = 0; + + parts[n] = Part::Copy(&buf[..1]); + n += 1; + + if buf.len() > 1 || min_ndigits > 1 { + parts[n] = Part::Copy(b"."); + parts[n + 1] = Part::Copy(&buf[1..]); + n += 2; + if min_ndigits > buf.len() { + parts[n] = Part::Zero(min_ndigits - buf.len()); + n += 1; + } + } + + // 0.1234 x 10^exp = 1.234 x 10^(exp-1) + let exp = exp as i32 - 1; // avoid underflow when exp is i16::MIN + if exp < 0 { + parts[n] = Part::Copy(if upper { b"E-" } else { b"e-" }); + parts[n + 1] = Part::Num(-exp as u16); + } else { + parts[n] = Part::Copy(if upper { b"E" } else { b"e" }); + parts[n + 1] = Part::Num(exp as u16); + } + &parts[..n + 2] +} + +/// Sign formatting options. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Sign { + /// Prints `-` only for the negative non-zero values. + Minus, // -inf -1 0 0 1 inf nan + /// Prints `-` only for any negative values (including the negative zero). + MinusRaw, // -inf -1 -0 0 1 inf nan + /// Prints `-` for the negative non-zero values, or `+` otherwise. + MinusPlus, // -inf -1 +0 +0 +1 +inf nan + /// Prints `-` for any negative values (including the negative zero), or `+` otherwise. + MinusPlusRaw, // -inf -1 -0 +0 +1 +inf nan +} + +/// Returns the static byte string corresponding to the sign to be formatted. +/// It can be either `b""`, `b"+"` or `b"-"`. +fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static [u8] { + match (*decoded, sign) { + (FullDecoded::Nan, _) => b"", + (FullDecoded::Zero, Sign::Minus) => b"", + (FullDecoded::Zero, Sign::MinusRaw) => if negative { b"-" } else { b"" }, + (FullDecoded::Zero, Sign::MinusPlus) => b"+", + (FullDecoded::Zero, Sign::MinusPlusRaw) => if negative { b"-" } else { b"+" }, + (_, Sign::Minus) | (_, Sign::MinusRaw) => if negative { b"-" } else { b"" }, + (_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => if negative { b"-" } else { b"+" }, + } +} + +/// Formats given floating point number into the decimal form with at least +/// given number of fractional digits. The result is stored to the supplied parts +/// array while utilizing given byte buffer as a scratch. `upper` is currently +/// unused but left for the future decision to change the case of non-finite values, +/// i.e. `inf` and `nan`. The first part to be rendered is always a `Part::Sign` +/// (which can be an empty string if no sign is rendered). +/// +/// `format_shortest` should be the underlying digit-generation function. +/// You probably would want `strategy::grisu::format_shortest` for this. +/// +/// `frac_digits` can be less than the number of actual fractional digits in `v`; +/// it will be ignored and full digits will be printed. It is only used to print +/// additional zeroes after rendered digits. Thus `frac_digits` of 0 means that +/// it will only print given digits and nothing else. +/// +/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long. +/// There should be at least 5 parts available, due to the worst case like +/// `[+][0.][0000][45][0000]` with `frac_digits = 10`. +pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, + sign: Sign, frac_digits: usize, _upper: bool, + buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> + where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { + assert!(parts.len() >= 4); + assert!(buf.len() >= MAX_SIG_DIGITS); + + let (negative, full_decoded) = decode(v); + let sign = determine_sign(sign, &full_decoded, negative); + match full_decoded { + FullDecoded::Nan => { + parts[0] = Part::Copy(b"NaN"); + Formatted { sign: sign, parts: &parts[..1] } + } + FullDecoded::Infinite => { + parts[0] = Part::Copy(b"inf"); + Formatted { sign: sign, parts: &parts[..1] } + } + FullDecoded::Zero => { + if frac_digits > 0 { // [0.][0000] + parts[0] = Part::Copy(b"0."); + parts[1] = Part::Zero(frac_digits); + Formatted { sign: sign, parts: &parts[..2] } + } else { + parts[0] = Part::Copy(b"0"); + Formatted { sign: sign, parts: &parts[..1] } + } + } + FullDecoded::Finite(ref decoded) => { + let (len, exp) = format_shortest(decoded, buf); + Formatted { sign: sign, + parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) } + } + } +} + +/// Formats given floating point number into the decimal form or +/// the exponential form, depending on the resulting exponent. The result is +/// stored to the supplied parts array while utilizing given byte buffer +/// as a scratch. `upper` is used to determine the case of non-finite values +/// (`inf` and `nan`) or the case of the exponent prefix (`e` or `E`). +/// The first part to be rendered is always a `Part::Sign` (which can be +/// an empty string if no sign is rendered). +/// +/// `format_shortest` should be the underlying digit-generation function. +/// You probably would want `strategy::grisu::format_shortest` for this. +/// +/// The `dec_bounds` is a tuple `(lo, hi)` such that the number is formatted +/// as decimal only when `10^lo <= V < 10^hi`. Note that this is the *apparent* `V` +/// instead of the actual `v`! Thus any printed exponent in the exponential form +/// cannot be in this range, avoiding any confusion. +/// +/// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long. +/// There should be at least 7 parts available, due to the worst case like +/// `[+][1][.][2345][e][-][67]`. +pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, + sign: Sign, dec_bounds: (i16, i16), upper: bool, + buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> + where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { + assert!(parts.len() >= 6); + assert!(buf.len() >= MAX_SIG_DIGITS); + assert!(dec_bounds.0 <= dec_bounds.1); + + let (negative, full_decoded) = decode(v); + let sign = determine_sign(sign, &full_decoded, negative); + match full_decoded { + FullDecoded::Nan => { + parts[0] = Part::Copy(b"NaN"); + Formatted { sign: sign, parts: &parts[..1] } + } + FullDecoded::Infinite => { + parts[0] = Part::Copy(b"inf"); + Formatted { sign: sign, parts: &parts[..1] } + } + FullDecoded::Zero => { + parts[0] = if dec_bounds.0 <= 0 && 0 < dec_bounds.1 { + Part::Copy(b"0") + } else { + Part::Copy(if upper { b"0E0" } else { b"0e0" }) + }; + Formatted { sign: sign, parts: &parts[..1] } + } + FullDecoded::Finite(ref decoded) => { + let (len, exp) = format_shortest(decoded, buf); + let vis_exp = exp as i32 - 1; + let parts = if dec_bounds.0 as i32 <= vis_exp && vis_exp < dec_bounds.1 as i32 { + digits_to_dec_str(&buf[..len], exp, 0, parts) + } else { + digits_to_exp_str(&buf[..len], exp, 0, upper, parts) + }; + Formatted { sign: sign, parts: parts } + } + } +} + +/// Returns rather crude approximation (upper bound) for the maximum buffer size +/// calculated from the given decoded exponent. +/// +/// The exact limit is: +/// +/// - when `exp < 0`, the maximum length is `ceil(log_10 (5^-exp * (2^64 - 1)))`. +/// - when `exp >= 0`, the maximum length is `ceil(log_10 (2^exp * (2^64 - 1)))`. +/// +/// `ceil(log_10 (x^exp * (2^64 - 1)))` is less than `ceil(log_10 (2^64 - 1)) + +/// ceil(exp * log_10 x)`, which is in turn less than `20 + (1 + exp * log_10 x)`. +/// We use the facts that `log_10 2 < 5/16` and `log_10 5 < 12/16`, which is +/// enough for our purposes. +/// +/// Why do we need this? `format_exact` functions will fill the entire buffer +/// unless limited by the last digit restriction, but it is possible that +/// the number of digits requested is ridiculously large (say, 30,000 digits). +/// The vast majority of buffer will be filled with zeroes, so we don't want to +/// allocate all the buffer beforehand. Consequently, for any given arguments, +/// 826 bytes of buffer should be sufficient for `f64`. Compare this with +/// the actual number for the worst case: 770 bytes (when `exp = -1074`). +fn estimate_max_buf_len(exp: i16) -> usize { + 21 + ((if exp < 0 { -12 } else { 5 } * exp as i32) as usize >> 4) +} + +/// Formats given floating point number into the exponential form with +/// exactly given number of significant digits. The result is stored to +/// the supplied parts array while utilizing given byte buffer as a scratch. +/// `upper` is used to determine the case of the exponent prefix (`e` or `E`). +/// The first part to be rendered is always a `Part::Sign` (which can be +/// an empty string if no sign is rendered). +/// +/// `format_exact` should be the underlying digit-generation function. +/// You probably would want `strategy::grisu::format_exact` for this. +/// +/// The byte buffer should be at least `ndigits` bytes long unless `ndigits` is +/// so large that only the fixed number of digits will be ever written. +/// (The tipping point for `f64` is about 800, so 1000 bytes should be enough.) +/// There should be at least 7 parts available, due to the worst case like +/// `[+][1][.][2345][e][-][67]`. +pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, + sign: Sign, ndigits: usize, upper: bool, + buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> + where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { + assert!(parts.len() >= 6); + assert!(ndigits > 0); + + let (negative, full_decoded) = decode(v); + let sign = determine_sign(sign, &full_decoded, negative); + match full_decoded { + FullDecoded::Nan => { + parts[0] = Part::Copy(b"NaN"); + Formatted { sign: sign, parts: &parts[..1] } + } + FullDecoded::Infinite => { + parts[0] = Part::Copy(b"inf"); + Formatted { sign: sign, parts: &parts[..1] } + } + FullDecoded::Zero => { + if ndigits > 1 { // [0.][0000][e0] + parts[0] = Part::Copy(b"0."); + parts[1] = Part::Zero(ndigits - 1); + parts[2] = Part::Copy(if upper { b"E0" } else { b"e0" }); + Formatted { sign: sign, parts: &parts[..3] } + } else { + parts[0] = Part::Copy(if upper { b"0E0" } else { b"0e0" }); + Formatted { sign: sign, parts: &parts[..1] } + } + } + FullDecoded::Finite(ref decoded) => { + let maxlen = estimate_max_buf_len(decoded.exp); + assert!(buf.len() >= ndigits || buf.len() >= maxlen); + + let trunc = if ndigits < maxlen { ndigits } else { maxlen }; + let (len, exp) = format_exact(decoded, &mut buf[..trunc], i16::MIN); + Formatted { sign: sign, + parts: digits_to_exp_str(&buf[..len], exp, ndigits, upper, parts) } + } + } +} + +/// Formats given floating point number into the decimal form with exactly +/// given number of fractional digits. The result is stored to the supplied parts +/// array while utilizing given byte buffer as a scratch. `upper` is currently +/// unused but left for the future decision to change the case of non-finite values, +/// i.e. `inf` and `nan`. The first part to be rendered is always a `Part::Sign` +/// (which can be an empty string if no sign is rendered). +/// +/// `format_exact` should be the underlying digit-generation function. +/// You probably would want `strategy::grisu::format_exact` for this. +/// +/// The byte buffer should be enough for the output unless `frac_digits` is +/// so large that only the fixed number of digits will be ever written. +/// (The tipping point for `f64` is about 800, and 1000 bytes should be enough.) +/// There should be at least 5 parts available, due to the worst case like +/// `[+][0.][0000][45][0000]` with `frac_digits = 10`. +pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T, + sign: Sign, frac_digits: usize, _upper: bool, + buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> + where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { + assert!(parts.len() >= 4); + + let (negative, full_decoded) = decode(v); + let sign = determine_sign(sign, &full_decoded, negative); + match full_decoded { + FullDecoded::Nan => { + parts[0] = Part::Copy(b"NaN"); + Formatted { sign: sign, parts: &parts[..1] } + } + FullDecoded::Infinite => { + parts[0] = Part::Copy(b"inf"); + Formatted { sign: sign, parts: &parts[..1] } + } + FullDecoded::Zero => { + if frac_digits > 0 { // [0.][0000] + parts[0] = Part::Copy(b"0."); + parts[1] = Part::Zero(frac_digits); + Formatted { sign: sign, parts: &parts[..2] } + } else { + parts[0] = Part::Copy(b"0"); + Formatted { sign: sign, parts: &parts[..1] } + } + } + FullDecoded::Finite(ref decoded) => { + let maxlen = estimate_max_buf_len(decoded.exp); + assert!(buf.len() >= maxlen); + + // it *is* possible that `frac_digits` is ridiculously large. + // `format_exact` will end rendering digits much earlier in this case, + // because we are strictly limited by `maxlen`. + let limit = if frac_digits < 0x8000 { -(frac_digits as i16) } else { i16::MIN }; + let (len, exp) = format_exact(decoded, &mut buf[..maxlen], limit); + if exp <= limit { + // the restriction couldn't been met, so this should render like zero no matter + // `exp` was. this does not include the case that the restriction has been met + // only after the final rounding-up; it's a regular case with `exp = limit + 1`. + debug_assert_eq!(len, 0); + if frac_digits > 0 { // [0.][0000] + parts[0] = Part::Copy(b"0."); + parts[1] = Part::Zero(frac_digits); + Formatted { sign: sign, parts: &parts[..2] } + } else { + parts[0] = Part::Copy(b"0"); + Formatted { sign: sign, parts: &parts[..1] } + } + } else { + Formatted { sign: sign, + parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) } + } + } + } +} + diff --git a/libcore/num/flt2dec/strategy/dragon.rs b/libcore/num/flt2dec/strategy/dragon.rs new file mode 100644 index 0000000..2d68c3a --- /dev/null +++ b/libcore/num/flt2dec/strategy/dragon.rs @@ -0,0 +1,329 @@ +// Copyright 2015 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. + +/*! +Almost direct (but slightly optimized) Rust translation of Figure 3 of [1]. + +[1] Burger, R. G. and Dybvig, R. K. 1996. Printing floating-point numbers + quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116. +*/ + +use prelude::v1::*; + +use cmp::Ordering; + +use num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up}; +use num::flt2dec::estimator::estimate_scaling_factor; +use num::bignum::Digit32 as Digit; +use num::bignum::Big32x40 as Big; + +static POW10: [Digit; 10] = [1, 10, 100, 1000, 10000, 100000, + 1000000, 10000000, 100000000, 1000000000]; +static TWOPOW10: [Digit; 10] = [2, 20, 200, 2000, 20000, 200000, + 2000000, 20000000, 200000000, 2000000000]; + +// precalculated arrays of `Digit`s for 10^(2^n) +static POW10TO16: [Digit; 2] = [0x6fc10000, 0x2386f2]; +static POW10TO32: [Digit; 4] = [0, 0x85acef81, 0x2d6d415b, 0x4ee]; +static POW10TO64: [Digit; 7] = [0, 0, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x184f03]; +static POW10TO128: [Digit; 14] = + [0, 0, 0, 0, 0x2e953e01, 0x3df9909, 0xf1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08, + 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x24e]; +static POW10TO256: [Digit; 27] = + [0, 0, 0, 0, 0, 0, 0, 0, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, + 0xcf4a6e70, 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, + 0xcc5573c0, 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x553f7]; + +#[doc(hidden)] +pub fn mul_pow10(x: &mut Big, n: usize) -> &mut Big { + debug_assert!(n < 512); + if n & 7 != 0 { x.mul_small(POW10[n & 7]); } + if n & 8 != 0 { x.mul_small(POW10[8]); } + if n & 16 != 0 { x.mul_digits(&POW10TO16); } + if n & 32 != 0 { x.mul_digits(&POW10TO32); } + if n & 64 != 0 { x.mul_digits(&POW10TO64); } + if n & 128 != 0 { x.mul_digits(&POW10TO128); } + if n & 256 != 0 { x.mul_digits(&POW10TO256); } + x +} + +fn div_2pow10(x: &mut Big, mut n: usize) -> &mut Big { + let largest = POW10.len() - 1; + while n > largest { + x.div_rem_small(POW10[largest]); + n -= largest; + } + x.div_rem_small(TWOPOW10[n]); + x +} + +// only usable when `x < 16 * scale`; `scaleN` should be `scale.mul_small(N)` +fn div_rem_upto_16<'a>(x: &'a mut Big, scale: &Big, + scale2: &Big, scale4: &Big, scale8: &Big) -> (u8, &'a mut Big) { + let mut d = 0; + if *x >= *scale8 { x.sub(scale8); d += 8; } + if *x >= *scale4 { x.sub(scale4); d += 4; } + if *x >= *scale2 { x.sub(scale2); d += 2; } + if *x >= *scale { x.sub(scale); d += 1; } + debug_assert!(*x < *scale); + (d, x) +} + +/// The shortest mode implementation for Dragon. +pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp*/ i16) { + // the number `v` to format is known to be: + // - equal to `mant * 2^exp`; + // - preceded by `(mant - 2 * minus) * 2^exp` in the original type; and + // - followed by `(mant + 2 * plus) * 2^exp` in the original type. + // + // obviously, `minus` and `plus` cannot be zero. (for infinities, we use out-of-range values.) + // also we assume that at least one digit is generated, i.e. `mant` cannot be zero too. + // + // this also means that any number between `low = (mant - minus) * 2^exp` and + // `high = (mant + plus) * 2^exp` will map to this exact floating point number, + // with bounds included when the original mantissa was even (i.e. `!mant_was_odd`). + + assert!(d.mant > 0); + assert!(d.minus > 0); + assert!(d.plus > 0); + assert!(d.mant.checked_add(d.plus).is_some()); + assert!(d.mant.checked_sub(d.minus).is_some()); + assert!(buf.len() >= MAX_SIG_DIGITS); + + // `a.cmp(&b) < rounding` is `if d.inclusive {a <= b} else {a < b}` + let rounding = if d.inclusive {Ordering::Greater} else {Ordering::Equal}; + + // estimate `k_0` from original inputs satisfying `10^(k_0-1) < high <= 10^(k_0+1)`. + // the tight bound `k` satisfying `10^(k-1) < high <= 10^k` is calculated later. + let mut k = estimate_scaling_factor(d.mant + d.plus, d.exp); + + // convert `{mant, plus, minus} * 2^exp` into the fractional form so that: + // - `v = mant / scale` + // - `low = (mant - minus) / scale` + // - `high = (mant + plus) / scale` + let mut mant = Big::from_u64(d.mant); + let mut minus = Big::from_u64(d.minus); + let mut plus = Big::from_u64(d.plus); + let mut scale = Big::from_small(1); + if d.exp < 0 { + scale.mul_pow2(-d.exp as usize); + } else { + mant.mul_pow2(d.exp as usize); + minus.mul_pow2(d.exp as usize); + plus.mul_pow2(d.exp as usize); + } + + // divide `mant` by `10^k`. now `scale / 10 < mant + plus <= scale * 10`. + if k >= 0 { + mul_pow10(&mut scale, k as usize); + } else { + mul_pow10(&mut mant, -k as usize); + mul_pow10(&mut minus, -k as usize); + mul_pow10(&mut plus, -k as usize); + } + + // fixup when `mant + plus > scale` (or `>=`). + // we are not actually modifying `scale`, since we can skip the initial multiplication instead. + // now `scale < mant + plus <= scale * 10` and we are ready to generate digits. + // + // note that `d[0]` *can* be zero, when `scale - plus < mant < scale`. + // in this case rounding-up condition (`up` below) will be triggered immediately. + if scale.cmp(mant.clone().add(&plus)) < rounding { + // equivalent to scaling `scale` by 10 + k += 1; + } else { + mant.mul_small(10); + minus.mul_small(10); + plus.mul_small(10); + } + + // cache `(2, 4, 8) * scale` for digit generation. + let mut scale2 = scale.clone(); scale2.mul_pow2(1); + let mut scale4 = scale.clone(); scale4.mul_pow2(2); + let mut scale8 = scale.clone(); scale8.mul_pow2(3); + + let mut down; + let mut up; + let mut i = 0; + loop { + // invariants, where `d[0..n-1]` are digits generated so far: + // - `v = mant / scale * 10^(k-n-1) + d[0..n-1] * 10^(k-n)` + // - `v - low = minus / scale * 10^(k-n-1)` + // - `high - v = plus / scale * 10^(k-n-1)` + // - `(mant + plus) / scale <= 10` (thus `mant / scale < 10`) + // where `d[i..j]` is a shorthand for `d[i] * 10^(j-i) + ... + d[j-1] * 10 + d[j]`. + + // generate one digit: `d[n] = floor(mant / scale) < 10`. + let (d, _) = div_rem_upto_16(&mut mant, &scale, &scale2, &scale4, &scale8); + debug_assert!(d < 10); + buf[i] = b'0' + d; + i += 1; + + // this is a simplified description of the modified Dragon algorithm. + // many intermediate derivations and completeness arguments are omitted for convenience. + // + // start with modified invariants, as we've updated `n`: + // - `v = mant / scale * 10^(k-n) + d[0..n-1] * 10^(k-n)` + // - `v - low = minus / scale * 10^(k-n)` + // - `high - v = plus / scale * 10^(k-n)` + // + // assume that `d[0..n-1]` is the shortest representation between `low` and `high`, + // i.e. `d[0..n-1]` satisfies both of the following but `d[0..n-2]` doesn't: + // - `low < d[0..n-1] * 10^(k-n) < high` (bijectivity: digits round to `v`); and + // - `abs(v / 10^(k-n) - d[0..n-1]) <= 1/2` (the last digit is correct). + // + // the second condition simplifies to `2 * mant <= scale`. + // solving invariants in terms of `mant`, `low` and `high` yields + // a simpler version of the first condition: `-plus < mant < minus`. + // since `-plus < 0 <= mant`, we have the correct shortest representation + // when `mant < minus` and `2 * mant <= scale`. + // (the former becomes `mant <= minus` when the original mantissa is even.) + // + // when the second doesn't hold (`2 * mant > scale`), we need to increase the last digit. + // this is enough for restoring that condition: we already know that + // the digit generation guarantees `0 <= v / 10^(k-n) - d[0..n-1] < 1`. + // in this case, the first condition becomes `-plus < mant - scale < minus`. + // since `mant < scale` after the generation, we have `scale < mant + plus`. + // (again, this becomes `scale <= mant + plus` when the original mantissa is even.) + // + // in short: + // - stop and round `down` (keep digits as is) when `mant < minus` (or `<=`). + // - stop and round `up` (increase the last digit) when `scale < mant + plus` (or `<=`). + // - keep generating otherwise. + down = mant.cmp(&minus) < rounding; + up = scale.cmp(mant.clone().add(&plus)) < rounding; + if down || up { break; } // we have the shortest representation, proceed to the rounding + + // restore the invariants. + // this makes the algorithm always terminating: `minus` and `plus` always increases, + // but `mant` is clipped modulo `scale` and `scale` is fixed. + mant.mul_small(10); + minus.mul_small(10); + plus.mul_small(10); + } + + // rounding up happens when + // i) only the rounding-up condition was triggered, or + // ii) both conditions were triggered and tie breaking prefers rounding up. + if up && (!down || *mant.mul_pow2(1) >= scale) { + // if rounding up changes the length, the exponent should also change. + // it seems that this condition is very hard to satisfy (possibly impossible), + // but we are just being safe and consistent here. + if let Some(c) = round_up(buf, i) { + buf[i] = c; + i += 1; + k += 1; + } + } + + (i, k) +} + +/// The exact and fixed mode implementation for Dragon. +pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usize, /*exp*/ i16) { + assert!(d.mant > 0); + assert!(d.minus > 0); + assert!(d.plus > 0); + assert!(d.mant.checked_add(d.plus).is_some()); + assert!(d.mant.checked_sub(d.minus).is_some()); + + // estimate `k_0` from original inputs satisfying `10^(k_0-1) < v <= 10^(k_0+1)`. + let mut k = estimate_scaling_factor(d.mant, d.exp); + + // `v = mant / scale`. + let mut mant = Big::from_u64(d.mant); + let mut scale = Big::from_small(1); + if d.exp < 0 { + scale.mul_pow2(-d.exp as usize); + } else { + mant.mul_pow2(d.exp as usize); + } + + // divide `mant` by `10^k`. now `scale / 10 < mant <= scale * 10`. + if k >= 0 { + mul_pow10(&mut scale, k as usize); + } else { + mul_pow10(&mut mant, -k as usize); + } + + // fixup when `mant + plus >= scale`, where `plus / scale = 10^-buf.len() / 2`. + // in order to keep the fixed-size bignum, we actually use `mant + floor(plus) >= scale`. + // we are not actually modifying `scale`, since we can skip the initial multiplication instead. + // again with the shortest algorithm, `d[0]` can be zero but will be eventually rounded up. + if *div_2pow10(&mut scale.clone(), buf.len()).add(&mant) >= scale { + // equivalent to scaling `scale` by 10 + k += 1; + } else { + mant.mul_small(10); + } + + // if we are working with the last-digit limitation, we need to shorten the buffer + // before the actual rendering in order to avoid double rounding. + // note that we have to enlarge the buffer again when rounding up happens! + let mut len = if k < limit { + // oops, we cannot even produce *one* digit. + // this is possible when, say, we've got something like 9.5 and it's being rounded to 10. + // we return an empty buffer, with an exception of the later rounding-up case + // which occurs when `k == limit` and has to produce exactly one digit. + 0 + } else if ((k as i32 - limit as i32) as usize) < buf.len() { + (k - limit) as usize + } else { + buf.len() + }; + + if len > 0 { + // cache `(2, 4, 8) * scale` for digit generation. + // (this can be expensive, so do not calculate them when the buffer is empty.) + let mut scale2 = scale.clone(); scale2.mul_pow2(1); + let mut scale4 = scale.clone(); scale4.mul_pow2(2); + let mut scale8 = scale.clone(); scale8.mul_pow2(3); + + for i in 0..len { + if mant.is_zero() { // following digits are all zeroes, we stop here + // do *not* try to perform rounding! rather, fill remaining digits. + for c in &mut buf[i..len] { *c = b'0'; } + return (len, k); + } + + let mut d = 0; + if mant >= scale8 { mant.sub(&scale8); d += 8; } + if mant >= scale4 { mant.sub(&scale4); d += 4; } + if mant >= scale2 { mant.sub(&scale2); d += 2; } + if mant >= scale { mant.sub(&scale); d += 1; } + debug_assert!(mant < scale); + debug_assert!(d < 10); + buf[i] = b'0' + d; + mant.mul_small(10); + } + } + + // rounding up if we stop in the middle of digits + // if the following digits are exactly 5000..., check the prior digit and try to + // round to even (i.e. avoid rounding up when the prior digit is even). + let order = mant.cmp(scale.mul_small(5)); + if order == Ordering::Greater || (order == Ordering::Equal && + (len == 0 || buf[len-1] & 1 == 1)) { + // if rounding up changes the length, the exponent should also change. + // but we've been requested a fixed number of digits, so do not alter the buffer... + if let Some(c) = round_up(buf, len) { + // ...unless we've been requested the fixed precision instead. + // we also need to check that, if the original buffer was empty, + // the additional digit can only be added when `k == limit` (edge case). + k += 1; + if k > limit && len < buf.len() { + buf[len] = c; + len += 1; + } + } + } + + (len, k) +} diff --git a/libcore/num/flt2dec/strategy/grisu.rs b/libcore/num/flt2dec/strategy/grisu.rs new file mode 100644 index 0000000..13e01d9 --- /dev/null +++ b/libcore/num/flt2dec/strategy/grisu.rs @@ -0,0 +1,696 @@ +// Copyright 2015 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. + +/*! +Rust adaptation of Grisu3 algorithm described in [1]. It uses about +1KB of precomputed table, and in turn, it's very quick for most inputs. + +[1] Florian Loitsch. 2010. Printing floating-point numbers quickly and + accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243. +*/ + +use prelude::v1::*; + +use num::diy_float::Fp; +use num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up}; + + +// see the comments in `format_shortest_opt` for the rationale. +#[doc(hidden)] pub const ALPHA: i16 = -60; +#[doc(hidden)] pub const GAMMA: i16 = -32; + +/* +# the following Python code generates this table: +for i in xrange(-308, 333, 8): + if i >= 0: f = 10**i; e = 0 + else: f = 2**(80-4*i) // 10**-i; e = 4 * i - 80 + l = f.bit_length() + f = ((f << 64 >> (l-1)) + 1) >> 1; e += l - 64 + print ' (%#018x, %5d, %4d),' % (f, e, i) +*/ + +#[doc(hidden)] +pub static CACHED_POW10: [(u64, i16, i16); 81] = [ // (f, e, k) + (0xe61acf033d1a45df, -1087, -308), + (0xab70fe17c79ac6ca, -1060, -300), + (0xff77b1fcbebcdc4f, -1034, -292), + (0xbe5691ef416bd60c, -1007, -284), + (0x8dd01fad907ffc3c, -980, -276), + (0xd3515c2831559a83, -954, -268), + (0x9d71ac8fada6c9b5, -927, -260), + (0xea9c227723ee8bcb, -901, -252), + (0xaecc49914078536d, -874, -244), + (0x823c12795db6ce57, -847, -236), + (0xc21094364dfb5637, -821, -228), + (0x9096ea6f3848984f, -794, -220), + (0xd77485cb25823ac7, -768, -212), + (0xa086cfcd97bf97f4, -741, -204), + (0xef340a98172aace5, -715, -196), + (0xb23867fb2a35b28e, -688, -188), + (0x84c8d4dfd2c63f3b, -661, -180), + (0xc5dd44271ad3cdba, -635, -172), + (0x936b9fcebb25c996, -608, -164), + (0xdbac6c247d62a584, -582, -156), + (0xa3ab66580d5fdaf6, -555, -148), + (0xf3e2f893dec3f126, -529, -140), + (0xb5b5ada8aaff80b8, -502, -132), + (0x87625f056c7c4a8b, -475, -124), + (0xc9bcff6034c13053, -449, -116), + (0x964e858c91ba2655, -422, -108), + (0xdff9772470297ebd, -396, -100), + (0xa6dfbd9fb8e5b88f, -369, -92), + (0xf8a95fcf88747d94, -343, -84), + (0xb94470938fa89bcf, -316, -76), + (0x8a08f0f8bf0f156b, -289, -68), + (0xcdb02555653131b6, -263, -60), + (0x993fe2c6d07b7fac, -236, -52), + (0xe45c10c42a2b3b06, -210, -44), + (0xaa242499697392d3, -183, -36), + (0xfd87b5f28300ca0e, -157, -28), + (0xbce5086492111aeb, -130, -20), + (0x8cbccc096f5088cc, -103, -12), + (0xd1b71758e219652c, -77, -4), + (0x9c40000000000000, -50, 4), + (0xe8d4a51000000000, -24, 12), + (0xad78ebc5ac620000, 3, 20), + (0x813f3978f8940984, 30, 28), + (0xc097ce7bc90715b3, 56, 36), + (0x8f7e32ce7bea5c70, 83, 44), + (0xd5d238a4abe98068, 109, 52), + (0x9f4f2726179a2245, 136, 60), + (0xed63a231d4c4fb27, 162, 68), + (0xb0de65388cc8ada8, 189, 76), + (0x83c7088e1aab65db, 216, 84), + (0xc45d1df942711d9a, 242, 92), + (0x924d692ca61be758, 269, 100), + (0xda01ee641a708dea, 295, 108), + (0xa26da3999aef774a, 322, 116), + (0xf209787bb47d6b85, 348, 124), + (0xb454e4a179dd1877, 375, 132), + (0x865b86925b9bc5c2, 402, 140), + (0xc83553c5c8965d3d, 428, 148), + (0x952ab45cfa97a0b3, 455, 156), + (0xde469fbd99a05fe3, 481, 164), + (0xa59bc234db398c25, 508, 172), + (0xf6c69a72a3989f5c, 534, 180), + (0xb7dcbf5354e9bece, 561, 188), + (0x88fcf317f22241e2, 588, 196), + (0xcc20ce9bd35c78a5, 614, 204), + (0x98165af37b2153df, 641, 212), + (0xe2a0b5dc971f303a, 667, 220), + (0xa8d9d1535ce3b396, 694, 228), + (0xfb9b7cd9a4a7443c, 720, 236), + (0xbb764c4ca7a44410, 747, 244), + (0x8bab8eefb6409c1a, 774, 252), + (0xd01fef10a657842c, 800, 260), + (0x9b10a4e5e9913129, 827, 268), + (0xe7109bfba19c0c9d, 853, 276), + (0xac2820d9623bf429, 880, 284), + (0x80444b5e7aa7cf85, 907, 292), + (0xbf21e44003acdd2d, 933, 300), + (0x8e679c2f5e44ff8f, 960, 308), + (0xd433179d9c8cb841, 986, 316), + (0x9e19db92b4e31ba9, 1013, 324), + (0xeb96bf6ebadf77d9, 1039, 332), +]; + +#[doc(hidden)] pub const CACHED_POW10_FIRST_E: i16 = -1087; +#[doc(hidden)] pub const CACHED_POW10_LAST_E: i16 = 1039; + +#[doc(hidden)] +pub fn cached_power(alpha: i16, gamma: i16) -> (i16, Fp) { + let offset = CACHED_POW10_FIRST_E as i32; + let range = (CACHED_POW10.len() as i32) - 1; + let domain = (CACHED_POW10_LAST_E - CACHED_POW10_FIRST_E) as i32; + let idx = ((gamma as i32) - offset) * range / domain; + let (f, e, k) = CACHED_POW10[idx as usize]; + debug_assert!(alpha <= e && e <= gamma); + (k, Fp { f: f, e: e }) +} + +/// Given `x > 0`, returns `(k, 10^k)` such that `10^k <= x < 10^(k+1)`. +#[doc(hidden)] +pub fn max_pow10_no_more_than(x: u32) -> (u8, u32) { + debug_assert!(x > 0); + + const X9: u32 = 10_0000_0000; + const X8: u32 = 1_0000_0000; + const X7: u32 = 1000_0000; + const X6: u32 = 100_0000; + const X5: u32 = 10_0000; + const X4: u32 = 1_0000; + const X3: u32 = 1000; + const X2: u32 = 100; + const X1: u32 = 10; + + if x < X4 { + if x < X2 { if x < X1 {(0, 1)} else {(1, X1)} } + else { if x < X3 {(2, X2)} else {(3, X3)} } + } else { + if x < X6 { if x < X5 {(4, X4)} else {(5, X5)} } + else if x < X8 { if x < X7 {(6, X6)} else {(7, X7)} } + else { if x < X9 {(8, X8)} else {(9, X9)} } + } +} + +/// The shortest mode implementation for Grisu. +/// +/// It returns `None` when it would return an inexact representation otherwise. +pub fn format_shortest_opt(d: &Decoded, + buf: &mut [u8]) -> Option<(/*#digits*/ usize, /*exp*/ i16)> { + assert!(d.mant > 0); + assert!(d.minus > 0); + assert!(d.plus > 0); + assert!(d.mant.checked_add(d.plus).is_some()); + assert!(d.mant.checked_sub(d.minus).is_some()); + assert!(buf.len() >= MAX_SIG_DIGITS); + assert!(d.mant + d.plus < (1 << 61)); // we need at least three bits of additional precision + + // start with the normalized values with the shared exponent + let plus = Fp { f: d.mant + d.plus, e: d.exp }.normalize(); + let minus = Fp { f: d.mant - d.minus, e: d.exp }.normalize_to(plus.e); + let v = Fp { f: d.mant, e: d.exp }.normalize_to(plus.e); + + // find any `cached = 10^minusk` such that `ALPHA <= minusk + plus.e + 64 <= GAMMA`. + // since `plus` is normalized, this means `2^(62 + ALPHA) <= plus * cached < 2^(64 + GAMMA)`; + // given our choices of `ALPHA` and `GAMMA`, this puts `plus * cached` into `[4, 2^32)`. + // + // it is obviously desirable to maximize `GAMMA - ALPHA`, + // so that we don't need many cached powers of 10, but there are some considerations: + // + // 1. we want to keep `floor(plus * cached)` within `u32` since it needs a costly division. + // (this is not really avoidable, remainder is required for accuracy estimation.) + // 2. the remainder of `floor(plus * cached)` repeatedly gets multiplied by 10, + // and it should not overflow. + // + // the first gives `64 + GAMMA <= 32`, while the second gives `10 * 2^-ALPHA <= 2^64`; + // -60 and -32 is the maximal range with this constraint, and V8 also uses them. + let (minusk, cached) = cached_power(ALPHA - plus.e - 64, GAMMA - plus.e - 64); + + // scale fps. this gives the maximal error of 1 ulp (proved from Theorem 5.1). + let plus = plus.mul(&cached); + let minus = minus.mul(&cached); + let v = v.mul(&cached); + debug_assert_eq!(plus.e, minus.e); + debug_assert_eq!(plus.e, v.e); + + // +- actual range of minus + // | <---|---------------------- unsafe region --------------------------> | + // | | | + // | |<--->| | <--------------- safe region ---------------> | | + // | | | | | | + // |1 ulp|1 ulp| |1 ulp|1 ulp| |1 ulp|1 ulp| + // |<--->|<--->| |<--->|<--->| |<--->|<--->| + // |-----|-----|-------...-------|-----|-----|-------...-------|-----|-----| + // | minus | | v | | plus | + // minus1 minus0 v - 1 ulp v + 1 ulp plus0 plus1 + // + // above `minus`, `v` and `plus` are *quantized* approximations (error < 1 ulp). + // as we don't know the error is positive or negative, we use two approximations spaced equally + // and have the maximal error of 2 ulps. + // + // the "unsafe region" is a liberal interval which we initially generate. + // the "safe region" is a conservative interval which we only accept. + // we start with the correct repr within the unsafe region, and try to find the closest repr + // to `v` which is also within the safe region. if we can't, we give up. + let plus1 = plus.f + 1; +// let plus0 = plus.f - 1; // only for explanation +// let minus0 = minus.f + 1; // only for explanation + let minus1 = minus.f - 1; + let e = -plus.e as usize; // shared exponent + + // divide `plus1` into integral and fractional parts. + // integral parts are guaranteed to fit in u32, since cached power guarantees `plus < 2^32` + // and normalized `plus.f` is always less than `2^64 - 2^4` due to the precision requirement. + let plus1int = (plus1 >> e) as u32; + let plus1frac = plus1 & ((1 << e) - 1); + + // calculate the largest `10^max_kappa` no more than `plus1` (thus `plus1 < 10^(max_kappa+1)`). + // this is an upper bound of `kappa` below. + let (max_kappa, max_ten_kappa) = max_pow10_no_more_than(plus1int); + + let mut i = 0; + let exp = max_kappa as i16 - minusk + 1; + + // Theorem 6.2: if `k` is the greatest integer s.t. `0 <= y mod 10^k <= y - x`, + // then `V = floor(y / 10^k) * 10^k` is in `[x, y]` and one of the shortest + // representations (with the minimal number of significant digits) in that range. + // + // find the digit length `kappa` between `(minus1, plus1)` as per Theorem 6.2. + // Theorem 6.2 can be adopted to exclude `x` by requiring `y mod 10^k < y - x` instead. + // (e.g. `x` = 32000, `y` = 32777; `kappa` = 2 since `y mod 10^3 = 777 < y - x = 777`.) + // the algorithm relies on the later verification phase to exclude `y`. + let delta1 = plus1 - minus1; +// let delta1int = (delta1 >> e) as usize; // only for explanation + let delta1frac = delta1 & ((1 << e) - 1); + + // render integral parts, while checking for the accuracy at each step. + let mut kappa = max_kappa as i16; + let mut ten_kappa = max_ten_kappa; // 10^kappa + let mut remainder = plus1int; // digits yet to be rendered + loop { // we always have at least one digit to render, as `plus1 >= 10^kappa` + // invariants: + // - `delta1int <= remainder < 10^(kappa+1)` + // - `plus1int = d[0..n-1] * 10^(kappa+1) + remainder` + // (it follows that `remainder = plus1int % 10^(kappa+1)`) + + // divide `remainder` by `10^kappa`. both are scaled by `2^-e`. + let q = remainder / ten_kappa; + let r = remainder % ten_kappa; + debug_assert!(q < 10); + buf[i] = b'0' + q as u8; + i += 1; + + let plus1rem = ((r as u64) << e) + plus1frac; // == (plus1 % 10^kappa) * 2^e + if plus1rem < delta1 { + // `plus1 % 10^kappa < delta1 = plus1 - minus1`; we've found the correct `kappa`. + let ten_kappa = (ten_kappa as u64) << e; // scale 10^kappa back to the shared exponent + return round_and_weed(&mut buf[..i], exp, plus1rem, delta1, plus1 - v.f, ten_kappa, 1); + } + + // break the loop when we have rendered all integral digits. + // the exact number of digits is `max_kappa + 1` as `plus1 < 10^(max_kappa+1)`. + if i > max_kappa as usize { + debug_assert_eq!(ten_kappa, 1); + debug_assert_eq!(kappa, 0); + break; + } + + // restore invariants + kappa -= 1; + ten_kappa /= 10; + remainder = r; + } + + // render fractional parts, while checking for the accuracy at each step. + // this time we rely on repeated multiplications, as division will lose the precision. + let mut remainder = plus1frac; + let mut threshold = delta1frac; + let mut ulp = 1; + loop { // the next digit should be significant as we've tested that before breaking out + // invariants, where `m = max_kappa + 1` (# of digits in the integral part): + // - `remainder < 2^e` + // - `plus1frac * 10^(n-m) = d[m..n-1] * 2^e + remainder` + + remainder *= 10; // won't overflow, `2^e * 10 < 2^64` + threshold *= 10; + ulp *= 10; + + // divide `remainder` by `10^kappa`. + // both are scaled by `2^e / 10^kappa`, so the latter is implicit here. + let q = remainder >> e; + let r = remainder & ((1 << e) - 1); + debug_assert!(q < 10); + buf[i] = b'0' + q as u8; + i += 1; + + if r < threshold { + let ten_kappa = 1 << e; // implicit divisor + return round_and_weed(&mut buf[..i], exp, r, threshold, + (plus1 - v.f) * ulp, ten_kappa, ulp); + } + + // restore invariants + kappa -= 1; + remainder = r; + } + + // we've generated all significant digits of `plus1`, but not sure if it's the optimal one. + // for example, if `minus1` is 3.14153... and `plus1` is 3.14158..., there are 5 different + // shortest representation from 3.14154 to 3.14158 but we only have the greatest one. + // we have to successively decrease the last digit and check if this is the optimal repr. + // there are at most 9 candidates (..1 to ..9), so this is fairly quick. ("rounding" phase) + // + // the function checks if this "optimal" repr is actually within the ulp ranges, + // and also, it is possible that the "second-to-optimal" repr can actually be optimal + // due to the rounding error. in either cases this returns `None`. ("weeding" phase) + // + // all arguments here are scaled by the common (but implicit) value `k`, so that: + // - `remainder = (plus1 % 10^kappa) * k` + // - `threshold = (plus1 - minus1) * k` (and also, `remainder < threshold`) + // - `plus1v = (plus1 - v) * k` (and also, `threshold > plus1v` from prior invariants) + // - `ten_kappa = 10^kappa * k` + // - `ulp = 2^-e * k` + fn round_and_weed(buf: &mut [u8], exp: i16, remainder: u64, threshold: u64, plus1v: u64, + ten_kappa: u64, ulp: u64) -> Option<(usize, i16)> { + assert!(!buf.is_empty()); + + // produce two approximations to `v` (actually `plus1 - v`) within 1.5 ulps. + // the resulting representation should be the closest representation to both. + // + // here `plus1 - v` is used since calculations are done with respect to `plus1` + // in order to avoid overflow/underflow (hence the seemingly swapped names). + let plus1v_down = plus1v + ulp; // plus1 - (v - 1 ulp) + let plus1v_up = plus1v - ulp; // plus1 - (v + 1 ulp) + + // decrease the last digit and stop at the closest representation to `v + 1 ulp`. + let mut plus1w = remainder; // plus1w(n) = plus1 - w(n) + { + let last = buf.last_mut().unwrap(); + + // we work with the approximated digits `w(n)`, which is initially equal to `plus1 - + // plus1 % 10^kappa`. after running the loop body `n` times, `w(n) = plus1 - + // plus1 % 10^kappa - n * 10^kappa`. we set `plus1w(n) = plus1 - w(n) = + // plus1 % 10^kappa + n * 10^kappa` (thus `remainder = plus1w(0)`) to simplify checks. + // note that `plus1w(n)` is always increasing. + // + // we have three conditions to terminate. any of them will make the loop unable to + // proceed, but we then have at least one valid representation known to be closest to + // `v + 1 ulp` anyway. we will denote them as TC1 through TC3 for brevity. + // + // TC1: `w(n) <= v + 1 ulp`, i.e. this is the last repr that can be the closest one. + // this is equivalent to `plus1 - w(n) = plus1w(n) >= plus1 - (v + 1 ulp) = plus1v_up`. + // combined with TC2 (which checks if `w(n+1)` is valid), this prevents the possible + // overflow on the calculation of `plus1w(n)`. + // + // TC2: `w(n+1) < minus1`, i.e. the next repr definitely does not round to `v`. + // this is equivalent to `plus1 - w(n) + 10^kappa = plus1w(n) + 10^kappa > + // plus1 - minus1 = threshold`. the left hand side can overflow, but we know + // `threshold > plus1v`, so if TC1 is false, `threshold - plus1w(n) > + // threshold - (plus1v - 1 ulp) > 1 ulp` and we can safely test if + // `threshold - plus1w(n) < 10^kappa` instead. + // + // TC3: `abs(w(n) - (v + 1 ulp)) <= abs(w(n+1) - (v + 1 ulp))`, i.e. the next repr is + // no closer to `v + 1 ulp` than the current repr. given `z(n) = plus1v_up - plus1w(n)`, + // this becomes `abs(z(n)) <= abs(z(n+1))`. again assuming that TC1 is false, we have + // `z(n) > 0`. we have two cases to consider: + // + // - when `z(n+1) >= 0`: TC3 becomes `z(n) <= z(n+1)`. as `plus1w(n)` is increasing, + // `z(n)` should be decreasing and this is clearly false. + // - when `z(n+1) < 0`: + // - TC3a: the precondition is `plus1v_up < plus1w(n) + 10^kappa`. assuming TC2 is + // false, `threshold >= plus1w(n) + 10^kappa` so it cannot overflow. + // - TC3b: TC3 becomes `z(n) <= -z(n+1)`, i.e. `plus1v_up - plus1w(n) >= + // plus1w(n+1) - plus1v_up = plus1w(n) + 10^kappa - plus1v_up`. the negated TC1 + // gives `plus1v_up > plus1w(n)`, so it cannot overflow or underflow when + // combined with TC3a. + // + // consequently, we should stop when `TC1 || TC2 || (TC3a && TC3b)`. the following is + // equal to its inverse, `!TC1 && !TC2 && (!TC3a || !TC3b)`. + while plus1w < plus1v_up && + threshold - plus1w >= ten_kappa && + (plus1w + ten_kappa < plus1v_up || + plus1v_up - plus1w >= plus1w + ten_kappa - plus1v_up) { + *last -= 1; + debug_assert!(*last > b'0'); // the shortest repr cannot end with `0` + plus1w += ten_kappa; + } + } + + // check if this representation is also the closest representation to `v - 1 ulp`. + // + // this is simply same to the terminating conditions for `v + 1 ulp`, with all `plus1v_up` + // replaced by `plus1v_down` instead. overflow analysis equally holds. + if plus1w < plus1v_down && + threshold - plus1w >= ten_kappa && + (plus1w + ten_kappa < plus1v_down || + plus1v_down - plus1w >= plus1w + ten_kappa - plus1v_down) { + return None; + } + + // now we have the closest representation to `v` between `plus1` and `minus1`. + // this is too liberal, though, so we reject any `w(n)` not between `plus0` and `minus0`, + // i.e. `plus1 - plus1w(n) <= minus0` or `plus1 - plus1w(n) >= plus0`. we utilize the facts + // that `threshold = plus1 - minus1` and `plus1 - plus0 = minus0 - minus1 = 2 ulp`. + if 2 * ulp <= plus1w && plus1w <= threshold - 4 * ulp { + Some((buf.len(), exp)) + } else { + None + } + } +} + +/// The shortest mode implementation for Grisu with Dragon fallback. +/// +/// This should be used for most cases. +pub fn format_shortest(d: &Decoded, buf: &mut [u8]) -> (/*#digits*/ usize, /*exp*/ i16) { + use num::flt2dec::strategy::dragon::format_shortest as fallback; + match format_shortest_opt(d, buf) { + Some(ret) => ret, + None => fallback(d, buf), + } +} + +/// The exact and fixed mode implementation for Grisu. +/// +/// It returns `None` when it would return an inexact representation otherwise. +pub fn format_exact_opt(d: &Decoded, buf: &mut [u8], limit: i16) + -> Option<(/*#digits*/ usize, /*exp*/ i16)> { + assert!(d.mant > 0); + assert!(d.mant < (1 << 61)); // we need at least three bits of additional precision + assert!(!buf.is_empty()); + + // normalize and scale `v`. + let v = Fp { f: d.mant, e: d.exp }.normalize(); + let (minusk, cached) = cached_power(ALPHA - v.e - 64, GAMMA - v.e - 64); + let v = v.mul(&cached); + + // divide `v` into integral and fractional parts. + let e = -v.e as usize; + let vint = (v.f >> e) as u32; + let vfrac = v.f & ((1 << e) - 1); + + // both old `v` and new `v` (scaled by `10^-k`) has an error of < 1 ulp (Theorem 5.1). + // as we don't know the error is positive or negative, we use two approximations + // spaced equally and have the maximal error of 2 ulps (same to the shortest case). + // + // the goal is to find the exactly rounded series of digits that are common to + // both `v - 1 ulp` and `v + 1 ulp`, so that we are maximally confident. + // if this is not possible, we don't know which one is the correct output for `v`, + // so we give up and fall back. + // + // `err` is defined as `1 ulp * 2^e` here (same to the ulp in `vfrac`), + // and we will scale it whenever `v` gets scaled. + let mut err = 1; + + // calculate the largest `10^max_kappa` no more than `v` (thus `v < 10^(max_kappa+1)`). + // this is an upper bound of `kappa` below. + let (max_kappa, max_ten_kappa) = max_pow10_no_more_than(vint); + + let mut i = 0; + let exp = max_kappa as i16 - minusk + 1; + + // if we are working with the last-digit limitation, we need to shorten the buffer + // before the actual rendering in order to avoid double rounding. + // note that we have to enlarge the buffer again when rounding up happens! + let len = if exp <= limit { + // oops, we cannot even produce *one* digit. + // this is possible when, say, we've got something like 9.5 and it's being rounded to 10. + // + // in principle we can immediately call `possibly_round` with an empty buffer, + // but scaling `max_ten_kappa << e` by 10 can result in overflow. + // thus we are being sloppy here and widen the error range by a factor of 10. + // this will increase the false negative rate, but only very, *very* slightly; + // it can only matter noticeably when the mantissa is bigger than 60 bits. + return possibly_round(buf, 0, exp, limit, v.f / 10, (max_ten_kappa as u64) << e, err << e); + } else if ((exp as i32 - limit as i32) as usize) < buf.len() { + (exp - limit) as usize + } else { + buf.len() + }; + debug_assert!(len > 0); + + // render integral parts. + // the error is entirely fractional, so we don't need to check it in this part. + let mut kappa = max_kappa as i16; + let mut ten_kappa = max_ten_kappa; // 10^kappa + let mut remainder = vint; // digits yet to be rendered + loop { // we always have at least one digit to render + // invariants: + // - `remainder < 10^(kappa+1)` + // - `vint = d[0..n-1] * 10^(kappa+1) + remainder` + // (it follows that `remainder = vint % 10^(kappa+1)`) + + // divide `remainder` by `10^kappa`. both are scaled by `2^-e`. + let q = remainder / ten_kappa; + let r = remainder % ten_kappa; + debug_assert!(q < 10); + buf[i] = b'0' + q as u8; + i += 1; + + // is the buffer full? run the rounding pass with the remainder. + if i == len { + let vrem = ((r as u64) << e) + vfrac; // == (v % 10^kappa) * 2^e + return possibly_round(buf, len, exp, limit, vrem, (ten_kappa as u64) << e, err << e); + } + + // break the loop when we have rendered all integral digits. + // the exact number of digits is `max_kappa + 1` as `plus1 < 10^(max_kappa+1)`. + if i > max_kappa as usize { + debug_assert_eq!(ten_kappa, 1); + debug_assert_eq!(kappa, 0); + break; + } + + // restore invariants + kappa -= 1; + ten_kappa /= 10; + remainder = r; + } + + // render fractional parts. + // + // in principle we can continue to the last available digit and check for the accuracy. + // unfortunately we are working with the finite-sized integers, so we need some criterion + // to detect the overflow. V8 uses `remainder > err`, which becomes false when + // the first `i` significant digits of `v - 1 ulp` and `v` differ. however this rejects + // too many otherwise valid input. + // + // since the later phase has a correct overflow detection, we instead use tighter criterion: + // we continue til `err` exceeds `10^kappa / 2`, so that the range between `v - 1 ulp` and + // `v + 1 ulp` definitely contains two or more rounded representations. this is same to + // the first two comparisons from `possibly_round`, for the reference. + let mut remainder = vfrac; + let maxerr = 1 << (e - 1); + while err < maxerr { + // invariants, where `m = max_kappa + 1` (# of digits in the integral part): + // - `remainder < 2^e` + // - `vfrac * 10^(n-m) = d[m..n-1] * 2^e + remainder` + // - `err = 10^(n-m)` + + remainder *= 10; // won't overflow, `2^e * 10 < 2^64` + err *= 10; // won't overflow, `err * 10 < 2^e * 5 < 2^64` + + // divide `remainder` by `10^kappa`. + // both are scaled by `2^e / 10^kappa`, so the latter is implicit here. + let q = remainder >> e; + let r = remainder & ((1 << e) - 1); + debug_assert!(q < 10); + buf[i] = b'0' + q as u8; + i += 1; + + // is the buffer full? run the rounding pass with the remainder. + if i == len { + return possibly_round(buf, len, exp, limit, r, 1 << e, err); + } + + // restore invariants + remainder = r; + } + + // further calculation is useless (`possibly_round` definitely fails), so we give up. + return None; + + // we've generated all requested digits of `v`, which should be also same to corresponding + // digits of `v - 1 ulp`. now we check if there is a unique representation shared by + // both `v - 1 ulp` and `v + 1 ulp`; this can be either same to generated digits, or + // to the rounded-up version of those digits. if the range contains multiple representations + // of the same length, we cannot be sure and should return `None` instead. + // + // all arguments here are scaled by the common (but implicit) value `k`, so that: + // - `remainder = (v % 10^kappa) * k` + // - `ten_kappa = 10^kappa * k` + // - `ulp = 2^-e * k` + fn possibly_round(buf: &mut [u8], mut len: usize, mut exp: i16, limit: i16, + remainder: u64, ten_kappa: u64, ulp: u64) -> Option<(usize, i16)> { + debug_assert!(remainder < ten_kappa); + + // 10^kappa + // : : :<->: : + // : : : : : + // :|1 ulp|1 ulp| : + // :|<--->|<--->| : + // ----|-----|-----|---- + // | v | + // v - 1 ulp v + 1 ulp + // + // (for the reference, the dotted line indicates the exact value for + // possible representations in given number of digits.) + // + // error is too large that there are at least three possible representations + // between `v - 1 ulp` and `v + 1 ulp`. we cannot determine which one is correct. + if ulp >= ten_kappa { return None; } + + // 10^kappa + // :<------->: + // : : + // : |1 ulp|1 ulp| + // : |<--->|<--->| + // ----|-----|-----|---- + // | v | + // v - 1 ulp v + 1 ulp + // + // in fact, 1/2 ulp is enough to introduce two possible representations. + // (remember that we need a unique representation for both `v - 1 ulp` and `v + 1 ulp`.) + // this won't overflow, as `ulp < ten_kappa` from the first check. + if ten_kappa - ulp <= ulp { return None; } + + // remainder + // :<->| : + // : | : + // :<--------- 10^kappa ---------->: + // | : | : + // |1 ulp|1 ulp| : + // |<--->|<--->| : + // ----|-----|-----|------------------------ + // | v | + // v - 1 ulp v + 1 ulp + // + // if `v + 1 ulp` is closer to the rounded-down representation (which is already in `buf`), + // then we can safely return. note that `v - 1 ulp` *can* be less than the current + // representation, but as `1 ulp < 10^kappa / 2`, this condition is enough: + // the distance between `v - 1 ulp` and the current representation + // cannot exceed `10^kappa / 2`. + // + // the condition equals to `remainder + ulp < 10^kappa / 2`. + // since this can easily overflow, first check if `remainder < 10^kappa / 2`. + // we've already verified that `ulp < 10^kappa / 2`, so as long as + // `10^kappa` did not overflow after all, the second check is fine. + if ten_kappa - remainder > remainder && ten_kappa - 2 * remainder >= 2 * ulp { + return Some((len, exp)); + } + + // :<------- remainder ------>| : + // : | : + // :<--------- 10^kappa --------->: + // : | | : | + // : |1 ulp|1 ulp| + // : |<--->|<--->| + // -----------------------|-----|-----|----- + // | v | + // v - 1 ulp v + 1 ulp + // + // on the other hands, if `v - 1 ulp` is closer to the rounded-up representation, + // we should round up and return. for the same reason we don't need to check `v + 1 ulp`. + // + // the condition equals to `remainder - ulp >= 10^kappa / 2`. + // again we first check if `remainder > ulp` (note that this is not `remainder >= ulp`, + // as `10^kappa` is never zero). also note that `remainder - ulp <= 10^kappa`, + // so the second check does not overflow. + if remainder > ulp && ten_kappa - (remainder - ulp) <= remainder - ulp { + if let Some(c) = round_up(buf, len) { + // only add an additional digit when we've been requested the fixed precision. + // we also need to check that, if the original buffer was empty, + // the additional digit can only be added when `exp == limit` (edge case). + exp += 1; + if exp > limit && len < buf.len() { + buf[len] = c; + len += 1; + } + } + return Some((len, exp)); + } + + // otherwise we are doomed (i.e. some values between `v - 1 ulp` and `v + 1 ulp` are + // rounding down and others are rounding up) and give up. + None + } +} + +/// The exact and fixed mode implementation for Grisu with Dragon fallback. +/// +/// This should be used for most cases. +pub fn format_exact(d: &Decoded, buf: &mut [u8], limit: i16) -> (/*#digits*/ usize, /*exp*/ i16) { + use num::flt2dec::strategy::dragon::format_exact as fallback; + match format_exact_opt(d, buf, limit) { + Some(ret) => ret, + None => fallback(d, buf, limit), + } +} diff --git a/libcore/num/i16.rs b/libcore/num/i16.rs new file mode 100644 index 0000000..1dd8209 --- /dev/null +++ b/libcore/num/i16.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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. + +//! The 16-bit signed integer type. +//! +//! *[See also the `i16` primitive type](../../std/primitive.i16.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +int_module! { i16, 16 } diff --git a/libcore/num/i32.rs b/libcore/num/i32.rs new file mode 100644 index 0000000..8a21689 --- /dev/null +++ b/libcore/num/i32.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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. + +//! The 32-bit signed integer type. +//! +//! *[See also the `i32` primitive type](../../std/primitive.i32.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +int_module! { i32, 32 } diff --git a/libcore/num/i64.rs b/libcore/num/i64.rs new file mode 100644 index 0000000..2ce9eb1 --- /dev/null +++ b/libcore/num/i64.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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. + +//! The 64-bit signed integer type. +//! +//! *[See also the `i64` primitive type](../../std/primitive.i64.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +int_module! { i64, 64 } diff --git a/libcore/num/i8.rs b/libcore/num/i8.rs new file mode 100644 index 0000000..8b5a7f1 --- /dev/null +++ b/libcore/num/i8.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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. + +//! The 8-bit signed integer type. +//! +//! *[See also the `i8` primitive type](../../std/primitive.i8.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +int_module! { i8, 8 } diff --git a/libcore/num/int_macros.rs b/libcore/num/int_macros.rs new file mode 100644 index 0000000..4234925 --- /dev/null +++ b/libcore/num/int_macros.rs @@ -0,0 +1,27 @@ +// Copyright 2012-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. + +#![doc(hidden)] + +macro_rules! int_module { ($T:ty, $bits:expr) => ( + +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `Bounded::min_value` function. +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MIN: $T = (-1 as $T) << ($bits - 1); +// FIXME(#9837): Compute MIN like this so the high bits that shouldn't exist are 0. +// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of +// calling the `Bounded::max_value` function. +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MAX: $T = !MIN; + +) } diff --git a/libcore/num/isize.rs b/libcore/num/isize.rs new file mode 100644 index 0000000..de5b177 --- /dev/null +++ b/libcore/num/isize.rs @@ -0,0 +1,20 @@ +// Copyright 2012-2015 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. + +//! The pointer-sized signed integer type. +//! +//! *[See also the `isize` primitive type](../../std/primitive.isize.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +#[cfg(target_pointer_width = "32")] +int_module! { isize, 32 } +#[cfg(target_pointer_width = "64")] +int_module! { isize, 64 } diff --git a/libcore/num/mod.rs b/libcore/num/mod.rs new file mode 100644 index 0000000..229a864 --- /dev/null +++ b/libcore/num/mod.rs @@ -0,0 +1,2516 @@ +// Copyright 2012-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. + +//! Numeric traits and functions for the built-in numeric types. + +#![stable(feature = "rust1", since = "1.0.0")] +#![allow(missing_docs)] + +use char::CharExt; +use cmp::{Eq, PartialOrd}; +use convert::From; +use fmt; +use intrinsics; +use marker::{Copy, Sized}; +use mem::size_of; +use option::Option::{self, Some, None}; +use result::Result::{self, Ok, Err}; +use str::{FromStr, StrExt}; +use slice::SliceExt; + +/// Provides intentionally-wrapped arithmetic on `T`. +/// +/// Operations like `+` on `u32` values is intended to never overflow, +/// and in some debug configurations overflow is detected and results +/// in a panic. While most arithmetic falls into this category, some +/// code explicitly expects and relies upon modular arithmetic (e.g., +/// hashing). +/// +/// Wrapping arithmetic can be achieved either through methods like +/// `wrapping_add`, or through the `Wrapping<T>` type, which says that +/// all standard arithmetic operations on the underlying value are +/// intended to have wrapping semantics. +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Default)] +pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T); + +mod wrapping; + +// All these modules are technically private and only exposed for libcoretest: +pub mod flt2dec; +pub mod dec2flt; +pub mod bignum; +pub mod diy_float; + +/// Types that have a "zero" value. +/// +/// This trait is intended for use in conjunction with `Add`, as an identity: +/// `x + T::zero() == x`. +#[unstable(feature = "zero_one", + reason = "unsure of placement, wants to use associated constants", + issue = "27739")] +pub trait Zero: Sized { + /// The "zero" (usually, additive identity) for this type. + fn zero() -> Self; +} + +/// Types that have a "one" value. +/// +/// This trait is intended for use in conjunction with `Mul`, as an identity: +/// `x * T::one() == x`. +#[unstable(feature = "zero_one", + reason = "unsure of placement, wants to use associated constants", + issue = "27739")] +pub trait One: Sized { + /// The "one" (usually, multiplicative identity) for this type. + fn one() -> Self; +} + +macro_rules! zero_one_impl { + ($($t:ty)*) => ($( + #[unstable(feature = "zero_one", + reason = "unsure of placement, wants to use associated constants", + issue = "27739")] + impl Zero for $t { + #[inline] + fn zero() -> Self { 0 } + } + #[unstable(feature = "zero_one", + reason = "unsure of placement, wants to use associated constants", + issue = "27739")] + impl One for $t { + #[inline] + fn one() -> Self { 1 } + } + )*) +} +zero_one_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } + +macro_rules! zero_one_impl_float { + ($($t:ty)*) => ($( + #[unstable(feature = "zero_one", + reason = "unsure of placement, wants to use associated constants", + issue = "27739")] + impl Zero for $t { + #[inline] + fn zero() -> Self { 0.0 } + } + #[unstable(feature = "zero_one", + reason = "unsure of placement, wants to use associated constants", + issue = "27739")] + impl One for $t { + #[inline] + fn one() -> Self { 1.0 } + } + )*) +} +zero_one_impl_float! { f32 f64 } + +macro_rules! checked_op { + ($U:ty, $op:path, $x:expr, $y:expr) => {{ + let (result, overflowed) = unsafe { $op($x as $U, $y as $U) }; + if overflowed { None } else { Some(result as Self) } + }} +} + +// `Int` + `SignedInt` implemented for signed integers +macro_rules! int_impl { + ($ActualT:ident, $UnsignedT:ty, $BITS:expr, + $add_with_overflow:path, + $sub_with_overflow:path, + $mul_with_overflow:path) => { + /// Returns the smallest value that can be represented by this integer type. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn min_value() -> Self { + (-1 as Self) << ($BITS - 1) + } + + /// Returns the largest value that can be represented by this integer type. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn max_value() -> Self { + !Self::min_value() + } + + /// Converts a string slice in a given base to an integer. + /// + /// Leading and trailing whitespace represent an error. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(u32::from_str_radix("A", 16), Ok(10)); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> { + from_str_radix(src, radix) + } + + /// Returns the number of ones in the binary representation of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0b01001100u8; + /// + /// assert_eq!(n.count_ones(), 3); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } + + /// Returns the number of zeros in the binary representation of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0b01001100u8; + /// + /// assert_eq!(n.count_zeros(), 5); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn count_zeros(self) -> u32 { + (!self).count_ones() + } + + /// Returns the number of leading zeros in the binary representation + /// of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0b0101000u16; + /// + /// assert_eq!(n.leading_zeros(), 10); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn leading_zeros(self) -> u32 { + (self as $UnsignedT).leading_zeros() + } + + /// Returns the number of trailing zeros in the binary representation + /// of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0b0101000u16; + /// + /// assert_eq!(n.trailing_zeros(), 3); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn trailing_zeros(self) -> u32 { + (self as $UnsignedT).trailing_zeros() + } + + /// Shifts the bits to the left by a specified amount, `n`, + /// wrapping the truncated bits to the end of the resulting integer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// let m = 0x3456789ABCDEF012u64; + /// + /// assert_eq!(n.rotate_left(12), m); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn rotate_left(self, n: u32) -> Self { + (self as $UnsignedT).rotate_left(n) as Self + } + + /// Shifts the bits to the right by a specified amount, `n`, + /// wrapping the truncated bits to the beginning of the resulting + /// integer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// let m = 0xDEF0123456789ABCu64; + /// + /// assert_eq!(n.rotate_right(12), m); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn rotate_right(self, n: u32) -> Self { + (self as $UnsignedT).rotate_right(n) as Self + } + + /// Reverses the byte order of the integer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// let m = 0xEFCDAB8967452301u64; + /// + /// assert_eq!(n.swap_bytes(), m); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn swap_bytes(self) -> Self { + (self as $UnsignedT).swap_bytes() as Self + } + + /// Converts an integer from big endian to the target's endianness. + /// + /// On big endian this is a no-op. On little endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// + /// if cfg!(target_endian = "big") { + /// assert_eq!(u64::from_be(n), n) + /// } else { + /// assert_eq!(u64::from_be(n), n.swap_bytes()) + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn from_be(x: Self) -> Self { + if cfg!(target_endian = "big") { x } else { x.swap_bytes() } + } + + /// Converts an integer from little endian to the target's endianness. + /// + /// On little endian this is a no-op. On big endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// + /// if cfg!(target_endian = "little") { + /// assert_eq!(u64::from_le(n), n) + /// } else { + /// assert_eq!(u64::from_le(n), n.swap_bytes()) + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn from_le(x: Self) -> Self { + if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + } + + /// Converts `self` to big endian from the target's endianness. + /// + /// On big endian this is a no-op. On little endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// + /// if cfg!(target_endian = "big") { + /// assert_eq!(n.to_be(), n) + /// } else { + /// assert_eq!(n.to_be(), n.swap_bytes()) + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn to_be(self) -> Self { // or not to be? + if cfg!(target_endian = "big") { self } else { self.swap_bytes() } + } + + /// Converts `self` to little endian from the target's endianness. + /// + /// On little endian this is a no-op. On big endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// + /// if cfg!(target_endian = "little") { + /// assert_eq!(n.to_le(), n) + /// } else { + /// assert_eq!(n.to_le(), n.swap_bytes()) + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn to_le(self) -> Self { + if cfg!(target_endian = "little") { self } else { self.swap_bytes() } + } + + /// Checked integer addition. Computes `self + other`, returning `None` + /// if overflow occurred. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(5u16.checked_add(65530), Some(65535)); + /// assert_eq!(6u16.checked_add(65530), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_add(self, other: Self) -> Option<Self> { + let (a, b) = self.overflowing_add(other); + if b {None} else {Some(a)} + } + + /// Checked integer subtraction. Computes `self - other`, returning + /// `None` if underflow occurred. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!((-127i8).checked_sub(1), Some(-128)); + /// assert_eq!((-128i8).checked_sub(1), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_sub(self, other: Self) -> Option<Self> { + let (a, b) = self.overflowing_sub(other); + if b {None} else {Some(a)} + } + + /// Checked integer multiplication. Computes `self * other`, returning + /// `None` if underflow or overflow occurred. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(5u8.checked_mul(51), Some(255)); + /// assert_eq!(5u8.checked_mul(52), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_mul(self, other: Self) -> Option<Self> { + let (a, b) = self.overflowing_mul(other); + if b {None} else {Some(a)} + } + + /// Checked integer division. Computes `self / other`, returning `None` + /// if `other == 0` or the operation results in underflow or overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!((-127i8).checked_div(-1), Some(127)); + /// assert_eq!((-128i8).checked_div(-1), None); + /// assert_eq!((1i8).checked_div(0), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_div(self, other: Self) -> Option<Self> { + if other == 0 { + None + } else { + let (a, b) = self.overflowing_div(other); + if b {None} else {Some(a)} + } + } + + /// Checked integer remainder. Computes `self % other`, returning `None` + /// if `other == 0` or the operation results in underflow or overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::i32; + /// + /// assert_eq!(5i32.checked_rem(2), Some(1)); + /// assert_eq!(5i32.checked_rem(0), None); + /// assert_eq!(i32::MIN.checked_rem(-1), None); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_rem(self, other: Self) -> Option<Self> { + if other == 0 { + None + } else { + let (a, b) = self.overflowing_rem(other); + if b {None} else {Some(a)} + } + } + + /// Checked negation. Computes `-self`, returning `None` if `self == + /// MIN`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::i32; + /// + /// assert_eq!(5i32.checked_neg(), Some(-5)); + /// assert_eq!(i32::MIN.checked_neg(), None); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_neg(self) -> Option<Self> { + let (a, b) = self.overflowing_neg(); + if b {None} else {Some(a)} + } + + /// Checked shift left. Computes `self << rhs`, returning `None` + /// if `rhs` is larger than or equal to the number of bits in `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(0x10i32.checked_shl(4), Some(0x100)); + /// assert_eq!(0x10i32.checked_shl(33), None); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_shl(self, rhs: u32) -> Option<Self> { + let (a, b) = self.overflowing_shl(rhs); + if b {None} else {Some(a)} + } + + /// Checked shift right. Computes `self >> rhs`, returning `None` + /// if `rhs` is larger than or equal to the number of bits in `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(0x10i32.checked_shr(4), Some(0x1)); + /// assert_eq!(0x10i32.checked_shr(33), None); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_shr(self, rhs: u32) -> Option<Self> { + let (a, b) = self.overflowing_shr(rhs); + if b {None} else {Some(a)} + } + + /// Saturating integer addition. Computes `self + other`, saturating at + /// the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.saturating_add(1), 101); + /// assert_eq!(100i8.saturating_add(127), 127); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn saturating_add(self, other: Self) -> Self { + match self.checked_add(other) { + Some(x) => x, + None if other >= Self::zero() => Self::max_value(), + None => Self::min_value(), + } + } + + /// Saturating integer subtraction. Computes `self - other`, saturating + /// at the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.saturating_sub(127), -27); + /// assert_eq!((-100i8).saturating_sub(127), -128); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn saturating_sub(self, other: Self) -> Self { + match self.checked_sub(other) { + Some(x) => x, + None if other >= Self::zero() => Self::min_value(), + None => Self::max_value(), + } + } + + /// Saturating integer multiplication. Computes `self * other`, + /// saturating at the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::i32; + /// + /// assert_eq!(100i32.saturating_mul(127), 12700); + /// assert_eq!((1i32 << 23).saturating_mul(1 << 23), i32::MAX); + /// assert_eq!((-1i32 << 23).saturating_mul(1 << 23), i32::MIN); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn saturating_mul(self, other: Self) -> Self { + self.checked_mul(other).unwrap_or_else(|| { + if (self < 0 && other < 0) || (self > 0 && other > 0) { + Self::max_value() + } else { + Self::min_value() + } + }) + } + + /// Wrapping (modular) addition. Computes `self + other`, + /// wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_add(27), 127); + /// assert_eq!(100i8.wrapping_add(127), -29); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_add(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_add(self, rhs) + } + } + + /// Wrapping (modular) subtraction. Computes `self - other`, + /// wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(0i8.wrapping_sub(127), -127); + /// assert_eq!((-2i8).wrapping_sub(127), 127); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_sub(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_sub(self, rhs) + } + } + + /// Wrapping (modular) multiplication. Computes `self * + /// other`, wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(10i8.wrapping_mul(12), 120); + /// assert_eq!(11i8.wrapping_mul(12), -124); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_mul(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_mul(self, rhs) + } + } + + /// Wrapping (modular) division. Computes `self / other`, + /// wrapping around at the boundary of the type. + /// + /// The only case where such wrapping can occur is when one + /// divides `MIN / -1` on a signed type (where `MIN` is the + /// negative minimal value for the type); this is equivalent + /// to `-MIN`, a positive value that is too large to represent + /// in the type. In such a case, this function returns `MIN` + /// itself. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100u8.wrapping_div(10), 10); + /// assert_eq!((-128i8).wrapping_div(-1), -128); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_div(self, rhs: Self) -> Self { + self.overflowing_div(rhs).0 + } + + /// Wrapping (modular) remainder. Computes `self % other`, + /// wrapping around at the boundary of the type. + /// + /// Such wrap-around never actually occurs mathematically; + /// implementation artifacts make `x % y` invalid for `MIN / + /// -1` on a signed type (where `MIN` is the negative + /// minimal value). In such a case, this function returns `0`. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_rem(10), 0); + /// assert_eq!((-128i8).wrapping_rem(-1), 0); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_rem(self, rhs: Self) -> Self { + self.overflowing_rem(rhs).0 + } + + /// Wrapping (modular) negation. Computes `-self`, + /// wrapping around at the boundary of the type. + /// + /// The only case where such wrapping can occur is when one + /// negates `MIN` on a signed type (where `MIN` is the + /// negative minimal value for the type); this is a positive + /// value that is too large to represent in the type. In such + /// a case, this function returns `MIN` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_neg(), -100); + /// assert_eq!((-128i8).wrapping_neg(), -128); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_neg(self) -> Self { + self.overflowing_neg().0 + } + + /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, + /// where `mask` removes any high-order bits of `rhs` that + /// would cause the shift to exceed the bitwidth of the type. + /// + /// Note that this is *not* the same as a rotate-left; the + /// RHS of a wrapping shift-left is restricted to the range + /// of the type, rather than the bits shifted out of the LHS + /// being returned to the other end. The primitive integer + /// types all implement a `rotate_left` function, which may + /// be what you want instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(1u8.wrapping_shl(7), 128); + /// assert_eq!(1u8.wrapping_shl(8), 1); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_shl(self, rhs: u32) -> Self { + self.overflowing_shl(rhs).0 + } + + /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, + /// where `mask` removes any high-order bits of `rhs` that + /// would cause the shift to exceed the bitwidth of the type. + /// + /// Note that this is *not* the same as a rotate-right; the + /// RHS of a wrapping shift-right is restricted to the range + /// of the type, rather than the bits shifted out of the LHS + /// being returned to the other end. The primitive integer + /// types all implement a `rotate_right` function, which may + /// be what you want instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(128u8.wrapping_shr(7), 1); + /// assert_eq!(128u8.wrapping_shr(8), 128); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_shr(self, rhs: u32) -> Self { + self.overflowing_shr(rhs).0 + } + + /// Calculates `self` + `rhs` + /// + /// Returns a tuple of the addition along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// use std::i32; + /// + /// assert_eq!(5i32.overflowing_add(2), (7, false)); + /// assert_eq!(i32::MAX.overflowing_add(1), (i32::MIN, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $add_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates `self` - `rhs` + /// + /// Returns a tuple of the subtraction along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// use std::i32; + /// + /// assert_eq!(5i32.overflowing_sub(2), (3, false)); + /// assert_eq!(i32::MIN.overflowing_sub(1), (i32::MAX, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $sub_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates the multiplication of `self` and `rhs`. + /// + /// Returns a tuple of the multiplication along with a boolean + /// indicating whether an arithmetic overflow would occur. If an + /// overflow would have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// assert_eq!(5i32.overflowing_mul(2), (10, false)); + /// assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $mul_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates the divisor when `self` is divided by `rhs`. + /// + /// Returns a tuple of the divisor along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// occur then self is returned. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// use std::i32; + /// + /// assert_eq!(5i32.overflowing_div(2), (2, false)); + /// assert_eq!(i32::MIN.overflowing_div(-1), (i32::MIN, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + if self == Self::min_value() && rhs == -1 { + (self, true) + } else { + (self / rhs, false) + } + } + + /// Calculates the remainder when `self` is divided by `rhs`. + /// + /// Returns a tuple of the remainder after dividing along with a boolean + /// indicating whether an arithmetic overflow would occur. If an + /// overflow would occur then 0 is returned. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// use std::i32; + /// + /// assert_eq!(5i32.overflowing_rem(2), (1, false)); + /// assert_eq!(i32::MIN.overflowing_rem(-1), (0, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + if self == Self::min_value() && rhs == -1 { + (0, true) + } else { + (self % rhs, false) + } + } + + /// Negates self, overflowing if this is equal to the minimum value. + /// + /// Returns a tuple of the negated version of self along with a boolean + /// indicating whether an overflow happened. If `self` is the minimum + /// value (e.g. `i32::MIN` for values of type `i32`), then the minimum + /// value will be returned again and `true` will be returned for an + /// overflow happening. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// use std::i32; + /// + /// assert_eq!(2i32.overflowing_neg(), (-2, false)); + /// assert_eq!(i32::MIN.overflowing_neg(), (i32::MIN, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_neg(self) -> (Self, bool) { + if self == Self::min_value() { + (Self::min_value(), true) + } else { + (-self, false) + } + } + + /// Shifts self left by `rhs` bits. + /// + /// Returns a tuple of the shifted version of self along with a boolean + /// indicating whether the shift value was larger than or equal to the + /// number of bits. If the shift value is too large, then value is + /// masked (N-1) where N is the number of bits, and this value is then + /// used to perform the shift. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// assert_eq!(0x10i32.overflowing_shl(4), (0x100, false)); + /// assert_eq!(0x10i32.overflowing_shl(36), (0x100, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { + (self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) + } + + /// Shifts self right by `rhs` bits. + /// + /// Returns a tuple of the shifted version of self along with a boolean + /// indicating whether the shift value was larger than or equal to the + /// number of bits. If the shift value is too large, then value is + /// masked (N-1) where N is the number of bits, and this value is then + /// used to perform the shift. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// assert_eq!(0x10i32.overflowing_shr(4), (0x1, false)); + /// assert_eq!(0x10i32.overflowing_shr(36), (0x1, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { + (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) + } + + /// Raises self to the power of `exp`, using exponentiation by squaring. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let x: i32 = 2; // or any other integer type + /// + /// assert_eq!(x.pow(4), 16); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + #[rustc_no_mir] // FIXME #29769 MIR overflow checking is TBD. + pub fn pow(self, mut exp: u32) -> Self { + let mut base = self; + let mut acc = Self::one(); + + while exp > 1 { + if (exp & 1) == 1 { + acc = acc * base; + } + exp /= 2; + base = base * base; + } + + // Deal with the final bit of the exponent separately, since + // squaring the base afterwards is not necessary and may cause a + // needless overflow. + if exp == 1 { + acc = acc * base; + } + + acc + } + + /// Computes the absolute value of `self`. + /// + /// # Overflow behavior + /// + /// The absolute value of `i32::min_value()` cannot be represented as an + /// `i32`, and attempting to calculate it will cause an overflow. This + /// means that code in debug mode will trigger a panic on this case and + /// optimized code will return `i32::min_value()` without a panic. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(10i8.abs(), 10); + /// assert_eq!((-10i8).abs(), 10); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + #[rustc_no_mir] // FIXME #29769 MIR overflow checking is TBD. + pub fn abs(self) -> Self { + if self.is_negative() { + // Note that the #[inline] above means that the overflow + // semantics of this negation depend on the crate we're being + // inlined into. + -self + } else { + self + } + } + + /// Returns a number representing sign of `self`. + /// + /// - `0` if the number is zero + /// - `1` if the number is positive + /// - `-1` if the number is negative + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(10i8.signum(), 1); + /// assert_eq!(0i8.signum(), 0); + /// assert_eq!((-10i8).signum(), -1); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn signum(self) -> Self { + match self { + n if n > 0 => 1, + 0 => 0, + _ => -1, + } + } + + /// Returns `true` if `self` is positive and `false` if the number + /// is zero or negative. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert!(10i8.is_positive()); + /// assert!(!(-10i8).is_positive()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_positive(self) -> bool { self > 0 } + + /// Returns `true` if `self` is negative and `false` if the number + /// is zero or positive. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert!((-10i8).is_negative()); + /// assert!(!10i8.is_negative()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_negative(self) -> bool { self < 0 } + } +} + +#[lang = "i8"] +impl i8 { + int_impl! { i8, u8, 8, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[lang = "i16"] +impl i16 { + int_impl! { i16, u16, 16, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[lang = "i32"] +impl i32 { + int_impl! { i32, u32, 32, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[lang = "i64"] +impl i64 { + int_impl! { i64, u64, 64, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[cfg(target_pointer_width = "32")] +#[lang = "isize"] +impl isize { + int_impl! { i32, u32, 32, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[cfg(target_pointer_width = "64")] +#[lang = "isize"] +impl isize { + int_impl! { i64, u64, 64, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +// `Int` + `UnsignedInt` implemented for unsigned integers +macro_rules! uint_impl { + ($ActualT:ty, $BITS:expr, + $ctpop:path, + $ctlz:path, + $cttz:path, + $bswap:path, + $add_with_overflow:path, + $sub_with_overflow:path, + $mul_with_overflow:path) => { + /// Returns the smallest value that can be represented by this integer type. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn min_value() -> Self { 0 } + + /// Returns the largest value that can be represented by this integer type. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn max_value() -> Self { !0 } + + /// Converts a string slice in a given base to an integer. + /// + /// Leading and trailing whitespace represent an error. + /// + /// # Arguments + /// + /// * src - A string slice + /// * radix - The base to use. Must lie in the range [2 .. 36] + /// + /// # Return value + /// + /// `Err(ParseIntError)` if the string did not represent a valid number. + /// Otherwise, `Ok(n)` where `n` is the integer represented by `src`. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> { + from_str_radix(src, radix) + } + + /// Returns the number of ones in the binary representation of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0b01001100u8; + /// + /// assert_eq!(n.count_ones(), 3); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn count_ones(self) -> u32 { + unsafe { $ctpop(self as $ActualT) as u32 } + } + + /// Returns the number of zeros in the binary representation of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0b01001100u8; + /// + /// assert_eq!(n.count_zeros(), 5); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn count_zeros(self) -> u32 { + (!self).count_ones() + } + + /// Returns the number of leading zeros in the binary representation + /// of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0b0101000u16; + /// + /// assert_eq!(n.leading_zeros(), 10); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn leading_zeros(self) -> u32 { + unsafe { $ctlz(self as $ActualT) as u32 } + } + + /// Returns the number of trailing zeros in the binary representation + /// of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0b0101000u16; + /// + /// assert_eq!(n.trailing_zeros(), 3); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn trailing_zeros(self) -> u32 { + // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic + // emits two conditional moves on x86_64. By promoting the value to + // u16 and setting bit 8, we get better code without any conditional + // operations. + // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284) + // pending, remove this workaround once LLVM generates better code + // for cttz8. + unsafe { + if $BITS == 8 { + intrinsics::cttz(self as u16 | 0x100) as u32 + } else { + intrinsics::cttz(self) as u32 + } + } + } + + /// Shifts the bits to the left by a specified amount, `n`, + /// wrapping the truncated bits to the end of the resulting integer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// let m = 0x3456789ABCDEF012u64; + /// + /// assert_eq!(n.rotate_left(12), m); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn rotate_left(self, n: u32) -> Self { + // Protect against undefined behaviour for over-long bit shifts + let n = n % $BITS; + (self << n) | (self >> (($BITS - n) % $BITS)) + } + + /// Shifts the bits to the right by a specified amount, `n`, + /// wrapping the truncated bits to the beginning of the resulting + /// integer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// let m = 0xDEF0123456789ABCu64; + /// + /// assert_eq!(n.rotate_right(12), m); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn rotate_right(self, n: u32) -> Self { + // Protect against undefined behaviour for over-long bit shifts + let n = n % $BITS; + (self >> n) | (self << (($BITS - n) % $BITS)) + } + + /// Reverses the byte order of the integer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// let m = 0xEFCDAB8967452301u64; + /// + /// assert_eq!(n.swap_bytes(), m); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn swap_bytes(self) -> Self { + unsafe { $bswap(self as $ActualT) as Self } + } + + /// Converts an integer from big endian to the target's endianness. + /// + /// On big endian this is a no-op. On little endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// + /// if cfg!(target_endian = "big") { + /// assert_eq!(u64::from_be(n), n) + /// } else { + /// assert_eq!(u64::from_be(n), n.swap_bytes()) + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn from_be(x: Self) -> Self { + if cfg!(target_endian = "big") { x } else { x.swap_bytes() } + } + + /// Converts an integer from little endian to the target's endianness. + /// + /// On little endian this is a no-op. On big endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// + /// if cfg!(target_endian = "little") { + /// assert_eq!(u64::from_le(n), n) + /// } else { + /// assert_eq!(u64::from_le(n), n.swap_bytes()) + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn from_le(x: Self) -> Self { + if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + } + + /// Converts `self` to big endian from the target's endianness. + /// + /// On big endian this is a no-op. On little endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// + /// if cfg!(target_endian = "big") { + /// assert_eq!(n.to_be(), n) + /// } else { + /// assert_eq!(n.to_be(), n.swap_bytes()) + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn to_be(self) -> Self { // or not to be? + if cfg!(target_endian = "big") { self } else { self.swap_bytes() } + } + + /// Converts `self` to little endian from the target's endianness. + /// + /// On little endian this is a no-op. On big endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let n = 0x0123456789ABCDEFu64; + /// + /// if cfg!(target_endian = "little") { + /// assert_eq!(n.to_le(), n) + /// } else { + /// assert_eq!(n.to_le(), n.swap_bytes()) + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn to_le(self) -> Self { + if cfg!(target_endian = "little") { self } else { self.swap_bytes() } + } + + /// Checked integer addition. Computes `self + other`, returning `None` + /// if overflow occurred. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(5u16.checked_add(65530), Some(65535)); + /// assert_eq!(6u16.checked_add(65530), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_add(self, other: Self) -> Option<Self> { + let (a, b) = self.overflowing_add(other); + if b {None} else {Some(a)} + } + + /// Checked integer subtraction. Computes `self - other`, returning + /// `None` if underflow occurred. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(1u8.checked_sub(1), Some(0)); + /// assert_eq!(0u8.checked_sub(1), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_sub(self, other: Self) -> Option<Self> { + let (a, b) = self.overflowing_sub(other); + if b {None} else {Some(a)} + } + + /// Checked integer multiplication. Computes `self * other`, returning + /// `None` if underflow or overflow occurred. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(5u8.checked_mul(51), Some(255)); + /// assert_eq!(5u8.checked_mul(52), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_mul(self, other: Self) -> Option<Self> { + let (a, b) = self.overflowing_mul(other); + if b {None} else {Some(a)} + } + + /// Checked integer division. Computes `self / other`, returning `None` + /// if `other == 0` or the operation results in underflow or overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(128u8.checked_div(2), Some(64)); + /// assert_eq!(1u8.checked_div(0), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_div(self, other: Self) -> Option<Self> { + match other { + 0 => None, + other => Some(self / other), + } + } + + /// Checked integer remainder. Computes `self % other`, returning `None` + /// if `other == 0` or the operation results in underflow or overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(5u32.checked_rem(2), Some(1)); + /// assert_eq!(5u32.checked_rem(0), None); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_rem(self, other: Self) -> Option<Self> { + if other == 0 { + None + } else { + Some(self % other) + } + } + + /// Checked negation. Computes `-self`, returning `None` unless `self == + /// 0`. + /// + /// Note that negating any positive integer will overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(0u32.checked_neg(), Some(0)); + /// assert_eq!(1u32.checked_neg(), None); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_neg(self) -> Option<Self> { + let (a, b) = self.overflowing_neg(); + if b {None} else {Some(a)} + } + + /// Checked shift left. Computes `self << rhs`, returning `None` + /// if `rhs` is larger than or equal to the number of bits in `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(0x10u32.checked_shl(4), Some(0x100)); + /// assert_eq!(0x10u32.checked_shl(33), None); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_shl(self, rhs: u32) -> Option<Self> { + let (a, b) = self.overflowing_shl(rhs); + if b {None} else {Some(a)} + } + + /// Checked shift right. Computes `self >> rhs`, returning `None` + /// if `rhs` is larger than or equal to the number of bits in `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(0x10u32.checked_shr(4), Some(0x1)); + /// assert_eq!(0x10u32.checked_shr(33), None); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_shr(self, rhs: u32) -> Option<Self> { + let (a, b) = self.overflowing_shr(rhs); + if b {None} else {Some(a)} + } + + /// Saturating integer addition. Computes `self + other`, saturating at + /// the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100u8.saturating_add(1), 101); + /// assert_eq!(200u8.saturating_add(127), 255); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn saturating_add(self, other: Self) -> Self { + match self.checked_add(other) { + Some(x) => x, + None => Self::max_value(), + } + } + + /// Saturating integer subtraction. Computes `self - other`, saturating + /// at the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100u8.saturating_sub(27), 73); + /// assert_eq!(13u8.saturating_sub(127), 0); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn saturating_sub(self, other: Self) -> Self { + match self.checked_sub(other) { + Some(x) => x, + None => Self::min_value(), + } + } + + /// Saturating integer multiplication. Computes `self * other`, + /// saturating at the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::u32; + /// + /// assert_eq!(100u32.saturating_mul(127), 12700); + /// assert_eq!((1u32 << 23).saturating_mul(1 << 23), u32::MAX); + /// ``` + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn saturating_mul(self, other: Self) -> Self { + self.checked_mul(other).unwrap_or(Self::max_value()) + } + + /// Wrapping (modular) addition. Computes `self + other`, + /// wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(200u8.wrapping_add(55), 255); + /// assert_eq!(200u8.wrapping_add(155), 99); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_add(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_add(self, rhs) + } + } + + /// Wrapping (modular) subtraction. Computes `self - other`, + /// wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100u8.wrapping_sub(100), 0); + /// assert_eq!(100u8.wrapping_sub(155), 201); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_sub(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_sub(self, rhs) + } + } + + /// Wrapping (modular) multiplication. Computes `self * + /// other`, wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(10u8.wrapping_mul(12), 120); + /// assert_eq!(25u8.wrapping_mul(12), 44); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_mul(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_mul(self, rhs) + } + } + + /// Wrapping (modular) division. Computes `self / other`. + /// Wrapped division on unsigned types is just normal division. + /// There's no way wrapping could ever happen. + /// This function exists, so that all operations + /// are accounted for in the wrapping operations. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100u8.wrapping_div(10), 10); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_div(self, rhs: Self) -> Self { + self / rhs + } + + /// Wrapping (modular) remainder. Computes `self % other`. + /// Wrapped remainder calculation on unsigned types is + /// just the regular remainder calculation. + /// There's no way wrapping could ever happen. + /// This function exists, so that all operations + /// are accounted for in the wrapping operations. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_rem(10), 0); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_rem(self, rhs: Self) -> Self { + self % rhs + } + + /// Wrapping (modular) negation. Computes `-self`, + /// wrapping around at the boundary of the type. + /// + /// Since unsigned types do not have negative equivalents + /// all applications of this function will wrap (except for `-0`). + /// For values smaller than the corresponding signed type's maximum + /// the result is the same as casting the corresponding signed value. + /// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where + /// `MAX` is the corresponding signed type's maximum. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100u8.wrapping_neg(), 156); + /// assert_eq!(0u8.wrapping_neg(), 0); + /// assert_eq!(180u8.wrapping_neg(), 76); + /// assert_eq!(180u8.wrapping_neg(), (127 + 1) - (180u8 - (127 + 1))); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_neg(self) -> Self { + self.overflowing_neg().0 + } + + /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, + /// where `mask` removes any high-order bits of `rhs` that + /// would cause the shift to exceed the bitwidth of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(1u8.wrapping_shl(7), 128); + /// assert_eq!(1u8.wrapping_shl(8), 1); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_shl(self, rhs: u32) -> Self { + self.overflowing_shl(rhs).0 + } + + /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, + /// where `mask` removes any high-order bits of `rhs` that + /// would cause the shift to exceed the bitwidth of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(128u8.wrapping_shr(7), 1); + /// assert_eq!(128u8.wrapping_shr(8), 128); + /// ``` + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline(always)] + pub fn wrapping_shr(self, rhs: u32) -> Self { + self.overflowing_shr(rhs).0 + } + + /// Calculates `self` + `rhs` + /// + /// Returns a tuple of the addition along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// use std::u32; + /// + /// assert_eq!(5u32.overflowing_add(2), (7, false)); + /// assert_eq!(u32::MAX.overflowing_add(1), (0, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $add_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates `self` - `rhs` + /// + /// Returns a tuple of the subtraction along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// use std::u32; + /// + /// assert_eq!(5u32.overflowing_sub(2), (3, false)); + /// assert_eq!(0u32.overflowing_sub(1), (u32::MAX, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $sub_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates the multiplication of `self` and `rhs`. + /// + /// Returns a tuple of the multiplication along with a boolean + /// indicating whether an arithmetic overflow would occur. If an + /// overflow would have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// assert_eq!(5u32.overflowing_mul(2), (10, false)); + /// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $mul_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates the divisor when `self` is divided by `rhs`. + /// + /// Returns a tuple of the divisor along with a boolean indicating + /// whether an arithmetic overflow would occur. Note that for unsigned + /// integers overflow never occurs, so the second value is always + /// `false`. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// assert_eq!(5u32.overflowing_div(2), (2, false)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + (self / rhs, false) + } + + /// Calculates the remainder when `self` is divided by `rhs`. + /// + /// Returns a tuple of the remainder after dividing along with a boolean + /// indicating whether an arithmetic overflow would occur. Note that for + /// unsigned integers overflow never occurs, so the second value is + /// always `false`. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// assert_eq!(5u32.overflowing_rem(2), (1, false)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + (self % rhs, false) + } + + /// Negates self in an overflowing fashion. + /// + /// Returns `!self + 1` using wrapping operations to return the value + /// that represents the negation of this unsigned value. Note that for + /// positive unsigned values overflow always occurs, but negating 0 does + /// not overflow. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// assert_eq!(0u32.overflowing_neg(), (0, false)); + /// assert_eq!(2u32.overflowing_neg(), (-2i32 as u32, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_neg(self) -> (Self, bool) { + ((!self).wrapping_add(1), self != 0) + } + + /// Shifts self left by `rhs` bits. + /// + /// Returns a tuple of the shifted version of self along with a boolean + /// indicating whether the shift value was larger than or equal to the + /// number of bits. If the shift value is too large, then value is + /// masked (N-1) where N is the number of bits, and this value is then + /// used to perform the shift. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// assert_eq!(0x10u32.overflowing_shl(4), (0x100, false)); + /// assert_eq!(0x10u32.overflowing_shl(36), (0x100, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { + (self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) + } + + /// Shifts self right by `rhs` bits. + /// + /// Returns a tuple of the shifted version of self along with a boolean + /// indicating whether the shift value was larger than or equal to the + /// number of bits. If the shift value is too large, then value is + /// masked (N-1) where N is the number of bits, and this value is then + /// used to perform the shift. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// assert_eq!(0x10u32.overflowing_shr(4), (0x1, false)); + /// assert_eq!(0x10u32.overflowing_shr(36), (0x1, true)); + /// ``` + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { + (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) + } + + /// Raises self to the power of `exp`, using exponentiation by squaring. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(2u32.pow(4), 16); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + #[rustc_no_mir] // FIXME #29769 MIR overflow checking is TBD. + pub fn pow(self, mut exp: u32) -> Self { + let mut base = self; + let mut acc = Self::one(); + + let mut prev_base = self; + let mut base_oflo = false; + while exp > 0 { + if (exp & 1) == 1 { + if base_oflo { + // ensure overflow occurs in the same manner it + // would have otherwise (i.e. signal any exception + // it would have otherwise). + acc = acc * (prev_base * prev_base); + } else { + acc = acc * base; + } + } + prev_base = base; + let (new_base, new_base_oflo) = base.overflowing_mul(base); + base = new_base; + base_oflo = new_base_oflo; + exp /= 2; + } + acc + } + + /// Returns `true` if and only if `self == 2^k` for some `k`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert!(16u8.is_power_of_two()); + /// assert!(!10u8.is_power_of_two()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_power_of_two(self) -> bool { + (self.wrapping_sub(Self::one())) & self == Self::zero() && + !(self == Self::zero()) + } + + /// Returns the smallest power of two greater than or equal to `self`. + /// Unspecified behavior on overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(2u8.next_power_of_two(), 2); + /// assert_eq!(3u8.next_power_of_two(), 4); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn next_power_of_two(self) -> Self { + let bits = size_of::<Self>() * 8; + let one: Self = Self::one(); + one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits) + } + + /// Returns the smallest power of two greater than or equal to `n`. If + /// the next power of two is greater than the type's maximum value, + /// `None` is returned, otherwise the power of two is wrapped in `Some`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(2u8.checked_next_power_of_two(), Some(2)); + /// assert_eq!(3u8.checked_next_power_of_two(), Some(4)); + /// assert_eq!(200u8.checked_next_power_of_two(), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn checked_next_power_of_two(self) -> Option<Self> { + let npot = self.next_power_of_two(); + if npot >= self { + Some(npot) + } else { + None + } + } + } +} + +#[lang = "u8"] +impl u8 { + uint_impl! { u8, 8, + intrinsics::ctpop, + intrinsics::ctlz, + intrinsics::cttz, + intrinsics::bswap, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[lang = "u16"] +impl u16 { + uint_impl! { u16, 16, + intrinsics::ctpop, + intrinsics::ctlz, + intrinsics::cttz, + intrinsics::bswap, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[lang = "u32"] +impl u32 { + uint_impl! { u32, 32, + intrinsics::ctpop, + intrinsics::ctlz, + intrinsics::cttz, + intrinsics::bswap, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[lang = "u64"] +impl u64 { + uint_impl! { u64, 64, + intrinsics::ctpop, + intrinsics::ctlz, + intrinsics::cttz, + intrinsics::bswap, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[cfg(target_pointer_width = "32")] +#[lang = "usize"] +impl usize { + uint_impl! { u32, 32, + intrinsics::ctpop, + intrinsics::ctlz, + intrinsics::cttz, + intrinsics::bswap, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +#[cfg(target_pointer_width = "64")] +#[lang = "usize"] +impl usize { + uint_impl! { u64, 64, + intrinsics::ctpop, + intrinsics::ctlz, + intrinsics::cttz, + intrinsics::bswap, + intrinsics::add_with_overflow, + intrinsics::sub_with_overflow, + intrinsics::mul_with_overflow } +} + +/// A classification of floating point numbers. +/// +/// This `enum` is used as the return type for [`f32::classify()`] and [`f64::classify()`]. See +/// their documentation for more. +/// +/// [`f32::classify()`]: ../../std/primitive.f32.html#method.classify +/// [`f64::classify()`]: ../../std/primitive.f64.html#method.classify +#[derive(Copy, Clone, PartialEq, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub enum FpCategory { + /// "Not a Number", often obtained by dividing by zero + #[stable(feature = "rust1", since = "1.0.0")] + Nan, + + /// Positive or negative infinity + #[stable(feature = "rust1", since = "1.0.0")] + Infinite , + + /// Positive or negative zero + #[stable(feature = "rust1", since = "1.0.0")] + Zero, + + /// De-normalized floating point representation (less precise than `Normal`) + #[stable(feature = "rust1", since = "1.0.0")] + Subnormal, + + /// A regular floating point number + #[stable(feature = "rust1", since = "1.0.0")] + Normal, +} + +/// A built-in floating point number. +#[doc(hidden)] +#[unstable(feature = "core_float", + reason = "stable interface is via `impl f{32,64}` in later crates", + issue = "32110")] +pub trait Float: Sized { + /// Returns the NaN value. + #[unstable(feature = "float_extras", reason = "needs removal", + issue = "27752")] + fn nan() -> Self; + /// Returns the infinite value. + #[unstable(feature = "float_extras", reason = "needs removal", + issue = "27752")] + fn infinity() -> Self; + /// Returns the negative infinite value. + #[unstable(feature = "float_extras", reason = "needs removal", + issue = "27752")] + fn neg_infinity() -> Self; + /// Returns -0.0. + #[unstable(feature = "float_extras", reason = "needs removal", + issue = "27752")] + fn neg_zero() -> Self; + /// Returns 0.0. + #[unstable(feature = "float_extras", reason = "needs removal", + issue = "27752")] + fn zero() -> Self; + /// Returns 1.0. + #[unstable(feature = "float_extras", reason = "needs removal", + issue = "27752")] + fn one() -> Self; + + /// Returns true if this value is NaN and false otherwise. + #[stable(feature = "core", since = "1.6.0")] + fn is_nan(self) -> bool; + /// Returns true if this value is positive infinity or negative infinity and + /// false otherwise. + #[stable(feature = "core", since = "1.6.0")] + fn is_infinite(self) -> bool; + /// Returns true if this number is neither infinite nor NaN. + #[stable(feature = "core", since = "1.6.0")] + fn is_finite(self) -> bool; + /// Returns true if this number is neither zero, infinite, denormal, or NaN. + #[stable(feature = "core", since = "1.6.0")] + fn is_normal(self) -> bool; + /// Returns the category that this number falls into. + #[stable(feature = "core", since = "1.6.0")] + fn classify(self) -> FpCategory; + + /// Returns the mantissa, exponent and sign as integers, respectively. + #[unstable(feature = "float_extras", reason = "signature is undecided", + issue = "27752")] + fn integer_decode(self) -> (u64, i16, i8); + + /// Computes the absolute value of `self`. Returns `Float::nan()` if the + /// number is `Float::nan()`. + #[stable(feature = "core", since = "1.6.0")] + fn abs(self) -> Self; + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` + /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` + /// - `Float::nan()` if the number is `Float::nan()` + #[stable(feature = "core", since = "1.6.0")] + fn signum(self) -> Self; + + /// Returns `true` if `self` is positive, including `+0.0` and + /// `Float::infinity()`. + #[stable(feature = "core", since = "1.6.0")] + fn is_sign_positive(self) -> bool; + /// Returns `true` if `self` is negative, including `-0.0` and + /// `Float::neg_infinity()`. + #[stable(feature = "core", since = "1.6.0")] + fn is_sign_negative(self) -> bool; + + /// Take the reciprocal (inverse) of a number, `1/x`. + #[stable(feature = "core", since = "1.6.0")] + fn recip(self) -> Self; + + /// Raise a number to an integer power. + /// + /// Using this function is generally faster than using `powf` + #[stable(feature = "core", since = "1.6.0")] + fn powi(self, n: i32) -> Self; + + /// Convert radians to degrees. + #[unstable(feature = "float_extras", reason = "desirability is unclear", + issue = "27752")] + fn to_degrees(self) -> Self; + /// Convert degrees to radians. + #[unstable(feature = "float_extras", reason = "desirability is unclear", + issue = "27752")] + fn to_radians(self) -> Self; +} + +macro_rules! from_str_radix_int_impl { + ($($t:ty)*) => {$( + #[stable(feature = "rust1", since = "1.0.0")] + impl FromStr for $t { + type Err = ParseIntError; + fn from_str(src: &str) -> Result<Self, ParseIntError> { + from_str_radix(src, 10) + } + } + )*} +} +from_str_radix_int_impl! { isize i8 i16 i32 i64 usize u8 u16 u32 u64 } + +#[doc(hidden)] +trait FromStrRadixHelper: PartialOrd + Copy { + fn min_value() -> Self; + fn from_u32(u: u32) -> Self; + fn checked_mul(&self, other: u32) -> Option<Self>; + fn checked_sub(&self, other: u32) -> Option<Self>; + fn checked_add(&self, other: u32) -> Option<Self>; +} + +macro_rules! doit { + ($($t:ty)*) => ($(impl FromStrRadixHelper for $t { + fn min_value() -> Self { Self::min_value() } + fn from_u32(u: u32) -> Self { u as Self } + fn checked_mul(&self, other: u32) -> Option<Self> { + Self::checked_mul(*self, other as Self) + } + fn checked_sub(&self, other: u32) -> Option<Self> { + Self::checked_sub(*self, other as Self) + } + fn checked_add(&self, other: u32) -> Option<Self> { + Self::checked_add(*self, other as Self) + } + })*) +} +doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } + +fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) + -> Result<T, ParseIntError> { + use self::IntErrorKind::*; + use self::ParseIntError as PIE; + + assert!(radix >= 2 && radix <= 36, + "from_str_radix_int: must lie in the range `[2, 36]` - found {}", + radix); + + if src.is_empty() { + return Err(PIE { kind: Empty }); + } + + let is_signed_ty = T::from_u32(0) > T::min_value(); + + // all valid digits are ascii, so we will just iterate over the utf8 bytes + // and cast them to chars. .to_digit() will safely return None for anything + // other than a valid ascii digit for the given radix, including the first-byte + // of multi-byte sequences + let src = src.as_bytes(); + + let (is_positive, digits) = match src[0] { + b'+' => (true, &src[1..]), + b'-' if is_signed_ty => (false, &src[1..]), + _ => (true, src) + }; + + if digits.is_empty() { + return Err(PIE { kind: Empty }); + } + + let mut result = T::from_u32(0); + if is_positive { + // The number is positive + for &c in digits { + let x = match (c as char).to_digit(radix) { + Some(x) => x, + None => return Err(PIE { kind: InvalidDigit }), + }; + result = match result.checked_mul(radix) { + Some(result) => result, + None => return Err(PIE { kind: Overflow }), + }; + result = match result.checked_add(x) { + Some(result) => result, + None => return Err(PIE { kind: Overflow }), + }; + } + } else { + // The number is negative + for &c in digits { + let x = match (c as char).to_digit(radix) { + Some(x) => x, + None => return Err(PIE { kind: InvalidDigit }), + }; + result = match result.checked_mul(radix) { + Some(result) => result, + None => return Err(PIE { kind: Underflow }), + }; + result = match result.checked_sub(x) { + Some(result) => result, + None => return Err(PIE { kind: Underflow }), + }; + } + } + Ok(result) +} + +/// An error which can be returned when parsing an integer. +/// +/// This error is used as the error type for the `from_str_radix()` functions +/// on the primitive integer types, such as [`i8::from_str_radix()`]. +/// +/// [`i8::from_str_radix()`]: ../../std/primitive.i8.html#method.from_str_radix +#[derive(Debug, Clone, PartialEq)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct ParseIntError { kind: IntErrorKind } + +#[derive(Debug, Clone, PartialEq)] +enum IntErrorKind { + Empty, + InvalidDigit, + Overflow, + Underflow, +} + +impl ParseIntError { + #[unstable(feature = "int_error_internals", + reason = "available through Error trait and this method should \ + not be exposed publicly", + issue = "0")] + #[doc(hidden)] + pub fn __description(&self) -> &str { + match self.kind { + IntErrorKind::Empty => "cannot parse integer from empty string", + IntErrorKind::InvalidDigit => "invalid digit found in string", + IntErrorKind::Overflow => "number too large to fit in target type", + IntErrorKind::Underflow => "number too small to fit in target type", + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Display for ParseIntError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.__description().fmt(f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +pub use num::dec2flt::ParseFloatError; + +// Conversion traits for primitive integer and float types +// Conversions T -> T are covered by a blanket impl and therefore excluded +// Some conversions from and to usize/isize are not implemented due to portability concerns +macro_rules! impl_from { + ($Small: ty, $Large: ty) => { + #[stable(feature = "lossless_prim_conv", since = "1.5.0")] + impl From<$Small> for $Large { + #[inline] + fn from(small: $Small) -> $Large { + small as $Large + } + } + } +} + +// Unsigned -> Unsigned +impl_from! { u8, u16 } +impl_from! { u8, u32 } +impl_from! { u8, u64 } +impl_from! { u8, usize } +impl_from! { u16, u32 } +impl_from! { u16, u64 } +impl_from! { u32, u64 } + +// Signed -> Signed +impl_from! { i8, i16 } +impl_from! { i8, i32 } +impl_from! { i8, i64 } +impl_from! { i8, isize } +impl_from! { i16, i32 } +impl_from! { i16, i64 } +impl_from! { i32, i64 } + +// Unsigned -> Signed +impl_from! { u8, i16 } +impl_from! { u8, i32 } +impl_from! { u8, i64 } +impl_from! { u16, i32 } +impl_from! { u16, i64 } +impl_from! { u32, i64 } + +// Note: integers can only be represented with full precision in a float if +// they fit in the significand, which is 24 bits in f32 and 53 bits in f64. +// Lossy float conversions are not implemented at this time. + +// Signed -> Float +impl_from! { i8, f32 } +impl_from! { i8, f64 } +impl_from! { i16, f32 } +impl_from! { i16, f64 } +impl_from! { i32, f64 } + +// Unsigned -> Float +impl_from! { u8, f32 } +impl_from! { u8, f64 } +impl_from! { u16, f32 } +impl_from! { u16, f64 } +impl_from! { u32, f64 } + +// Float -> Float +impl_from! { f32, f64 } diff --git a/libcore/num/u16.rs b/libcore/num/u16.rs new file mode 100644 index 0000000..d34d87c --- /dev/null +++ b/libcore/num/u16.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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. + +//! The 16-bit unsigned integer type. +//! +//! *[See also the `u16` primitive type](../../std/primitive.u16.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +uint_module! { u16, 16 } diff --git a/libcore/num/u32.rs b/libcore/num/u32.rs new file mode 100644 index 0000000..f9c9099 --- /dev/null +++ b/libcore/num/u32.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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. + +//! The 32-bit unsigned integer type. +//! +//! *[See also the `u32` primitive type](../../std/primitive.u32.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +uint_module! { u32, 32 } diff --git a/libcore/num/u64.rs b/libcore/num/u64.rs new file mode 100644 index 0000000..8dfe433 --- /dev/null +++ b/libcore/num/u64.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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. + +//! The 64-bit unsigned integer type. +//! +//! *[See also the `u64` primitive type](../../std/primitive.u64.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +uint_module! { u64, 64 } diff --git a/libcore/num/u8.rs b/libcore/num/u8.rs new file mode 100644 index 0000000..0106ee8 --- /dev/null +++ b/libcore/num/u8.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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. + +//! The 8-bit unsigned integer type. +//! +//! *[See also the `u8` primitive type](../../std/primitive.u8.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +uint_module! { u8, 8 } diff --git a/libcore/num/uint_macros.rs b/libcore/num/uint_macros.rs new file mode 100644 index 0000000..6479836 --- /dev/null +++ b/libcore/num/uint_macros.rs @@ -0,0 +1,22 @@ +// Copyright 2012-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. + +#![doc(hidden)] + +macro_rules! uint_module { ($T:ty, $bits:expr) => ( + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MIN: $T = 0 as $T; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(missing_docs)] +pub const MAX: $T = !0 as $T; + +) } diff --git a/libcore/num/usize.rs b/libcore/num/usize.rs new file mode 100644 index 0000000..0c7d16a --- /dev/null +++ b/libcore/num/usize.rs @@ -0,0 +1,20 @@ +// Copyright 2012-2015 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. + +//! The pointer-sized unsigned integer type. +//! +//! *[See also the `usize` primitive type](../../std/primitive.usize.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +#[cfg(target_pointer_width = "32")] +uint_module! { usize, 32 } +#[cfg(target_pointer_width = "64")] +uint_module! { usize, 64 } diff --git a/libcore/num/wrapping.rs b/libcore/num/wrapping.rs new file mode 100644 index 0000000..e28a36a --- /dev/null +++ b/libcore/num/wrapping.rs @@ -0,0 +1,309 @@ +// 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. + +use super::Wrapping; + +use ops::*; + +macro_rules! sh_impl_signed { + ($t:ident, $f:ident) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Shl<$f> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn shl(self, other: $f) -> Wrapping<$t> { + if other < 0 { + Wrapping(self.0.wrapping_shr((-other & self::shift_max::$t as $f) as u32)) + } else { + Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) + } + } + } + + #[stable(feature = "wrapping_impls", since = "1.7.0")] + impl ShlAssign<$f> for Wrapping<$t> { + #[inline(always)] + fn shl_assign(&mut self, other: $f) { + *self = *self << other; + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Shr<$f> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn shr(self, other: $f) -> Wrapping<$t> { + if other < 0 { + Wrapping(self.0.wrapping_shl((-other & self::shift_max::$t as $f) as u32)) + } else { + Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) + } + } + } + + #[stable(feature = "wrapping_impls", since = "1.7.0")] + impl ShrAssign<$f> for Wrapping<$t> { + #[inline(always)] + fn shr_assign(&mut self, other: $f) { + *self = *self >> other; + } + } + ) +} + +macro_rules! sh_impl_unsigned { + ($t:ident, $f:ident) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Shl<$f> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn shl(self, other: $f) -> Wrapping<$t> { + Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) + } + } + + #[stable(feature = "wrapping_impls", since = "1.7.0")] + impl ShlAssign<$f> for Wrapping<$t> { + #[inline(always)] + fn shl_assign(&mut self, other: $f) { + *self = *self << other; + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Shr<$f> for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn shr(self, other: $f) -> Wrapping<$t> { + Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) + } + } + + #[stable(feature = "wrapping_impls", since = "1.7.0")] + impl ShrAssign<$f> for Wrapping<$t> { + #[inline(always)] + fn shr_assign(&mut self, other: $f) { + *self = *self >> other; + } + } + ) +} + +// FIXME (#23545): uncomment the remaining impls +macro_rules! sh_impl_all { + ($($t:ident)*) => ($( + //sh_impl_unsigned! { $t, u8 } + //sh_impl_unsigned! { $t, u16 } + //sh_impl_unsigned! { $t, u32 } + //sh_impl_unsigned! { $t, u64 } + sh_impl_unsigned! { $t, usize } + + //sh_impl_signed! { $t, i8 } + //sh_impl_signed! { $t, i16 } + //sh_impl_signed! { $t, i32 } + //sh_impl_signed! { $t, i64 } + //sh_impl_signed! { $t, isize } + )*) +} + +sh_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } + +// FIXME(30524): impl Op<T> for Wrapping<T>, impl OpAssign<T> for Wrapping<T> +macro_rules! wrapping_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Add for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn add(self, other: Wrapping<$t>) -> Wrapping<$t> { + Wrapping(self.0.wrapping_add(other.0)) + } + } + + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl AddAssign for Wrapping<$t> { + #[inline(always)] + fn add_assign(&mut self, other: Wrapping<$t>) { + *self = *self + other; + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Sub for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn sub(self, other: Wrapping<$t>) -> Wrapping<$t> { + Wrapping(self.0.wrapping_sub(other.0)) + } + } + + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl SubAssign for Wrapping<$t> { + #[inline(always)] + fn sub_assign(&mut self, other: Wrapping<$t>) { + *self = *self - other; + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Mul for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn mul(self, other: Wrapping<$t>) -> Wrapping<$t> { + Wrapping(self.0.wrapping_mul(other.0)) + } + } + + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl MulAssign for Wrapping<$t> { + #[inline(always)] + fn mul_assign(&mut self, other: Wrapping<$t>) { + *self = *self * other; + } + } + + #[stable(feature = "wrapping_div", since = "1.3.0")] + impl Div for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn div(self, other: Wrapping<$t>) -> Wrapping<$t> { + Wrapping(self.0.wrapping_div(other.0)) + } + } + + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl DivAssign for Wrapping<$t> { + #[inline(always)] + fn div_assign(&mut self, other: Wrapping<$t>) { + *self = *self / other; + } + } + + #[stable(feature = "wrapping_impls", since = "1.7.0")] + impl Rem for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn rem(self, other: Wrapping<$t>) -> Wrapping<$t> { + Wrapping(self.0.wrapping_rem(other.0)) + } + } + + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl RemAssign for Wrapping<$t> { + #[inline(always)] + fn rem_assign(&mut self, other: Wrapping<$t>) { + *self = *self % other; + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Not for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn not(self) -> Wrapping<$t> { + Wrapping(!self.0) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl BitXor for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn bitxor(self, other: Wrapping<$t>) -> Wrapping<$t> { + Wrapping(self.0 ^ other.0) + } + } + + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl BitXorAssign for Wrapping<$t> { + #[inline(always)] + fn bitxor_assign(&mut self, other: Wrapping<$t>) { + *self = *self ^ other; + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl BitOr for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn bitor(self, other: Wrapping<$t>) -> Wrapping<$t> { + Wrapping(self.0 | other.0) + } + } + + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl BitOrAssign for Wrapping<$t> { + #[inline(always)] + fn bitor_assign(&mut self, other: Wrapping<$t>) { + *self = *self | other; + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl BitAnd for Wrapping<$t> { + type Output = Wrapping<$t>; + + #[inline(always)] + fn bitand(self, other: Wrapping<$t>) -> Wrapping<$t> { + Wrapping(self.0 & other.0) + } + } + + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl BitAndAssign for Wrapping<$t> { + #[inline(always)] + fn bitand_assign(&mut self, other: Wrapping<$t>) { + *self = *self & other; + } + } + )*) +} + +wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +mod shift_max { + #![allow(non_upper_case_globals)] + + #[cfg(target_pointer_width = "32")] + mod platform { + pub const usize: u32 = super::u32; + pub const isize: u32 = super::i32; + } + + #[cfg(target_pointer_width = "64")] + mod platform { + pub const usize: u32 = super::u64; + pub const isize: u32 = super::i64; + } + + pub const i8: u32 = (1 << 3) - 1; + pub const i16: u32 = (1 << 4) - 1; + pub const i32: u32 = (1 << 5) - 1; + pub const i64: u32 = (1 << 6) - 1; + pub use self::platform::isize; + + pub const u8: u32 = i8; + pub const u16: u32 = i16; + pub const u32: u32 = i32; + pub const u64: u32 = i64; + pub use self::platform::usize; +} diff --git a/libcore/ops.rs b/libcore/ops.rs new file mode 100644 index 0000000..44c498e --- /dev/null +++ b/libcore/ops.rs @@ -0,0 +1,2152 @@ +// Copyright 2012 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. + +//! Overloadable operators. +//! +//! Implementing these traits allows you to get an effect similar to +//! overloading operators. +//! +//! Some of these traits are imported by the prelude, so they are available in +//! every Rust program. +//! +//! Many of the operators take their operands by value. In non-generic +//! contexts involving built-in types, this is usually not a problem. +//! However, using these operators in generic code, requires some +//! attention if values have to be reused as opposed to letting the operators +//! consume them. One option is to occasionally use `clone()`. +//! Another option is to rely on the types involved providing additional +//! operator implementations for references. For example, for a user-defined +//! type `T` which is supposed to support addition, it is probably a good +//! idea to have both `T` and `&T` implement the traits `Add<T>` and `Add<&T>` +//! so that generic code can be written without unnecessary cloning. +//! +//! # Examples +//! +//! This example creates a `Point` struct that implements `Add` and `Sub`, and +//! then demonstrates adding and subtracting two `Point`s. +//! +//! ```rust +//! use std::ops::{Add, Sub}; +//! +//! #[derive(Debug)] +//! struct Point { +//! x: i32, +//! y: i32, +//! } +//! +//! impl Add for Point { +//! type Output = Point; +//! +//! fn add(self, other: Point) -> Point { +//! Point {x: self.x + other.x, y: self.y + other.y} +//! } +//! } +//! +//! impl Sub for Point { +//! type Output = Point; +//! +//! fn sub(self, other: Point) -> Point { +//! Point {x: self.x - other.x, y: self.y - other.y} +//! } +//! } +//! fn main() { +//! println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3}); +//! println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3}); +//! } +//! ``` +//! +//! See the documentation for each trait for a minimum implementation that +//! prints something to the screen. + +#![stable(feature = "rust1", since = "1.0.0")] + +use cmp::PartialOrd; +use fmt; +use convert::From; +use marker::{Sized, Unsize}; +use num::One; + +/// The `Drop` trait is used to run some code when a value goes out of scope. +/// This is sometimes called a 'destructor'. +/// +/// # Examples +/// +/// A trivial implementation of `Drop`. The `drop` method is called when `_x` +/// goes out of scope, and therefore `main` prints `Dropping!`. +/// +/// ``` +/// struct HasDrop; +/// +/// impl Drop for HasDrop { +/// fn drop(&mut self) { +/// println!("Dropping!"); +/// } +/// } +/// +/// fn main() { +/// let _x = HasDrop; +/// } +/// ``` +#[lang = "drop"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Drop { + /// A method called when the value goes out of scope. + /// + /// When this method has been called, `self` has not yet been deallocated. + /// If it were, `self` would be a dangling reference. + /// + /// After this function is over, the memory of `self` will be deallocated. + /// + /// # Panics + /// + /// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in + /// a `drop()` implementation will likely abort. + #[stable(feature = "rust1", since = "1.0.0")] + fn drop(&mut self); +} + +// implements the unary operator "op &T" +// based on "op T" where T is expected to be `Copy`able +macro_rules! forward_ref_unop { + (impl $imp:ident, $method:ident for $t:ty) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a> $imp for &'a $t { + type Output = <$t as $imp>::Output; + + #[inline] + fn $method(self) -> <$t as $imp>::Output { + $imp::$method(*self) + } + } + } +} + +// implements binary operators "&T op U", "T op &U", "&T op &U" +// based on "T op U" where T and U are expected to be `Copy`able +macro_rules! forward_ref_binop { + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a> $imp<$u> for &'a $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, other) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a> $imp<&'a $u> for $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { + $imp::$method(self, *other) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, 'b> $imp<&'a $u> for &'b $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, *other) + } + } + } +} + +/// The `Add` trait is used to specify the functionality of `+`. +/// +/// # Examples +/// +/// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up +/// calling `add`, and therefore, `main` prints `Adding!`. +/// +/// ``` +/// use std::ops::Add; +/// +/// struct Foo; +/// +/// impl Add for Foo { +/// type Output = Foo; +/// +/// fn add(self, _rhs: Foo) -> Foo { +/// println!("Adding!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo + Foo; +/// } +/// ``` +#[lang = "add"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Add<RHS=Self> { + /// The resulting type after applying the `+` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the `+` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn add(self, rhs: RHS) -> Self::Output; +} + +macro_rules! add_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Add for $t { + type Output = $t; + + #[inline] + fn add(self, other: $t) -> $t { self + other } + } + + forward_ref_binop! { impl Add, add for $t, $t } + )*) +} + +add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } + +/// The `Sub` trait is used to specify the functionality of `-`. +/// +/// # Examples +/// +/// A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up +/// calling `sub`, and therefore, `main` prints `Subtracting!`. +/// +/// ``` +/// use std::ops::Sub; +/// +/// struct Foo; +/// +/// impl Sub for Foo { +/// type Output = Foo; +/// +/// fn sub(self, _rhs: Foo) -> Foo { +/// println!("Subtracting!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo - Foo; +/// } +/// ``` +#[lang = "sub"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Sub<RHS=Self> { + /// The resulting type after applying the `-` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the `-` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn sub(self, rhs: RHS) -> Self::Output; +} + +macro_rules! sub_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Sub for $t { + type Output = $t; + + #[inline] + fn sub(self, other: $t) -> $t { self - other } + } + + forward_ref_binop! { impl Sub, sub for $t, $t } + )*) +} + +sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } + +/// The `Mul` trait is used to specify the functionality of `*`. +/// +/// # Examples +/// +/// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up +/// calling `mul`, and therefore, `main` prints `Multiplying!`. +/// +/// ``` +/// use std::ops::Mul; +/// +/// struct Foo; +/// +/// impl Mul for Foo { +/// type Output = Foo; +/// +/// fn mul(self, _rhs: Foo) -> Foo { +/// println!("Multiplying!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo * Foo; +/// } +/// ``` +#[lang = "mul"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Mul<RHS=Self> { + /// The resulting type after applying the `*` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the `*` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn mul(self, rhs: RHS) -> Self::Output; +} + +macro_rules! mul_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Mul for $t { + type Output = $t; + + #[inline] + fn mul(self, other: $t) -> $t { self * other } + } + + forward_ref_binop! { impl Mul, mul for $t, $t } + )*) +} + +mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } + +/// The `Div` trait is used to specify the functionality of `/`. +/// +/// # Examples +/// +/// A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up +/// calling `div`, and therefore, `main` prints `Dividing!`. +/// +/// ``` +/// use std::ops::Div; +/// +/// struct Foo; +/// +/// impl Div for Foo { +/// type Output = Foo; +/// +/// fn div(self, _rhs: Foo) -> Foo { +/// println!("Dividing!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo / Foo; +/// } +/// ``` +#[lang = "div"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Div<RHS=Self> { + /// The resulting type after applying the `/` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the `/` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn div(self, rhs: RHS) -> Self::Output; +} + +macro_rules! div_impl_integer { + ($($t:ty)*) => ($( + /// This operation rounds towards zero, truncating any + /// fractional part of the exact result. + #[stable(feature = "rust1", since = "1.0.0")] + impl Div for $t { + type Output = $t; + + #[inline] + fn div(self, other: $t) -> $t { self / other } + } + + forward_ref_binop! { impl Div, div for $t, $t } + )*) +} + +div_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +macro_rules! div_impl_float { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Div for $t { + type Output = $t; + + #[inline] + fn div(self, other: $t) -> $t { self / other } + } + + forward_ref_binop! { impl Div, div for $t, $t } + )*) +} + +div_impl_float! { f32 f64 } + +/// The `Rem` trait is used to specify the functionality of `%`. +/// +/// # Examples +/// +/// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up +/// calling `rem`, and therefore, `main` prints `Remainder-ing!`. +/// +/// ``` +/// use std::ops::Rem; +/// +/// struct Foo; +/// +/// impl Rem for Foo { +/// type Output = Foo; +/// +/// fn rem(self, _rhs: Foo) -> Foo { +/// println!("Remainder-ing!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo % Foo; +/// } +/// ``` +#[lang = "rem"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Rem<RHS=Self> { + /// The resulting type after applying the `%` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output = Self; + + /// The method for the `%` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn rem(self, rhs: RHS) -> Self::Output; +} + +macro_rules! rem_impl_integer { + ($($t:ty)*) => ($( + /// This operation satisfies `n % d == n - (n / d) * d`. The + /// result has the same sign as the left operand. + #[stable(feature = "rust1", since = "1.0.0")] + impl Rem for $t { + type Output = $t; + + #[inline] + fn rem(self, other: $t) -> $t { self % other } + } + + forward_ref_binop! { impl Rem, rem for $t, $t } + )*) +} + +rem_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +macro_rules! rem_impl_float { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Rem for $t { + type Output = $t; + + #[inline] + fn rem(self, other: $t) -> $t { self % other } + } + + forward_ref_binop! { impl Rem, rem for $t, $t } + )*) +} + +rem_impl_float! { f32 f64 } + +/// The `Neg` trait is used to specify the functionality of unary `-`. +/// +/// # Examples +/// +/// A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling +/// `neg`, and therefore, `main` prints `Negating!`. +/// +/// ``` +/// use std::ops::Neg; +/// +/// struct Foo; +/// +/// impl Neg for Foo { +/// type Output = Foo; +/// +/// fn neg(self) -> Foo { +/// println!("Negating!"); +/// self +/// } +/// } +/// +/// fn main() { +/// -Foo; +/// } +/// ``` +#[lang = "neg"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Neg { + /// The resulting type after applying the `-` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the unary `-` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn neg(self) -> Self::Output; +} + + + +macro_rules! neg_impl_core { + ($id:ident => $body:expr, $($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Neg for $t { + type Output = $t; + + #[inline] + fn neg(self) -> $t { let $id = self; $body } + } + + forward_ref_unop! { impl Neg, neg for $t } + )*) +} + +macro_rules! neg_impl_numeric { + ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} } +} + +macro_rules! neg_impl_unsigned { + ($($t:ty)*) => { + neg_impl_core!{ x => { + !x.wrapping_add(1) + }, $($t)*} } +} + +// neg_impl_unsigned! { usize u8 u16 u32 u64 } +neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 } + +/// The `Not` trait is used to specify the functionality of unary `!`. +/// +/// # Examples +/// +/// A trivial implementation of `Not`. When `!Foo` happens, it ends up calling +/// `not`, and therefore, `main` prints `Not-ing!`. +/// +/// ``` +/// use std::ops::Not; +/// +/// struct Foo; +/// +/// impl Not for Foo { +/// type Output = Foo; +/// +/// fn not(self) -> Foo { +/// println!("Not-ing!"); +/// self +/// } +/// } +/// +/// fn main() { +/// !Foo; +/// } +/// ``` +#[lang = "not"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Not { + /// The resulting type after applying the `!` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the unary `!` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn not(self) -> Self::Output; +} + +macro_rules! not_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl Not for $t { + type Output = $t; + + #[inline] + fn not(self) -> $t { !self } + } + + forward_ref_unop! { impl Not, not for $t } + )*) +} + +not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +/// The `BitAnd` trait is used to specify the functionality of `&`. +/// +/// # Examples +/// +/// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up +/// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`. +/// +/// ``` +/// use std::ops::BitAnd; +/// +/// struct Foo; +/// +/// impl BitAnd for Foo { +/// type Output = Foo; +/// +/// fn bitand(self, _rhs: Foo) -> Foo { +/// println!("Bitwise And-ing!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo & Foo; +/// } +/// ``` +#[lang = "bitand"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait BitAnd<RHS=Self> { + /// The resulting type after applying the `&` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the `&` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn bitand(self, rhs: RHS) -> Self::Output; +} + +macro_rules! bitand_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl BitAnd for $t { + type Output = $t; + + #[inline] + fn bitand(self, rhs: $t) -> $t { self & rhs } + } + + forward_ref_binop! { impl BitAnd, bitand for $t, $t } + )*) +} + +bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +/// The `BitOr` trait is used to specify the functionality of `|`. +/// +/// # Examples +/// +/// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up +/// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`. +/// +/// ``` +/// use std::ops::BitOr; +/// +/// struct Foo; +/// +/// impl BitOr for Foo { +/// type Output = Foo; +/// +/// fn bitor(self, _rhs: Foo) -> Foo { +/// println!("Bitwise Or-ing!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo | Foo; +/// } +/// ``` +#[lang = "bitor"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait BitOr<RHS=Self> { + /// The resulting type after applying the `|` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the `|` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn bitor(self, rhs: RHS) -> Self::Output; +} + +macro_rules! bitor_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl BitOr for $t { + type Output = $t; + + #[inline] + fn bitor(self, rhs: $t) -> $t { self | rhs } + } + + forward_ref_binop! { impl BitOr, bitor for $t, $t } + )*) +} + +bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +/// The `BitXor` trait is used to specify the functionality of `^`. +/// +/// # Examples +/// +/// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up +/// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`. +/// +/// ``` +/// use std::ops::BitXor; +/// +/// struct Foo; +/// +/// impl BitXor for Foo { +/// type Output = Foo; +/// +/// fn bitxor(self, _rhs: Foo) -> Foo { +/// println!("Bitwise Xor-ing!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo ^ Foo; +/// } +/// ``` +#[lang = "bitxor"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait BitXor<RHS=Self> { + /// The resulting type after applying the `^` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the `^` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn bitxor(self, rhs: RHS) -> Self::Output; +} + +macro_rules! bitxor_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl BitXor for $t { + type Output = $t; + + #[inline] + fn bitxor(self, other: $t) -> $t { self ^ other } + } + + forward_ref_binop! { impl BitXor, bitxor for $t, $t } + )*) +} + +bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +/// The `Shl` trait is used to specify the functionality of `<<`. +/// +/// # Examples +/// +/// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up +/// calling `shl`, and therefore, `main` prints `Shifting left!`. +/// +/// ``` +/// use std::ops::Shl; +/// +/// struct Foo; +/// +/// impl Shl<Foo> for Foo { +/// type Output = Foo; +/// +/// fn shl(self, _rhs: Foo) -> Foo { +/// println!("Shifting left!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo << Foo; +/// } +/// ``` +#[lang = "shl"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Shl<RHS> { + /// The resulting type after applying the `<<` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the `<<` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn shl(self, rhs: RHS) -> Self::Output; +} + +macro_rules! shl_impl { + ($t:ty, $f:ty) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Shl<$f> for $t { + type Output = $t; + + #[inline] + fn shl(self, other: $f) -> $t { + self << other + } + } + + forward_ref_binop! { impl Shl, shl for $t, $f } + ) +} + +macro_rules! shl_impl_all { + ($($t:ty)*) => ($( + shl_impl! { $t, u8 } + shl_impl! { $t, u16 } + shl_impl! { $t, u32 } + shl_impl! { $t, u64 } + shl_impl! { $t, usize } + + shl_impl! { $t, i8 } + shl_impl! { $t, i16 } + shl_impl! { $t, i32 } + shl_impl! { $t, i64 } + shl_impl! { $t, isize } + )*) +} + +shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } + +/// The `Shr` trait is used to specify the functionality of `>>`. +/// +/// # Examples +/// +/// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up +/// calling `shr`, and therefore, `main` prints `Shifting right!`. +/// +/// ``` +/// use std::ops::Shr; +/// +/// struct Foo; +/// +/// impl Shr<Foo> for Foo { +/// type Output = Foo; +/// +/// fn shr(self, _rhs: Foo) -> Foo { +/// println!("Shifting right!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo >> Foo; +/// } +/// ``` +#[lang = "shr"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Shr<RHS> { + /// The resulting type after applying the `>>` operator + #[stable(feature = "rust1", since = "1.0.0")] + type Output; + + /// The method for the `>>` operator + #[stable(feature = "rust1", since = "1.0.0")] + fn shr(self, rhs: RHS) -> Self::Output; +} + +macro_rules! shr_impl { + ($t:ty, $f:ty) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Shr<$f> for $t { + type Output = $t; + + #[inline] + fn shr(self, other: $f) -> $t { + self >> other + } + } + + forward_ref_binop! { impl Shr, shr for $t, $f } + ) +} + +macro_rules! shr_impl_all { + ($($t:ty)*) => ($( + shr_impl! { $t, u8 } + shr_impl! { $t, u16 } + shr_impl! { $t, u32 } + shr_impl! { $t, u64 } + shr_impl! { $t, usize } + + shr_impl! { $t, i8 } + shr_impl! { $t, i16 } + shr_impl! { $t, i32 } + shr_impl! { $t, i64 } + shr_impl! { $t, isize } + )*) +} + +shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } + +/// The `AddAssign` trait is used to specify the functionality of `+=`. +/// +/// # Examples +/// +/// A trivial implementation of `AddAssign`. When `Foo += Foo` happens, it ends up +/// calling `add_assign`, and therefore, `main` prints `Adding!`. +/// +/// ``` +/// use std::ops::AddAssign; +/// +/// struct Foo; +/// +/// impl AddAssign for Foo { +/// fn add_assign(&mut self, _rhs: Foo) { +/// println!("Adding!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo += Foo; +/// } +/// ``` +#[lang = "add_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait AddAssign<Rhs=Self> { + /// The method for the `+=` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn add_assign(&mut self, Rhs); +} + +macro_rules! add_assign_impl { + ($($t:ty)+) => ($( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl AddAssign for $t { + #[inline] + fn add_assign(&mut self, other: $t) { *self += other } + } + )+) +} + +add_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } + +/// The `SubAssign` trait is used to specify the functionality of `-=`. +/// +/// # Examples +/// +/// A trivial implementation of `SubAssign`. When `Foo -= Foo` happens, it ends up +/// calling `sub_assign`, and therefore, `main` prints `Subtracting!`. +/// +/// ``` +/// use std::ops::SubAssign; +/// +/// struct Foo; +/// +/// impl SubAssign for Foo { +/// fn sub_assign(&mut self, _rhs: Foo) { +/// println!("Subtracting!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo -= Foo; +/// } +/// ``` +#[lang = "sub_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait SubAssign<Rhs=Self> { + /// The method for the `-=` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn sub_assign(&mut self, Rhs); +} + +macro_rules! sub_assign_impl { + ($($t:ty)+) => ($( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl SubAssign for $t { + #[inline] + fn sub_assign(&mut self, other: $t) { *self -= other } + } + )+) +} + +sub_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } + +/// The `MulAssign` trait is used to specify the functionality of `*=`. +/// +/// # Examples +/// +/// A trivial implementation of `MulAssign`. When `Foo *= Foo` happens, it ends up +/// calling `mul_assign`, and therefore, `main` prints `Multiplying!`. +/// +/// ``` +/// use std::ops::MulAssign; +/// +/// struct Foo; +/// +/// impl MulAssign for Foo { +/// fn mul_assign(&mut self, _rhs: Foo) { +/// println!("Multiplying!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo *= Foo; +/// } +/// ``` +#[lang = "mul_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait MulAssign<Rhs=Self> { + /// The method for the `*=` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn mul_assign(&mut self, Rhs); +} + +macro_rules! mul_assign_impl { + ($($t:ty)+) => ($( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl MulAssign for $t { + #[inline] + fn mul_assign(&mut self, other: $t) { *self *= other } + } + )+) +} + +mul_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } + +/// The `DivAssign` trait is used to specify the functionality of `/=`. +/// +/// # Examples +/// +/// A trivial implementation of `DivAssign`. When `Foo /= Foo` happens, it ends up +/// calling `div_assign`, and therefore, `main` prints `Dividing!`. +/// +/// ``` +/// use std::ops::DivAssign; +/// +/// struct Foo; +/// +/// impl DivAssign for Foo { +/// fn div_assign(&mut self, _rhs: Foo) { +/// println!("Dividing!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo /= Foo; +/// } +/// ``` +#[lang = "div_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait DivAssign<Rhs=Self> { + /// The method for the `/=` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn div_assign(&mut self, Rhs); +} + +macro_rules! div_assign_impl { + ($($t:ty)+) => ($( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl DivAssign for $t { + #[inline] + fn div_assign(&mut self, other: $t) { *self /= other } + } + )+) +} + +div_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } + +/// The `RemAssign` trait is used to specify the functionality of `%=`. +/// +/// # Examples +/// +/// A trivial implementation of `RemAssign`. When `Foo %= Foo` happens, it ends up +/// calling `rem_assign`, and therefore, `main` prints `Remainder-ing!`. +/// +/// ``` +/// use std::ops::RemAssign; +/// +/// struct Foo; +/// +/// impl RemAssign for Foo { +/// fn rem_assign(&mut self, _rhs: Foo) { +/// println!("Remainder-ing!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo %= Foo; +/// } +/// ``` +#[lang = "rem_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait RemAssign<Rhs=Self> { + /// The method for the `%=` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn rem_assign(&mut self, Rhs); +} + +macro_rules! rem_assign_impl { + ($($t:ty)+) => ($( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl RemAssign for $t { + #[inline] + fn rem_assign(&mut self, other: $t) { *self %= other } + } + )+) +} + +rem_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } + +/// The `BitAndAssign` trait is used to specify the functionality of `&=`. +/// +/// # Examples +/// +/// A trivial implementation of `BitAndAssign`. When `Foo &= Foo` happens, it ends up +/// calling `bitand_assign`, and therefore, `main` prints `Bitwise And-ing!`. +/// +/// ``` +/// use std::ops::BitAndAssign; +/// +/// struct Foo; +/// +/// impl BitAndAssign for Foo { +/// fn bitand_assign(&mut self, _rhs: Foo) { +/// println!("Bitwise And-ing!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo &= Foo; +/// } +/// ``` +#[lang = "bitand_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait BitAndAssign<Rhs=Self> { + /// The method for the `&` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn bitand_assign(&mut self, Rhs); +} + +macro_rules! bitand_assign_impl { + ($($t:ty)+) => ($( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl BitAndAssign for $t { + #[inline] + fn bitand_assign(&mut self, other: $t) { *self &= other } + } + )+) +} + +bitand_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +/// The `BitOrAssign` trait is used to specify the functionality of `|=`. +/// +/// # Examples +/// +/// A trivial implementation of `BitOrAssign`. When `Foo |= Foo` happens, it ends up +/// calling `bitor_assign`, and therefore, `main` prints `Bitwise Or-ing!`. +/// +/// ``` +/// use std::ops::BitOrAssign; +/// +/// struct Foo; +/// +/// impl BitOrAssign for Foo { +/// fn bitor_assign(&mut self, _rhs: Foo) { +/// println!("Bitwise Or-ing!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo |= Foo; +/// } +/// ``` +#[lang = "bitor_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait BitOrAssign<Rhs=Self> { + /// The method for the `|=` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn bitor_assign(&mut self, Rhs); +} + +macro_rules! bitor_assign_impl { + ($($t:ty)+) => ($( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl BitOrAssign for $t { + #[inline] + fn bitor_assign(&mut self, other: $t) { *self |= other } + } + )+) +} + +bitor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +/// The `BitXorAssign` trait is used to specify the functionality of `^=`. +/// +/// # Examples +/// +/// A trivial implementation of `BitXorAssign`. When `Foo ^= Foo` happens, it ends up +/// calling `bitxor_assign`, and therefore, `main` prints `Bitwise Xor-ing!`. +/// +/// ``` +/// use std::ops::BitXorAssign; +/// +/// struct Foo; +/// +/// impl BitXorAssign for Foo { +/// fn bitxor_assign(&mut self, _rhs: Foo) { +/// println!("Bitwise Xor-ing!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo ^= Foo; +/// } +/// ``` +#[lang = "bitxor_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait BitXorAssign<Rhs=Self> { + /// The method for the `^=` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn bitxor_assign(&mut self, Rhs); +} + +macro_rules! bitxor_assign_impl { + ($($t:ty)+) => ($( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl BitXorAssign for $t { + #[inline] + fn bitxor_assign(&mut self, other: $t) { *self ^= other } + } + )+) +} + +bitxor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 } + +/// The `ShlAssign` trait is used to specify the functionality of `<<=`. +/// +/// # Examples +/// +/// A trivial implementation of `ShlAssign`. When `Foo <<= Foo` happens, it ends up +/// calling `shl_assign`, and therefore, `main` prints `Shifting left!`. +/// +/// ``` +/// use std::ops::ShlAssign; +/// +/// struct Foo; +/// +/// impl ShlAssign<Foo> for Foo { +/// fn shl_assign(&mut self, _rhs: Foo) { +/// println!("Shifting left!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo <<= Foo; +/// } +/// ``` +#[lang = "shl_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait ShlAssign<Rhs> { + /// The method for the `<<=` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn shl_assign(&mut self, Rhs); +} + +macro_rules! shl_assign_impl { + ($t:ty, $f:ty) => ( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl ShlAssign<$f> for $t { + #[inline] + fn shl_assign(&mut self, other: $f) { + *self <<= other + } + } + ) +} + +macro_rules! shl_assign_impl_all { + ($($t:ty)*) => ($( + shl_assign_impl! { $t, u8 } + shl_assign_impl! { $t, u16 } + shl_assign_impl! { $t, u32 } + shl_assign_impl! { $t, u64 } + shl_assign_impl! { $t, usize } + + shl_assign_impl! { $t, i8 } + shl_assign_impl! { $t, i16 } + shl_assign_impl! { $t, i32 } + shl_assign_impl! { $t, i64 } + shl_assign_impl! { $t, isize } + )*) +} + +shl_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } + +/// The `ShrAssign` trait is used to specify the functionality of `>>=`. +/// +/// # Examples +/// +/// A trivial implementation of `ShrAssign`. When `Foo >>= Foo` happens, it ends up +/// calling `shr_assign`, and therefore, `main` prints `Shifting right!`. +/// +/// ``` +/// use std::ops::ShrAssign; +/// +/// struct Foo; +/// +/// impl ShrAssign<Foo> for Foo { +/// fn shr_assign(&mut self, _rhs: Foo) { +/// println!("Shifting right!"); +/// } +/// } +/// +/// # #[allow(unused_assignments)] +/// fn main() { +/// let mut foo = Foo; +/// foo >>= Foo; +/// } +/// ``` +#[lang = "shr_assign"] +#[stable(feature = "op_assign_traits", since = "1.8.0")] +pub trait ShrAssign<Rhs=Self> { + /// The method for the `>>=` operator + #[stable(feature = "op_assign_traits", since = "1.8.0")] + fn shr_assign(&mut self, Rhs); +} + +macro_rules! shr_assign_impl { + ($t:ty, $f:ty) => ( + #[stable(feature = "op_assign_traits", since = "1.8.0")] + impl ShrAssign<$f> for $t { + #[inline] + fn shr_assign(&mut self, other: $f) { + *self >>= other + } + } + ) +} + +macro_rules! shr_assign_impl_all { + ($($t:ty)*) => ($( + shr_assign_impl! { $t, u8 } + shr_assign_impl! { $t, u16 } + shr_assign_impl! { $t, u32 } + shr_assign_impl! { $t, u64 } + shr_assign_impl! { $t, usize } + + shr_assign_impl! { $t, i8 } + shr_assign_impl! { $t, i16 } + shr_assign_impl! { $t, i32 } + shr_assign_impl! { $t, i64 } + shr_assign_impl! { $t, isize } + )*) +} + +shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } + +/// The `Index` trait is used to specify the functionality of indexing operations +/// like `arr[idx]` when used in an immutable context. +/// +/// # Examples +/// +/// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up +/// calling `index`, and therefore, `main` prints `Indexing!`. +/// +/// ``` +/// use std::ops::Index; +/// +/// #[derive(Copy, Clone)] +/// struct Foo; +/// struct Bar; +/// +/// impl Index<Bar> for Foo { +/// type Output = Foo; +/// +/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo { +/// println!("Indexing!"); +/// self +/// } +/// } +/// +/// fn main() { +/// Foo[Bar]; +/// } +/// ``` +#[lang = "index"] +#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Index<Idx: ?Sized> { + /// The returned type after indexing + #[stable(feature = "rust1", since = "1.0.0")] + type Output: ?Sized; + + /// The method for the indexing (`Foo[Bar]`) operation + #[stable(feature = "rust1", since = "1.0.0")] + fn index(&self, index: Idx) -> &Self::Output; +} + +/// The `IndexMut` trait is used to specify the functionality of indexing +/// operations like `arr[idx]`, when used in a mutable context. +/// +/// # Examples +/// +/// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up +/// calling `index_mut`, and therefore, `main` prints `Indexing!`. +/// +/// ``` +/// use std::ops::{Index, IndexMut}; +/// +/// #[derive(Copy, Clone)] +/// struct Foo; +/// struct Bar; +/// +/// impl Index<Bar> for Foo { +/// type Output = Foo; +/// +/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo { +/// self +/// } +/// } +/// +/// impl IndexMut<Bar> for Foo { +/// fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo { +/// println!("Indexing!"); +/// self +/// } +/// } +/// +/// fn main() { +/// &mut Foo[Bar]; +/// } +/// ``` +#[lang = "index_mut"] +#[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait IndexMut<Idx: ?Sized>: Index<Idx> { + /// The method for the indexing (`Foo[Bar]`) operation + #[stable(feature = "rust1", since = "1.0.0")] + fn index_mut(&mut self, index: Idx) -> &mut Self::Output; +} + +/// An unbounded range. Use `..` (two dots) for its shorthand. +/// +/// Its primary use case is slicing index. It cannot serve as an iterator +/// because it doesn't have a starting point. +/// +/// # Examples +/// +/// ``` +/// fn main() { +/// assert_eq!((..), std::ops::RangeFull); +/// +/// let arr = [0, 1, 2, 3]; +/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull +/// assert_eq!(arr[ ..3], [0,1,2 ]); +/// assert_eq!(arr[1.. ], [ 1,2,3]); +/// assert_eq!(arr[1..3], [ 1,2 ]); +/// } +/// ``` +#[derive(Copy, Clone, PartialEq, Eq)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct RangeFull; + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for RangeFull { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "..") + } +} + +/// A (half-open) range which is bounded at both ends: { x | start <= x < end }. +/// Use `start..end` (two dots) for its shorthand. +/// +/// See the [`contains()`](#method.contains) method for its characterization. +/// +/// # Examples +/// +/// ``` +/// #![feature(iter_arith)] +/// fn main() { +/// assert_eq!((3..5), std::ops::Range{ start: 3, end: 5 }); +/// assert_eq!(3+4+5, (3..6).sum()); +/// +/// let arr = [0, 1, 2, 3]; +/// assert_eq!(arr[ .. ], [0,1,2,3]); +/// assert_eq!(arr[ ..3], [0,1,2 ]); +/// assert_eq!(arr[1.. ], [ 1,2,3]); +/// assert_eq!(arr[1..3], [ 1,2 ]); // Range +/// } +/// ``` +#[derive(Clone, PartialEq, Eq)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Range<Idx> { + /// The lower bound of the range (inclusive). + #[stable(feature = "rust1", since = "1.0.0")] + pub start: Idx, + /// The upper bound of the range (exclusive). + #[stable(feature = "rust1", since = "1.0.0")] + pub end: Idx, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{:?}..{:?}", self.start, self.end) + } +} + +#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] +impl<Idx: PartialOrd<Idx>> Range<Idx> { + /// # Examples + /// + /// ``` + /// #![feature(range_contains)] + /// fn main() { + /// assert!( ! (3..5).contains(2)); + /// assert!( (3..5).contains(3)); + /// assert!( (3..5).contains(4)); + /// assert!( ! (3..5).contains(5)); + /// + /// assert!( ! (3..3).contains(3)); + /// assert!( ! (3..2).contains(3)); + /// } + /// ``` + pub fn contains(&self, item: Idx) -> bool { + (self.start <= item) && (item < self.end) + } +} + +/// A range which is only bounded below: { x | start <= x }. +/// Use `start..` for its shorthand. +/// +/// See the [`contains()`](#method.contains) method for its characterization. +/// +/// # Examples +/// +/// ``` +/// #![feature(iter_arith)] +/// fn main() { +/// assert_eq!((2..), std::ops::RangeFrom{ start: 2 }); +/// assert_eq!(2+3+4, (2..).take(3).sum()); +/// +/// let arr = [0, 1, 2, 3]; +/// assert_eq!(arr[ .. ], [0,1,2,3]); +/// assert_eq!(arr[ ..3], [0,1,2 ]); +/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom +/// assert_eq!(arr[1..3], [ 1,2 ]); +/// } +/// ``` +#[derive(Clone, PartialEq, Eq)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct RangeFrom<Idx> { + /// The lower bound of the range (inclusive). + #[stable(feature = "rust1", since = "1.0.0")] + pub start: Idx, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{:?}..", self.start) + } +} + +#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] +impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> { + /// # Examples + /// + /// ``` + /// #![feature(range_contains)] + /// fn main() { + /// assert!( ! (3..).contains(2)); + /// assert!( (3..).contains(3)); + /// assert!( (3..).contains(1_000_000_000)); + /// } + /// ``` + pub fn contains(&self, item: Idx) -> bool { + (self.start <= item) + } +} + +/// A range which is only bounded above: { x | x < end }. +/// Use `..end` (two dots) for its shorthand. +/// +/// See the [`contains()`](#method.contains) method for its characterization. +/// +/// It cannot serve as an iterator because it doesn't have a starting point. +/// ``` +/// fn main() { +/// assert_eq!((..5), std::ops::RangeTo{ end: 5 }); +/// +/// let arr = [0, 1, 2, 3]; +/// assert_eq!(arr[ .. ], [0,1,2,3]); +/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo +/// assert_eq!(arr[1.. ], [ 1,2,3]); +/// assert_eq!(arr[1..3], [ 1,2 ]); +/// } +/// ``` +#[derive(Copy, Clone, PartialEq, Eq)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct RangeTo<Idx> { + /// The upper bound of the range (exclusive). + #[stable(feature = "rust1", since = "1.0.0")] + pub end: Idx, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "..{:?}", self.end) + } +} + +#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] +impl<Idx: PartialOrd<Idx>> RangeTo<Idx> { + /// # Examples + /// + /// ``` + /// #![feature(range_contains)] + /// fn main() { + /// assert!( (..5).contains(-1_000_000_000)); + /// assert!( (..5).contains(4)); + /// assert!( ! (..5).contains(5)); + /// } + /// ``` + pub fn contains(&self, item: Idx) -> bool { + (item < self.end) + } +} + +/// An inclusive range which is bounded at both ends: { x | start <= x <= end }. +/// Use `start...end` (three dots) for its shorthand. +/// +/// See the [`contains()`](#method.contains) method for its characterization. +/// +/// # Examples +/// +/// ``` +/// #![feature(inclusive_range,inclusive_range_syntax,iter_arith)] +/// fn main() { +/// assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 }); +/// assert_eq!(3+4+5, (3...5).sum()); +/// +/// let arr = [0, 1, 2, 3]; +/// assert_eq!(arr[ ...2], [0,1,2 ]); +/// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive +/// } +/// ``` +#[derive(Copy, Clone, PartialEq, Eq)] +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +pub enum RangeInclusive<Idx> { + /// Empty range (iteration has finished) + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + Empty { + /// The point at which iteration finished + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + at: Idx + }, + /// Non-empty range (iteration will yield value(s)) + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + NonEmpty { + /// The lower bound of the range (inclusive). + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + start: Idx, + /// The upper bound of the range (inclusive). + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + end: Idx, + }, +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + use self::RangeInclusive::*; + + match *self { + Empty { ref at } => write!(fmt, "[empty range @ {:?}]", at), + NonEmpty { ref start, ref end } => write!(fmt, "{:?}...{:?}", start, end), + } + } +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<Idx: PartialOrd + One + Sub<Output=Idx>> From<Range<Idx>> for RangeInclusive<Idx> { + fn from(range: Range<Idx>) -> RangeInclusive<Idx> { + use self::RangeInclusive::*; + + if range.start < range.end { + NonEmpty { + start: range.start, + end: range.end - Idx::one() // can't underflow because end > start >= MIN + } + } else { + Empty { + at: range.start + } + } + } +} + +#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] +impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> { + /// # Examples + /// + /// ``` + /// #![feature(range_contains,inclusive_range_syntax)] + /// fn main() { + /// assert!( ! (3...5).contains(2)); + /// assert!( (3...5).contains(3)); + /// assert!( (3...5).contains(4)); + /// assert!( (3...5).contains(5)); + /// assert!( ! (3...5).contains(6)); + /// + /// assert!( (3...3).contains(3)); + /// assert!( ! (3...2).contains(3)); + /// } + /// ``` + pub fn contains(&self, item: Idx) -> bool { + if let &RangeInclusive::NonEmpty{ref start, ref end} = self { + (*start <= item) && (item <= *end) + } else { false } + } +} + +/// An inclusive range which is only bounded above: { x | x <= end }. +/// Use `...end` (three dots) for its shorthand. +/// +/// See the [`contains()`](#method.contains) method for its characterization. +/// +/// It cannot serve as an iterator because it doesn't have a starting point. +/// +/// # Examples +/// +/// ``` +/// #![feature(inclusive_range,inclusive_range_syntax)] +/// fn main() { +/// assert_eq!((...5), std::ops::RangeToInclusive{ end: 5 }); +/// +/// let arr = [0, 1, 2, 3]; +/// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive +/// assert_eq!(arr[1...2], [ 1,2 ]); +/// } +/// ``` +#[derive(Copy, Clone, PartialEq, Eq)] +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +pub struct RangeToInclusive<Idx> { + /// The upper bound of the range (inclusive) + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + pub end: Idx, +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "...{:?}", self.end) + } +} + +#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] +impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> { + /// # Examples + /// + /// ``` + /// #![feature(range_contains,inclusive_range_syntax)] + /// fn main() { + /// assert!( (...5).contains(-1_000_000_000)); + /// assert!( (...5).contains(5)); + /// assert!( ! (...5).contains(6)); + /// } + /// ``` + pub fn contains(&self, item: Idx) -> bool { + (item <= self.end) + } +} + +// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>> +// because underflow would be possible with (..0).into() + +/// The `Deref` trait is used to specify the functionality of dereferencing +/// operations, like `*v`. +/// +/// `Deref` also enables ['`Deref` coercions'][coercions]. +/// +/// [coercions]: ../../book/deref-coercions.html +/// +/// # Examples +/// +/// A struct with a single field which is accessible via dereferencing the +/// struct. +/// +/// ``` +/// use std::ops::Deref; +/// +/// struct DerefExample<T> { +/// value: T +/// } +/// +/// impl<T> Deref for DerefExample<T> { +/// type Target = T; +/// +/// fn deref(&self) -> &T { +/// &self.value +/// } +/// } +/// +/// fn main() { +/// let x = DerefExample { value: 'a' }; +/// assert_eq!('a', *x); +/// } +/// ``` +#[lang = "deref"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Deref { + /// The resulting type after dereferencing + #[stable(feature = "rust1", since = "1.0.0")] + type Target: ?Sized; + + /// The method called to dereference a value + #[stable(feature = "rust1", since = "1.0.0")] + fn deref(&self) -> &Self::Target; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Deref for &'a T { + type Target = T; + + fn deref(&self) -> &T { *self } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> Deref for &'a mut T { + type Target = T; + + fn deref(&self) -> &T { *self } +} + +/// The `DerefMut` trait is used to specify the functionality of dereferencing +/// mutably like `*v = 1;` +/// +/// `DerefMut` also enables ['`Deref` coercions'][coercions]. +/// +/// [coercions]: ../../book/deref-coercions.html +/// +/// # Examples +/// +/// A struct with a single field which is modifiable via dereferencing the +/// struct. +/// +/// ``` +/// use std::ops::{Deref, DerefMut}; +/// +/// struct DerefMutExample<T> { +/// value: T +/// } +/// +/// impl<T> Deref for DerefMutExample<T> { +/// type Target = T; +/// +/// fn deref<'a>(&'a self) -> &'a T { +/// &self.value +/// } +/// } +/// +/// impl<T> DerefMut for DerefMutExample<T> { +/// fn deref_mut<'a>(&'a mut self) -> &'a mut T { +/// &mut self.value +/// } +/// } +/// +/// fn main() { +/// let mut x = DerefMutExample { value: 'a' }; +/// *x = 'b'; +/// assert_eq!('b', *x); +/// } +/// ``` +#[lang = "deref_mut"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait DerefMut: Deref { + /// The method called to mutably dereference a value + #[stable(feature = "rust1", since = "1.0.0")] + fn deref_mut(&mut self) -> &mut Self::Target; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T: ?Sized> DerefMut for &'a mut T { + fn deref_mut(&mut self) -> &mut T { *self } +} + +/// A version of the call operator that takes an immutable receiver. +#[lang = "fn"] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_paren_sugar] +#[fundamental] // so that regex can rely that `&str: !FnMut` +pub trait Fn<Args> : FnMut<Args> { + /// This is called when the call operator is used. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call(&self, args: Args) -> Self::Output; +} + +/// A version of the call operator that takes a mutable receiver. +#[lang = "fn_mut"] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_paren_sugar] +#[fundamental] // so that regex can rely that `&str: !FnMut` +pub trait FnMut<Args> : FnOnce<Args> { + /// This is called when the call operator is used. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; +} + +/// A version of the call operator that takes a by-value receiver. +#[lang = "fn_once"] +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_paren_sugar] +#[fundamental] // so that regex can rely that `&str: !FnMut` +pub trait FnOnce<Args> { + /// The returned type after the call operator is used. + #[unstable(feature = "fn_traits", issue = "29625")] + type Output; + + /// This is called when the call operator is used. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +mod impls { + use marker::Sized; + use super::{Fn, FnMut, FnOnce}; + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a,A,F:?Sized> Fn<A> for &'a F + where F : Fn<A> + { + extern "rust-call" fn call(&self, args: A) -> F::Output { + (**self).call(args) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a,A,F:?Sized> FnMut<A> for &'a F + where F : Fn<A> + { + extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { + (**self).call(args) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a,A,F:?Sized> FnOnce<A> for &'a F + where F : Fn<A> + { + type Output = F::Output; + + extern "rust-call" fn call_once(self, args: A) -> F::Output { + (*self).call(args) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a,A,F:?Sized> FnMut<A> for &'a mut F + where F : FnMut<A> + { + extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { + (*self).call_mut(args) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a,A,F:?Sized> FnOnce<A> for &'a mut F + where F : FnMut<A> + { + type Output = F::Output; + extern "rust-call" fn call_once(mut self, args: A) -> F::Output { + (*self).call_mut(args) + } + } +} + +/// Trait that indicates that this is a pointer or a wrapper for one, +/// where unsizing can be performed on the pointee. +#[unstable(feature = "coerce_unsized", issue = "27732")] +#[lang="coerce_unsized"] +pub trait CoerceUnsized<T> { + // Empty. +} + +// &mut T -> &mut U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} +// &mut T -> &U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} +// &mut T -> *mut U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} +// &mut T -> *const U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} + +// &T -> &U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +// &T -> *const U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {} + +// *mut T -> *mut U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +// *mut T -> *const U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {} + +// *const T -> *const U +#[unstable(feature = "coerce_unsized", issue = "27732")] +impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} + +/// Both `in (PLACE) EXPR` and `box EXPR` desugar into expressions +/// that allocate an intermediate "place" that holds uninitialized +/// state. The desugaring evaluates EXPR, and writes the result at +/// the address returned by the `pointer` method of this trait. +/// +/// A `Place` can be thought of as a special representation for a +/// hypothetical `&uninit` reference (which Rust cannot currently +/// express directly). That is, it represents a pointer to +/// uninitialized storage. +/// +/// The client is responsible for two steps: First, initializing the +/// payload (it can access its address via `pointer`). Second, +/// converting the agent to an instance of the owning pointer, via the +/// appropriate `finalize` method (see the `InPlace`. +/// +/// If evaluating EXPR fails, then the destructor for the +/// implementation of Place to clean up any intermediate state +/// (e.g. deallocate box storage, pop a stack, etc). +#[unstable(feature = "placement_new_protocol", issue = "27779")] +pub trait Place<Data: ?Sized> { + /// Returns the address where the input value will be written. + /// Note that the data at this address is generally uninitialized, + /// and thus one should use `ptr::write` for initializing it. + fn pointer(&mut self) -> *mut Data; +} + +/// Interface to implementations of `in (PLACE) EXPR`. +/// +/// `in (PLACE) EXPR` effectively desugars into: +/// +/// ```rust,ignore +/// let p = PLACE; +/// let mut place = Placer::make_place(p); +/// let raw_place = Place::pointer(&mut place); +/// let value = EXPR; +/// unsafe { +/// std::ptr::write(raw_place, value); +/// InPlace::finalize(place) +/// } +/// ``` +/// +/// The type of `in (PLACE) EXPR` is derived from the type of `PLACE`; +/// if the type of `PLACE` is `P`, then the final type of the whole +/// expression is `P::Place::Owner` (see the `InPlace` and `Boxed` +/// traits). +/// +/// Values for types implementing this trait usually are transient +/// intermediate values (e.g. the return value of `Vec::emplace_back`) +/// or `Copy`, since the `make_place` method takes `self` by value. +#[unstable(feature = "placement_new_protocol", issue = "27779")] +pub trait Placer<Data: ?Sized> { + /// `Place` is the intermedate agent guarding the + /// uninitialized state for `Data`. + type Place: InPlace<Data>; + + /// Creates a fresh place from `self`. + fn make_place(self) -> Self::Place; +} + +/// Specialization of `Place` trait supporting `in (PLACE) EXPR`. +#[unstable(feature = "placement_new_protocol", issue = "27779")] +pub trait InPlace<Data: ?Sized>: Place<Data> { + /// `Owner` is the type of the end value of `in (PLACE) EXPR` + /// + /// Note that when `in (PLACE) EXPR` is solely used for + /// side-effecting an existing data-structure, + /// e.g. `Vec::emplace_back`, then `Owner` need not carry any + /// information at all (e.g. it can be the unit type `()` in that + /// case). + type Owner; + + /// Converts self into the final value, shifting + /// deallocation/cleanup responsibilities (if any remain), over to + /// the returned instance of `Owner` and forgetting self. + unsafe fn finalize(self) -> Self::Owner; +} + +/// Core trait for the `box EXPR` form. +/// +/// `box EXPR` effectively desugars into: +/// +/// ```rust,ignore +/// let mut place = BoxPlace::make_place(); +/// let raw_place = Place::pointer(&mut place); +/// let value = EXPR; +/// unsafe { +/// ::std::ptr::write(raw_place, value); +/// Boxed::finalize(place) +/// } +/// ``` +/// +/// The type of `box EXPR` is supplied from its surrounding +/// context; in the above expansion, the result type `T` is used +/// to determine which implementation of `Boxed` to use, and that +/// `<T as Boxed>` in turn dictates determines which +/// implementation of `BoxPlace` to use, namely: +/// `<<T as Boxed>::Place as BoxPlace>`. +#[unstable(feature = "placement_new_protocol", issue = "27779")] +pub trait Boxed { + /// The kind of data that is stored in this kind of box. + type Data; /* (`Data` unused b/c cannot yet express below bound.) */ + /// The place that will negotiate the storage of the data. + type Place: BoxPlace<Self::Data>; + + /// Converts filled place into final owning value, shifting + /// deallocation/cleanup responsibilities (if any remain), over to + /// returned instance of `Self` and forgetting `filled`. + unsafe fn finalize(filled: Self::Place) -> Self; +} + +/// Specialization of `Place` trait supporting `box EXPR`. +#[unstable(feature = "placement_new_protocol", issue = "27779")] +pub trait BoxPlace<Data: ?Sized> : Place<Data> { + /// Creates a globally fresh place. + fn make_place() -> Self; +} diff --git a/libcore/option.rs b/libcore/option.rs new file mode 100644 index 0000000..beed207 --- /dev/null +++ b/libcore/option.rs @@ -0,0 +1,930 @@ +// Copyright 2012-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. +//! +//! ``` +//! fn divide(numerator: f64, denominator: f64) -> Option<f64> { +//! if denominator == 0.0 { +//! None +//! } else { +//! Some(numerator / denominator) +//! } +//! } +//! +//! // The return value of the function is an option +//! let result = divide(2.0, 3.0); +//! +//! // Pattern match to retrieve the value +//! match result { +//! // The division was valid +//! Some(x) => println!("Result: {}", x), +//! // The division was invalid +//! None => println!("Cannot divide by 0"), +//! } +//! ``` +//! +// +// 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<Box<T>>`. +//! +//! The following example uses `Option` to create an optional box of +//! `i32`. Notice that in order to use the inner `i32` 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<Box<i32>> = None; +//! check_optional(&optional); +//! +//! let optional: Option<Box<i32>> = Some(Box::new(9000)); +//! check_optional(&optional); +//! +//! fn check_optional(optional: &Option<Box<i32>>) { +//! 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<Box<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 +//! if let Some(ref m) = msg { +//! println!("{}", *m); +//! } +//! +//! // Remove the contained string, destroying the Option +//! let unwrapped_msg = msg.unwrap_or("default message"); +//! ``` +//! +//! Initialize a result to `None` before a loop: +//! +//! ``` +//! enum Kingdom { Plant(u32, &'static str), Animal(u32, &'static str) } +//! +//! // A list of data to search through. +//! let all_the_big_things = [ +//! Kingdom::Plant(250, "redwood"), +//! Kingdom::Plant(230, "noble fir"), +//! Kingdom::Plant(229, "sugar pine"), +//! Kingdom::Animal(25, "blue whale"), +//! Kingdom::Animal(19, "fin whale"), +//! Kingdom::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 { +//! match *big_thing { +//! Kingdom::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); +//! } +//! Kingdom::Animal(..) | Kingdom::Plant(..) => () +//! } +//! } +//! +//! match name_of_biggest_animal { +//! Some(name) => println!("the biggest animal is {}", name), +//! None => println!("there are no animals :("), +//! } +//! ``` + +#![stable(feature = "rust1", since = "1.0.0")] + +use self::Option::*; + +use clone::Clone; +use cmp::{Eq, Ord}; +use default::Default; +use iter::ExactSizeIterator; +use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator}; +use mem; +use ops::FnOnce; +use result::Result::{Ok, Err}; +use result::Result; + +// Note that this is not a lang item per se, but it has a hidden dependency on +// `Iterator`, which is one. The compiler assumes that the `next` method of +// `Iterator` is an enumeration with one type parameter and two variants, +// which basically means it must be `Option`. + +/// The `Option` type. See [the module level documentation](index.html) for more. +#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Option<T> { + /// No value + #[stable(feature = "rust1", since = "1.0.0")] + None, + /// Some value `T` + #[stable(feature = "rust1", since = "1.0.0")] + Some(#[stable(feature = "rust1", since = "1.0.0")] T) +} + +///////////////////////////////////////////////////////////////////////////// +// Type implementation +///////////////////////////////////////////////////////////////////////////// + +impl<T> Option<T> { + ///////////////////////////////////////////////////////////////////////// + // Querying the contained values + ///////////////////////////////////////////////////////////////////////// + + /// Returns `true` if the option is a `Some` value + /// + /// # Examples + /// + /// ``` + /// let x: Option<u32> = Some(2); + /// assert_eq!(x.is_some(), true); + /// + /// let x: Option<u32> = None; + /// assert_eq!(x.is_some(), false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_some(&self) -> bool { + match *self { + Some(_) => true, + None => false, + } + } + + /// Returns `true` if the option is a `None` value + /// + /// # Examples + /// + /// ``` + /// let x: Option<u32> = Some(2); + /// assert_eq!(x.is_none(), false); + /// + /// let x: Option<u32> = None; + /// assert_eq!(x.is_none(), true); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_none(&self) -> bool { + !self.is_some() + } + + ///////////////////////////////////////////////////////////////////////// + // Adapter for working with references + ///////////////////////////////////////////////////////////////////////// + + /// Converts from `Option<T>` to `Option<&T>` + /// + /// # Examples + /// + /// Convert an `Option<String>` into an `Option<usize>`, preserving the original. + /// The `map` method takes the `self` argument by value, consuming the original, + /// so this technique uses `as_ref` to first take an `Option` to a reference + /// to the value inside the original. + /// + /// ``` + /// let num_as_str: Option<String> = Some("10".to_string()); + /// // First, cast `Option<String>` to `Option<&String>` with `as_ref`, + /// // then consume *that* with `map`, leaving `num_as_str` on the stack. + /// let num_as_int: Option<usize> = num_as_str.as_ref().map(|n| n.len()); + /// println!("still can print num_as_str: {:?}", num_as_str); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn as_ref(&self) -> Option<&T> { + match *self { + Some(ref x) => Some(x), + None => None, + } + } + + /// Converts from `Option<T>` to `Option<&mut T>` + /// + /// # Examples + /// + /// ``` + /// let mut x = Some(2); + /// match x.as_mut() { + /// Some(v) => *v = 42, + /// None => {}, + /// } + /// assert_eq!(x, Some(42)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn as_mut(&mut self) -> Option<&mut T> { + match *self { + Some(ref mut x) => Some(x), + None => None, + } + } + + ///////////////////////////////////////////////////////////////////////// + // Getting to contained values + ///////////////////////////////////////////////////////////////////////// + + /// Unwraps an option, yielding the content of a `Some`. + /// + /// # Panics + /// + /// Panics if the value is a `None` with a custom panic message provided by + /// `msg`. + /// + /// # Examples + /// + /// ``` + /// let x = Some("value"); + /// assert_eq!(x.expect("the world is ending"), "value"); + /// ``` + /// + /// ```{.should_panic} + /// let x: Option<&str> = None; + /// x.expect("the world is ending"); // panics with `the world is ending` + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn expect(self, msg: &str) -> T { + match self { + Some(val) => val, + None => expect_failed(msg), + } + } + + /// Moves the value `v` out of the `Option<T>` if it is `Some(v)`. + /// + /// # Panics + /// + /// Panics if the self value equals `None`. + /// + /// # Safety note + /// + /// In general, because this function may panic, its use is discouraged. + /// Instead, prefer to use pattern matching and handle the `None` + /// case explicitly. + /// + /// # Examples + /// + /// ``` + /// let x = Some("air"); + /// assert_eq!(x.unwrap(), "air"); + /// ``` + /// + /// ```{.should_panic} + /// let x: Option<&str> = None; + /// assert_eq!(x.unwrap(), "air"); // fails + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap(self) -> T { + match self { + Some(val) => val, + None => panic!("called `Option::unwrap()` on a `None` value"), + } + } + + /// Returns the contained value or a default. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(Some("car").unwrap_or("bike"), "car"); + /// assert_eq!(None.unwrap_or("bike"), "bike"); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap_or(self, def: T) -> T { + match self { + Some(x) => x, + None => def, + } + } + + /// Returns the contained value or computes it from a closure. + /// + /// # Examples + /// + /// ``` + /// let k = 10; + /// assert_eq!(Some(4).unwrap_or_else(|| 2 * k), 4); + /// assert_eq!(None.unwrap_or_else(|| 2 * k), 20); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T { + match self { + Some(x) => x, + None => f(), + } + } + + ///////////////////////////////////////////////////////////////////////// + // Transforming contained values + ///////////////////////////////////////////////////////////////////////// + + /// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value + /// + /// # Examples + /// + /// Convert an `Option<String>` into an `Option<usize>`, consuming the original: + /// + /// ``` + /// let maybe_some_string = Some(String::from("Hello, World!")); + /// // `Option::map` takes self *by value*, consuming `maybe_some_string` + /// let maybe_some_len = maybe_some_string.map(|s| s.len()); + /// + /// assert_eq!(maybe_some_len, Some(13)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { + match self { + Some(x) => Some(f(x)), + None => None, + } + } + + /// Applies a function to the contained value (if any), + /// or returns a `default` (if not). + /// + /// # Examples + /// + /// ``` + /// let x = Some("foo"); + /// assert_eq!(x.map_or(42, |v| v.len()), 3); + /// + /// let x: Option<&str> = None; + /// assert_eq!(x.map_or(42, |v| v.len()), 42); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U { + match self { + Some(t) => f(t), + None => default, + } + } + + /// Applies a function to the contained value (if any), + /// or computes a `default` (if not). + /// + /// # Examples + /// + /// ``` + /// let k = 21; + /// + /// let x = Some("foo"); + /// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 3); + /// + /// let x: Option<&str> = None; + /// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 42); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U { + match self { + Some(t) => f(t), + None => default(), + } + } + + /// Transforms the `Option<T>` into a `Result<T, E>`, mapping `Some(v)` to + /// `Ok(v)` and `None` to `Err(err)`. + /// + /// # Examples + /// + /// ``` + /// let x = Some("foo"); + /// assert_eq!(x.ok_or(0), Ok("foo")); + /// + /// let x: Option<&str> = None; + /// assert_eq!(x.ok_or(0), Err(0)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn ok_or<E>(self, err: E) -> Result<T, E> { + match self { + Some(v) => Ok(v), + None => Err(err), + } + } + + /// Transforms the `Option<T>` into a `Result<T, E>`, mapping `Some(v)` to + /// `Ok(v)` and `None` to `Err(err())`. + /// + /// # Examples + /// + /// ``` + /// let x = Some("foo"); + /// assert_eq!(x.ok_or_else(|| 0), Ok("foo")); + /// + /// let x: Option<&str> = None; + /// assert_eq!(x.ok_or_else(|| 0), Err(0)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> { + match self { + Some(v) => Ok(v), + None => Err(err()), + } + } + + ///////////////////////////////////////////////////////////////////////// + // Iterator constructors + ///////////////////////////////////////////////////////////////////////// + + /// Returns an iterator over the possibly contained value. + /// + /// # Examples + /// + /// ``` + /// let x = Some(4); + /// assert_eq!(x.iter().next(), Some(&4)); + /// + /// let x: Option<u32> = None; + /// assert_eq!(x.iter().next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter(&self) -> Iter<T> { + Iter { inner: Item { opt: self.as_ref() } } + } + + /// Returns a mutable iterator over the possibly contained value. + /// + /// # Examples + /// + /// ``` + /// let mut x = Some(4); + /// match x.iter_mut().next() { + /// Some(v) => *v = 42, + /// None => {}, + /// } + /// assert_eq!(x, Some(42)); + /// + /// let mut x: Option<u32> = None; + /// assert_eq!(x.iter_mut().next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter_mut(&mut self) -> IterMut<T> { + IterMut { inner: Item { opt: self.as_mut() } } + } + + ///////////////////////////////////////////////////////////////////////// + // Boolean operations on the values, eager and lazy + ///////////////////////////////////////////////////////////////////////// + + /// Returns `None` if the option is `None`, otherwise returns `optb`. + /// + /// # Examples + /// + /// ``` + /// let x = Some(2); + /// let y: Option<&str> = None; + /// assert_eq!(x.and(y), None); + /// + /// let x: Option<u32> = None; + /// let y = Some("foo"); + /// assert_eq!(x.and(y), None); + /// + /// let x = Some(2); + /// let y = Some("foo"); + /// assert_eq!(x.and(y), Some("foo")); + /// + /// let x: Option<u32> = None; + /// let y: Option<&str> = None; + /// assert_eq!(x.and(y), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn and<U>(self, optb: Option<U>) -> Option<U> { + match self { + Some(_) => optb, + None => None, + } + } + + /// Returns `None` if the option is `None`, otherwise calls `f` with the + /// wrapped value and returns the result. + /// + /// Some languages call this operation flatmap. + /// + /// # Examples + /// + /// ``` + /// fn sq(x: u32) -> Option<u32> { Some(x * x) } + /// fn nope(_: u32) -> Option<u32> { None } + /// + /// assert_eq!(Some(2).and_then(sq).and_then(sq), Some(16)); + /// assert_eq!(Some(2).and_then(sq).and_then(nope), None); + /// assert_eq!(Some(2).and_then(nope).and_then(sq), None); + /// assert_eq!(None.and_then(sq).and_then(sq), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> { + match self { + Some(x) => f(x), + None => None, + } + } + + /// Returns the option if it contains a value, otherwise returns `optb`. + /// + /// # Examples + /// + /// ``` + /// let x = Some(2); + /// let y = None; + /// assert_eq!(x.or(y), Some(2)); + /// + /// let x = None; + /// let y = Some(100); + /// assert_eq!(x.or(y), Some(100)); + /// + /// let x = Some(2); + /// let y = Some(100); + /// assert_eq!(x.or(y), Some(2)); + /// + /// let x: Option<u32> = None; + /// let y = None; + /// assert_eq!(x.or(y), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn or(self, optb: Option<T>) -> Option<T> { + match self { + Some(_) => self, + None => optb, + } + } + + /// Returns the option if it contains a value, otherwise calls `f` and + /// returns the result. + /// + /// # Examples + /// + /// ``` + /// fn nobody() -> Option<&'static str> { None } + /// fn vikings() -> Option<&'static str> { Some("vikings") } + /// + /// assert_eq!(Some("barbarians").or_else(vikings), Some("barbarians")); + /// assert_eq!(None.or_else(vikings), Some("vikings")); + /// assert_eq!(None.or_else(nobody), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> { + match self { + Some(_) => self, + None => f(), + } + } + + ///////////////////////////////////////////////////////////////////////// + // Misc + ///////////////////////////////////////////////////////////////////////// + + /// Takes the value out of the option, leaving a `None` in its place. + /// + /// # Examples + /// + /// ``` + /// let mut x = Some(2); + /// x.take(); + /// assert_eq!(x, None); + /// + /// let mut x: Option<u32> = None; + /// x.take(); + /// assert_eq!(x, None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn take(&mut self) -> Option<T> { + mem::replace(self, None) + } +} + +impl<'a, T: Clone> Option<&'a T> { + /// Maps an `Option<&T>` to an `Option<T>` by cloning the contents of the + /// option. + #[stable(feature = "rust1", since = "1.0.0")] + pub fn cloned(self) -> Option<T> { + self.map(|t| t.clone()) + } +} + +impl<T: Default> Option<T> { + /// Returns the contained value or a default + /// + /// Consumes the `self` argument then, if `Some`, returns the contained + /// value, otherwise if `None`, returns the default value for that + /// type. + /// + /// # Examples + /// + /// Convert a string to an integer, turning poorly-formed strings + /// into 0 (the default value for integers). `parse` converts + /// a string to any other type that implements `FromStr`, returning + /// `None` on error. + /// + /// ``` + /// let good_year_from_input = "1909"; + /// let bad_year_from_input = "190blarg"; + /// let good_year = good_year_from_input.parse().ok().unwrap_or_default(); + /// let bad_year = bad_year_from_input.parse().ok().unwrap_or_default(); + /// + /// assert_eq!(1909, good_year); + /// assert_eq!(0, bad_year); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap_or_default(self) -> T { + match self { + Some(x) => x, + None => Default::default(), + } + } +} + +// This is a separate function to reduce the code size of .expect() itself. +#[inline(never)] +#[cold] +fn expect_failed(msg: &str) -> ! { + panic!("{}", msg) +} + + +///////////////////////////////////////////////////////////////////////////// +// Trait implementations +///////////////////////////////////////////////////////////////////////////// + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> Default for Option<T> { + #[inline] + fn default() -> Option<T> { None } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> IntoIterator for Option<T> { + type Item = T; + type IntoIter = IntoIter<T>; + + /// Returns a consuming iterator over the possibly contained value. + /// + /// # Examples + /// + /// ``` + /// let x = Some("string"); + /// let v: Vec<&str> = x.into_iter().collect(); + /// assert_eq!(v, ["string"]); + /// + /// let x = None; + /// let v: Vec<&str> = x.into_iter().collect(); + /// assert!(v.is_empty()); + /// ``` + #[inline] + fn into_iter(self) -> IntoIter<T> { + IntoIter { inner: Item { opt: self } } + } +} + +#[stable(since = "1.4.0", feature = "option_iter")] +impl<'a, T> IntoIterator for &'a Option<T> { + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +#[stable(since = "1.4.0", feature = "option_iter")] +impl<'a, T> IntoIterator for &'a mut Option<T> { + type Item = &'a mut T; + type IntoIter = IterMut<'a, T>; + + fn into_iter(mut self) -> IterMut<'a, T> { + self.iter_mut() + } +} + +///////////////////////////////////////////////////////////////////////////// +// The Option Iterators +///////////////////////////////////////////////////////////////////////////// + +#[derive(Clone, Debug)] +struct Item<A> { + opt: Option<A> +} + +impl<A> Iterator for Item<A> { + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { + self.opt.take() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + match self.opt { + Some(_) => (1, Some(1)), + None => (0, Some(0)), + } + } +} + +impl<A> DoubleEndedIterator for Item<A> { + #[inline] + fn next_back(&mut self) -> Option<A> { + self.opt.take() + } +} + +impl<A> ExactSizeIterator for Item<A> {} + +/// An iterator over a reference of the contained item in an Option. +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Debug)] +pub struct Iter<'a, A: 'a> { inner: Item<&'a A> } + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, A> Iterator for Iter<'a, A> { + type Item = &'a A; + + #[inline] + fn next(&mut self) -> Option<&'a A> { self.inner.next() } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, A> DoubleEndedIterator for Iter<'a, A> { + #[inline] + fn next_back(&mut self) -> Option<&'a A> { self.inner.next_back() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, A> ExactSizeIterator for Iter<'a, A> {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, A> Clone for Iter<'a, A> { + fn clone(&self) -> Iter<'a, A> { + Iter { inner: self.inner.clone() } + } +} + +/// An iterator over a mutable reference of the contained item in an Option. +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Debug)] +pub struct IterMut<'a, A: 'a> { inner: Item<&'a mut A> } + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, A> Iterator for IterMut<'a, A> { + type Item = &'a mut A; + + #[inline] + fn next(&mut self) -> Option<&'a mut A> { self.inner.next() } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, A> DoubleEndedIterator for IterMut<'a, A> { + #[inline] + fn next_back(&mut self) -> Option<&'a mut A> { self.inner.next_back() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, A> ExactSizeIterator for IterMut<'a, A> {} + +/// An iterator over the item contained inside an Option. +#[derive(Clone, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IntoIter<A> { inner: Item<A> } + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A> Iterator for IntoIter<A> { + type Item = A; + + #[inline] + fn next(&mut self) -> Option<A> { self.inner.next() } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A> DoubleEndedIterator for IntoIter<A> { + #[inline] + fn next_back(&mut self) -> Option<A> { self.inner.next_back() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A> ExactSizeIterator for IntoIter<A> {} + +///////////////////////////////////////////////////////////////////////////// +// FromIterator +///////////////////////////////////////////////////////////////////////////// + +#[stable(feature = "rust1", since = "1.0.0")] +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: + /// + /// ``` + /// use std::u16; + /// + /// let v = vec!(1, 2); + /// let res: Option<Vec<u16>> = v.iter().map(|&x: &u16| + /// if x == u16::MAX { None } + /// else { Some(x + 1) } + /// ).collect(); + /// assert!(res == Some(vec!(2, 3))); + /// ``` + #[inline] + fn from_iter<I: IntoIterator<Item=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<Item=Option<T>>> Iterator for Adapter<Iter> { + type Item = T; + + #[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, + } + } + } + + let mut adapter = Adapter { iter: iter.into_iter(), found_none: false }; + let v: V = FromIterator::from_iter(adapter.by_ref()); + + if adapter.found_none { + None + } else { + Some(v) + } + } +} diff --git a/libcore/panicking.rs b/libcore/panicking.rs new file mode 100644 index 0000000..93ddfa7 --- /dev/null +++ b/libcore/panicking.rs @@ -0,0 +1,70 @@ +// 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. + +//! Panic support for libcore +//! +//! The core library cannot define panicking, but it does *declare* panicking. This +//! means that the functions inside of libcore are allowed to panic, but to be +//! useful an upstream crate must define panicking for libcore to use. The current +//! interface for panicking is: +//! +//! ```ignore +//! fn panic_impl(fmt: fmt::Arguments, &(&'static str, u32)) -> !; +//! ``` +//! +//! This definition allows for panicking with any general message, but it does not +//! allow for failing with a `Box<Any>` value. The reason for this is that libcore +//! is not allowed to allocate. +//! +//! This module contains a few other panicking functions, but these are just the +//! necessary lang items for the compiler. All panics are funneled through this +//! one function. Currently, the actual symbol is declared in the standard +//! library, but the location of this may change over time. + +#![allow(dead_code, missing_docs)] +#![unstable(feature = "core_panic", + reason = "internal details of the implementation of the `panic!` \ + and related macros", + issue = "0")] + +use fmt; + +#[cold] #[inline(never)] // this is the slow path, always +#[lang = "panic"] +pub fn panic(expr_file_line: &(&'static str, &'static str, u32)) -> ! { + // Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially + // reduce size overhead. The format_args! macro uses str's Display trait to + // write expr, which calls Formatter::pad, which must accommodate string + // truncation and padding (even though none is used here). Using + // Arguments::new_v1 may allow the compiler to omit Formatter::pad from the + // output binary, saving up to a few kilobytes. + let (expr, file, line) = *expr_file_line; + panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), &(file, line)) +} + +#[cold] #[inline(never)] +#[lang = "panic_bounds_check"] +fn panic_bounds_check(file_line: &(&'static str, u32), + index: usize, len: usize) -> ! { + panic_fmt(format_args!("index out of bounds: the len is {} but the index is {}", + len, index), file_line) +} + +#[cold] #[inline(never)] +pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! { + #[allow(improper_ctypes)] + extern { + #[lang = "panic_fmt"] + #[unwind] + fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: u32) -> !; + } + let (file, line) = *file_line; + unsafe { panic_impl(fmt, file, line) } +} diff --git a/libcore/prelude/mod.rs b/libcore/prelude/mod.rs new file mode 100644 index 0000000..99b1947 --- /dev/null +++ b/libcore/prelude/mod.rs @@ -0,0 +1,15 @@ +// Copyright 2015 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. + +//! The libcore prelude + +#![stable(feature = "core_prelude", since = "1.4.0")] + +pub mod v1; diff --git a/libcore/prelude/v1.rs b/libcore/prelude/v1.rs new file mode 100644 index 0000000..75db6fc --- /dev/null +++ b/libcore/prelude/v1.rs @@ -0,0 +1,53 @@ +// 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. + +//! The core prelude +//! +//! This module is intended for users of libcore which do not link to libstd as +//! well. This module is imported by default when `#![no_std]` is used in the +//! same manner as the standard library's prelude. + +#![stable(feature = "core_prelude", since = "1.4.0")] + +// Reexported core operators +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync}; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce}; + +// Reexported functions +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use mem::drop; + +// Reexported types and traits +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use clone::Clone; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From}; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use default::Default; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use iter::{Iterator, Extend, IntoIterator}; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use iter::{DoubleEndedIterator, ExactSizeIterator}; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use option::Option::{self, Some, None}; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use result::Result::{self, Ok, Err}; + +// Reexported extension traits for primitive types +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use slice::SliceExt; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use str::StrExt; +#[stable(feature = "core_prelude", since = "1.4.0")] +#[doc(no_inline)] pub use char::CharExt; diff --git a/libcore/ptr.rs b/libcore/ptr.rs new file mode 100644 index 0000000..42aef3a --- /dev/null +++ b/libcore/ptr.rs @@ -0,0 +1,744 @@ +// Copyright 2012-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. + +// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory + +//! Raw, unsafe pointers, `*const T`, and `*mut T`. +//! +//! *[See also the pointer primitive types](../../std/primitive.pointer.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +use clone::Clone; +use intrinsics; +use ops::{CoerceUnsized, Deref}; +use fmt; +use hash; +use option::Option::{self, Some, None}; +use marker::{Copy, PhantomData, Send, Sized, Sync, Unsize}; +use mem; +use nonzero::NonZero; + +use cmp::{PartialEq, Eq, Ord, PartialOrd}; +use cmp::Ordering::{self, Less, Equal, Greater}; + +// FIXME #19649: intrinsic docs don't render, so these have no docs :( + +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::copy_nonoverlapping; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::copy; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::write_bytes; + +#[stable(feature = "drop_in_place", since = "1.8.0")] +pub use intrinsics::drop_in_place; + +/// Creates a null raw pointer. +/// +/// # Examples +/// +/// ``` +/// use std::ptr; +/// +/// let p: *const i32 = ptr::null(); +/// assert!(p.is_null()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub const fn null<T>() -> *const T { 0 as *const T } + +/// Creates a null mutable raw pointer. +/// +/// # Examples +/// +/// ``` +/// use std::ptr; +/// +/// let p: *mut i32 = ptr::null_mut(); +/// assert!(p.is_null()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub const fn null_mut<T>() -> *mut T { 0 as *mut T } + +/// Swaps the values at two mutable locations of the same type, without +/// deinitializing either. They may overlap, unlike `mem::swap` which is +/// otherwise equivalent. +/// +/// # Safety +/// +/// This is only unsafe because it accepts a raw pointer. +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn swap<T>(x: *mut T, y: *mut T) { + // Give ourselves some scratch space to work with + let mut tmp: T = mem::uninitialized(); + + // Perform the swap + copy_nonoverlapping(x, &mut tmp, 1); + copy(y, x, 1); // `x` and `y` may overlap + copy_nonoverlapping(&tmp, y, 1); + + // y and t now point to the same thing, but we need to completely forget `tmp` + // because it's no longer relevant. + mem::forget(tmp); +} + +/// Replaces the value at `dest` with `src`, returning the old +/// value, without dropping either. +/// +/// # Safety +/// +/// This is only unsafe because it accepts a raw pointer. +/// Otherwise, this operation is identical to `mem::replace`. +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T { + mem::swap(&mut *dest, &mut src); // cannot overlap + src +} + +/// Reads the value from `src` without moving it. This leaves the +/// memory in `src` unchanged. +/// +/// # Safety +/// +/// Beyond accepting a raw pointer, this is unsafe because it semantically +/// moves the value out of `src` without preventing further usage of `src`. +/// If `T` is not `Copy`, then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with `write`, +/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use +/// because it will attempt to drop the value previously at `*src`. +#[inline(always)] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn read<T>(src: *const T) -> T { + let mut tmp: T = mem::uninitialized(); + copy_nonoverlapping(src, &mut tmp, 1); + tmp +} + +#[allow(missing_docs)] +#[inline(always)] +#[unstable(feature = "filling_drop", + reason = "may play a larger role in std::ptr future extensions", + issue = "5016")] +pub unsafe fn read_and_drop<T>(dest: *mut T) -> T { + // Copy the data out from `dest`: + let tmp = read(&*dest); + + // Now mark `dest` as dropped: + write_bytes(dest, mem::POST_DROP_U8, 1); + + tmp +} + +/// Overwrites a memory location with the given value without reading or +/// dropping the old value. +/// +/// # Safety +/// +/// This operation is marked unsafe because it accepts a raw pointer. +/// +/// It does not drop the contents of `dst`. This is safe, but it could leak +/// allocations or resources, so care must be taken not to overwrite an object +/// that should be dropped. +/// +/// This is appropriate for initializing uninitialized memory, or overwriting +/// memory that has previously been `read` from. +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn write<T>(dst: *mut T, src: T) { + intrinsics::move_val_init(&mut *dst, src) +} + +/// Performs a volatile read of the value from `src` without moving it. This +/// leaves the memory in `src` unchanged. +/// +/// Volatile operations are intended to act on I/O memory, and are guaranteed +/// to not be elided or reordered by the compiler across other volatile +/// operations. See the LLVM documentation on [[volatile]]. +/// +/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses +/// +/// # Safety +/// +/// Beyond accepting a raw pointer, this is unsafe because it semantically +/// moves the value out of `src` without preventing further usage of `src`. +/// If `T` is not `Copy`, then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with `write`, +/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use +/// because it will attempt to drop the value previously at `*src`. +#[inline] +#[unstable(feature = "volatile", reason = "recently added", issue = "31756")] +pub unsafe fn read_volatile<T>(src: *const T) -> T { + intrinsics::volatile_load(src) +} + +/// Performs a volatile write of a memory location with the given value without +/// reading or dropping the old value. +/// +/// Volatile operations are intended to act on I/O memory, and are guaranteed +/// to not be elided or reordered by the compiler across other volatile +/// operations. See the LLVM documentation on [[volatile]]. +/// +/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses +/// +/// # Safety +/// +/// This operation is marked unsafe because it accepts a raw pointer. +/// +/// It does not drop the contents of `dst`. This is safe, but it could leak +/// allocations or resources, so care must be taken not to overwrite an object +/// that should be dropped. +/// +/// This is appropriate for initializing uninitialized memory, or overwriting +/// memory that has previously been `read` from. +#[inline] +#[unstable(feature = "volatile", reason = "recently added", issue = "31756")] +pub unsafe fn write_volatile<T>(dst: *mut T, src: T) { + intrinsics::volatile_store(dst, src); +} + +#[lang = "const_ptr"] +impl<T: ?Sized> *const T { + /// Returns true if the pointer is null. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s: &str = "Follow the rabbit"; + /// let ptr: *const u8 = s.as_ptr(); + /// assert!(!ptr.is_null()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_null(self) -> bool where T: Sized { + self == null() + } + + /// Returns `None` if the pointer is null, or else returns a reference to + /// the value wrapped in `Some`. + /// + /// # Safety + /// + /// While this method and its mutable counterpart are useful for + /// null-safety, it is important to note that this is still an unsafe + /// operation because the returned value could be pointing to invalid + /// memory. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ```ignore + /// let val: *const u8 = &10u8 as *const u8; + /// + /// unsafe { + /// if let Some(val_back) = val.as_ref() { + /// println!("We got back the value: {}!", val_back); + /// } + /// } + /// ``` + #[unstable(feature = "ptr_as_ref", + reason = "Option is not clearly the right return type, and we \ + may want to tie the return lifetime to a borrow of \ + the raw pointer", + issue = "27780")] + #[inline] + pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized { + if self.is_null() { + None + } else { + Some(&**self) + } + } + + /// Calculates the offset from a pointer. `count` is in units of T; e.g. a + /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes. + /// + /// # Safety + /// + /// Both the starting and resulting pointer must be either in bounds or one + /// byte past the end of an allocated object. If either pointer is out of + /// bounds or arithmetic overflow occurs then + /// any further use of the returned value will result in undefined behavior. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s: &str = "123"; + /// let ptr: *const u8 = s.as_ptr(); + /// + /// unsafe { + /// println!("{}", *ptr.offset(1) as char); + /// println!("{}", *ptr.offset(2) as char); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub unsafe fn offset(self, count: isize) -> *const T where T: Sized { + intrinsics::offset(self, count) + } +} + +#[lang = "mut_ptr"] +impl<T: ?Sized> *mut T { + /// Returns true if the pointer is null. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let mut s = [1, 2, 3]; + /// let ptr: *mut u32 = s.as_mut_ptr(); + /// assert!(!ptr.is_null()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_null(self) -> bool where T: Sized { + self == null_mut() + } + + /// Returns `None` if the pointer is null, or else returns a reference to + /// the value wrapped in `Some`. + /// + /// # Safety + /// + /// While this method and its mutable counterpart are useful for + /// null-safety, it is important to note that this is still an unsafe + /// operation because the returned value could be pointing to invalid + /// memory. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ```ignore + /// let val: *mut u8 = &mut 10u8 as *mut u8; + /// + /// unsafe { + /// if let Some(val_back) = val.as_ref() { + /// println!("We got back the value: {}!", val_back); + /// } + /// } + /// ``` + #[unstable(feature = "ptr_as_ref", + reason = "Option is not clearly the right return type, and we \ + may want to tie the return lifetime to a borrow of \ + the raw pointer", + issue = "27780")] + #[inline] + pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized { + if self.is_null() { + None + } else { + Some(&**self) + } + } + + /// Calculates the offset from a pointer. `count` is in units of T; e.g. a + /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes. + /// + /// # Safety + /// + /// The offset must be in-bounds of the object, or one-byte-past-the-end. + /// Otherwise `offset` invokes Undefined Behavior, regardless of whether + /// the pointer is used. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let mut s = [1, 2, 3]; + /// let ptr: *mut u32 = s.as_mut_ptr(); + /// + /// unsafe { + /// println!("{}", *ptr.offset(1)); + /// println!("{}", *ptr.offset(2)); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized { + intrinsics::offset(self, count) as *mut T + } + + /// Returns `None` if the pointer is null, or else returns a mutable + /// reference to the value wrapped in `Some`. + /// + /// # Safety + /// + /// As with `as_ref`, this is unsafe because it cannot verify the validity + /// of the returned pointer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let mut s = [1, 2, 3]; + /// let ptr: *mut u32 = s.as_mut_ptr(); + /// ``` + #[unstable(feature = "ptr_as_ref", + reason = "return value does not necessarily convey all possible \ + information", + issue = "27780")] + #[inline] + pub unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> where T: Sized { + if self.is_null() { + None + } else { + Some(&mut **self) + } + } +} + +// Equality for pointers +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> PartialEq for *const T { + #[inline] + fn eq(&self, other: &*const T) -> bool { *self == *other } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Eq for *const T {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> PartialEq for *mut T { + #[inline] + fn eq(&self, other: &*mut T) -> bool { *self == *other } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Eq for *mut T {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Clone for *const T { + #[inline] + fn clone(&self) -> *const T { + *self + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Clone for *mut T { + #[inline] + fn clone(&self) -> *mut T { + *self + } +} + +// Impls for function pointers +macro_rules! fnptr_impls_safety_abi { + ($FnTy: ty, $($Arg: ident),*) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl<Ret, $($Arg),*> Clone for $FnTy { + #[inline] + fn clone(&self) -> Self { + *self + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> PartialEq for $FnTy { + #[inline] + fn eq(&self, other: &Self) -> bool { + *self as usize == *other as usize + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> Eq for $FnTy {} + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> PartialOrd for $FnTy { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + (*self as usize).partial_cmp(&(*other as usize)) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> Ord for $FnTy { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + (*self as usize).cmp(&(*other as usize)) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> hash::Hash for $FnTy { + fn hash<HH: hash::Hasher>(&self, state: &mut HH) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> fmt::Pointer for $FnTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&(*self as *const ()), f) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl<Ret, $($Arg),*> fmt::Debug for $FnTy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&(*self as *const ()), f) + } + } + } +} + +macro_rules! fnptr_impls_args { + ($($Arg: ident),*) => { + fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { extern "C" fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),*) -> Ret, $($Arg),* } + } +} + +fnptr_impls_args! { } +fnptr_impls_args! { A } +fnptr_impls_args! { A, B } +fnptr_impls_args! { A, B, C } +fnptr_impls_args! { A, B, C, D } +fnptr_impls_args! { A, B, C, D, E } +fnptr_impls_args! { A, B, C, D, E, F } +fnptr_impls_args! { A, B, C, D, E, F, G } +fnptr_impls_args! { A, B, C, D, E, F, G, H } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } + +// Comparison for pointers +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Ord for *const T { + #[inline] + fn cmp(&self, other: &*const T) -> Ordering { + if self < other { + Less + } else if self == other { + Equal + } else { + Greater + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> PartialOrd for *const T { + #[inline] + fn partial_cmp(&self, other: &*const T) -> Option<Ordering> { + Some(self.cmp(other)) + } + + #[inline] + fn lt(&self, other: &*const T) -> bool { *self < *other } + + #[inline] + fn le(&self, other: &*const T) -> bool { *self <= *other } + + #[inline] + fn gt(&self, other: &*const T) -> bool { *self > *other } + + #[inline] + fn ge(&self, other: &*const T) -> bool { *self >= *other } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> Ord for *mut T { + #[inline] + fn cmp(&self, other: &*mut T) -> Ordering { + if self < other { + Less + } else if self == other { + Equal + } else { + Greater + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: ?Sized> PartialOrd for *mut T { + #[inline] + fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> { + Some(self.cmp(other)) + } + + #[inline] + fn lt(&self, other: &*mut T) -> bool { *self < *other } + + #[inline] + fn le(&self, other: &*mut T) -> bool { *self <= *other } + + #[inline] + fn gt(&self, other: &*mut T) -> bool { *self > *other } + + #[inline] + fn ge(&self, other: &*mut T) -> bool { *self >= *other } +} + +/// A wrapper around a raw non-null `*mut T` that indicates that the possessor +/// of this wrapper owns the referent. This in turn implies that the +/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw +/// `*mut T` (which conveys no particular ownership semantics). It +/// also implies that the referent of the pointer should not be +/// modified without a unique path to the `Unique` reference. Useful +/// for building abstractions like `Vec<T>` or `Box<T>`, which +/// internally use raw pointers to manage the memory that they own. +#[allow(missing_debug_implementations)] +#[unstable(feature = "unique", reason = "needs an RFC to flesh out design", + issue = "27730")] +pub struct Unique<T: ?Sized> { + pointer: NonZero<*const T>, + // NOTE: this marker has no consequences for variance, but is necessary + // for dropck to understand that we logically own a `T`. + // + // For details, see: + // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data + _marker: PhantomData<T>, +} + +/// `Unique` pointers are `Send` if `T` is `Send` because the data they +/// reference is unaliased. Note that this aliasing invariant is +/// unenforced by the type system; the abstraction using the +/// `Unique` must enforce it. +#[unstable(feature = "unique", issue = "27730")] +unsafe impl<T: Send + ?Sized> Send for Unique<T> { } + +/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they +/// reference is unaliased. Note that this aliasing invariant is +/// unenforced by the type system; the abstraction using the +/// `Unique` must enforce it. +#[unstable(feature = "unique", issue = "27730")] +unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { } + +#[unstable(feature = "unique", issue = "27730")] +impl<T: ?Sized> Unique<T> { + /// Creates a new `Unique`. + /// + /// # Safety + /// + /// `ptr` must be non-null. + pub const unsafe fn new(ptr: *mut T) -> Unique<T> { + Unique { pointer: NonZero::new(ptr), _marker: PhantomData } + } + + /// Dereferences the content. + pub unsafe fn get(&self) -> &T { + &**self.pointer + } + + /// Mutably dereferences the content. + pub unsafe fn get_mut(&mut self) -> &mut T { + &mut ***self + } +} + +#[unstable(feature = "unique", issue = "27730")] +impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { } + +#[unstable(feature = "unique", issue= "27730")] +impl<T:?Sized> Deref for Unique<T> { + type Target = *mut T; + + #[inline] + fn deref(&self) -> &*mut T { + unsafe { mem::transmute(&*self.pointer) } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> fmt::Pointer for Unique<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&*self.pointer, f) + } +} + +/// A wrapper around a raw non-null `*mut T` that indicates that the possessor +/// of this wrapper has shared ownership of the referent. Useful for +/// building abstractions like `Rc<T>` or `Arc<T>`, which internally +/// use raw pointers to manage the memory that they own. +#[allow(missing_debug_implementations)] +#[unstable(feature = "shared", reason = "needs an RFC to flesh out design", + issue = "27730")] +pub struct Shared<T: ?Sized> { + pointer: NonZero<*const T>, + // NOTE: this marker has no consequences for variance, but is necessary + // for dropck to understand that we logically own a `T`. + // + // For details, see: + // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data + _marker: PhantomData<T>, +} + +/// `Shared` pointers are not `Send` because the data they reference may be aliased. +// NB: This impl is unnecessary, but should provide better error messages. +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> !Send for Shared<T> { } + +/// `Shared` pointers are not `Sync` because the data they reference may be aliased. +// NB: This impl is unnecessary, but should provide better error messages. +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> !Sync for Shared<T> { } + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> Shared<T> { + /// Creates a new `Shared`. + /// + /// # Safety + /// + /// `ptr` must be non-null. + pub unsafe fn new(ptr: *mut T) -> Self { + Shared { pointer: NonZero::new(ptr), _marker: PhantomData } + } +} + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> Clone for Shared<T> { + fn clone(&self) -> Self { + *self + } +} + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> Copy for Shared<T> { } + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized, U: ?Sized> CoerceUnsized<Shared<U>> for Shared<T> where T: Unsize<U> { } + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> Deref for Shared<T> { + type Target = *mut T; + + #[inline] + fn deref(&self) -> &*mut T { + unsafe { mem::transmute(&*self.pointer) } + } +} + +#[unstable(feature = "shared", issue = "27730")] +impl<T> fmt::Pointer for Shared<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&*self.pointer, f) + } +} diff --git a/libcore/raw.rs b/libcore/raw.rs new file mode 100644 index 0000000..20c85b5 --- /dev/null +++ b/libcore/raw.rs @@ -0,0 +1,165 @@ +// Copyright 2013 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. + +#![allow(missing_docs)] +#![unstable(feature = "raw", issue = "27751")] + +//! Contains struct definitions for the layout of compiler built-in types. +//! +//! They can be used as targets of transmutes in unsafe code for manipulating +//! the raw representations directly. +//! +//! Their definition should always match the ABI defined in `rustc::back::abi`. + +use clone::Clone; +use marker::Copy; +use mem; + +/// The representation of a slice like `&[T]`. +/// +/// This struct is guaranteed to have the layout of types like `&[T]`, +/// `&str`, and `Box<[T]>`, but is not the type of such slices +/// (e.g. the fields are not directly accessible on a `&[T]`) nor does +/// it control that layout (changing the definition will not change +/// the layout of a `&[T]`). It is only designed to be used by unsafe +/// code that needs to manipulate the low-level details. +/// +/// However, it is not recommended to use this type for such code, +/// since there are alternatives which may be safer: +/// +/// - Creating a slice from a data pointer and length can be done with +/// `std::slice::from_raw_parts` or `std::slice::from_raw_parts_mut` +/// instead of `std::mem::transmute`ing a value of type `Slice`. +/// - Extracting the data pointer and length from a slice can be +/// performed with the `as_ptr` (or `as_mut_ptr`) and `len` +/// methods. +/// +/// If one does decide to convert a slice value to a `Slice`, the +/// `Repr` trait in this module provides a method for a safe +/// conversion from `&[T]` (and `&str`) to a `Slice`, more type-safe +/// than a call to `transmute`. +/// +/// # Examples +/// +/// ``` +/// #![feature(raw)] +/// +/// use std::raw::{self, Repr}; +/// +/// let slice: &[u16] = &[1, 2, 3, 4]; +/// +/// let repr: raw::Slice<u16> = slice.repr(); +/// println!("data pointer = {:?}, length = {}", repr.data, repr.len); +/// ``` +#[repr(C)] +#[allow(missing_debug_implementations)] +pub struct Slice<T> { + pub data: *const T, + pub len: usize, +} + +impl<T> Copy for Slice<T> {} +impl<T> Clone for Slice<T> { + fn clone(&self) -> Slice<T> { *self } +} + +/// The representation of a trait object like `&SomeTrait`. +/// +/// This struct has the same layout as types like `&SomeTrait` and +/// `Box<AnotherTrait>`. The [Trait Objects chapter of the +/// Book][moreinfo] contains more details about the precise nature of +/// these internals. +/// +/// [moreinfo]: ../../book/trait-objects.html#representation +/// +/// `TraitObject` is guaranteed to match layouts, but it is not the +/// type of trait objects (e.g. the fields are not directly accessible +/// on a `&SomeTrait`) nor does it control that layout (changing the +/// definition will not change the layout of a `&SomeTrait`). It is +/// only designed to be used by unsafe code that needs to manipulate +/// the low-level details. +/// +/// There is no `Repr` implementation for `TraitObject` because there +/// is no way to refer to all trait objects generically, so the only +/// way to create values of this type is with functions like +/// `std::mem::transmute`. Similarly, the only way to create a true +/// trait object from a `TraitObject` value is with `transmute`. +/// +/// Synthesizing a trait object with mismatched types—one where the +/// vtable does not correspond to the type of the value to which the +/// data pointer points—is highly likely to lead to undefined +/// behavior. +/// +/// # Examples +/// +/// ``` +/// #![feature(raw)] +/// +/// use std::mem; +/// use std::raw; +/// +/// // an example trait +/// trait Foo { +/// fn bar(&self) -> i32; +/// } +/// impl Foo for i32 { +/// fn bar(&self) -> i32 { +/// *self + 1 +/// } +/// } +/// +/// let value: i32 = 123; +/// +/// // let the compiler make a trait object +/// let object: &Foo = &value; +/// +/// // look at the raw representation +/// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) }; +/// +/// // the data pointer is the address of `value` +/// assert_eq!(raw_object.data as *const i32, &value as *const _); +/// +/// +/// let other_value: i32 = 456; +/// +/// // construct a new object, pointing to a different `i32`, being +/// // careful to use the `i32` vtable from `object` +/// let synthesized: &Foo = unsafe { +/// mem::transmute(raw::TraitObject { +/// data: &other_value as *const _ as *mut (), +/// vtable: raw_object.vtable +/// }) +/// }; +/// +/// // it should work just like we constructed a trait object out of +/// // `other_value` directly +/// assert_eq!(synthesized.bar(), 457); +/// ``` +#[repr(C)] +#[derive(Copy, Clone)] +#[allow(missing_debug_implementations)] +pub struct TraitObject { + pub data: *mut (), + pub vtable: *mut (), +} + +/// This trait is meant to map equivalences between raw structs and their +/// corresponding rust values. +pub unsafe trait Repr<T> { + /// This function "unwraps" a rust value (without consuming it) into its raw + /// struct representation. This can be used to read/write different values + /// for the struct. This is a safe method because by default it does not + /// enable write-access to the fields of the return value in safe code. + #[inline] + fn repr(&self) -> T { unsafe { mem::transmute_copy(&self) } } +} + +unsafe impl<T> Repr<Slice<T>> for [T] {} +unsafe impl Repr<Slice<u8>> for str {} diff --git a/libcore/result.rs b/libcore/result.rs new file mode 100644 index 0000000..7f8cf53 --- /dev/null +++ b/libcore/result.rs @@ -0,0 +1,944 @@ +// Copyright 2012-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. + +//! Error handling with the `Result` type. +//! +//! `Result<T, E>` is the type used for returning and propagating +//! errors. It is an enum with the variants, `Ok(T)`, representing +//! success and containing a value, and `Err(E)`, representing error +//! and containing an error value. +//! +//! ``` +//! # #[allow(dead_code)] +//! enum Result<T, E> { +//! Ok(T), +//! Err(E) +//! } +//! ``` +//! +//! Functions return `Result` whenever errors are expected and +//! recoverable. In the `std` crate `Result` is most prominently used +//! for [I/O](../../std/io/index.html). +//! +//! A simple function returning `Result` might be +//! defined and used like so: +//! +//! ``` +//! #[derive(Debug)] +//! enum Version { Version1, Version2 } +//! +//! fn parse_version(header: &[u8]) -> Result<Version, &'static str> { +//! match header.get(0) { +//! None => Err("invalid header length"), +//! Some(&1) => Ok(Version::Version1), +//! Some(&2) => Ok(Version::Version2), +//! Some(_) => Err("invalid version") +//! } +//! } +//! +//! let version = parse_version(&[1, 2, 3, 4]); +//! match version { +//! Ok(v) => println!("working with version: {:?}", v), +//! Err(e) => println!("error parsing header: {:?}", e), +//! } +//! ``` +//! +//! Pattern matching on `Result`s is clear and straightforward for +//! simple cases, but `Result` comes with some convenience methods +//! that make working with it more succinct. +//! +//! ``` +//! let good_result: Result<i32, i32> = Ok(10); +//! let bad_result: Result<i32, i32> = Err(10); +//! +//! // The `is_ok` and `is_err` methods do what they say. +//! assert!(good_result.is_ok() && !good_result.is_err()); +//! assert!(bad_result.is_err() && !bad_result.is_ok()); +//! +//! // `map` consumes the `Result` and produces another. +//! let good_result: Result<i32, i32> = good_result.map(|i| i + 1); +//! let bad_result: Result<i32, i32> = bad_result.map(|i| i - 1); +//! +//! // Use `and_then` to continue the computation. +//! let good_result: Result<bool, i32> = good_result.and_then(|i| Ok(i == 11)); +//! +//! // Use `or_else` to handle the error. +//! let bad_result: Result<i32, i32> = bad_result.or_else(|i| Ok(i + 20)); +//! +//! // Consume the result and return the contents with `unwrap`. +//! let final_awesome_result = good_result.unwrap(); +//! ``` +//! +//! # Results must be used +//! +//! A common problem with using return values to indicate errors is +//! that it is easy to ignore the return value, thus failing to handle +//! the error. Result is annotated with the #[must_use] attribute, +//! which will cause the compiler to issue a warning when a Result +//! value is ignored. This makes `Result` especially useful with +//! functions that may encounter errors but don't otherwise return a +//! useful value. +//! +//! Consider the `write_all` method defined for I/O types +//! by the [`Write`](../../std/io/trait.Write.html) trait: +//! +//! ``` +//! use std::io; +//! +//! trait Write { +//! fn write_all(&mut self, bytes: &[u8]) -> Result<(), io::Error>; +//! } +//! ``` +//! +//! *Note: The actual definition of `Write` uses `io::Result`, which +//! is just a synonym for `Result<T, io::Error>`.* +//! +//! This method doesn't produce a value, but the write may +//! fail. It's crucial to handle the error case, and *not* write +//! something like this: +//! +//! ```no_run +//! # #![allow(unused_must_use)] // \o/ +//! use std::fs::File; +//! use std::io::prelude::*; +//! +//! let mut file = File::create("valuable_data.txt").unwrap(); +//! // If `write_all` errors, then we'll never know, because the return +//! // value is ignored. +//! file.write_all(b"important message"); +//! ``` +//! +//! If you *do* write that in Rust, the compiler will give you a +//! warning (by default, controlled by the `unused_must_use` lint). +//! +//! You might instead, if you don't want to handle the error, simply +//! assert success with `expect`. This will panic if the +//! write fails, providing a marginally useful message indicating why: +//! +//! ```{.no_run} +//! use std::fs::File; +//! use std::io::prelude::*; +//! +//! let mut file = File::create("valuable_data.txt").unwrap(); +//! file.write_all(b"important message").expect("failed to write message"); +//! ``` +//! +//! You might also simply assert success: +//! +//! ```{.no_run} +//! # use std::fs::File; +//! # use std::io::prelude::*; +//! # let mut file = File::create("valuable_data.txt").unwrap(); +//! assert!(file.write_all(b"important message").is_ok()); +//! ``` +//! +//! Or propagate the error up the call stack with `try!`: +//! +//! ``` +//! # use std::fs::File; +//! # use std::io::prelude::*; +//! # use std::io; +//! # #[allow(dead_code)] +//! fn write_message() -> io::Result<()> { +//! let mut file = try!(File::create("valuable_data.txt")); +//! try!(file.write_all(b"important message")); +//! Ok(()) +//! } +//! ``` +//! +//! # The `try!` macro +//! +//! When writing code that calls many functions that return the +//! `Result` type, the error handling can be tedious. The `try!` +//! macro hides some of the boilerplate of propagating errors up the +//! call stack. +//! +//! It replaces this: +//! +//! ``` +//! # #![allow(dead_code)] +//! use std::fs::File; +//! use std::io::prelude::*; +//! use std::io; +//! +//! struct Info { +//! name: String, +//! age: i32, +//! rating: i32, +//! } +//! +//! fn write_info(info: &Info) -> io::Result<()> { +//! let mut file = try!(File::create("my_best_friends.txt")); +//! // Early return on error +//! if let Err(e) = file.write_all(format!("name: {}\n", info.name).as_bytes()) { +//! return Err(e) +//! } +//! if let Err(e) = file.write_all(format!("age: {}\n", info.age).as_bytes()) { +//! return Err(e) +//! } +//! if let Err(e) = file.write_all(format!("rating: {}\n", info.rating).as_bytes()) { +//! return Err(e) +//! } +//! Ok(()) +//! } +//! ``` +//! +//! With this: +//! +//! ``` +//! # #![allow(dead_code)] +//! use std::fs::File; +//! use std::io::prelude::*; +//! use std::io; +//! +//! struct Info { +//! name: String, +//! age: i32, +//! rating: i32, +//! } +//! +//! fn write_info(info: &Info) -> io::Result<()> { +//! let mut file = try!(File::create("my_best_friends.txt")); +//! // Early return on error +//! try!(file.write_all(format!("name: {}\n", info.name).as_bytes())); +//! try!(file.write_all(format!("age: {}\n", info.age).as_bytes())); +//! try!(file.write_all(format!("rating: {}\n", info.rating).as_bytes())); +//! Ok(()) +//! } +//! ``` +//! +//! *It's much nicer!* +//! +//! Wrapping an expression in `try!` will result in the unwrapped +//! success (`Ok`) value, unless the result is `Err`, in which case +//! `Err` is returned early from the enclosing function. Its simple definition +//! makes it clear: +//! +//! ``` +//! macro_rules! try { +//! ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) }) +//! } +//! ``` +//! +//! `try!` is imported by the prelude and is available everywhere, but it can only +//! be used in functions that return `Result` because of the early return of +//! `Err` that it provides. + +#![stable(feature = "rust1", since = "1.0.0")] + +use self::Result::{Ok, Err}; + +use clone::Clone; +use fmt; +use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator}; +use ops::FnOnce; +use option::Option::{self, None, Some}; + +/// `Result` is a type that represents either success (`Ok`) or failure (`Err`). +/// +/// See the [`std::result`](index.html) module documentation for details. +#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] +#[must_use] +#[stable(feature = "rust1", since = "1.0.0")] +pub enum Result<T, E> { + /// Contains the success value + #[stable(feature = "rust1", since = "1.0.0")] + Ok(#[stable(feature = "rust1", since = "1.0.0")] T), + + /// Contains the error value + #[stable(feature = "rust1", since = "1.0.0")] + Err(#[stable(feature = "rust1", since = "1.0.0")] E) +} + +///////////////////////////////////////////////////////////////////////////// +// Type implementation +///////////////////////////////////////////////////////////////////////////// + +impl<T, E> Result<T, E> { + ///////////////////////////////////////////////////////////////////////// + // Querying the contained values + ///////////////////////////////////////////////////////////////////////// + + /// Returns true if the result is `Ok` + /// + /// # Examples + /// + /// ``` + /// let x: Result<i32, &str> = Ok(-3); + /// assert_eq!(x.is_ok(), true); + /// + /// let x: Result<i32, &str> = Err("Some error message"); + /// assert_eq!(x.is_ok(), false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_ok(&self) -> bool { + match *self { + Ok(_) => true, + Err(_) => false + } + } + + /// Returns true if the result is `Err` + /// + /// # Examples + /// + /// ``` + /// let x: Result<i32, &str> = Ok(-3); + /// assert_eq!(x.is_err(), false); + /// + /// let x: Result<i32, &str> = Err("Some error message"); + /// assert_eq!(x.is_err(), true); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn is_err(&self) -> bool { + !self.is_ok() + } + + ///////////////////////////////////////////////////////////////////////// + // Adapter for each variant + ///////////////////////////////////////////////////////////////////////// + + /// Converts from `Result<T, E>` to `Option<T>` + /// + /// Converts `self` into an `Option<T>`, consuming `self`, + /// and discarding the error, if any. + /// + /// # Examples + /// + /// ``` + /// let x: Result<u32, &str> = Ok(2); + /// assert_eq!(x.ok(), Some(2)); + /// + /// let x: Result<u32, &str> = Err("Nothing here"); + /// assert_eq!(x.ok(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn ok(self) -> Option<T> { + match self { + Ok(x) => Some(x), + Err(_) => None, + } + } + + /// Converts from `Result<T, E>` to `Option<E>` + /// + /// Converts `self` into an `Option<E>`, consuming `self`, + /// and discarding the success value, if any. + /// + /// # Examples + /// + /// ``` + /// let x: Result<u32, &str> = Ok(2); + /// assert_eq!(x.err(), None); + /// + /// let x: Result<u32, &str> = Err("Nothing here"); + /// assert_eq!(x.err(), Some("Nothing here")); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn err(self) -> Option<E> { + match self { + Ok(_) => None, + Err(x) => Some(x), + } + } + + ///////////////////////////////////////////////////////////////////////// + // Adapter for working with references + ///////////////////////////////////////////////////////////////////////// + + /// Converts from `Result<T, E>` to `Result<&T, &E>` + /// + /// Produces a new `Result`, containing a reference + /// into the original, leaving the original in place. + /// + /// ``` + /// let x: Result<u32, &str> = Ok(2); + /// assert_eq!(x.as_ref(), Ok(&2)); + /// + /// let x: Result<u32, &str> = Err("Error"); + /// assert_eq!(x.as_ref(), Err(&"Error")); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn as_ref(&self) -> Result<&T, &E> { + match *self { + Ok(ref x) => Ok(x), + Err(ref x) => Err(x), + } + } + + /// Converts from `Result<T, E>` to `Result<&mut T, &mut E>` + /// + /// ``` + /// fn mutate(r: &mut Result<i32, i32>) { + /// match r.as_mut() { + /// Ok(&mut ref mut v) => *v = 42, + /// Err(&mut ref mut e) => *e = 0, + /// } + /// } + /// + /// let mut x: Result<i32, i32> = Ok(2); + /// mutate(&mut x); + /// assert_eq!(x.unwrap(), 42); + /// + /// let mut x: Result<i32, i32> = Err(13); + /// mutate(&mut x); + /// assert_eq!(x.unwrap_err(), 0); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn as_mut(&mut self) -> Result<&mut T, &mut E> { + match *self { + Ok(ref mut x) => Ok(x), + Err(ref mut x) => Err(x), + } + } + + ///////////////////////////////////////////////////////////////////////// + // Transforming contained values + ///////////////////////////////////////////////////////////////////////// + + /// Maps a `Result<T, E>` to `Result<U, E>` by applying a function to a + /// contained `Ok` value, leaving an `Err` value untouched. + /// + /// This function can be used to compose the results of two functions. + /// + /// # Examples + /// + /// Print the numbers on each line of a string multiplied by two. + /// + /// ``` + /// let line = "1\n2\n3\n4\n"; + /// + /// for num in line.lines() { + /// match num.parse::<i32>().map(|i| i * 2) { + /// Ok(n) => println!("{}", n), + /// Err(..) => {} + /// } + /// } + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U,E> { + match self { + Ok(t) => Ok(op(t)), + Err(e) => Err(e) + } + } + + /// Maps a `Result<T, E>` to `Result<T, F>` by applying a function to a + /// contained `Err` value, leaving an `Ok` value untouched. + /// + /// This function can be used to pass through a successful result while handling + /// an error. + /// + /// # Examples + /// + /// ``` + /// fn stringify(x: u32) -> String { format!("error code: {}", x) } + /// + /// let x: Result<u32, u32> = Ok(2); + /// assert_eq!(x.map_err(stringify), Ok(2)); + /// + /// let x: Result<u32, u32> = Err(13); + /// assert_eq!(x.map_err(stringify), Err("error code: 13".to_string())); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T,F> { + match self { + Ok(t) => Ok(t), + Err(e) => Err(op(e)) + } + } + + ///////////////////////////////////////////////////////////////////////// + // Iterator constructors + ///////////////////////////////////////////////////////////////////////// + + /// Returns an iterator over the possibly contained value. + /// + /// # Examples + /// + /// ``` + /// let x: Result<u32, &str> = Ok(7); + /// assert_eq!(x.iter().next(), Some(&7)); + /// + /// let x: Result<u32, &str> = Err("nothing!"); + /// assert_eq!(x.iter().next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter(&self) -> Iter<T> { + Iter { inner: self.as_ref().ok() } + } + + /// Returns a mutable iterator over the possibly contained value. + /// + /// # Examples + /// + /// ``` + /// let mut x: Result<u32, &str> = Ok(7); + /// match x.iter_mut().next() { + /// Some(v) => *v = 40, + /// None => {}, + /// } + /// assert_eq!(x, Ok(40)); + /// + /// let mut x: Result<u32, &str> = Err("nothing!"); + /// assert_eq!(x.iter_mut().next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn iter_mut(&mut self) -> IterMut<T> { + IterMut { inner: self.as_mut().ok() } + } + + //////////////////////////////////////////////////////////////////////// + // Boolean operations on the values, eager and lazy + ///////////////////////////////////////////////////////////////////////// + + /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`. + /// + /// # Examples + /// + /// ``` + /// let x: Result<u32, &str> = Ok(2); + /// let y: Result<&str, &str> = Err("late error"); + /// assert_eq!(x.and(y), Err("late error")); + /// + /// let x: Result<u32, &str> = Err("early error"); + /// let y: Result<&str, &str> = Ok("foo"); + /// assert_eq!(x.and(y), Err("early error")); + /// + /// let x: Result<u32, &str> = Err("not a 2"); + /// let y: Result<&str, &str> = Err("late error"); + /// assert_eq!(x.and(y), Err("not a 2")); + /// + /// let x: Result<u32, &str> = Ok(2); + /// let y: Result<&str, &str> = Ok("different result type"); + /// assert_eq!(x.and(y), Ok("different result type")); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> { + match self { + Ok(_) => res, + Err(e) => Err(e), + } + } + + /// Calls `op` if the result is `Ok`, otherwise returns the `Err` value of `self`. + /// + /// This function can be used for control flow based on result values. + /// + /// # Examples + /// + /// ``` + /// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) } + /// fn err(x: u32) -> Result<u32, u32> { Err(x) } + /// + /// assert_eq!(Ok(2).and_then(sq).and_then(sq), Ok(16)); + /// assert_eq!(Ok(2).and_then(sq).and_then(err), Err(4)); + /// assert_eq!(Ok(2).and_then(err).and_then(sq), Err(2)); + /// assert_eq!(Err(3).and_then(sq).and_then(sq), Err(3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E> { + match self { + Ok(t) => op(t), + Err(e) => Err(e), + } + } + + /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`. + /// + /// # Examples + /// + /// ``` + /// let x: Result<u32, &str> = Ok(2); + /// let y: Result<u32, &str> = Err("late error"); + /// assert_eq!(x.or(y), Ok(2)); + /// + /// let x: Result<u32, &str> = Err("early error"); + /// let y: Result<u32, &str> = Ok(2); + /// assert_eq!(x.or(y), Ok(2)); + /// + /// let x: Result<u32, &str> = Err("not a 2"); + /// let y: Result<u32, &str> = Err("late error"); + /// assert_eq!(x.or(y), Err("late error")); + /// + /// let x: Result<u32, &str> = Ok(2); + /// let y: Result<u32, &str> = Ok(100); + /// assert_eq!(x.or(y), Ok(2)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn or<F>(self, res: Result<T, F>) -> Result<T, F> { + match self { + Ok(v) => Ok(v), + Err(_) => res, + } + } + + /// Calls `op` if the result is `Err`, otherwise returns the `Ok` value of `self`. + /// + /// This function can be used for control flow based on result values. + /// + /// # Examples + /// + /// ``` + /// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) } + /// fn err(x: u32) -> Result<u32, u32> { Err(x) } + /// + /// assert_eq!(Ok(2).or_else(sq).or_else(sq), Ok(2)); + /// assert_eq!(Ok(2).or_else(err).or_else(sq), Ok(2)); + /// assert_eq!(Err(3).or_else(sq).or_else(err), Ok(9)); + /// assert_eq!(Err(3).or_else(err).or_else(err), Err(3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> { + match self { + Ok(t) => Ok(t), + Err(e) => op(e), + } + } + + /// Unwraps a result, yielding the content of an `Ok`. + /// Else it returns `optb`. + /// + /// # Examples + /// + /// ``` + /// let optb = 2; + /// let x: Result<u32, &str> = Ok(9); + /// assert_eq!(x.unwrap_or(optb), 9); + /// + /// let x: Result<u32, &str> = Err("error"); + /// assert_eq!(x.unwrap_or(optb), optb); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap_or(self, optb: T) -> T { + match self { + Ok(t) => t, + Err(_) => optb + } + } + + /// Unwraps a result, yielding the content of an `Ok`. + /// If the value is an `Err` then it calls `op` with its value. + /// + /// # Examples + /// + /// ``` + /// fn count(x: &str) -> usize { x.len() } + /// + /// assert_eq!(Ok(2).unwrap_or_else(count), 2); + /// assert_eq!(Err("foo").unwrap_or_else(count), 3); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T { + match self { + Ok(t) => t, + Err(e) => op(e) + } + } +} + +impl<T, E: fmt::Debug> Result<T, E> { + /// Unwraps a result, yielding the content of an `Ok`. + /// + /// # Panics + /// + /// Panics if the value is an `Err`, with a panic message provided by the + /// `Err`'s value. + /// + /// # Examples + /// + /// ``` + /// let x: Result<u32, &str> = Ok(2); + /// assert_eq!(x.unwrap(), 2); + /// ``` + /// + /// ```{.should_panic} + /// let x: Result<u32, &str> = Err("emergency failure"); + /// x.unwrap(); // panics with `emergency failure` + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap(self) -> T { + match self { + Ok(t) => t, + Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", e), + } + } + + /// Unwraps a result, yielding the content of an `Ok`. + /// + /// # Panics + /// + /// Panics if the value is an `Err`, with a panic message including the + /// passed message, and the content of the `Err`. + /// + /// # Examples + /// ```{.should_panic} + /// let x: Result<u32, &str> = Err("emergency failure"); + /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure` + /// ``` + #[inline] + #[stable(feature = "result_expect", since = "1.4.0")] + pub fn expect(self, msg: &str) -> T { + match self { + Ok(t) => t, + Err(e) => unwrap_failed(msg, e), + } + } +} + +impl<T: fmt::Debug, E> Result<T, E> { + /// Unwraps a result, yielding the content of an `Err`. + /// + /// # Panics + /// + /// Panics if the value is an `Ok`, with a custom panic message provided + /// by the `Ok`'s value. + /// + /// # Examples + /// + /// ```{.should_panic} + /// let x: Result<u32, &str> = Ok(2); + /// x.unwrap_err(); // panics with `2` + /// ``` + /// + /// ``` + /// let x: Result<u32, &str> = Err("emergency failure"); + /// assert_eq!(x.unwrap_err(), "emergency failure"); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn unwrap_err(self) -> E { + match self { + Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", t), + Err(e) => e, + } + } +} + +// This is a separate function to reduce the code size of the methods +#[inline(never)] +#[cold] +fn unwrap_failed<E: fmt::Debug>(msg: &str, error: E) -> ! { + panic!("{}: {:?}", msg, error) +} + +///////////////////////////////////////////////////////////////////////////// +// Trait implementations +///////////////////////////////////////////////////////////////////////////// + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T, E> IntoIterator for Result<T, E> { + type Item = T; + type IntoIter = IntoIter<T>; + + /// Returns a consuming iterator over the possibly contained value. + /// + /// # Examples + /// + /// ``` + /// let x: Result<u32, &str> = Ok(5); + /// let v: Vec<u32> = x.into_iter().collect(); + /// assert_eq!(v, [5]); + /// + /// let x: Result<u32, &str> = Err("nothing!"); + /// let v: Vec<u32> = x.into_iter().collect(); + /// assert_eq!(v, []); + /// ``` + #[inline] + fn into_iter(self) -> IntoIter<T> { + IntoIter { inner: self.ok() } + } +} + +#[stable(since = "1.4.0", feature = "result_iter")] +impl<'a, T, E> IntoIterator for &'a Result<T, E> { + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +#[stable(since = "1.4.0", feature = "result_iter")] +impl<'a, T, E> IntoIterator for &'a mut Result<T, E> { + type Item = &'a mut T; + type IntoIter = IterMut<'a, T>; + + fn into_iter(mut self) -> IterMut<'a, T> { + self.iter_mut() + } +} + +///////////////////////////////////////////////////////////////////////////// +// The Result Iterators +///////////////////////////////////////////////////////////////////////////// + +/// An iterator over a reference to the `Ok` variant of a `Result`. +#[derive(Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Iter<'a, T: 'a> { inner: Option<&'a T> } + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Iterator for Iter<'a, T> { + type Item = &'a T; + + #[inline] + fn next(&mut self) -> Option<&'a T> { self.inner.take() } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let n = if self.inner.is_some() {1} else {0}; + (n, Some(n)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> DoubleEndedIterator for Iter<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a T> { self.inner.take() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> ExactSizeIterator for Iter<'a, T> {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Clone for Iter<'a, T> { + fn clone(&self) -> Iter<'a, T> { Iter { inner: self.inner } } +} + +/// An iterator over a mutable reference to the `Ok` variant of a `Result`. +#[derive(Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IterMut<'a, T: 'a> { inner: Option<&'a mut T> } + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Iterator for IterMut<'a, T> { + type Item = &'a mut T; + + #[inline] + fn next(&mut self) -> Option<&'a mut T> { self.inner.take() } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let n = if self.inner.is_some() {1} else {0}; + (n, Some(n)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a mut T> { self.inner.take() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} + +/// An iterator over the value in a `Ok` variant of a `Result`. +#[derive(Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IntoIter<T> { inner: Option<T> } + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> Iterator for IntoIter<T> { + type Item = T; + + #[inline] + fn next(&mut self) -> Option<T> { self.inner.take() } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let n = if self.inner.is_some() {1} else {0}; + (n, Some(n)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> DoubleEndedIterator for IntoIter<T> { + #[inline] + fn next_back(&mut self) -> Option<T> { self.inner.take() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ExactSizeIterator for IntoIter<T> {} + +///////////////////////////////////////////////////////////////////////////// +// FromIterator +///////////////////////////////////////////////////////////////////////////// + +#[stable(feature = "rust1", since = "1.0.0")] +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: + /// + /// ``` + /// use std::u32; + /// + /// let v = vec!(1, 2); + /// let res: Result<Vec<u32>, &'static str> = v.iter().map(|&x: &u32| + /// if x == u32::MAX { Err("Overflow!") } + /// else { Ok(x + 1) } + /// ).collect(); + /// assert!(res == Ok(vec!(2, 3))); + /// ``` + #[inline] + fn from_iter<I: IntoIterator<Item=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<Item=Result<T, E>>> Iterator for Adapter<Iter, E> { + type Item = T; + + #[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, + } + } + } + + let mut adapter = Adapter { iter: iter.into_iter(), err: None }; + let v: V = FromIterator::from_iter(adapter.by_ref()); + + match adapter.err { + Some(err) => Err(err), + None => Ok(v), + } + } +} diff --git a/libcore/slice.rs b/libcore/slice.rs new file mode 100644 index 0000000..25082ee --- /dev/null +++ b/libcore/slice.rs @@ -0,0 +1,1832 @@ +// Copyright 2012-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. + +//! Slice management and manipulation +//! +//! For more details `std::slice`. + +#![stable(feature = "rust1", since = "1.0.0")] + +// How this module is organized. +// +// The library infrastructure for slices is fairly messy. There's +// a lot of stuff defined here. Let's keep it clean. +// +// Since slices don't support inherent methods; all operations +// on them are defined on traits, which are then reexported from +// the prelude for convenience. So there are a lot of traits here. +// +// The layout of this file is thus: +// +// * Slice-specific 'extension' traits and their implementations. This +// is where most of the slice API resides. +// * Implementations of a few common traits with important slice ops. +// * Definitions of a bunch of iterators. +// * Free functions. +// * The `raw` and `bytes` submodules. +// * Boilerplate trait implementations. + +use clone::Clone; +use cmp::{Ordering, PartialEq, PartialOrd, Eq, Ord}; +use cmp::Ordering::{Less, Equal, Greater}; +use cmp; +use default::Default; +use fmt; +use intrinsics::assume; +use iter::*; +use ops::{FnMut, self, Index}; +use ops::RangeFull; +use option::Option; +use option::Option::{None, Some}; +use result::Result; +use result::Result::{Ok, Err}; +use ptr; +use mem; +use marker::{Copy, Send, Sync, self}; +use raw::Repr; +// Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module. +use raw::Slice as RawSlice; + + +// +// Extension traits +// + +/// Extension methods for slices. +#[unstable(feature = "core_slice_ext", + reason = "stable interface provided by `impl [T]` in later crates", + issue = "32110")] +#[allow(missing_docs)] // documented elsewhere +pub trait SliceExt { + type Item; + + #[stable(feature = "core", since = "1.6.0")] + fn split_at(&self, mid: usize) -> (&[Self::Item], &[Self::Item]); + #[stable(feature = "core", since = "1.6.0")] + fn iter(&self) -> Iter<Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn split<P>(&self, pred: P) -> Split<Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn splitn<P>(&self, n: usize, pred: P) -> SplitN<Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn rsplitn<P>(&self, n: usize, pred: P) -> RSplitN<Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn windows(&self, size: usize) -> Windows<Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn chunks(&self, size: usize) -> Chunks<Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn get(&self, index: usize) -> Option<&Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn first(&self) -> Option<&Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn split_first(&self) -> Option<(&Self::Item, &[Self::Item])>; + #[stable(feature = "core", since = "1.6.0")] + fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])>; + #[stable(feature = "core", since = "1.6.0")] + fn last(&self) -> Option<&Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + unsafe fn get_unchecked(&self, index: usize) -> &Self::Item; + #[stable(feature = "core", since = "1.6.0")] + fn as_ptr(&self) -> *const Self::Item; + #[stable(feature = "core", since = "1.6.0")] + fn binary_search(&self, x: &Self::Item) -> Result<usize, usize> + where Self::Item: Ord; + #[stable(feature = "core", since = "1.6.0")] + fn binary_search_by<F>(&self, f: F) -> Result<usize, usize> + where F: FnMut(&Self::Item) -> Ordering; + #[stable(feature = "core", since = "1.6.0")] + fn len(&self) -> usize; + #[stable(feature = "core", since = "1.6.0")] + fn is_empty(&self) -> bool { self.len() == 0 } + #[stable(feature = "core", since = "1.6.0")] + fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn iter_mut(&mut self) -> IterMut<Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn first_mut(&mut self) -> Option<&mut Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn split_first_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>; + #[stable(feature = "core", since = "1.6.0")] + fn split_last_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>; + #[stable(feature = "core", since = "1.6.0")] + fn last_mut(&mut self) -> Option<&mut Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn split_mut<P>(&mut self, pred: P) -> SplitMut<Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn rsplitn_mut<P>(&mut self, n: usize, pred: P) -> RSplitNMut<Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<Self::Item>; + #[stable(feature = "core", since = "1.6.0")] + fn swap(&mut self, a: usize, b: usize); + #[stable(feature = "core", since = "1.6.0")] + fn split_at_mut(&mut self, mid: usize) -> (&mut [Self::Item], &mut [Self::Item]); + #[stable(feature = "core", since = "1.6.0")] + fn reverse(&mut self); + #[stable(feature = "core", since = "1.6.0")] + unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut Self::Item; + #[stable(feature = "core", since = "1.6.0")] + fn as_mut_ptr(&mut self) -> *mut Self::Item; + + #[stable(feature = "core", since = "1.6.0")] + fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq; + + #[stable(feature = "core", since = "1.6.0")] + fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + #[stable(feature = "core", since = "1.6.0")] + fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + #[stable(feature = "clone_from_slice", since = "1.7.0")] + fn clone_from_slice(&mut self, &[Self::Item]) where Self::Item: Clone; + #[unstable(feature = "copy_from_slice", issue = "31755")] + fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy; +} + +// Use macros to be generic over const/mut +macro_rules! slice_offset { + ($ptr:expr, $by:expr) => {{ + let ptr = $ptr; + if size_from_ptr(ptr) == 0 { + ::intrinsics::arith_offset(ptr as *mut i8, $by) as *mut _ + } else { + ptr.offset($by) + } + }}; +} + +macro_rules! slice_ref { + ($ptr:expr) => {{ + let ptr = $ptr; + if size_from_ptr(ptr) == 0 { + // Use a non-null pointer value + &mut *(1 as *mut _) + } else { + mem::transmute(ptr) + } + }}; +} + +#[unstable(feature = "core_slice_ext", + reason = "stable interface provided by `impl [T]` in later crates", + issue = "32110")] +impl<T> SliceExt for [T] { + type Item = T; + + #[inline] + fn split_at(&self, mid: usize) -> (&[T], &[T]) { + (&self[..mid], &self[mid..]) + } + + #[inline] + fn iter(&self) -> Iter<T> { + unsafe { + let p = if mem::size_of::<T>() == 0 { + 1 as *const _ + } else { + let p = self.as_ptr(); + assume(!p.is_null()); + p + }; + + Iter { + ptr: p, + end: slice_offset!(p, self.len() as isize), + _marker: marker::PhantomData + } + } + } + + #[inline] + fn split<P>(&self, pred: P) -> Split<T, P> where P: FnMut(&T) -> bool { + Split { + v: self, + pred: pred, + finished: false + } + } + + #[inline] + fn splitn<P>(&self, n: usize, pred: P) -> SplitN<T, P> where + P: FnMut(&T) -> bool, + { + SplitN { + inner: GenericSplitN { + iter: self.split(pred), + count: n, + invert: false + } + } + } + + #[inline] + fn rsplitn<P>(&self, n: usize, pred: P) -> RSplitN<T, P> where + P: FnMut(&T) -> bool, + { + RSplitN { + inner: GenericSplitN { + iter: self.split(pred), + count: n, + invert: true + } + } + } + + #[inline] + fn windows(&self, size: usize) -> Windows<T> { + assert!(size != 0); + Windows { v: self, size: size } + } + + #[inline] + fn chunks(&self, size: usize) -> Chunks<T> { + assert!(size != 0); + Chunks { v: self, size: size } + } + + #[inline] + fn get(&self, index: usize) -> Option<&T> { + if index < self.len() { Some(&self[index]) } else { None } + } + + #[inline] + fn first(&self) -> Option<&T> { + if self.is_empty() { None } else { Some(&self[0]) } + } + + #[inline] + fn split_first(&self) -> Option<(&T, &[T])> { + if self.is_empty() { None } else { Some((&self[0], &self[1..])) } + } + + #[inline] + fn split_last(&self) -> Option<(&T, &[T])> { + let len = self.len(); + if len == 0 { None } else { Some((&self[len - 1], &self[..(len - 1)])) } + } + + #[inline] + fn last(&self) -> Option<&T> { + if self.is_empty() { None } else { Some(&self[self.len() - 1]) } + } + + #[inline] + unsafe fn get_unchecked(&self, index: usize) -> &T { + &*(self.as_ptr().offset(index as isize)) + } + + #[inline] + fn as_ptr(&self) -> *const T { + self as *const [T] as *const T + } + + fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize> where + F: FnMut(&T) -> Ordering + { + let mut base = 0usize; + let mut s = self; + + loop { + let (head, tail) = s.split_at(s.len() >> 1); + if tail.is_empty() { + return Err(base) + } + match f(&tail[0]) { + Less => { + base += head.len() + 1; + s = &tail[1..]; + } + Greater => s = head, + Equal => return Ok(base + head.len()), + } + } + } + + #[inline] + fn len(&self) -> usize { self.repr().len } + + #[inline] + fn get_mut(&mut self, index: usize) -> Option<&mut T> { + if index < self.len() { Some(&mut self[index]) } else { None } + } + + #[inline] + fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { + let len = self.len(); + let ptr = self.as_mut_ptr(); + + unsafe { + assert!(mid <= len); + + (from_raw_parts_mut(ptr, mid), + from_raw_parts_mut(ptr.offset(mid as isize), len - mid)) + } + } + + #[inline] + fn iter_mut(&mut self) -> IterMut<T> { + unsafe { + let p = if mem::size_of::<T>() == 0 { + 1 as *mut _ + } else { + let p = self.as_mut_ptr(); + assume(!p.is_null()); + p + }; + + IterMut { + ptr: p, + end: slice_offset!(p, self.len() as isize), + _marker: marker::PhantomData + } + } + } + + #[inline] + fn last_mut(&mut self) -> Option<&mut T> { + let len = self.len(); + if len == 0 { return None; } + Some(&mut self[len - 1]) + } + + #[inline] + fn first_mut(&mut self) -> Option<&mut T> { + if self.is_empty() { None } else { Some(&mut self[0]) } + } + + #[inline] + fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> { + if self.is_empty() { None } else { + let split = self.split_at_mut(1); + Some((&mut split.0[0], split.1)) + } + } + + #[inline] + fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> { + let len = self.len(); + if len == 0 { None } else { + let split = self.split_at_mut(len - 1); + Some((&mut split.1[0], split.0)) + } + } + + #[inline] + fn split_mut<P>(&mut self, pred: P) -> SplitMut<T, P> where P: FnMut(&T) -> bool { + SplitMut { v: self, pred: pred, finished: false } + } + + #[inline] + fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<T, P> where + P: FnMut(&T) -> bool + { + SplitNMut { + inner: GenericSplitN { + iter: self.split_mut(pred), + count: n, + invert: false + } + } + } + + #[inline] + fn rsplitn_mut<P>(&mut self, n: usize, pred: P) -> RSplitNMut<T, P> where + P: FnMut(&T) -> bool, + { + RSplitNMut { + inner: GenericSplitN { + iter: self.split_mut(pred), + count: n, + invert: true + } + } + } + + #[inline] + fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> { + assert!(chunk_size > 0); + ChunksMut { v: self, chunk_size: chunk_size } + } + + #[inline] + fn swap(&mut self, a: usize, b: usize) { + unsafe { + // Can't take two mutable loans from one vector, so instead just cast + // them to their raw pointers to do the swap + let pa: *mut T = &mut self[a]; + let pb: *mut T = &mut self[b]; + ptr::swap(pa, pb); + } + } + + fn reverse(&mut self) { + let mut i: usize = 0; + let ln = self.len(); + while i < ln / 2 { + // Unsafe swap to avoid the bounds check in safe swap. + unsafe { + let pa: *mut T = self.get_unchecked_mut(i); + let pb: *mut T = self.get_unchecked_mut(ln - i - 1); + ptr::swap(pa, pb); + } + i += 1; + } + } + + #[inline] + unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { + &mut *self.as_mut_ptr().offset(index as isize) + } + + #[inline] + fn as_mut_ptr(&mut self) -> *mut T { + self as *mut [T] as *mut T + } + + #[inline] + fn contains(&self, x: &T) -> bool where T: PartialEq { + self.iter().any(|elt| *x == *elt) + } + + #[inline] + fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq { + let n = needle.len(); + self.len() >= n && needle == &self[..n] + } + + #[inline] + fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq { + let (m, n) = (self.len(), needle.len()); + m >= n && needle == &self[m-n..] + } + + fn binary_search(&self, x: &T) -> Result<usize, usize> where T: Ord { + self.binary_search_by(|p| p.cmp(x)) + } + + #[inline] + fn clone_from_slice(&mut self, src: &[T]) where T: Clone { + assert!(self.len() == src.len(), + "destination and source slices have different lengths"); + // NOTE: We need to explicitly slice them to the same length + // for bounds checking to be elided, and the optimizer will + // generate memcpy for simple cases (for example T = u8). + let len = self.len(); + let src = &src[..len]; + for i in 0..len { + self[i].clone_from(&src[i]); + } + } + + #[inline] + fn copy_from_slice(&mut self, src: &[T]) where T: Copy { + assert!(self.len() == src.len(), + "destination and source slices have different lengths"); + unsafe { + ptr::copy_nonoverlapping( + src.as_ptr(), self.as_mut_ptr(), self.len()); + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::Index<usize> for [T] { + type Output = T; + + fn index(&self, index: usize) -> &T { + assert!(index < self.len()); + unsafe { self.get_unchecked(index) } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::IndexMut<usize> for [T] { + #[inline] + fn index_mut(&mut self, index: usize) -> &mut T { + assert!(index < self.len()); + unsafe { self.get_unchecked_mut(index) } + } +} + +#[inline(never)] +#[cold] +fn slice_index_len_fail(index: usize, len: usize) -> ! { + panic!("index {} out of range for slice of length {}", index, len); +} + +#[inline(never)] +#[cold] +fn slice_index_order_fail(index: usize, end: usize) -> ! { + panic!("slice index starts at {} but ends at {}", index, end); +} + +// FIXME implement indexing with inclusive ranges + +/// Implements slicing with syntax `&self[begin .. end]`. +/// +/// Returns a slice of self for the index range [`begin`..`end`). +/// +/// This operation is `O(1)`. +/// +/// # Panics +/// +/// Requires that `begin <= end` and `end <= self.len()`, +/// otherwise slicing will panic. +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::Index<ops::Range<usize>> for [T] { + type Output = [T]; + + #[inline] + fn index(&self, index: ops::Range<usize>) -> &[T] { + if index.start > index.end { + slice_index_order_fail(index.start, index.end); + } else if index.end > self.len() { + slice_index_len_fail(index.end, self.len()); + } + unsafe { + from_raw_parts ( + self.as_ptr().offset(index.start as isize), + index.end - index.start + ) + } + } +} + +/// Implements slicing with syntax `&self[.. end]`. +/// +/// Returns a slice of self from the beginning until but not including +/// the index `end`. +/// +/// Equivalent to `&self[0 .. end]` +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::Index<ops::RangeTo<usize>> for [T] { + type Output = [T]; + + #[inline] + fn index(&self, index: ops::RangeTo<usize>) -> &[T] { + self.index(0 .. index.end) + } +} + +/// Implements slicing with syntax `&self[begin ..]`. +/// +/// Returns a slice of self from and including the index `begin` until the end. +/// +/// Equivalent to `&self[begin .. self.len()]` +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::Index<ops::RangeFrom<usize>> for [T] { + type Output = [T]; + + #[inline] + fn index(&self, index: ops::RangeFrom<usize>) -> &[T] { + self.index(index.start .. self.len()) + } +} + +/// Implements slicing with syntax `&self[..]`. +/// +/// Returns a slice of the whole slice. This operation can not panic. +/// +/// Equivalent to `&self[0 .. self.len()]` +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::Index<RangeFull> for [T] { + type Output = [T]; + + #[inline] + fn index(&self, _index: RangeFull) -> &[T] { + self + } +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<T> ops::Index<ops::RangeInclusive<usize>> for [T] { + type Output = [T]; + + #[inline] + fn index(&self, index: ops::RangeInclusive<usize>) -> &[T] { + match index { + ops::RangeInclusive::Empty { .. } => &[], + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => + panic!("attempted to index slice up to maximum usize"), + ops::RangeInclusive::NonEmpty { start, end } => + self.index(start .. end+1) + } + } +} +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<T> ops::Index<ops::RangeToInclusive<usize>> for [T] { + type Output = [T]; + + #[inline] + fn index(&self, index: ops::RangeToInclusive<usize>) -> &[T] { + self.index(0...index.end) + } +} + +/// Implements mutable slicing with syntax `&mut self[begin .. end]`. +/// +/// Returns a slice of self for the index range [`begin`..`end`). +/// +/// This operation is `O(1)`. +/// +/// # Panics +/// +/// Requires that `begin <= end` and `end <= self.len()`, +/// otherwise slicing will panic. +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::IndexMut<ops::Range<usize>> for [T] { + #[inline] + fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] { + if index.start > index.end { + slice_index_order_fail(index.start, index.end); + } else if index.end > self.len() { + slice_index_len_fail(index.end, self.len()); + } + unsafe { + from_raw_parts_mut( + self.as_mut_ptr().offset(index.start as isize), + index.end - index.start + ) + } + } +} + +/// Implements mutable slicing with syntax `&mut self[.. end]`. +/// +/// Returns a slice of self from the beginning until but not including +/// the index `end`. +/// +/// Equivalent to `&mut self[0 .. end]` +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::IndexMut<ops::RangeTo<usize>> for [T] { + #[inline] + fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] { + self.index_mut(0 .. index.end) + } +} + +/// Implements mutable slicing with syntax `&mut self[begin ..]`. +/// +/// Returns a slice of self from and including the index `begin` until the end. +/// +/// Equivalent to `&mut self[begin .. self.len()]` +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::IndexMut<ops::RangeFrom<usize>> for [T] { + #[inline] + fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] { + let len = self.len(); + self.index_mut(index.start .. len) + } +} + +/// Implements mutable slicing with syntax `&mut self[..]`. +/// +/// Returns a slice of the whole slice. This operation can not panic. +/// +/// Equivalent to `&mut self[0 .. self.len()]` +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> ops::IndexMut<RangeFull> for [T] { + #[inline] + fn index_mut(&mut self, _index: RangeFull) -> &mut [T] { + self + } +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<T> ops::IndexMut<ops::RangeInclusive<usize>> for [T] { + #[inline] + fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut [T] { + match index { + ops::RangeInclusive::Empty { .. } => &mut [], + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => + panic!("attempted to index slice up to maximum usize"), + ops::RangeInclusive::NonEmpty { start, end } => + self.index_mut(start .. end+1) + } + } +} +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl<T> ops::IndexMut<ops::RangeToInclusive<usize>> for [T] { + #[inline] + fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut [T] { + self.index_mut(0...index.end) + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Common traits +//////////////////////////////////////////////////////////////////////////////// + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Default for &'a [T] { + fn default() -> &'a [T] { &[] } +} + +#[stable(feature = "mut_slice_default", since = "1.5.0")] +impl<'a, T> Default for &'a mut [T] { + fn default() -> &'a mut [T] { &mut [] } +} + +// +// Iterators +// + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> IntoIterator for &'a [T] { + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> IntoIterator for &'a mut [T] { + type Item = &'a mut T; + type IntoIter = IterMut<'a, T>; + + fn into_iter(self) -> IterMut<'a, T> { + self.iter_mut() + } +} + +#[inline(always)] +fn size_from_ptr<T>(_: *const T) -> usize { + mem::size_of::<T>() +} + +// The shared definition of the `Iter` and `IterMut` iterators +macro_rules! iterator { + (struct $name:ident -> $ptr:ty, $elem:ty) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T> Iterator for $name<'a, T> { + type Item = $elem; + + #[inline] + fn next(&mut self) -> Option<$elem> { + // could be implemented with slices, but this avoids bounds checks + unsafe { + if mem::size_of::<T>() != 0 { + assume(!self.ptr.is_null()); + assume(!self.end.is_null()); + } + if self.ptr == self.end { + None + } else { + let old = self.ptr; + self.ptr = slice_offset!(self.ptr, 1); + Some(slice_ref!(old)) + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let diff = (self.end as usize).wrapping_sub(self.ptr as usize); + let size = mem::size_of::<T>(); + let exact = diff / (if size == 0 {1} else {size}); + (exact, Some(exact)) + } + + #[inline] + fn count(self) -> usize { + self.size_hint().0 + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<$elem> { + // Call helper method. Can't put the definition here because mut versus const. + self.iter_nth(n) + } + + #[inline] + fn last(mut self) -> Option<$elem> { + self.next_back() + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T> DoubleEndedIterator for $name<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<$elem> { + // could be implemented with slices, but this avoids bounds checks + unsafe { + if mem::size_of::<T>() != 0 { + assume(!self.ptr.is_null()); + assume(!self.end.is_null()); + } + if self.end == self.ptr { + None + } else { + self.end = slice_offset!(self.end, -1); + Some(slice_ref!(self.end)) + } + } + } + } + } +} + +macro_rules! make_slice { + ($start: expr, $end: expr) => {{ + let start = $start; + let diff = ($end as usize).wrapping_sub(start as usize); + if size_from_ptr(start) == 0 { + // use a non-null pointer value + unsafe { from_raw_parts(1 as *const _, diff) } + } else { + let len = diff / size_from_ptr(start); + unsafe { from_raw_parts(start, len) } + } + }} +} + +macro_rules! make_mut_slice { + ($start: expr, $end: expr) => {{ + let start = $start; + let diff = ($end as usize).wrapping_sub(start as usize); + if size_from_ptr(start) == 0 { + // use a non-null pointer value + unsafe { from_raw_parts_mut(1 as *mut _, diff) } + } else { + let len = diff / size_from_ptr(start); + unsafe { from_raw_parts_mut(start, len) } + } + }} +} + +/// Immutable slice iterator +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Iter<'a, T: 'a> { + ptr: *const T, + end: *const T, + _marker: marker::PhantomData<&'a T>, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("Iter") + .field(&self.as_slice()) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {} +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<'a, T: Sync> Send for Iter<'a, T> {} + +impl<'a, T> Iter<'a, T> { + /// View the underlying data as a subslice of the original data. + /// + /// This has the same lifetime as the original slice, and so the + /// iterator can continue to be used while this exists. + #[stable(feature = "iter_to_slice", since = "1.4.0")] + pub fn as_slice(&self) -> &'a [T] { + make_slice!(self.ptr, self.end) + } + + // Helper function for Iter::nth + fn iter_nth(&mut self, n: usize) -> Option<&'a T> { + match self.as_slice().get(n) { + Some(elem_ref) => unsafe { + self.ptr = slice_offset!(self.ptr, (n as isize).wrapping_add(1)); + Some(elem_ref) + }, + None => { + self.ptr = self.end; + None + } + } + } +} + +iterator!{struct Iter -> *const T, &'a T} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> ExactSizeIterator for Iter<'a, T> {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Clone for Iter<'a, T> { + fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } } +} + +/// Mutable slice iterator. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct IterMut<'a, T: 'a> { + ptr: *mut T, + end: *mut T, + _marker: marker::PhantomData<&'a mut T>, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("IterMut") + .field(&make_slice!(self.ptr, self.end)) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {} +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<'a, T: Send> Send for IterMut<'a, T> {} + +impl<'a, T> IterMut<'a, T> { + /// View the underlying data as a subslice of the original data. + /// + /// To avoid creating `&mut` references that alias, this is forced + /// to consume the iterator. Consider using the `Slice` and + /// `SliceMut` implementations for obtaining slices with more + /// restricted lifetimes that do not consume the iterator. + #[stable(feature = "iter_to_slice", since = "1.4.0")] + pub fn into_slice(self) -> &'a mut [T] { + make_mut_slice!(self.ptr, self.end) + } + + // Helper function for IterMut::nth + fn iter_nth(&mut self, n: usize) -> Option<&'a mut T> { + match make_mut_slice!(self.ptr, self.end).get_mut(n) { + Some(elem_ref) => unsafe { + self.ptr = slice_offset!(self.ptr, (n as isize).wrapping_add(1)); + Some(elem_ref) + }, + None => { + self.ptr = self.end; + None + } + } + } +} + +iterator!{struct IterMut -> *mut T, &'a mut T} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} + +/// An internal abstraction over the splitting iterators, so that +/// splitn, splitn_mut etc can be implemented once. +#[doc(hidden)] +trait SplitIter: DoubleEndedIterator { + /// Mark the underlying iterator as complete, extracting the remaining + /// portion of the slice. + fn finish(&mut self) -> Option<Self::Item>; +} + +/// An iterator over subslices separated by elements that match a predicate +/// function. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Split<'a, T:'a, P> where P: FnMut(&T) -> bool { + v: &'a [T], + pred: P, + finished: bool +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for Split<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Split") + .field("v", &self.v) + .field("finished", &self.finished) + .finish() + } +} + +// FIXME(#19839) Remove in favor of `#[derive(Clone)]` +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, P> Clone for Split<'a, T, P> where P: Clone + FnMut(&T) -> bool { + fn clone(&self) -> Split<'a, T, P> { + Split { + v: self.v, + pred: self.pred.clone(), + finished: self.finished, + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool { + type Item = &'a [T]; + + #[inline] + fn next(&mut self) -> Option<&'a [T]> { + if self.finished { return None; } + + match self.v.iter().position(|x| (self.pred)(x)) { + None => self.finish(), + Some(idx) => { + let ret = Some(&self.v[..idx]); + self.v = &self.v[idx + 1..]; + ret + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + if self.finished { + (0, Some(0)) + } else { + (1, Some(self.v.len() + 1)) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P> where P: FnMut(&T) -> bool { + #[inline] + fn next_back(&mut self) -> Option<&'a [T]> { + if self.finished { return None; } + + match self.v.iter().rposition(|x| (self.pred)(x)) { + None => self.finish(), + Some(idx) => { + let ret = Some(&self.v[idx + 1..]); + self.v = &self.v[..idx]; + ret + } + } + } +} + +impl<'a, T, P> SplitIter for Split<'a, T, P> where P: FnMut(&T) -> bool { + #[inline] + fn finish(&mut self) -> Option<&'a [T]> { + if self.finished { None } else { self.finished = true; Some(self.v) } + } +} + +/// An iterator over the subslices of the vector which are separated +/// by elements that match `pred`. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct SplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool { + v: &'a mut [T], + pred: P, + finished: bool +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SplitMut") + .field("v", &self.v) + .field("finished", &self.finished) + .finish() + } +} + +impl<'a, T, P> SplitIter for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { + #[inline] + fn finish(&mut self) -> Option<&'a mut [T]> { + if self.finished { + None + } else { + self.finished = true; + Some(mem::replace(&mut self.v, &mut [])) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { + type Item = &'a mut [T]; + + #[inline] + fn next(&mut self) -> Option<&'a mut [T]> { + if self.finished { return None; } + + let idx_opt = { // work around borrowck limitations + let pred = &mut self.pred; + self.v.iter().position(|x| (*pred)(x)) + }; + match idx_opt { + None => self.finish(), + Some(idx) => { + let tmp = mem::replace(&mut self.v, &mut []); + let (head, tail) = tmp.split_at_mut(idx); + self.v = &mut tail[1..]; + Some(head) + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + if self.finished { + (0, Some(0)) + } else { + // if the predicate doesn't match anything, we yield one slice + // if it matches every element, we yield len+1 empty slices. + (1, Some(self.v.len() + 1)) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where + P: FnMut(&T) -> bool, +{ + #[inline] + fn next_back(&mut self) -> Option<&'a mut [T]> { + if self.finished { return None; } + + let idx_opt = { // work around borrowck limitations + let pred = &mut self.pred; + self.v.iter().rposition(|x| (*pred)(x)) + }; + match idx_opt { + None => self.finish(), + Some(idx) => { + let tmp = mem::replace(&mut self.v, &mut []); + let (head, tail) = tmp.split_at_mut(idx); + self.v = head; + Some(&mut tail[1..]) + } + } + } +} + +/// An private iterator over subslices separated by elements that +/// match a predicate function, splitting at most a fixed number of +/// times. +#[derive(Debug)] +struct GenericSplitN<I> { + iter: I, + count: usize, + invert: bool +} + +impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> { + type Item = T; + + #[inline] + fn next(&mut self) -> Option<T> { + match self.count { + 0 => None, + 1 => { self.count -= 1; self.iter.finish() } + _ => { + self.count -= 1; + if self.invert {self.iter.next_back()} else {self.iter.next()} + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (lower, upper_opt) = self.iter.size_hint(); + (lower, upper_opt.map(|upper| cmp::min(self.count, upper))) + } +} + +/// An iterator over subslices separated by elements that match a predicate +/// function, limited to a given number of splits. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN<Split<'a, T, P>> +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitN<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SplitN") + .field("inner", &self.inner) + .finish() + } +} + +/// An iterator over subslices separated by elements that match a +/// predicate function, limited to a given number of splits, starting +/// from the end of the slice. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN<Split<'a, T, P>> +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitN<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("RSplitN") + .field("inner", &self.inner) + .finish() + } +} + +/// An iterator over subslices separated by elements that match a predicate +/// function, limited to a given number of splits. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN<SplitMut<'a, T, P>> +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitNMut<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SplitNMut") + .field("inner", &self.inner) + .finish() + } +} + +/// An iterator over subslices separated by elements that match a +/// predicate function, limited to a given number of splits, starting +/// from the end of the slice. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN<SplitMut<'a, T, P>> +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitNMut<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("RSplitNMut") + .field("inner", &self.inner) + .finish() + } +} + +macro_rules! forward_iterator { + ($name:ident: $elem:ident, $iter_of:ty) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, $elem, P> Iterator for $name<'a, $elem, P> where + P: FnMut(&T) -> bool + { + type Item = $iter_of; + + #[inline] + fn next(&mut self) -> Option<$iter_of> { + self.inner.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.inner.size_hint() + } + } + } +} + +forward_iterator! { SplitN: T, &'a [T] } +forward_iterator! { RSplitN: T, &'a [T] } +forward_iterator! { SplitNMut: T, &'a mut [T] } +forward_iterator! { RSplitNMut: T, &'a mut [T] } + +/// An iterator over overlapping subslices of length `size`. +#[derive(Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Windows<'a, T:'a> { + v: &'a [T], + size: usize +} + +// FIXME(#19839) Remove in favor of `#[derive(Clone)]` +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Clone for Windows<'a, T> { + fn clone(&self) -> Windows<'a, T> { + Windows { + v: self.v, + size: self.size, + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Iterator for Windows<'a, T> { + type Item = &'a [T]; + + #[inline] + fn next(&mut self) -> Option<&'a [T]> { + if self.size > self.v.len() { + None + } else { + let ret = Some(&self.v[..self.size]); + self.v = &self.v[1..]; + ret + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + if self.size > self.v.len() { + (0, Some(0)) + } else { + let size = self.v.len() - self.size + 1; + (size, Some(size)) + } + } + + #[inline] + fn count(self) -> usize { + self.size_hint().0 + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<Self::Item> { + let (end, overflow) = self.size.overflowing_add(n); + if end > self.v.len() || overflow { + self.v = &[]; + None + } else { + let nth = &self.v[n..end]; + self.v = &self.v[n+1..]; + Some(nth) + } + } + + #[inline] + fn last(self) -> Option<Self::Item> { + if self.size > self.v.len() { + None + } else { + let start = self.v.len() - self.size; + Some(&self.v[start..]) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> DoubleEndedIterator for Windows<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a [T]> { + if self.size > self.v.len() { + None + } else { + let ret = Some(&self.v[self.v.len()-self.size..]); + self.v = &self.v[..self.v.len()-1]; + ret + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> ExactSizeIterator for Windows<'a, T> {} + +/// An iterator over a slice in (non-overlapping) chunks (`size` elements at a +/// time). +/// +/// When the slice len is not evenly divided by the chunk size, the last slice +/// of the iteration will be the remainder. +#[derive(Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Chunks<'a, T:'a> { + v: &'a [T], + size: usize +} + +// FIXME(#19839) Remove in favor of `#[derive(Clone)]` +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Clone for Chunks<'a, T> { + fn clone(&self) -> Chunks<'a, T> { + Chunks { + v: self.v, + size: self.size, + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Iterator for Chunks<'a, T> { + type Item = &'a [T]; + + #[inline] + fn next(&mut self) -> Option<&'a [T]> { + if self.v.is_empty() { + None + } else { + let chunksz = cmp::min(self.v.len(), self.size); + let (fst, snd) = self.v.split_at(chunksz); + self.v = snd; + Some(fst) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + if self.v.is_empty() { + (0, Some(0)) + } else { + let n = self.v.len() / self.size; + let rem = self.v.len() % self.size; + let n = if rem > 0 { n+1 } else { n }; + (n, Some(n)) + } + } + + #[inline] + fn count(self) -> usize { + self.size_hint().0 + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<Self::Item> { + let (start, overflow) = n.overflowing_mul(self.size); + if start >= self.v.len() || overflow { + self.v = &[]; + None + } else { + let end = match start.checked_add(self.size) { + Some(sum) => cmp::min(self.v.len(), sum), + None => self.v.len(), + }; + let nth = &self.v[start..end]; + self.v = &self.v[end..]; + Some(nth) + } + } + + #[inline] + fn last(self) -> Option<Self::Item> { + if self.v.is_empty() { + None + } else { + let start = (self.v.len() - 1) / self.size * self.size; + Some(&self.v[start..]) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a [T]> { + if self.v.is_empty() { + None + } else { + let remainder = self.v.len() % self.size; + let chunksz = if remainder != 0 { remainder } else { self.size }; + let (fst, snd) = self.v.split_at(self.v.len() - chunksz); + self.v = fst; + Some(snd) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> ExactSizeIterator for Chunks<'a, T> {} + +/// An iterator over a slice in (non-overlapping) mutable chunks (`size` +/// elements at a time). When the slice len is not evenly divided by the chunk +/// size, the last slice of the iteration will be the remainder. +#[derive(Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct ChunksMut<'a, T:'a> { + v: &'a mut [T], + chunk_size: usize +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> Iterator for ChunksMut<'a, T> { + type Item = &'a mut [T]; + + #[inline] + fn next(&mut self) -> Option<&'a mut [T]> { + if self.v.is_empty() { + None + } else { + let sz = cmp::min(self.v.len(), self.chunk_size); + let tmp = mem::replace(&mut self.v, &mut []); + let (head, tail) = tmp.split_at_mut(sz); + self.v = tail; + Some(head) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + if self.v.is_empty() { + (0, Some(0)) + } else { + let n = self.v.len() / self.chunk_size; + let rem = self.v.len() % self.chunk_size; + let n = if rem > 0 { n + 1 } else { n }; + (n, Some(n)) + } + } + + #[inline] + fn count(self) -> usize { + self.size_hint().0 + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<&'a mut [T]> { + let (start, overflow) = n.overflowing_mul(self.chunk_size); + if start >= self.v.len() || overflow { + self.v = &mut []; + None + } else { + let end = match start.checked_add(self.chunk_size) { + Some(sum) => cmp::min(self.v.len(), sum), + None => self.v.len(), + }; + let tmp = mem::replace(&mut self.v, &mut []); + let (head, tail) = tmp.split_at_mut(end); + let (_, nth) = head.split_at_mut(start); + self.v = tail; + Some(nth) + } + } + + #[inline] + fn last(self) -> Option<Self::Item> { + if self.v.is_empty() { + None + } else { + let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size; + Some(&mut self.v[start..]) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a mut [T]> { + if self.v.is_empty() { + None + } else { + let remainder = self.v.len() % self.chunk_size; + let sz = if remainder != 0 { remainder } else { self.chunk_size }; + let tmp = mem::replace(&mut self.v, &mut []); + let tmp_len = tmp.len(); + let (head, tail) = tmp.split_at_mut(tmp_len - sz); + self.v = head; + Some(tail) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {} + +// +// Free functions +// + +/// Forms a slice from a pointer and a length. +/// +/// The `len` argument is the number of **elements**, not the number of bytes. +/// +/// # Safety +/// +/// This function is unsafe as there is no guarantee that the given pointer is +/// valid for `len` elements, nor whether the lifetime inferred is a suitable +/// lifetime for the returned slice. +/// +/// `p` must be non-null, even for zero-length slices. +/// +/// # Caveat +/// +/// The lifetime for the returned slice is inferred from its usage. To +/// prevent accidental misuse, it's suggested to tie the lifetime to whichever +/// source lifetime is safe in the context, such as by providing a helper +/// function taking the lifetime of a host value for the slice, or by explicit +/// annotation. +/// +/// # Examples +/// +/// ``` +/// use std::slice; +/// +/// // manifest a slice out of thin air! +/// let ptr = 0x1234 as *const usize; +/// let amt = 10; +/// unsafe { +/// let slice = slice::from_raw_parts(ptr, amt); +/// } +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] { + mem::transmute(RawSlice { data: p, len: len }) +} + +/// Performs the same functionality as `from_raw_parts`, except that a mutable +/// slice is returned. +/// +/// This function is unsafe for the same reasons as `from_raw_parts`, as well +/// as not being able to provide a non-aliasing guarantee of the returned +/// mutable slice. +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] { + mem::transmute(RawSlice { data: p, len: len }) +} + +// +// Comparison traits +// + +extern { + /// Call implementation provided memcmp + /// + /// Interprets the data as u8. + /// + /// Return 0 for equal, < 0 for less than and > 0 for greater + /// than. + // FIXME(#32610): Return type should be c_int + fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> { + fn eq(&self, other: &[B]) -> bool { + SlicePartialEq::equal(self, other) + } + + fn ne(&self, other: &[B]) -> bool { + SlicePartialEq::not_equal(self, other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: Eq> Eq for [T] {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: Ord> Ord for [T] { + fn cmp(&self, other: &[T]) -> Ordering { + SliceOrd::compare(self, other) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T: PartialOrd> PartialOrd for [T] { + fn partial_cmp(&self, other: &[T]) -> Option<Ordering> { + SlicePartialOrd::partial_compare(self, other) + } +} + +#[doc(hidden)] +// intermediate trait for specialization of slice's PartialEq +trait SlicePartialEq<B> { + fn equal(&self, other: &[B]) -> bool; + fn not_equal(&self, other: &[B]) -> bool; +} + +// Generic slice equality +impl<A, B> SlicePartialEq<B> for [A] + where A: PartialEq<B> +{ + default fn equal(&self, other: &[B]) -> bool { + if self.len() != other.len() { + return false; + } + + for i in 0..self.len() { + if !self[i].eq(&other[i]) { + return false; + } + } + + true + } + + default fn not_equal(&self, other: &[B]) -> bool { + if self.len() != other.len() { + return true; + } + + for i in 0..self.len() { + if self[i].ne(&other[i]) { + return true; + } + } + + false + } +} + +// Use memcmp for bytewise equality when the types allow +impl<A> SlicePartialEq<A> for [A] + where A: PartialEq<A> + BytewiseEquality +{ + fn equal(&self, other: &[A]) -> bool { + if self.len() != other.len() { + return false; + } + unsafe { + let size = mem::size_of_val(self); + memcmp(self.as_ptr() as *const u8, + other.as_ptr() as *const u8, size) == 0 + } + } + + fn not_equal(&self, other: &[A]) -> bool { + !self.equal(other) + } +} + +#[doc(hidden)] +// intermediate trait for specialization of slice's PartialOrd +trait SlicePartialOrd<B> { + fn partial_compare(&self, other: &[B]) -> Option<Ordering>; +} + +impl<A> SlicePartialOrd<A> for [A] + where A: PartialOrd +{ + default fn partial_compare(&self, other: &[A]) -> Option<Ordering> { + let l = cmp::min(self.len(), other.len()); + + // Slice to the loop iteration range to enable bound check + // elimination in the compiler + let lhs = &self[..l]; + let rhs = &other[..l]; + + for i in 0..l { + match lhs[i].partial_cmp(&rhs[i]) { + Some(Ordering::Equal) => (), + non_eq => return non_eq, + } + } + + self.len().partial_cmp(&other.len()) + } +} + +impl SlicePartialOrd<u8> for [u8] { + #[inline] + fn partial_compare(&self, other: &[u8]) -> Option<Ordering> { + Some(SliceOrd::compare(self, other)) + } +} + +#[doc(hidden)] +// intermediate trait for specialization of slice's Ord +trait SliceOrd<B> { + fn compare(&self, other: &[B]) -> Ordering; +} + +impl<A> SliceOrd<A> for [A] + where A: Ord +{ + default fn compare(&self, other: &[A]) -> Ordering { + let l = cmp::min(self.len(), other.len()); + + // Slice to the loop iteration range to enable bound check + // elimination in the compiler + let lhs = &self[..l]; + let rhs = &other[..l]; + + for i in 0..l { + match lhs[i].cmp(&rhs[i]) { + Ordering::Equal => (), + non_eq => return non_eq, + } + } + + self.len().cmp(&other.len()) + } +} + +// memcmp compares a sequence of unsigned bytes lexicographically. +// this matches the order we want for [u8], but no others (not even [i8]). +impl SliceOrd<u8> for [u8] { + #[inline] + fn compare(&self, other: &[u8]) -> Ordering { + let order = unsafe { + memcmp(self.as_ptr(), other.as_ptr(), + cmp::min(self.len(), other.len())) + }; + if order == 0 { + self.len().cmp(&other.len()) + } else if order < 0 { + Less + } else { + Greater + } + } +} + +#[doc(hidden)] +/// Trait implemented for types that can be compared for equality using +/// their bytewise representation +trait BytewiseEquality { } + +macro_rules! impl_marker_for { + ($traitname:ident, $($ty:ty)*) => { + $( + impl $traitname for $ty { } + )* + } +} + +impl_marker_for!(BytewiseEquality, + u8 i8 u16 i16 u32 i32 u64 i64 usize isize char bool); + diff --git a/libcore/str/mod.rs b/libcore/str/mod.rs new file mode 100644 index 0000000..305546d --- /dev/null +++ b/libcore/str/mod.rs @@ -0,0 +1,2102 @@ +// Copyright 2012-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. + +//! String manipulation +//! +//! For more details, see std::str + +#![stable(feature = "rust1", since = "1.0.0")] + +use self::pattern::Pattern; +use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; + +use char::{self, CharExt}; +use clone::Clone; +use cmp::Eq; +use convert::AsRef; +use default::Default; +use fmt; +use iter::ExactSizeIterator; +use iter::{Map, Cloned, Iterator, DoubleEndedIterator}; +use marker::Sized; +use mem; +use ops::{Fn, FnMut, FnOnce}; +use option::Option::{self, None, Some}; +use raw::{Repr, Slice}; +use result::Result::{self, Ok, Err}; +use slice::{self, SliceExt}; + +pub mod pattern; + +/// A trait to abstract the idea of creating a new instance of a type from a +/// string. +/// +/// `FromStr`'s [`from_str()`] method is often used implicitly, through +/// [`str`]'s [`parse()`] method. See [`parse()`]'s documentation for examples. +/// +/// [`from_str()`]: #tymethod.from_str +/// [`str`]: ../../std/primitive.str.html +/// [`parse()`]: ../../std/primitive.str.html#method.parse +#[stable(feature = "rust1", since = "1.0.0")] +pub trait FromStr: Sized { + /// The associated error which can be returned from parsing. + #[stable(feature = "rust1", since = "1.0.0")] + type Err; + + /// Parses a string `s` to return a value of this type. + /// + /// If parsing succeeds, return the value inside `Ok`, otherwise + /// when the string is ill-formatted return an error specific to the + /// inside `Err`. The error type is specific to implementation of the trait. + /// + /// # Examples + /// + /// Basic usage with [`i32`][ithirtytwo], a type that implements `FromStr`: + /// + /// [ithirtytwo]: ../../std/primitive.i32.html + /// + /// ``` + /// use std::str::FromStr; + /// + /// let s = "5"; + /// let x = i32::from_str(s).unwrap(); + /// + /// assert_eq!(5, x); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn from_str(s: &str) -> Result<Self, Self::Err>; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl FromStr for bool { + type Err = ParseBoolError; + + /// Parse a `bool` from a string. + /// + /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not + /// actually be parseable. + /// + /// # Examples + /// + /// ``` + /// use std::str::FromStr; + /// + /// assert_eq!(FromStr::from_str("true"), Ok(true)); + /// assert_eq!(FromStr::from_str("false"), Ok(false)); + /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err()); + /// ``` + /// + /// Note, in many cases, the `.parse()` method on `str` is more proper. + /// + /// ``` + /// assert_eq!("true".parse(), Ok(true)); + /// assert_eq!("false".parse(), Ok(false)); + /// assert!("not even a boolean".parse::<bool>().is_err()); + /// ``` + #[inline] + fn from_str(s: &str) -> Result<bool, ParseBoolError> { + match s { + "true" => Ok(true), + "false" => Ok(false), + _ => Err(ParseBoolError { _priv: () }), + } + } +} + +/// An error returned when parsing a `bool` from a string fails. +#[derive(Debug, Clone, PartialEq)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct ParseBoolError { _priv: () } + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Display for ParseBoolError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + "provided string was not `true` or `false`".fmt(f) + } +} + +/* +Section: Creating a string +*/ + +/// Errors which can occur when attempting to interpret a sequence of `u8` +/// as a string. +/// +/// As such, the `from_utf8` family of functions and methods for both `String`s +/// and `&str`s make use of this error, for example. +#[derive(Copy, Eq, PartialEq, Clone, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Utf8Error { + valid_up_to: usize, +} + +impl Utf8Error { + /// Returns the index in the given string up to which valid UTF-8 was + /// verified. + /// + /// It is the maximum index such that `from_utf8(input[..index])` + /// would return `Some(_)`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::str; + /// + /// // some invalid bytes, in a vector + /// let sparkle_heart = vec![0, 159, 146, 150]; + /// + /// // std::str::from_utf8 returns a Utf8Error + /// let error = str::from_utf8(&sparkle_heart).unwrap_err(); + /// + /// // the second byte is invalid here + /// assert_eq!(1, error.valid_up_to()); + /// ``` + #[stable(feature = "utf8_error", since = "1.5.0")] + pub fn valid_up_to(&self) -> usize { self.valid_up_to } +} + +/// Converts a slice of bytes to a string slice. +/// +/// A string slice (`&str`) is made of bytes (`u8`), and a byte slice (`&[u8]`) +/// is made of bytes, so this function converts between the two. Not all byte +/// slices are valid string slices, however: `&str` requires that it is valid +/// UTF-8. `from_utf8()` checks to ensure that the bytes are valid UTF-8, and +/// then does the conversion. +/// +/// If you are sure that the byte slice is valid UTF-8, and you don't want to +/// incur the overhead of the validity check, there is an unsafe version of +/// this function, [`from_utf8_unchecked()`][fromutf8u], which has the same +/// behavior but skips the check. +/// +/// [fromutf8u]: fn.from_utf8_unchecked.html +/// +/// If you need a `String` instead of a `&str`, consider +/// [`String::from_utf8()`][string]. +/// +/// [string]: ../../std/string/struct.String.html#method.from_utf8 +/// +/// Because you can stack-allocate a `[u8; N]`, and you can take a `&[u8]` of +/// it, this function is one way to have a stack-allocated string. There is +/// an example of this in the examples section below. +/// +/// # Errors +/// +/// Returns `Err` if the slice is not UTF-8 with a description as to why the +/// provided slice is not UTF-8. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::str; +/// +/// // some bytes, in a vector +/// let sparkle_heart = vec![240, 159, 146, 150]; +/// +/// // We know these bytes are valid, so just use `unwrap()`. +/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap(); +/// +/// assert_eq!("💖", sparkle_heart); +/// ``` +/// +/// Incorrect bytes: +/// +/// ``` +/// use std::str; +/// +/// // some invalid bytes, in a vector +/// let sparkle_heart = vec![0, 159, 146, 150]; +/// +/// assert!(str::from_utf8(&sparkle_heart).is_err()); +/// ``` +/// +/// See the docs for [`Utf8Error`][error] for more details on the kinds of +/// errors that can be returned. +/// +/// [error]: struct.Utf8Error.html +/// +/// A "stack allocated string": +/// +/// ``` +/// use std::str; +/// +/// // some bytes, in a stack-allocated array +/// let sparkle_heart = [240, 159, 146, 150]; +/// +/// // We know these bytes are valid, so just use `unwrap()`. +/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap(); +/// +/// assert_eq!("💖", sparkle_heart); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { + run_utf8_validation(v)?; + Ok(unsafe { from_utf8_unchecked(v) }) +} + +/// Forms a str from a pointer and a length. +/// +/// The `len` argument is the number of bytes in the string. +/// +/// # Safety +/// +/// This function is unsafe as there is no guarantee that the given pointer is +/// valid for `len` bytes, nor whether the lifetime inferred is a suitable +/// lifetime for the returned str. +/// +/// The data must be valid UTF-8 +/// +/// `p` must be non-null, even for zero-length str. +/// +/// # Caveat +/// +/// The lifetime for the returned str is inferred from its usage. To +/// prevent accidental misuse, it's suggested to tie the lifetime to whichever +/// source lifetime is safe in the context, such as by providing a helper +/// function taking the lifetime of a host value for the str, or by explicit +/// annotation. +/// Performs the same functionality as `from_raw_parts`, except that a mutable +/// str is returned. +/// +unsafe fn from_raw_parts_mut<'a>(p: *mut u8, len: usize) -> &'a mut str { + mem::transmute::<&mut [u8], &mut str>(slice::from_raw_parts_mut(p, len)) +} + +/// Converts a slice of bytes to a string slice without checking +/// that the string contains valid UTF-8. +/// +/// See the safe version, [`from_utf8()`][fromutf8], for more information. +/// +/// [fromutf8]: fn.from_utf8.html +/// +/// # Safety +/// +/// This function is unsafe because it does not check that the bytes passed to +/// it are valid UTF-8. If this constraint is violated, undefined behavior +/// results, as the rest of Rust assumes that `&str`s are valid UTF-8. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::str; +/// +/// // some bytes, in a vector +/// let sparkle_heart = vec![240, 159, 146, 150]; +/// +/// let sparkle_heart = unsafe { +/// str::from_utf8_unchecked(&sparkle_heart) +/// }; +/// +/// assert_eq!("💖", sparkle_heart); +/// ``` +#[inline(always)] +#[stable(feature = "rust1", since = "1.0.0")] +pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { + mem::transmute(v) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Display for Utf8Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "invalid utf-8: invalid byte near index {}", self.valid_up_to) + } +} + +/* +Section: Iterators +*/ + +/// Iterator for the char (representing *Unicode Scalar Values*) of a string +/// +/// Created with the method [`chars()`]. +/// +/// [`chars()`]: ../../std/primitive.str.html#method.chars +#[derive(Clone, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Chars<'a> { + iter: slice::Iter<'a, u8> +} + +/// Return the initial codepoint accumulator for the first byte. +/// The first byte is special, only want bottom 5 bits for width 2, 4 bits +/// for width 3, and 3 bits for width 4. +#[inline] +fn utf8_first_byte(byte: u8, width: u32) -> u32 { (byte & (0x7F >> width)) as u32 } + +/// Return the value of `ch` updated with continuation byte `byte`. +#[inline] +fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 { (ch << 6) | (byte & CONT_MASK) as u32 } + +/// Checks whether the byte is a UTF-8 continuation byte (i.e. starts with the +/// bits `10`). +#[inline] +fn utf8_is_cont_byte(byte: u8) -> bool { (byte & !CONT_MASK) == TAG_CONT_U8 } + +#[inline] +fn unwrap_or_0(opt: Option<&u8>) -> u8 { + match opt { + Some(&byte) => byte, + None => 0, + } +} + +/// Reads the next code point out of a byte iterator (assuming a +/// UTF-8-like encoding). +#[unstable(feature = "str_internals", issue = "0")] +#[inline] +pub fn next_code_point(bytes: &mut slice::Iter<u8>) -> Option<u32> { + // Decode UTF-8 + let x = match bytes.next() { + None => return None, + Some(&next_byte) if next_byte < 128 => return Some(next_byte as u32), + Some(&next_byte) => next_byte, + }; + + // Multibyte case follows + // Decode from a byte combination out of: [[[x y] z] w] + // NOTE: Performance is sensitive to the exact formulation here + let init = utf8_first_byte(x, 2); + let y = unwrap_or_0(bytes.next()); + let mut ch = utf8_acc_cont_byte(init, y); + if x >= 0xE0 { + // [[x y z] w] case + // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid + let z = unwrap_or_0(bytes.next()); + let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z); + ch = init << 12 | y_z; + if x >= 0xF0 { + // [x y z w] case + // use only the lower 3 bits of `init` + let w = unwrap_or_0(bytes.next()); + ch = (init & 7) << 18 | utf8_acc_cont_byte(y_z, w); + } + } + + Some(ch) +} + +/// Reads the last code point out of a byte iterator (assuming a +/// UTF-8-like encoding). +#[inline] +fn next_code_point_reverse(bytes: &mut slice::Iter<u8>) -> Option<u32> { + // Decode UTF-8 + let w = match bytes.next_back() { + None => return None, + Some(&next_byte) if next_byte < 128 => return Some(next_byte as u32), + Some(&back_byte) => back_byte, + }; + + // Multibyte case follows + // Decode from a byte combination out of: [x [y [z w]]] + let mut ch; + let z = unwrap_or_0(bytes.next_back()); + ch = utf8_first_byte(z, 2); + if utf8_is_cont_byte(z) { + let y = unwrap_or_0(bytes.next_back()); + ch = utf8_first_byte(y, 3); + if utf8_is_cont_byte(y) { + let x = unwrap_or_0(bytes.next_back()); + ch = utf8_first_byte(x, 4); + ch = utf8_acc_cont_byte(ch, y); + } + ch = utf8_acc_cont_byte(ch, z); + } + ch = utf8_acc_cont_byte(ch, w); + + Some(ch) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> Iterator for Chars<'a> { + type Item = char; + + #[inline] + fn next(&mut self) -> Option<char> { + next_code_point(&mut self.iter).map(|ch| { + // str invariant says `ch` is a valid Unicode Scalar Value + unsafe { + char::from_u32_unchecked(ch) + } + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let (len, _) = self.iter.size_hint(); + // `(len + 3)` can't overflow, because we know that the `slice::Iter` + // belongs to a slice in memory which has a maximum length of + // `isize::MAX` (that's well below `usize::MAX`). + ((len + 3) / 4, Some(len)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> DoubleEndedIterator for Chars<'a> { + #[inline] + fn next_back(&mut self) -> Option<char> { + next_code_point_reverse(&mut self.iter).map(|ch| { + // str invariant says `ch` is a valid Unicode Scalar Value + unsafe { + char::from_u32_unchecked(ch) + } + }) + } +} + +impl<'a> Chars<'a> { + /// View the underlying data as a subslice of the original data. + /// + /// This has the same lifetime as the original slice, and so the + /// iterator can continue to be used while this exists. + #[stable(feature = "iter_to_slice", since = "1.4.0")] + #[inline] + pub fn as_str(&self) -> &'a str { + unsafe { from_utf8_unchecked(self.iter.as_slice()) } + } +} + +/// Iterator for a string's characters and their byte offsets. +#[derive(Clone, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct CharIndices<'a> { + front_offset: usize, + iter: Chars<'a>, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> Iterator for CharIndices<'a> { + type Item = (usize, char); + + #[inline] + fn next(&mut self) -> Option<(usize, char)> { + let (pre_len, _) = self.iter.iter.size_hint(); + match self.iter.next() { + None => None, + Some(ch) => { + let index = self.front_offset; + let (len, _) = self.iter.iter.size_hint(); + self.front_offset += pre_len - len; + Some((index, ch)) + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> DoubleEndedIterator for CharIndices<'a> { + #[inline] + fn next_back(&mut self) -> Option<(usize, char)> { + match self.iter.next_back() { + None => None, + Some(ch) => { + let (len, _) = self.iter.iter.size_hint(); + let index = self.front_offset + len; + Some((index, ch)) + } + } + } +} + +impl<'a> CharIndices<'a> { + /// View the underlying data as a subslice of the original data. + /// + /// This has the same lifetime as the original slice, and so the + /// iterator can continue to be used while this exists. + #[stable(feature = "iter_to_slice", since = "1.4.0")] + #[inline] + pub fn as_str(&self) -> &'a str { + self.iter.as_str() + } +} + +/// External iterator for a string's bytes. +/// Use with the `std::iter` module. +/// +/// Created with the method [`bytes()`]. +/// +/// [`bytes()`]: ../../std/primitive.str.html#method.bytes +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone, Debug)] +pub struct Bytes<'a>(Cloned<slice::Iter<'a, u8>>); + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> Iterator for Bytes<'a> { + type Item = u8; + + #[inline] + fn next(&mut self) -> Option<u8> { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.0.size_hint() + } + + #[inline] + fn count(self) -> usize { + self.0.count() + } + + #[inline] + fn last(self) -> Option<Self::Item> { + self.0.last() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<Self::Item> { + self.0.nth(n) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> DoubleEndedIterator for Bytes<'a> { + #[inline] + fn next_back(&mut self) -> Option<u8> { + self.0.next_back() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> ExactSizeIterator for Bytes<'a> { + #[inline] + fn len(&self) -> usize { + self.0.len() + } +} + +/// This macro generates a Clone impl for string pattern API +/// wrapper types of the form X<'a, P> +macro_rules! derive_pattern_clone { + (clone $t:ident with |$s:ident| $e:expr) => { + impl<'a, P: Pattern<'a>> Clone for $t<'a, P> + where P::Searcher: Clone + { + fn clone(&self) -> Self { + let $s = self; + $e + } + } + } +} + +/// This macro generates two public iterator structs +/// wrapping a private internal one that makes use of the `Pattern` API. +/// +/// For all patterns `P: Pattern<'a>` the following items will be +/// generated (generics omitted): +/// +/// struct $forward_iterator($internal_iterator); +/// struct $reverse_iterator($internal_iterator); +/// +/// impl Iterator for $forward_iterator +/// { /* internal ends up calling Searcher::next_match() */ } +/// +/// impl DoubleEndedIterator for $forward_iterator +/// where P::Searcher: DoubleEndedSearcher +/// { /* internal ends up calling Searcher::next_match_back() */ } +/// +/// impl Iterator for $reverse_iterator +/// where P::Searcher: ReverseSearcher +/// { /* internal ends up calling Searcher::next_match_back() */ } +/// +/// impl DoubleEndedIterator for $reverse_iterator +/// where P::Searcher: DoubleEndedSearcher +/// { /* internal ends up calling Searcher::next_match() */ } +/// +/// The internal one is defined outside the macro, and has almost the same +/// semantic as a DoubleEndedIterator by delegating to `pattern::Searcher` and +/// `pattern::ReverseSearcher` for both forward and reverse iteration. +/// +/// "Almost", because a `Searcher` and a `ReverseSearcher` for a given +/// `Pattern` might not return the same elements, so actually implementing +/// `DoubleEndedIterator` for it would be incorrect. +/// (See the docs in `str::pattern` for more details) +/// +/// However, the internal struct still represents a single ended iterator from +/// either end, and depending on pattern is also a valid double ended iterator, +/// so the two wrapper structs implement `Iterator` +/// and `DoubleEndedIterator` depending on the concrete pattern type, leading +/// to the complex impls seen above. +macro_rules! generate_pattern_iterators { + { + // Forward iterator + forward: + $(#[$forward_iterator_attribute:meta])* + struct $forward_iterator:ident; + + // Reverse iterator + reverse: + $(#[$reverse_iterator_attribute:meta])* + struct $reverse_iterator:ident; + + // Stability of all generated items + stability: + $(#[$common_stability_attribute:meta])* + + // Internal almost-iterator that is being delegated to + internal: + $internal_iterator:ident yielding ($iterty:ty); + + // Kind of delgation - either single ended or double ended + delegate $($t:tt)* + } => { + $(#[$forward_iterator_attribute])* + $(#[$common_stability_attribute])* + pub struct $forward_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>); + + $(#[$common_stability_attribute])* + impl<'a, P: Pattern<'a>> fmt::Debug for $forward_iterator<'a, P> + where P::Searcher: fmt::Debug + { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple(stringify!($forward_iterator)) + .field(&self.0) + .finish() + } + } + + $(#[$common_stability_attribute])* + impl<'a, P: Pattern<'a>> Iterator for $forward_iterator<'a, P> { + type Item = $iterty; + + #[inline] + fn next(&mut self) -> Option<$iterty> { + self.0.next() + } + } + + $(#[$common_stability_attribute])* + impl<'a, P: Pattern<'a>> Clone for $forward_iterator<'a, P> + where P::Searcher: Clone + { + fn clone(&self) -> Self { + $forward_iterator(self.0.clone()) + } + } + + $(#[$reverse_iterator_attribute])* + $(#[$common_stability_attribute])* + pub struct $reverse_iterator<'a, P: Pattern<'a>>($internal_iterator<'a, P>); + + $(#[$common_stability_attribute])* + impl<'a, P: Pattern<'a>> fmt::Debug for $reverse_iterator<'a, P> + where P::Searcher: fmt::Debug + { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple(stringify!($reverse_iterator)) + .field(&self.0) + .finish() + } + } + + $(#[$common_stability_attribute])* + impl<'a, P: Pattern<'a>> Iterator for $reverse_iterator<'a, P> + where P::Searcher: ReverseSearcher<'a> + { + type Item = $iterty; + + #[inline] + fn next(&mut self) -> Option<$iterty> { + self.0.next_back() + } + } + + $(#[$common_stability_attribute])* + impl<'a, P: Pattern<'a>> Clone for $reverse_iterator<'a, P> + where P::Searcher: Clone + { + fn clone(&self) -> Self { + $reverse_iterator(self.0.clone()) + } + } + + generate_pattern_iterators!($($t)* with $(#[$common_stability_attribute])*, + $forward_iterator, + $reverse_iterator, $iterty); + }; + { + double ended; with $(#[$common_stability_attribute:meta])*, + $forward_iterator:ident, + $reverse_iterator:ident, $iterty:ty + } => { + $(#[$common_stability_attribute])* + impl<'a, P: Pattern<'a>> DoubleEndedIterator for $forward_iterator<'a, P> + where P::Searcher: DoubleEndedSearcher<'a> + { + #[inline] + fn next_back(&mut self) -> Option<$iterty> { + self.0.next_back() + } + } + + $(#[$common_stability_attribute])* + impl<'a, P: Pattern<'a>> DoubleEndedIterator for $reverse_iterator<'a, P> + where P::Searcher: DoubleEndedSearcher<'a> + { + #[inline] + fn next_back(&mut self) -> Option<$iterty> { + self.0.next() + } + } + }; + { + single ended; with $(#[$common_stability_attribute:meta])*, + $forward_iterator:ident, + $reverse_iterator:ident, $iterty:ty + } => {} +} + +derive_pattern_clone!{ + clone SplitInternal + with |s| SplitInternal { matcher: s.matcher.clone(), ..*s } +} + +struct SplitInternal<'a, P: Pattern<'a>> { + start: usize, + end: usize, + matcher: P::Searcher, + allow_trailing_empty: bool, + finished: bool, +} + +impl<'a, P: Pattern<'a>> fmt::Debug for SplitInternal<'a, P> where P::Searcher: fmt::Debug { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SplitInternal") + .field("start", &self.start) + .field("end", &self.end) + .field("matcher", &self.matcher) + .field("allow_trailing_empty", &self.allow_trailing_empty) + .field("finished", &self.finished) + .finish() + } +} + +impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { + #[inline] + fn get_end(&mut self) -> Option<&'a str> { + if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) { + self.finished = true; + unsafe { + let string = self.matcher.haystack().slice_unchecked(self.start, self.end); + Some(string) + } + } else { + None + } + } + + #[inline] + fn next(&mut self) -> Option<&'a str> { + if self.finished { return None } + + let haystack = self.matcher.haystack(); + match self.matcher.next_match() { + Some((a, b)) => unsafe { + let elt = haystack.slice_unchecked(self.start, a); + self.start = b; + Some(elt) + }, + None => self.get_end(), + } + } + + #[inline] + fn next_back(&mut self) -> Option<&'a str> + where P::Searcher: ReverseSearcher<'a> + { + if self.finished { return None } + + if !self.allow_trailing_empty { + self.allow_trailing_empty = true; + match self.next_back() { + Some(elt) if !elt.is_empty() => return Some(elt), + _ => if self.finished { return None } + } + } + + let haystack = self.matcher.haystack(); + match self.matcher.next_match_back() { + Some((a, b)) => unsafe { + let elt = haystack.slice_unchecked(b, self.end); + self.end = a; + Some(elt) + }, + None => unsafe { + self.finished = true; + Some(haystack.slice_unchecked(self.start, self.end)) + }, + } + } +} + +generate_pattern_iterators! { + forward: + /// Created with the method [`split()`]. + /// + /// [`split()`]: ../../std/primitive.str.html#method.split + struct Split; + reverse: + /// Created with the method [`rsplit()`]. + /// + /// [`rsplit()`]: ../../std/primitive.str.html#method.rsplit + struct RSplit; + stability: + #[stable(feature = "rust1", since = "1.0.0")] + internal: + SplitInternal yielding (&'a str); + delegate double ended; +} + +generate_pattern_iterators! { + forward: + /// Created with the method [`split_terminator()`]. + /// + /// [`split_terminator()`]: ../../std/primitive.str.html#method.split_terminator + struct SplitTerminator; + reverse: + /// Created with the method [`rsplit_terminator()`]. + /// + /// [`rsplit_terminator()`]: ../../std/primitive.str.html#method.rsplit_terminator + struct RSplitTerminator; + stability: + #[stable(feature = "rust1", since = "1.0.0")] + internal: + SplitInternal yielding (&'a str); + delegate double ended; +} + +derive_pattern_clone!{ + clone SplitNInternal + with |s| SplitNInternal { iter: s.iter.clone(), ..*s } +} + +struct SplitNInternal<'a, P: Pattern<'a>> { + iter: SplitInternal<'a, P>, + /// The number of splits remaining + count: usize, +} + +impl<'a, P: Pattern<'a>> fmt::Debug for SplitNInternal<'a, P> where P::Searcher: fmt::Debug { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SplitNInternal") + .field("iter", &self.iter) + .field("count", &self.count) + .finish() + } +} + +impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> { + #[inline] + fn next(&mut self) -> Option<&'a str> { + match self.count { + 0 => None, + 1 => { self.count = 0; self.iter.get_end() } + _ => { self.count -= 1; self.iter.next() } + } + } + + #[inline] + fn next_back(&mut self) -> Option<&'a str> + where P::Searcher: ReverseSearcher<'a> + { + match self.count { + 0 => None, + 1 => { self.count = 0; self.iter.get_end() } + _ => { self.count -= 1; self.iter.next_back() } + } + } +} + +generate_pattern_iterators! { + forward: + /// Created with the method [`splitn()`]. + /// + /// [`splitn()`]: ../../std/primitive.str.html#method.splitn + struct SplitN; + reverse: + /// Created with the method [`rsplitn()`]. + /// + /// [`rsplitn()`]: ../../std/primitive.str.html#method.rsplitn + struct RSplitN; + stability: + #[stable(feature = "rust1", since = "1.0.0")] + internal: + SplitNInternal yielding (&'a str); + delegate single ended; +} + +derive_pattern_clone!{ + clone MatchIndicesInternal + with |s| MatchIndicesInternal(s.0.clone()) +} + +struct MatchIndicesInternal<'a, P: Pattern<'a>>(P::Searcher); + +impl<'a, P: Pattern<'a>> fmt::Debug for MatchIndicesInternal<'a, P> where P::Searcher: fmt::Debug { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("MatchIndicesInternal") + .field(&self.0) + .finish() + } +} + +impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { + #[inline] + fn next(&mut self) -> Option<(usize, &'a str)> { + self.0.next_match().map(|(start, end)| unsafe { + (start, self.0.haystack().slice_unchecked(start, end)) + }) + } + + #[inline] + fn next_back(&mut self) -> Option<(usize, &'a str)> + where P::Searcher: ReverseSearcher<'a> + { + self.0.next_match_back().map(|(start, end)| unsafe { + (start, self.0.haystack().slice_unchecked(start, end)) + }) + } +} + +generate_pattern_iterators! { + forward: + /// Created with the method [`match_indices()`]. + /// + /// [`match_indices()`]: ../../std/primitive.str.html#method.match_indices + struct MatchIndices; + reverse: + /// Created with the method [`rmatch_indices()`]. + /// + /// [`rmatch_indices()`]: ../../std/primitive.str.html#method.rmatch_indices + struct RMatchIndices; + stability: + #[stable(feature = "str_match_indices", since = "1.5.0")] + internal: + MatchIndicesInternal yielding ((usize, &'a str)); + delegate double ended; +} + +derive_pattern_clone!{ + clone MatchesInternal + with |s| MatchesInternal(s.0.clone()) +} + +struct MatchesInternal<'a, P: Pattern<'a>>(P::Searcher); + +impl<'a, P: Pattern<'a>> fmt::Debug for MatchesInternal<'a, P> where P::Searcher: fmt::Debug { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("MatchesInternal") + .field(&self.0) + .finish() + } +} + +impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { + #[inline] + fn next(&mut self) -> Option<&'a str> { + self.0.next_match().map(|(a, b)| unsafe { + // Indices are known to be on utf8 boundaries + self.0.haystack().slice_unchecked(a, b) + }) + } + + #[inline] + fn next_back(&mut self) -> Option<&'a str> + where P::Searcher: ReverseSearcher<'a> + { + self.0.next_match_back().map(|(a, b)| unsafe { + // Indices are known to be on utf8 boundaries + self.0.haystack().slice_unchecked(a, b) + }) + } +} + +generate_pattern_iterators! { + forward: + /// Created with the method [`matches()`]. + /// + /// [`matches()`]: ../../std/primitive.str.html#method.matches + struct Matches; + reverse: + /// Created with the method [`rmatches()`]. + /// + /// [`rmatches()`]: ../../std/primitive.str.html#method.rmatches + struct RMatches; + stability: + #[stable(feature = "str_matches", since = "1.2.0")] + internal: + MatchesInternal yielding (&'a str); + delegate double ended; +} + +/// Created with the method [`lines()`]. +/// +/// [`lines()`]: ../../std/primitive.str.html#method.lines +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone, Debug)] +pub struct Lines<'a>(Map<SplitTerminator<'a, char>, LinesAnyMap>); + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> Iterator for Lines<'a> { + type Item = &'a str; + + #[inline] + fn next(&mut self) -> Option<&'a str> { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.0.size_hint() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> DoubleEndedIterator for Lines<'a> { + #[inline] + fn next_back(&mut self) -> Option<&'a str> { + self.0.next_back() + } +} + +/// Created with the method [`lines_any()`]. +/// +/// [`lines_any()`]: ../../std/primitive.str.html#method.lines_any +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")] +#[derive(Clone, Debug)] +#[allow(deprecated)] +pub struct LinesAny<'a>(Lines<'a>); + +/// A nameable, cloneable fn type +#[derive(Clone)] +struct LinesAnyMap; + +impl<'a> Fn<(&'a str,)> for LinesAnyMap { + #[inline] + extern "rust-call" fn call(&self, (line,): (&'a str,)) -> &'a str { + let l = line.len(); + if l > 0 && line.as_bytes()[l - 1] == b'\r' { &line[0 .. l - 1] } + else { line } + } +} + +impl<'a> FnMut<(&'a str,)> for LinesAnyMap { + #[inline] + extern "rust-call" fn call_mut(&mut self, (line,): (&'a str,)) -> &'a str { + Fn::call(&*self, (line,)) + } +} + +impl<'a> FnOnce<(&'a str,)> for LinesAnyMap { + type Output = &'a str; + + #[inline] + extern "rust-call" fn call_once(self, (line,): (&'a str,)) -> &'a str { + Fn::call(&self, (line,)) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] +impl<'a> Iterator for LinesAny<'a> { + type Item = &'a str; + + #[inline] + fn next(&mut self) -> Option<&'a str> { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.0.size_hint() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] +impl<'a> DoubleEndedIterator for LinesAny<'a> { + #[inline] + fn next_back(&mut self) -> Option<&'a str> { + self.0.next_back() + } +} + +/* +Section: Comparing strings +*/ + +/// Bytewise slice equality +/// NOTE: This function is (ab)used in rustc::middle::trans::_match +/// to compare &[u8] byte slices that are not necessarily valid UTF-8. +#[lang = "str_eq"] +#[inline] +fn eq_slice(a: &str, b: &str) -> bool { + a.as_bytes() == b.as_bytes() +} + +/* +Section: UTF-8 validation +*/ + +// use truncation to fit u64 into usize +const NONASCII_MASK: usize = 0x80808080_80808080u64 as usize; + +/// Return `true` if any byte in the word `x` is nonascii (>= 128). +#[inline] +fn contains_nonascii(x: usize) -> bool { + (x & NONASCII_MASK) != 0 +} + +/// Walk through `iter` checking that it's a valid UTF-8 sequence, +/// returning `true` in that case, or, if it is invalid, `false` with +/// `iter` reset such that it is pointing at the first byte in the +/// invalid sequence. +#[inline(always)] +fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { + let mut offset = 0; + let len = v.len(); + while offset < len { + let old_offset = offset; + macro_rules! err { () => {{ + return Err(Utf8Error { + valid_up_to: old_offset + }) + }}} + + macro_rules! next { () => {{ + offset += 1; + // we needed data, but there was none: error! + if offset >= len { + err!() + } + v[offset] + }}} + + let first = v[offset]; + if first >= 128 { + let w = UTF8_CHAR_WIDTH[first as usize]; + let second = next!(); + // 2-byte encoding is for codepoints \u{0080} to \u{07ff} + // first C2 80 last DF BF + // 3-byte encoding is for codepoints \u{0800} to \u{ffff} + // first E0 A0 80 last EF BF BF + // excluding surrogates codepoints \u{d800} to \u{dfff} + // ED A0 80 to ED BF BF + // 4-byte encoding is for codepoints \u{1000}0 to \u{10ff}ff + // first F0 90 80 80 last F4 8F BF BF + // + // Use the UTF-8 syntax from the RFC + // + // https://tools.ietf.org/html/rfc3629 + // UTF8-1 = %x00-7F + // UTF8-2 = %xC2-DF UTF8-tail + // UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / + // %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail ) + // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / + // %xF4 %x80-8F 2( UTF8-tail ) + match w { + 2 => if second & !CONT_MASK != TAG_CONT_U8 {err!()}, + 3 => { + match (first, second, next!() & !CONT_MASK) { + (0xE0 , 0xA0 ... 0xBF, TAG_CONT_U8) | + (0xE1 ... 0xEC, 0x80 ... 0xBF, TAG_CONT_U8) | + (0xED , 0x80 ... 0x9F, TAG_CONT_U8) | + (0xEE ... 0xEF, 0x80 ... 0xBF, TAG_CONT_U8) => {} + _ => err!() + } + } + 4 => { + match (first, second, next!() & !CONT_MASK, next!() & !CONT_MASK) { + (0xF0 , 0x90 ... 0xBF, TAG_CONT_U8, TAG_CONT_U8) | + (0xF1 ... 0xF3, 0x80 ... 0xBF, TAG_CONT_U8, TAG_CONT_U8) | + (0xF4 , 0x80 ... 0x8F, TAG_CONT_U8, TAG_CONT_U8) => {} + _ => err!() + } + } + _ => err!() + } + offset += 1; + } else { + // Ascii case, try to skip forward quickly. + // When the pointer is aligned, read 2 words of data per iteration + // until we find a word containing a non-ascii byte. + let usize_bytes = mem::size_of::<usize>(); + let bytes_per_iteration = 2 * usize_bytes; + let ptr = v.as_ptr(); + let align = (ptr as usize + offset) & (usize_bytes - 1); + if align == 0 { + if len >= bytes_per_iteration { + while offset <= len - bytes_per_iteration { + unsafe { + let u = *(ptr.offset(offset as isize) as *const usize); + let v = *(ptr.offset((offset + usize_bytes) as isize) as *const usize); + + // break if there is a nonascii byte + let zu = contains_nonascii(u); + let zv = contains_nonascii(v); + if zu || zv { + break; + } + } + offset += bytes_per_iteration; + } + } + // step from the point where the wordwise loop stopped + while offset < len && v[offset] < 128 { + offset += 1; + } + } else { + offset += 1; + } + } + } + + Ok(()) +} + +// https://tools.ietf.org/html/rfc3629 +static UTF8_CHAR_WIDTH: [u8; 256] = [ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF +0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF +4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF +]; + +/// Struct that contains a `char` and the index of the first byte of +/// the next `char` in a string. This can be used as a data structure +/// for iterating over the UTF-8 bytes of a string. +#[derive(Copy, Clone, Debug)] +#[unstable(feature = "str_char", + reason = "existence of this struct is uncertain as it is frequently \ + able to be replaced with char.len_utf8() and/or \ + char/char_indices iterators", + issue = "27754")] +pub struct CharRange { + /// Current `char` + pub ch: char, + /// Index of the first byte of the next `char` + pub next: usize, +} + +/// Mask of the value bits of a continuation byte +const CONT_MASK: u8 = 0b0011_1111; +/// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte +const TAG_CONT_U8: u8 = 0b1000_0000; + +/* +Section: Trait implementations +*/ + +mod traits { + use cmp::{Ord, Ordering, PartialEq, PartialOrd, Eq}; + use iter::Iterator; + use option::Option; + use option::Option::Some; + use ops; + use str::{StrExt, eq_slice}; + + #[stable(feature = "rust1", since = "1.0.0")] + impl Ord for str { + #[inline] + fn cmp(&self, other: &str) -> Ordering { + self.as_bytes().cmp(other.as_bytes()) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl PartialEq for str { + #[inline] + fn eq(&self, other: &str) -> bool { + eq_slice(self, other) + } + #[inline] + fn ne(&self, other: &str) -> bool { !(*self).eq(other) } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Eq for str {} + + #[stable(feature = "rust1", since = "1.0.0")] + impl PartialOrd for str { + #[inline] + fn partial_cmp(&self, other: &str) -> Option<Ordering> { + Some(self.cmp(other)) + } + } + + /// Implements substring slicing with syntax `&self[begin .. end]`. + /// + /// Returns a slice of the given string from the byte range + /// [`begin`..`end`). + /// + /// This operation is `O(1)`. + /// + /// # Panics + /// + /// Panics if `begin` or `end` does not point to the starting + /// byte offset of a character (as defined by `is_char_boundary`). + /// Requires that `begin <= end` and `end <= len` where `len` is the + /// length of the string. + /// + /// # Examples + /// + /// ``` + /// let s = "Löwe 老虎 Léopard"; + /// assert_eq!(&s[0 .. 1], "L"); + /// + /// assert_eq!(&s[1 .. 9], "öwe 老"); + /// + /// // these will panic: + /// // byte 2 lies within `ö`: + /// // &s[2 ..3]; + /// + /// // byte 8 lies within `老` + /// // &s[1 .. 8]; + /// + /// // byte 100 is outside the string + /// // &s[3 .. 100]; + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + impl ops::Index<ops::Range<usize>> for str { + type Output = str; + #[inline] + fn index(&self, index: ops::Range<usize>) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if index.start <= index.end && + self.is_char_boundary(index.start) && + self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(index.start, index.end) } + } else { + super::slice_error_fail(self, index.start, index.end) + } + } + } + + /// Implements mutable substring slicing with syntax + /// `&mut self[begin .. end]`. + /// + /// Returns a mutable slice of the given string from the byte range + /// [`begin`..`end`). + /// + /// This operation is `O(1)`. + /// + /// # Panics + /// + /// Panics if `begin` or `end` does not point to the starting + /// byte offset of a character (as defined by `is_char_boundary`). + /// Requires that `begin <= end` and `end <= len` where `len` is the + /// length of the string. + #[stable(feature = "derefmut_for_string", since = "1.2.0")] + impl ops::IndexMut<ops::Range<usize>> for str { + #[inline] + fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str { + // is_char_boundary checks that the index is in [0, .len()] + if index.start <= index.end && + self.is_char_boundary(index.start) && + self.is_char_boundary(index.end) { + unsafe { self.slice_mut_unchecked(index.start, index.end) } + } else { + super::slice_error_fail(self, index.start, index.end) + } + } + } + + /// Implements substring slicing with syntax `&self[.. end]`. + /// + /// Returns a slice of the string from the beginning to byte offset + /// `end`. + /// + /// Equivalent to `&self[0 .. end]`. + #[stable(feature = "rust1", since = "1.0.0")] + impl ops::Index<ops::RangeTo<usize>> for str { + type Output = str; + + #[inline] + fn index(&self, index: ops::RangeTo<usize>) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(0, index.end) } + } else { + super::slice_error_fail(self, 0, index.end) + } + } + } + + /// Implements mutable substring slicing with syntax `&mut self[.. end]`. + /// + /// Returns a mutable slice of the string from the beginning to byte offset + /// `end`. + /// + /// Equivalent to `&mut self[0 .. end]`. + #[stable(feature = "derefmut_for_string", since = "1.2.0")] + impl ops::IndexMut<ops::RangeTo<usize>> for str { + #[inline] + fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.end) { + unsafe { self.slice_mut_unchecked(0, index.end) } + } else { + super::slice_error_fail(self, 0, index.end) + } + } + } + + /// Implements substring slicing with syntax `&self[begin ..]`. + /// + /// Returns a slice of the string from byte offset `begin` + /// to the end of the string. + /// + /// Equivalent to `&self[begin .. len]`. + #[stable(feature = "rust1", since = "1.0.0")] + impl ops::Index<ops::RangeFrom<usize>> for str { + type Output = str; + + #[inline] + fn index(&self, index: ops::RangeFrom<usize>) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.start) { + unsafe { self.slice_unchecked(index.start, self.len()) } + } else { + super::slice_error_fail(self, index.start, self.len()) + } + } + } + + /// Implements mutable substring slicing with syntax `&mut self[begin ..]`. + /// + /// Returns a mutable slice of the string from byte offset `begin` + /// to the end of the string. + /// + /// Equivalent to `&mut self[begin .. len]`. + #[stable(feature = "derefmut_for_string", since = "1.2.0")] + impl ops::IndexMut<ops::RangeFrom<usize>> for str { + #[inline] + fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.start) { + let len = self.len(); + unsafe { self.slice_mut_unchecked(index.start, len) } + } else { + super::slice_error_fail(self, index.start, self.len()) + } + } + } + + /// Implements substring slicing with syntax `&self[..]`. + /// + /// Returns a slice of the whole string. This operation can + /// never panic. + /// + /// Equivalent to `&self[0 .. len]`. + #[stable(feature = "rust1", since = "1.0.0")] + impl ops::Index<ops::RangeFull> for str { + type Output = str; + + #[inline] + fn index(&self, _index: ops::RangeFull) -> &str { + self + } + } + + /// Implements mutable substring slicing with syntax `&mut self[..]`. + /// + /// Returns a mutable slice of the whole string. This operation can + /// never panic. + /// + /// Equivalent to `&mut self[0 .. len]`. + #[stable(feature = "derefmut_for_string", since = "1.2.0")] + impl ops::IndexMut<ops::RangeFull> for str { + #[inline] + fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str { + self + } + } + + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ops::Index<ops::RangeInclusive<usize>> for str { + type Output = str; + + #[inline] + fn index(&self, index: ops::RangeInclusive<usize>) -> &str { + match index { + ops::RangeInclusive::Empty { .. } => "", + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => + panic!("attempted to index slice up to maximum usize"), + ops::RangeInclusive::NonEmpty { start, end } => + self.index(start .. end+1) + } + } + } + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ops::Index<ops::RangeToInclusive<usize>> for str { + type Output = str; + + #[inline] + fn index(&self, index: ops::RangeToInclusive<usize>) -> &str { + self.index(0...index.end) + } + } + + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ops::IndexMut<ops::RangeInclusive<usize>> for str { + #[inline] + fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str { + match index { + ops::RangeInclusive::Empty { .. } => &mut self[0..0], // `&mut ""` doesn't work + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => + panic!("attempted to index str up to maximum usize"), + ops::RangeInclusive::NonEmpty { start, end } => + self.index_mut(start .. end+1) + } + } + } + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ops::IndexMut<ops::RangeToInclusive<usize>> for str { + #[inline] + fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str { + self.index_mut(0...index.end) + } + } +} + +/// Methods for string slices +#[allow(missing_docs)] +#[doc(hidden)] +#[unstable(feature = "core_str_ext", + reason = "stable interface provided by `impl str` in later crates", + issue = "32110")] +pub trait StrExt { + // NB there are no docs here are they're all located on the StrExt trait in + // libcollections, not here. + + #[stable(feature = "core", since = "1.6.0")] + fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn chars(&self) -> Chars; + #[stable(feature = "core", since = "1.6.0")] + fn bytes(&self) -> Bytes; + #[stable(feature = "core", since = "1.6.0")] + fn char_indices(&self) -> CharIndices; + #[stable(feature = "core", since = "1.6.0")] + fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P>; + #[stable(feature = "core", since = "1.6.0")] + fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P> + where P::Searcher: ReverseSearcher<'a>; + #[stable(feature = "core", since = "1.6.0")] + fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P>; + #[stable(feature = "core", since = "1.6.0")] + fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> + where P::Searcher: ReverseSearcher<'a>; + #[stable(feature = "core", since = "1.6.0")] + fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>; + #[stable(feature = "core", since = "1.6.0")] + fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P> + where P::Searcher: ReverseSearcher<'a>; + #[stable(feature = "core", since = "1.6.0")] + fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P>; + #[stable(feature = "core", since = "1.6.0")] + fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P> + where P::Searcher: ReverseSearcher<'a>; + #[stable(feature = "core", since = "1.6.0")] + fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>; + #[stable(feature = "core", since = "1.6.0")] + fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P> + where P::Searcher: ReverseSearcher<'a>; + #[stable(feature = "core", since = "1.6.0")] + fn lines(&self) -> Lines; + #[stable(feature = "core", since = "1.6.0")] + #[rustc_deprecated(since = "1.6.0", reason = "use lines() instead now")] + #[allow(deprecated)] + fn lines_any(&self) -> LinesAny; + #[stable(feature = "core", since = "1.6.0")] + unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str; + #[stable(feature = "core", since = "1.6.0")] + unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str; + #[stable(feature = "core", since = "1.6.0")] + fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool + where P::Searcher: ReverseSearcher<'a>; + #[stable(feature = "core", since = "1.6.0")] + fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str + where P::Searcher: DoubleEndedSearcher<'a>; + #[stable(feature = "core", since = "1.6.0")] + fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str; + #[stable(feature = "core", since = "1.6.0")] + fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str + where P::Searcher: ReverseSearcher<'a>; + #[unstable(feature = "str_char", + reason = "it is unclear whether this method pulls its weight \ + with the existence of the char_indices iterator or \ + this method may want to be replaced with checked \ + slicing", + issue = "27754")] + fn is_char_boundary(&self, index: usize) -> bool; + #[unstable(feature = "str_char", + reason = "often replaced by char_indices, this method may \ + be removed in favor of just char_at() or eventually \ + removed altogether", + issue = "27754")] + fn char_range_at(&self, start: usize) -> CharRange; + #[unstable(feature = "str_char", + reason = "often replaced by char_indices, this method may \ + be removed in favor of just char_at_reverse() or \ + eventually removed altogether", + issue = "27754")] + fn char_range_at_reverse(&self, start: usize) -> CharRange; + #[unstable(feature = "str_char", + reason = "frequently replaced by the chars() iterator, this \ + method may be removed or possibly renamed in the \ + future; it is normally replaced by chars/char_indices \ + iterators or by getting the first char from a \ + subslice", + issue = "27754")] + fn char_at(&self, i: usize) -> char; + #[unstable(feature = "str_char", + reason = "see char_at for more details, but reverse semantics \ + are also somewhat unclear, especially with which \ + cases generate panics", + issue = "27754")] + fn char_at_reverse(&self, i: usize) -> char; + #[stable(feature = "core", since = "1.6.0")] + fn as_bytes(&self) -> &[u8]; + #[stable(feature = "core", since = "1.6.0")] + fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>; + #[stable(feature = "core", since = "1.6.0")] + fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> + where P::Searcher: ReverseSearcher<'a>; + fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>; + #[stable(feature = "core", since = "1.6.0")] + fn split_at(&self, mid: usize) -> (&str, &str); + #[stable(feature = "core", since = "1.6.0")] + fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str); + #[unstable(feature = "str_char", + reason = "awaiting conventions about shifting and slices and \ + may not be warranted with the existence of the chars \ + and/or char_indices iterators", + issue = "27754")] + fn slice_shift_char(&self) -> Option<(char, &str)>; + #[stable(feature = "core", since = "1.6.0")] + fn as_ptr(&self) -> *const u8; + #[stable(feature = "core", since = "1.6.0")] + fn len(&self) -> usize; + #[stable(feature = "core", since = "1.6.0")] + fn is_empty(&self) -> bool; + #[stable(feature = "core", since = "1.6.0")] + fn parse<T: FromStr>(&self) -> Result<T, T::Err>; +} + +// truncate `&str` to length at most equal to `max` +// return `true` if it were truncated, and the new str. +fn truncate_to_char_boundary(s: &str, mut max: usize) -> (bool, &str) { + if max >= s.len() { + (false, s) + } else { + while !s.is_char_boundary(max) { + max -= 1; + } + (true, &s[..max]) + } +} + +#[inline(never)] +#[cold] +fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { + const MAX_DISPLAY_LENGTH: usize = 256; + let (truncated, s) = truncate_to_char_boundary(s, MAX_DISPLAY_LENGTH); + let ellipsis = if truncated { "[...]" } else { "" }; + + assert!(begin <= end, "begin <= end ({} <= {}) when slicing `{}`{}", + begin, end, s, ellipsis); + panic!("index {} and/or {} in `{}`{} do not lie on character boundary", + begin, end, s, ellipsis); +} + +#[stable(feature = "core", since = "1.6.0")] +impl StrExt for str { + #[inline] + fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool { + pat.is_contained_in(self) + } + + #[inline] + fn chars(&self) -> Chars { + Chars{iter: self.as_bytes().iter()} + } + + #[inline] + fn bytes(&self) -> Bytes { + Bytes(self.as_bytes().iter().cloned()) + } + + #[inline] + fn char_indices(&self) -> CharIndices { + CharIndices { front_offset: 0, iter: self.chars() } + } + + #[inline] + fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> { + Split(SplitInternal { + start: 0, + end: self.len(), + matcher: pat.into_searcher(self), + allow_trailing_empty: true, + finished: false, + }) + } + + #[inline] + fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P> + where P::Searcher: ReverseSearcher<'a> + { + RSplit(self.split(pat).0) + } + + #[inline] + fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> { + SplitN(SplitNInternal { + iter: self.split(pat).0, + count: count, + }) + } + + #[inline] + fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> + where P::Searcher: ReverseSearcher<'a> + { + RSplitN(self.splitn(count, pat).0) + } + + #[inline] + fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> { + SplitTerminator(SplitInternal { + allow_trailing_empty: false, + ..self.split(pat).0 + }) + } + + #[inline] + fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P> + where P::Searcher: ReverseSearcher<'a> + { + RSplitTerminator(self.split_terminator(pat).0) + } + + #[inline] + fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> { + Matches(MatchesInternal(pat.into_searcher(self))) + } + + #[inline] + fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P> + where P::Searcher: ReverseSearcher<'a> + { + RMatches(self.matches(pat).0) + } + + #[inline] + fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> { + MatchIndices(MatchIndicesInternal(pat.into_searcher(self))) + } + + #[inline] + fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P> + where P::Searcher: ReverseSearcher<'a> + { + RMatchIndices(self.match_indices(pat).0) + } + #[inline] + fn lines(&self) -> Lines { + Lines(self.split_terminator('\n').map(LinesAnyMap)) + } + + #[inline] + #[allow(deprecated)] + fn lines_any(&self) -> LinesAny { + LinesAny(self.lines()) + } + + #[inline] + unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str { + mem::transmute(Slice { + data: self.as_ptr().offset(begin as isize), + len: end - begin, + }) + } + + #[inline] + unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str { + mem::transmute(Slice { + data: self.as_ptr().offset(begin as isize), + len: end - begin, + }) + } + + #[inline] + fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool { + pat.is_prefix_of(self) + } + + #[inline] + fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool + where P::Searcher: ReverseSearcher<'a> + { + pat.is_suffix_of(self) + } + + #[inline] + fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str + where P::Searcher: DoubleEndedSearcher<'a> + { + let mut i = 0; + let mut j = 0; + let mut matcher = pat.into_searcher(self); + if let Some((a, b)) = matcher.next_reject() { + i = a; + j = b; // Remember earliest known match, correct it below if + // last match is different + } + if let Some((_, b)) = matcher.next_reject_back() { + j = b; + } + unsafe { + // Searcher is known to return valid indices + self.slice_unchecked(i, j) + } + } + + #[inline] + fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { + let mut i = self.len(); + let mut matcher = pat.into_searcher(self); + if let Some((a, _)) = matcher.next_reject() { + i = a; + } + unsafe { + // Searcher is known to return valid indices + self.slice_unchecked(i, self.len()) + } + } + + #[inline] + fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str + where P::Searcher: ReverseSearcher<'a> + { + let mut j = 0; + let mut matcher = pat.into_searcher(self); + if let Some((_, b)) = matcher.next_reject_back() { + j = b; + } + unsafe { + // Searcher is known to return valid indices + self.slice_unchecked(0, j) + } + } + + #[inline] + fn is_char_boundary(&self, index: usize) -> bool { + // 0 and len are always ok. + // Test for 0 explicitly so that it can optimize out the check + // easily and skip reading string data for that case. + if index == 0 || index == self.len() { return true; } + match self.as_bytes().get(index) { + None => false, + Some(&b) => b < 128 || b >= 192, + } + } + + #[inline] + fn char_range_at(&self, i: usize) -> CharRange { + let (c, n) = char_range_at_raw(self.as_bytes(), i); + CharRange { ch: unsafe { char::from_u32_unchecked(c) }, next: n } + } + + #[inline] + fn char_range_at_reverse(&self, start: usize) -> CharRange { + let mut prev = start; + + prev = prev.saturating_sub(1); + if self.as_bytes()[prev] < 128 { + return CharRange{ch: self.as_bytes()[prev] as char, next: prev} + } + + // Multibyte case is a fn to allow char_range_at_reverse to inline cleanly + fn multibyte_char_range_at_reverse(s: &str, mut i: usize) -> CharRange { + // while there is a previous byte == 10...... + while i > 0 && s.as_bytes()[i] & !CONT_MASK == TAG_CONT_U8 { + i -= 1; + } + + let first= s.as_bytes()[i]; + let w = UTF8_CHAR_WIDTH[first as usize]; + assert!(w != 0); + + let mut val = utf8_first_byte(first, w as u32); + val = utf8_acc_cont_byte(val, s.as_bytes()[i + 1]); + if w > 2 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 2]); } + if w > 3 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 3]); } + + CharRange {ch: unsafe { char::from_u32_unchecked(val) }, next: i} + } + + multibyte_char_range_at_reverse(self, prev) + } + + #[inline] + fn char_at(&self, i: usize) -> char { + self.char_range_at(i).ch + } + + #[inline] + fn char_at_reverse(&self, i: usize) -> char { + self.char_range_at_reverse(i).ch + } + + #[inline] + fn as_bytes(&self) -> &[u8] { + unsafe { mem::transmute(self) } + } + + fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> { + pat.into_searcher(self).next_match().map(|(i, _)| i) + } + + fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> + where P::Searcher: ReverseSearcher<'a> + { + pat.into_searcher(self).next_match_back().map(|(i, _)| i) + } + + fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> { + self.find(pat) + } + + #[inline] + fn split_at(&self, mid: usize) -> (&str, &str) { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(mid) { + unsafe { + (self.slice_unchecked(0, mid), + self.slice_unchecked(mid, self.len())) + } + } else { + slice_error_fail(self, 0, mid) + } + } + + fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(mid) { + let len = self.len(); + let ptr = self.as_ptr() as *mut u8; + unsafe { + (from_raw_parts_mut(ptr, mid), + from_raw_parts_mut(ptr.offset(mid as isize), len - mid)) + } + } else { + slice_error_fail(self, 0, mid) + } + } + + #[inline] + fn slice_shift_char(&self) -> Option<(char, &str)> { + if self.is_empty() { + None + } else { + let ch = self.char_at(0); + let next_s = unsafe { self.slice_unchecked(ch.len_utf8(), self.len()) }; + Some((ch, next_s)) + } + } + + #[inline] + fn as_ptr(&self) -> *const u8 { + self as *const str as *const u8 + } + + #[inline] + fn len(&self) -> usize { self.repr().len } + + #[inline] + fn is_empty(&self) -> bool { self.len() == 0 } + + #[inline] + fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl AsRef<[u8]> for str { + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +/// Pluck a code point out of a UTF-8-like byte slice and return the +/// index of the next code point. +#[inline] +fn char_range_at_raw(bytes: &[u8], i: usize) -> (u32, usize) { + if bytes[i] < 128 { + return (bytes[i] as u32, i + 1); + } + + // Multibyte case is a fn to allow char_range_at to inline cleanly + fn multibyte_char_range_at(bytes: &[u8], i: usize) -> (u32, usize) { + let first = bytes[i]; + let w = UTF8_CHAR_WIDTH[first as usize]; + assert!(w != 0); + + let mut val = utf8_first_byte(first, w as u32); + val = utf8_acc_cont_byte(val, bytes[i + 1]); + if w > 2 { val = utf8_acc_cont_byte(val, bytes[i + 2]); } + if w > 3 { val = utf8_acc_cont_byte(val, bytes[i + 3]); } + + (val, i + w as usize) + } + + multibyte_char_range_at(bytes, i) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a> Default for &'a str { + fn default() -> &'a str { "" } +} diff --git a/libcore/str/pattern.rs b/libcore/str/pattern.rs new file mode 100644 index 0000000..b803539 --- /dev/null +++ b/libcore/str/pattern.rs @@ -0,0 +1,1213 @@ +// Copyright 2015 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. + +//! The string Pattern API. +//! +//! For more details, see the traits `Pattern`, `Searcher`, +//! `ReverseSearcher` and `DoubleEndedSearcher`. + +#![unstable(feature = "pattern", + reason = "API not fully fleshed out and ready to be stabilized", + issue = "27721")] + +use prelude::v1::*; + +use cmp; +use fmt; +use usize; + +// Pattern + +/// A string pattern. +/// +/// A `Pattern<'a>` expresses that the implementing type +/// can be used as a string pattern for searching in a `&'a str`. +/// +/// For example, both `'a'` and `"aa"` are patterns that +/// would match at index `1` in the string `"baaaab"`. +/// +/// The trait itself acts as a builder for an associated +/// `Searcher` type, which does the actual work of finding +/// occurrences of the pattern in a string. +pub trait Pattern<'a>: Sized { + /// Associated searcher for this pattern + type Searcher: Searcher<'a>; + + /// Constructs the associated searcher from + /// `self` and the `haystack` to search in. + fn into_searcher(self, haystack: &'a str) -> Self::Searcher; + + /// Checks whether the pattern matches anywhere in the haystack + #[inline] + fn is_contained_in(self, haystack: &'a str) -> bool { + self.into_searcher(haystack).next_match().is_some() + } + + /// Checks whether the pattern matches at the front of the haystack + #[inline] + fn is_prefix_of(self, haystack: &'a str) -> bool { + match self.into_searcher(haystack).next() { + SearchStep::Match(0, _) => true, + _ => false, + } + } + + /// Checks whether the pattern matches at the back of the haystack + #[inline] + fn is_suffix_of(self, haystack: &'a str) -> bool + where Self::Searcher: ReverseSearcher<'a> + { + match self.into_searcher(haystack).next_back() { + SearchStep::Match(_, j) if haystack.len() == j => true, + _ => false, + } + } +} + +// Searcher + +/// Result of calling `Searcher::next()` or `ReverseSearcher::next_back()`. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub enum SearchStep { + /// Expresses that a match of the pattern has been found at + /// `haystack[a..b]`. + Match(usize, usize), + /// Expresses that `haystack[a..b]` has been rejected as a possible match + /// of the pattern. + /// + /// Note that there might be more than one `Reject` between two `Match`es, + /// there is no requirement for them to be combined into one. + Reject(usize, usize), + /// Expresses that every byte of the haystack has been visted, ending + /// the iteration. + Done +} + +/// A searcher for a string pattern. +/// +/// This trait provides methods for searching for non-overlapping +/// matches of a pattern starting from the front (left) of a string. +/// +/// It will be implemented by associated `Searcher` +/// types of the `Pattern` trait. +/// +/// The trait is marked unsafe because the indices returned by the +/// `next()` methods are required to lie on valid utf8 boundaries in +/// the haystack. This enables consumers of this trait to +/// slice the haystack without additional runtime checks. +pub unsafe trait Searcher<'a> { + /// Getter for the underlaying string to be searched in + /// + /// Will always return the same `&str` + fn haystack(&self) -> &'a str; + + /// Performs the next search step starting from the front. + /// + /// - Returns `Match(a, b)` if `haystack[a..b]` matches the pattern. + /// - Returns `Reject(a, b)` if `haystack[a..b]` can not match the + /// pattern, even partially. + /// - Returns `Done` if every byte of the haystack has been visited + /// + /// The stream of `Match` and `Reject` values up to a `Done` + /// will contain index ranges that are adjacent, non-overlapping, + /// covering the whole haystack, and laying on utf8 boundaries. + /// + /// A `Match` result needs to contain the whole matched pattern, + /// however `Reject` results may be split up into arbitrary + /// many adjacent fragments. Both ranges may have zero length. + /// + /// As an example, the pattern `"aaa"` and the haystack `"cbaaaaab"` + /// might produce the stream + /// `[Reject(0, 1), Reject(1, 2), Match(2, 5), Reject(5, 8)]` + fn next(&mut self) -> SearchStep; + + /// Find the next `Match` result. See `next()` + #[inline] + fn next_match(&mut self) -> Option<(usize, usize)> { + loop { + match self.next() { + SearchStep::Match(a, b) => return Some((a, b)), + SearchStep::Done => return None, + _ => continue, + } + } + } + + /// Find the next `Reject` result. See `next()` + #[inline] + fn next_reject(&mut self) -> Option<(usize, usize)> { + loop { + match self.next() { + SearchStep::Reject(a, b) => return Some((a, b)), + SearchStep::Done => return None, + _ => continue, + } + } + } +} + +/// A reverse searcher for a string pattern. +/// +/// This trait provides methods for searching for non-overlapping +/// matches of a pattern starting from the back (right) of a string. +/// +/// It will be implemented by associated `Searcher` +/// types of the `Pattern` trait if the pattern supports searching +/// for it from the back. +/// +/// The index ranges returned by this trait are not required +/// to exactly match those of the forward search in reverse. +/// +/// For the reason why this trait is marked unsafe, see them +/// parent trait `Searcher`. +pub unsafe trait ReverseSearcher<'a>: Searcher<'a> { + /// Performs the next search step starting from the back. + /// + /// - Returns `Match(a, b)` if `haystack[a..b]` matches the pattern. + /// - Returns `Reject(a, b)` if `haystack[a..b]` can not match the + /// pattern, even partially. + /// - Returns `Done` if every byte of the haystack has been visited + /// + /// The stream of `Match` and `Reject` values up to a `Done` + /// will contain index ranges that are adjacent, non-overlapping, + /// covering the whole haystack, and laying on utf8 boundaries. + /// + /// A `Match` result needs to contain the whole matched pattern, + /// however `Reject` results may be split up into arbitrary + /// many adjacent fragments. Both ranges may have zero length. + /// + /// As an example, the pattern `"aaa"` and the haystack `"cbaaaaab"` + /// might produce the stream + /// `[Reject(7, 8), Match(4, 7), Reject(1, 4), Reject(0, 1)]` + fn next_back(&mut self) -> SearchStep; + + /// Find the next `Match` result. See `next_back()` + #[inline] + fn next_match_back(&mut self) -> Option<(usize, usize)>{ + loop { + match self.next_back() { + SearchStep::Match(a, b) => return Some((a, b)), + SearchStep::Done => return None, + _ => continue, + } + } + } + + /// Find the next `Reject` result. See `next_back()` + #[inline] + fn next_reject_back(&mut self) -> Option<(usize, usize)>{ + loop { + match self.next_back() { + SearchStep::Reject(a, b) => return Some((a, b)), + SearchStep::Done => return None, + _ => continue, + } + } + } +} + +/// A marker trait to express that a `ReverseSearcher` +/// can be used for a `DoubleEndedIterator` implementation. +/// +/// For this, the impl of `Searcher` and `ReverseSearcher` need +/// to follow these conditions: +/// +/// - All results of `next()` need to be identical +/// to the results of `next_back()` in reverse order. +/// - `next()` and `next_back()` need to behave as +/// the two ends of a range of values, that is they +/// can not "walk past each other". +/// +/// # Examples +/// +/// `char::Searcher` is a `DoubleEndedSearcher` because searching for a +/// `char` only requires looking at one at a time, which behaves the same +/// from both ends. +/// +/// `(&str)::Searcher` is not a `DoubleEndedSearcher` because +/// the pattern `"aa"` in the haystack `"aaa"` matches as either +/// `"[aa]a"` or `"a[aa]"`, depending from which side it is searched. +pub trait DoubleEndedSearcher<'a>: ReverseSearcher<'a> {} + +///////////////////////////////////////////////////////////////////////////// +// Impl for a CharEq wrapper +///////////////////////////////////////////////////////////////////////////// + +#[doc(hidden)] +trait CharEq { + fn matches(&mut self, char) -> bool; + fn only_ascii(&self) -> bool; +} + +impl CharEq for char { + #[inline] + fn matches(&mut self, c: char) -> bool { *self == c } + + #[inline] + fn only_ascii(&self) -> bool { (*self as u32) < 128 } +} + +impl<F> CharEq for F where F: FnMut(char) -> bool { + #[inline] + fn matches(&mut self, c: char) -> bool { (*self)(c) } + + #[inline] + fn only_ascii(&self) -> bool { false } +} + +impl<'a> CharEq for &'a [char] { + #[inline] + fn matches(&mut self, c: char) -> bool { + self.iter().any(|&m| { let mut m = m; m.matches(c) }) + } + + #[inline] + fn only_ascii(&self) -> bool { + self.iter().all(|m| m.only_ascii()) + } +} + +struct CharEqPattern<C: CharEq>(C); + +#[derive(Clone, Debug)] +struct CharEqSearcher<'a, C: CharEq> { + char_eq: C, + haystack: &'a str, + char_indices: super::CharIndices<'a>, + #[allow(dead_code)] + ascii_only: bool, +} + +impl<'a, C: CharEq> Pattern<'a> for CharEqPattern<C> { + type Searcher = CharEqSearcher<'a, C>; + + #[inline] + fn into_searcher(self, haystack: &'a str) -> CharEqSearcher<'a, C> { + CharEqSearcher { + ascii_only: self.0.only_ascii(), + haystack: haystack, + char_eq: self.0, + char_indices: haystack.char_indices(), + } + } +} + +unsafe impl<'a, C: CharEq> Searcher<'a> for CharEqSearcher<'a, C> { + #[inline] + fn haystack(&self) -> &'a str { + self.haystack + } + + #[inline] + fn next(&mut self) -> SearchStep { + let s = &mut self.char_indices; + // Compare lengths of the internal byte slice iterator + // to find length of current char + let (pre_len, _) = s.iter.iter.size_hint(); + if let Some((i, c)) = s.next() { + let (len, _) = s.iter.iter.size_hint(); + let char_len = pre_len - len; + if self.char_eq.matches(c) { + return SearchStep::Match(i, i + char_len); + } else { + return SearchStep::Reject(i, i + char_len); + } + } + SearchStep::Done + } +} + +unsafe impl<'a, C: CharEq> ReverseSearcher<'a> for CharEqSearcher<'a, C> { + #[inline] + fn next_back(&mut self) -> SearchStep { + let s = &mut self.char_indices; + // Compare lengths of the internal byte slice iterator + // to find length of current char + let (pre_len, _) = s.iter.iter.size_hint(); + if let Some((i, c)) = s.next_back() { + let (len, _) = s.iter.iter.size_hint(); + let char_len = pre_len - len; + if self.char_eq.matches(c) { + return SearchStep::Match(i, i + char_len); + } else { + return SearchStep::Reject(i, i + char_len); + } + } + SearchStep::Done + } +} + +impl<'a, C: CharEq> DoubleEndedSearcher<'a> for CharEqSearcher<'a, C> {} + +///////////////////////////////////////////////////////////////////////////// + +macro_rules! pattern_methods { + ($t:ty, $pmap:expr, $smap:expr) => { + type Searcher = $t; + + #[inline] + fn into_searcher(self, haystack: &'a str) -> $t { + ($smap)(($pmap)(self).into_searcher(haystack)) + } + + #[inline] + fn is_contained_in(self, haystack: &'a str) -> bool { + ($pmap)(self).is_contained_in(haystack) + } + + #[inline] + fn is_prefix_of(self, haystack: &'a str) -> bool { + ($pmap)(self).is_prefix_of(haystack) + } + + #[inline] + fn is_suffix_of(self, haystack: &'a str) -> bool + where $t: ReverseSearcher<'a> + { + ($pmap)(self).is_suffix_of(haystack) + } + } +} + +macro_rules! searcher_methods { + (forward) => { + #[inline] + fn haystack(&self) -> &'a str { + self.0.haystack() + } + #[inline] + fn next(&mut self) -> SearchStep { + self.0.next() + } + #[inline] + fn next_match(&mut self) -> Option<(usize, usize)> { + self.0.next_match() + } + #[inline] + fn next_reject(&mut self) -> Option<(usize, usize)> { + self.0.next_reject() + } + }; + (reverse) => { + #[inline] + fn next_back(&mut self) -> SearchStep { + self.0.next_back() + } + #[inline] + fn next_match_back(&mut self) -> Option<(usize, usize)> { + self.0.next_match_back() + } + #[inline] + fn next_reject_back(&mut self) -> Option<(usize, usize)> { + self.0.next_reject_back() + } + } +} + +///////////////////////////////////////////////////////////////////////////// +// Impl for char +///////////////////////////////////////////////////////////////////////////// + +/// Associated type for `<char as Pattern<'a>>::Searcher`. +#[derive(Clone, Debug)] +pub struct CharSearcher<'a>(<CharEqPattern<char> as Pattern<'a>>::Searcher); + +unsafe impl<'a> Searcher<'a> for CharSearcher<'a> { + searcher_methods!(forward); +} + +unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> { + searcher_methods!(reverse); +} + +impl<'a> DoubleEndedSearcher<'a> for CharSearcher<'a> {} + +/// Searches for chars that are equal to a given char +impl<'a> Pattern<'a> for char { + pattern_methods!(CharSearcher<'a>, CharEqPattern, CharSearcher); +} + +///////////////////////////////////////////////////////////////////////////// +// Impl for &[char] +///////////////////////////////////////////////////////////////////////////// + +// Todo: Change / Remove due to ambiguity in meaning. + +/// Associated type for `<&[char] as Pattern<'a>>::Searcher`. +#[derive(Clone, Debug)] +pub struct CharSliceSearcher<'a, 'b>(<CharEqPattern<&'b [char]> as Pattern<'a>>::Searcher); + +unsafe impl<'a, 'b> Searcher<'a> for CharSliceSearcher<'a, 'b> { + searcher_methods!(forward); +} + +unsafe impl<'a, 'b> ReverseSearcher<'a> for CharSliceSearcher<'a, 'b> { + searcher_methods!(reverse); +} + +impl<'a, 'b> DoubleEndedSearcher<'a> for CharSliceSearcher<'a, 'b> {} + +/// Searches for chars that are equal to any of the chars in the array +impl<'a, 'b> Pattern<'a> for &'b [char] { + pattern_methods!(CharSliceSearcher<'a, 'b>, CharEqPattern, CharSliceSearcher); +} + +///////////////////////////////////////////////////////////////////////////// +// Impl for F: FnMut(char) -> bool +///////////////////////////////////////////////////////////////////////////// + +/// Associated type for `<F as Pattern<'a>>::Searcher`. +#[derive(Clone)] +pub struct CharPredicateSearcher<'a, F>(<CharEqPattern<F> as Pattern<'a>>::Searcher) + where F: FnMut(char) -> bool; + +impl<'a, F> fmt::Debug for CharPredicateSearcher<'a, F> + where F: FnMut(char) -> bool +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("CharPredicateSearcher") + .field("haystack", &self.0.haystack) + .field("char_indices", &self.0.char_indices) + .field("ascii_only", &self.0.ascii_only) + .finish() + } +} +unsafe impl<'a, F> Searcher<'a> for CharPredicateSearcher<'a, F> + where F: FnMut(char) -> bool +{ + searcher_methods!(forward); +} + +unsafe impl<'a, F> ReverseSearcher<'a> for CharPredicateSearcher<'a, F> + where F: FnMut(char) -> bool +{ + searcher_methods!(reverse); +} + +impl<'a, F> DoubleEndedSearcher<'a> for CharPredicateSearcher<'a, F> + where F: FnMut(char) -> bool {} + +/// Searches for chars that match the given predicate +impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool { + pattern_methods!(CharPredicateSearcher<'a, F>, CharEqPattern, CharPredicateSearcher); +} + +///////////////////////////////////////////////////////////////////////////// +// Impl for &&str +///////////////////////////////////////////////////////////////////////////// + +/// Delegates to the `&str` impl. +impl<'a, 'b, 'c> Pattern<'a> for &'c &'b str { + pattern_methods!(StrSearcher<'a, 'b>, |&s| s, |s| s); +} + +///////////////////////////////////////////////////////////////////////////// +// Impl for &str +///////////////////////////////////////////////////////////////////////////// + +/// Non-allocating substring search. +/// +/// Will handle the pattern `""` as returning empty matches at each character +/// boundary. +impl<'a, 'b> Pattern<'a> for &'b str { + type Searcher = StrSearcher<'a, 'b>; + + #[inline] + fn into_searcher(self, haystack: &'a str) -> StrSearcher<'a, 'b> { + StrSearcher::new(haystack, self) + } + + /// Checks whether the pattern matches at the front of the haystack + #[inline] + fn is_prefix_of(self, haystack: &'a str) -> bool { + haystack.is_char_boundary(self.len()) && + self == &haystack[..self.len()] + } + + /// Checks whether the pattern matches at the back of the haystack + #[inline] + fn is_suffix_of(self, haystack: &'a str) -> bool { + self.len() <= haystack.len() && + haystack.is_char_boundary(haystack.len() - self.len()) && + self == &haystack[haystack.len() - self.len()..] + } +} + + +///////////////////////////////////////////////////////////////////////////// +// Two Way substring searcher +///////////////////////////////////////////////////////////////////////////// + +#[derive(Clone, Debug)] +/// Associated type for `<&str as Pattern<'a>>::Searcher`. +pub struct StrSearcher<'a, 'b> { + haystack: &'a str, + needle: &'b str, + + searcher: StrSearcherImpl, +} + +#[derive(Clone, Debug)] +enum StrSearcherImpl { + Empty(EmptyNeedle), + TwoWay(TwoWaySearcher), +} + +#[derive(Clone, Debug)] +struct EmptyNeedle { + position: usize, + end: usize, + is_match_fw: bool, + is_match_bw: bool, +} + +impl<'a, 'b> StrSearcher<'a, 'b> { + fn new(haystack: &'a str, needle: &'b str) -> StrSearcher<'a, 'b> { + if needle.is_empty() { + StrSearcher { + haystack: haystack, + needle: needle, + searcher: StrSearcherImpl::Empty(EmptyNeedle { + position: 0, + end: haystack.len(), + is_match_fw: true, + is_match_bw: true, + }), + } + } else { + StrSearcher { + haystack: haystack, + needle: needle, + searcher: StrSearcherImpl::TwoWay( + TwoWaySearcher::new(needle.as_bytes(), haystack.len()) + ), + } + } + } +} + +unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> { + fn haystack(&self) -> &'a str { self.haystack } + + #[inline] + fn next(&mut self) -> SearchStep { + match self.searcher { + StrSearcherImpl::Empty(ref mut searcher) => { + // empty needle rejects every char and matches every empty string between them + let is_match = searcher.is_match_fw; + searcher.is_match_fw = !searcher.is_match_fw; + let pos = searcher.position; + match self.haystack[pos..].chars().next() { + _ if is_match => SearchStep::Match(pos, pos), + None => SearchStep::Done, + Some(ch) => { + searcher.position += ch.len_utf8(); + SearchStep::Reject(pos, searcher.position) + } + } + } + StrSearcherImpl::TwoWay(ref mut searcher) => { + // TwoWaySearcher produces valid *Match* indices that split at char boundaries + // as long as it does correct matching and that haystack and needle are + // valid UTF-8 + // *Rejects* from the algorithm can fall on any indices, but we will walk them + // manually to the next character boundary, so that they are utf-8 safe. + if searcher.position == self.haystack.len() { + return SearchStep::Done; + } + let is_long = searcher.memory == usize::MAX; + match searcher.next::<RejectAndMatch>(self.haystack.as_bytes(), + self.needle.as_bytes(), + is_long) + { + SearchStep::Reject(a, mut b) => { + // skip to next char boundary + while !self.haystack.is_char_boundary(b) { + b += 1; + } + searcher.position = cmp::max(b, searcher.position); + SearchStep::Reject(a, b) + } + otherwise => otherwise, + } + } + } + } + + #[inline(always)] + fn next_match(&mut self) -> Option<(usize, usize)> { + match self.searcher { + StrSearcherImpl::Empty(..) => { + loop { + match self.next() { + SearchStep::Match(a, b) => return Some((a, b)), + SearchStep::Done => return None, + SearchStep::Reject(..) => { } + } + } + } + StrSearcherImpl::TwoWay(ref mut searcher) => { + let is_long = searcher.memory == usize::MAX; + // write out `true` and `false` cases to encourage the compiler + // to specialize the two cases separately. + if is_long { + searcher.next::<MatchOnly>(self.haystack.as_bytes(), + self.needle.as_bytes(), + true) + } else { + searcher.next::<MatchOnly>(self.haystack.as_bytes(), + self.needle.as_bytes(), + false) + } + } + } + } +} + +unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b> { + #[inline] + fn next_back(&mut self) -> SearchStep { + match self.searcher { + StrSearcherImpl::Empty(ref mut searcher) => { + let is_match = searcher.is_match_bw; + searcher.is_match_bw = !searcher.is_match_bw; + let end = searcher.end; + match self.haystack[..end].chars().next_back() { + _ if is_match => SearchStep::Match(end, end), + None => SearchStep::Done, + Some(ch) => { + searcher.end -= ch.len_utf8(); + SearchStep::Reject(searcher.end, end) + } + } + } + StrSearcherImpl::TwoWay(ref mut searcher) => { + if searcher.end == 0 { + return SearchStep::Done; + } + let is_long = searcher.memory == usize::MAX; + match searcher.next_back::<RejectAndMatch>(self.haystack.as_bytes(), + self.needle.as_bytes(), + is_long) + { + SearchStep::Reject(mut a, b) => { + // skip to next char boundary + while !self.haystack.is_char_boundary(a) { + a -= 1; + } + searcher.end = cmp::min(a, searcher.end); + SearchStep::Reject(a, b) + } + otherwise => otherwise, + } + } + } + } + + #[inline] + fn next_match_back(&mut self) -> Option<(usize, usize)> { + match self.searcher { + StrSearcherImpl::Empty(..) => { + loop { + match self.next_back() { + SearchStep::Match(a, b) => return Some((a, b)), + SearchStep::Done => return None, + SearchStep::Reject(..) => { } + } + } + } + StrSearcherImpl::TwoWay(ref mut searcher) => { + let is_long = searcher.memory == usize::MAX; + // write out `true` and `false`, like `next_match` + if is_long { + searcher.next_back::<MatchOnly>(self.haystack.as_bytes(), + self.needle.as_bytes(), + true) + } else { + searcher.next_back::<MatchOnly>(self.haystack.as_bytes(), + self.needle.as_bytes(), + false) + } + } + } + } +} + +/// The internal state of the two-way substring search algorithm. +#[derive(Clone, Debug)] +struct TwoWaySearcher { + // constants + /// critical factorization index + crit_pos: usize, + /// critical factorization index for reversed needle + crit_pos_back: usize, + period: usize, + /// `byteset` is an extension (not part of the two way algorithm); + /// it's a 64-bit "fingerprint" where each set bit `j` corresponds + /// to a (byte & 63) == j present in the needle. + byteset: u64, + + // variables + position: usize, + end: usize, + /// index into needle before which we have already matched + memory: usize, + /// index into needle after which we have already matched + memory_back: usize, +} + +/* + This is the Two-Way search algorithm, which was introduced in the paper: + Crochemore, M., Perrin, D., 1991, Two-way string-matching, Journal of the ACM 38(3):651-675. + + Here's some background information. + + A *word* is a string of symbols. The *length* of a word should be a familiar + notion, and here we denote it for any word x by |x|. + (We also allow for the possibility of the *empty word*, a word of length zero). + + If x is any non-empty word, then an integer p with 0 < p <= |x| is said to be a + *period* for x iff for all i with 0 <= i <= |x| - p - 1, we have x[i] == x[i+p]. + For example, both 1 and 2 are periods for the string "aa". As another example, + the only period of the string "abcd" is 4. + + We denote by period(x) the *smallest* period of x (provided that x is non-empty). + This is always well-defined since every non-empty word x has at least one period, + |x|. We sometimes call this *the period* of x. + + If u, v and x are words such that x = uv, where uv is the concatenation of u and + v, then we say that (u, v) is a *factorization* of x. + + Let (u, v) be a factorization for a word x. Then if w is a non-empty word such + that both of the following hold + + - either w is a suffix of u or u is a suffix of w + - either w is a prefix of v or v is a prefix of w + + then w is said to be a *repetition* for the factorization (u, v). + + Just to unpack this, there are four possibilities here. Let w = "abc". Then we + might have: + + - w is a suffix of u and w is a prefix of v. ex: ("lolabc", "abcde") + - w is a suffix of u and v is a prefix of w. ex: ("lolabc", "ab") + - u is a suffix of w and w is a prefix of v. ex: ("bc", "abchi") + - u is a suffix of w and v is a prefix of w. ex: ("bc", "a") + + Note that the word vu is a repetition for any factorization (u,v) of x = uv, + so every factorization has at least one repetition. + + If x is a string and (u, v) is a factorization for x, then a *local period* for + (u, v) is an integer r such that there is some word w such that |w| = r and w is + a repetition for (u, v). + + We denote by local_period(u, v) the smallest local period of (u, v). We sometimes + call this *the local period* of (u, v). Provided that x = uv is non-empty, this + is well-defined (because each non-empty word has at least one factorization, as + noted above). + + It can be proven that the following is an equivalent definition of a local period + for a factorization (u, v): any positive integer r such that x[i] == x[i+r] for + all i such that |u| - r <= i <= |u| - 1 and such that both x[i] and x[i+r] are + defined. (i.e. i > 0 and i + r < |x|). + + Using the above reformulation, it is easy to prove that + + 1 <= local_period(u, v) <= period(uv) + + A factorization (u, v) of x such that local_period(u,v) = period(x) is called a + *critical factorization*. + + The algorithm hinges on the following theorem, which is stated without proof: + + **Critical Factorization Theorem** Any word x has at least one critical + factorization (u, v) such that |u| < period(x). + + The purpose of maximal_suffix is to find such a critical factorization. + + If the period is short, compute another factorization x = u' v' to use + for reverse search, chosen instead so that |v'| < period(x). + +*/ +impl TwoWaySearcher { + fn new(needle: &[u8], end: usize) -> TwoWaySearcher { + let (crit_pos_false, period_false) = TwoWaySearcher::maximal_suffix(needle, false); + let (crit_pos_true, period_true) = TwoWaySearcher::maximal_suffix(needle, true); + + let (crit_pos, period) = + if crit_pos_false > crit_pos_true { + (crit_pos_false, period_false) + } else { + (crit_pos_true, period_true) + }; + + // A particularly readable explanation of what's going on here can be found + // in Crochemore and Rytter's book "Text Algorithms", ch 13. Specifically + // see the code for "Algorithm CP" on p. 323. + // + // What's going on is we have some critical factorization (u, v) of the + // needle, and we want to determine whether u is a suffix of + // &v[..period]. If it is, we use "Algorithm CP1". Otherwise we use + // "Algorithm CP2", which is optimized for when the period of the needle + // is large. + if &needle[..crit_pos] == &needle[period.. period + crit_pos] { + // short period case -- the period is exact + // compute a separate critical factorization for the reversed needle + // x = u' v' where |v'| < period(x). + // + // This is sped up by the period being known already. + // Note that a case like x = "acba" may be factored exactly forwards + // (crit_pos = 1, period = 3) while being factored with approximate + // period in reverse (crit_pos = 2, period = 2). We use the given + // reverse factorization but keep the exact period. + let crit_pos_back = needle.len() - cmp::max( + TwoWaySearcher::reverse_maximal_suffix(needle, period, false), + TwoWaySearcher::reverse_maximal_suffix(needle, period, true)); + + TwoWaySearcher { + crit_pos: crit_pos, + crit_pos_back: crit_pos_back, + period: period, + byteset: Self::byteset_create(&needle[..period]), + + position: 0, + end: end, + memory: 0, + memory_back: needle.len(), + } + } else { + // long period case -- we have an approximation to the actual period, + // and don't use memorization. + // + // Approximate the period by lower bound max(|u|, |v|) + 1. + // The critical factorization is efficient to use for both forward and + // reverse search. + + TwoWaySearcher { + crit_pos: crit_pos, + crit_pos_back: crit_pos, + period: cmp::max(crit_pos, needle.len() - crit_pos) + 1, + byteset: Self::byteset_create(needle), + + position: 0, + end: end, + memory: usize::MAX, // Dummy value to signify that the period is long + memory_back: usize::MAX, + } + } + } + + #[inline] + fn byteset_create(bytes: &[u8]) -> u64 { + bytes.iter().fold(0, |a, &b| (1 << (b & 0x3f)) | a) + } + + #[inline(always)] + fn byteset_contains(&self, byte: u8) -> bool { + (self.byteset >> ((byte & 0x3f) as usize)) & 1 != 0 + } + + // One of the main ideas of Two-Way is that we factorize the needle into + // two halves, (u, v), and begin trying to find v in the haystack by scanning + // left to right. If v matches, we try to match u by scanning right to left. + // How far we can jump when we encounter a mismatch is all based on the fact + // that (u, v) is a critical factorization for the needle. + #[inline(always)] + fn next<S>(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) + -> S::Output + where S: TwoWayStrategy + { + // `next()` uses `self.position` as its cursor + let old_pos = self.position; + let needle_last = needle.len() - 1; + 'search: loop { + // Check that we have room to search in + // position + needle_last can not overflow if we assume slices + // are bounded by isize's range. + let tail_byte = match haystack.get(self.position + needle_last) { + Some(&b) => b, + None => { + self.position = haystack.len(); + return S::rejecting(old_pos, self.position); + } + }; + + if S::use_early_reject() && old_pos != self.position { + return S::rejecting(old_pos, self.position); + } + + // Quickly skip by large portions unrelated to our substring + if !self.byteset_contains(tail_byte) { + self.position += needle.len(); + if !long_period { + self.memory = 0; + } + continue 'search; + } + + // See if the right part of the needle matches + let start = if long_period { self.crit_pos } + else { cmp::max(self.crit_pos, self.memory) }; + for i in start..needle.len() { + if needle[i] != haystack[self.position + i] { + self.position += i - self.crit_pos + 1; + if !long_period { + self.memory = 0; + } + continue 'search; + } + } + + // See if the left part of the needle matches + let start = if long_period { 0 } else { self.memory }; + for i in (start..self.crit_pos).rev() { + if needle[i] != haystack[self.position + i] { + self.position += self.period; + if !long_period { + self.memory = needle.len() - self.period; + } + continue 'search; + } + } + + // We have found a match! + let match_pos = self.position; + + // Note: add self.period instead of needle.len() to have overlapping matches + self.position += needle.len(); + if !long_period { + self.memory = 0; // set to needle.len() - self.period for overlapping matches + } + + return S::matching(match_pos, match_pos + needle.len()); + } + } + + // Follows the ideas in `next()`. + // + // The definitions are symmetrical, with period(x) = period(reverse(x)) + // and local_period(u, v) = local_period(reverse(v), reverse(u)), so if (u, v) + // is a critical factorization, so is (reverse(v), reverse(u)). + // + // For the reverse case we have computed a critical factorization x = u' v' + // (field `crit_pos_back`). We need |u| < period(x) for the forward case and + // thus |v'| < period(x) for the reverse. + // + // To search in reverse through the haystack, we search forward through + // a reversed haystack with a reversed needle, matching first u' and then v'. + #[inline] + fn next_back<S>(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) + -> S::Output + where S: TwoWayStrategy + { + // `next_back()` uses `self.end` as its cursor -- so that `next()` and `next_back()` + // are independent. + let old_end = self.end; + 'search: loop { + // Check that we have room to search in + // end - needle.len() will wrap around when there is no more room, + // but due to slice length limits it can never wrap all the way back + // into the length of haystack. + let front_byte = match haystack.get(self.end.wrapping_sub(needle.len())) { + Some(&b) => b, + None => { + self.end = 0; + return S::rejecting(0, old_end); + } + }; + + if S::use_early_reject() && old_end != self.end { + return S::rejecting(self.end, old_end); + } + + // Quickly skip by large portions unrelated to our substring + if !self.byteset_contains(front_byte) { + self.end -= needle.len(); + if !long_period { + self.memory_back = needle.len(); + } + continue 'search; + } + + // See if the left part of the needle matches + let crit = if long_period { self.crit_pos_back } + else { cmp::min(self.crit_pos_back, self.memory_back) }; + for i in (0..crit).rev() { + if needle[i] != haystack[self.end - needle.len() + i] { + self.end -= self.crit_pos_back - i; + if !long_period { + self.memory_back = needle.len(); + } + continue 'search; + } + } + + // See if the right part of the needle matches + let needle_end = if long_period { needle.len() } + else { self.memory_back }; + for i in self.crit_pos_back..needle_end { + if needle[i] != haystack[self.end - needle.len() + i] { + self.end -= self.period; + if !long_period { + self.memory_back = self.period; + } + continue 'search; + } + } + + // We have found a match! + let match_pos = self.end - needle.len(); + // Note: sub self.period instead of needle.len() to have overlapping matches + self.end -= needle.len(); + if !long_period { + self.memory_back = needle.len(); + } + + return S::matching(match_pos, match_pos + needle.len()); + } + } + + // Compute the maximal suffix of `arr`. + // + // The maximal suffix is a possible critical factorization (u, v) of `arr`. + // + // Returns (`i`, `p`) where `i` is the starting index of v and `p` is the + // period of v. + // + // `order_greater` determines if lexical order is `<` or `>`. Both + // orders must be computed -- the ordering with the largest `i` gives + // a critical factorization. + // + // For long period cases, the resulting period is not exact (it is too short). + #[inline] + fn maximal_suffix(arr: &[u8], order_greater: bool) -> (usize, usize) { + let mut left = 0; // Corresponds to i in the paper + let mut right = 1; // Corresponds to j in the paper + let mut offset = 0; // Corresponds to k in the paper, but starting at 0 + // to match 0-based indexing. + let mut period = 1; // Corresponds to p in the paper + + while let Some(&a) = arr.get(right + offset) { + // `left` will be inbounds when `right` is. + let b = arr[left + offset]; + if (a < b && !order_greater) || (a > b && order_greater) { + // Suffix is smaller, period is entire prefix so far. + right += offset + 1; + offset = 0; + period = right - left; + } else if a == b { + // Advance through repetition of the current period. + if offset + 1 == period { + right += offset + 1; + offset = 0; + } else { + offset += 1; + } + } else { + // Suffix is larger, start over from current location. + left = right; + right += 1; + offset = 0; + period = 1; + } + } + (left, period) + } + + // Compute the maximal suffix of the reverse of `arr`. + // + // The maximal suffix is a possible critical factorization (u', v') of `arr`. + // + // Returns `i` where `i` is the starting index of v', from the back; + // returns immedately when a period of `known_period` is reached. + // + // `order_greater` determines if lexical order is `<` or `>`. Both + // orders must be computed -- the ordering with the largest `i` gives + // a critical factorization. + // + // For long period cases, the resulting period is not exact (it is too short). + fn reverse_maximal_suffix(arr: &[u8], known_period: usize, + order_greater: bool) -> usize + { + let mut left = 0; // Corresponds to i in the paper + let mut right = 1; // Corresponds to j in the paper + let mut offset = 0; // Corresponds to k in the paper, but starting at 0 + // to match 0-based indexing. + let mut period = 1; // Corresponds to p in the paper + let n = arr.len(); + + while right + offset < n { + let a = arr[n - (1 + right + offset)]; + let b = arr[n - (1 + left + offset)]; + if (a < b && !order_greater) || (a > b && order_greater) { + // Suffix is smaller, period is entire prefix so far. + right += offset + 1; + offset = 0; + period = right - left; + } else if a == b { + // Advance through repetition of the current period. + if offset + 1 == period { + right += offset + 1; + offset = 0; + } else { + offset += 1; + } + } else { + // Suffix is larger, start over from current location. + left = right; + right += 1; + offset = 0; + period = 1; + } + if period == known_period { + break; + } + } + debug_assert!(period <= known_period); + left + } +} + +// TwoWayStrategy allows the algorithm to either skip non-matches as quickly +// as possible, or to work in a mode where it emits Rejects relatively quickly. +trait TwoWayStrategy { + type Output; + fn use_early_reject() -> bool; + fn rejecting(usize, usize) -> Self::Output; + fn matching(usize, usize) -> Self::Output; +} + +/// Skip to match intervals as quickly as possible +enum MatchOnly { } + +impl TwoWayStrategy for MatchOnly { + type Output = Option<(usize, usize)>; + + #[inline] + fn use_early_reject() -> bool { false } + #[inline] + fn rejecting(_a: usize, _b: usize) -> Self::Output { None } + #[inline] + fn matching(a: usize, b: usize) -> Self::Output { Some((a, b)) } +} + +/// Emit Rejects regularly +enum RejectAndMatch { } + +impl TwoWayStrategy for RejectAndMatch { + type Output = SearchStep; + + #[inline] + fn use_early_reject() -> bool { true } + #[inline] + fn rejecting(a: usize, b: usize) -> Self::Output { SearchStep::Reject(a, b) } + #[inline] + fn matching(a: usize, b: usize) -> Self::Output { SearchStep::Match(a, b) } +} diff --git a/libcore/sync/atomic.rs b/libcore/sync/atomic.rs new file mode 100644 index 0000000..483c382 --- /dev/null +++ b/libcore/sync/atomic.rs @@ -0,0 +1,1559 @@ +// Copyright 2012-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. + +//! Atomic types +//! +//! Atomic types provide primitive shared-memory communication between +//! threads, and are the building blocks of other concurrent +//! types. +//! +//! This module defines atomic versions of a select number of primitive +//! types, including `AtomicBool`, `AtomicIsize`, and `AtomicUsize`. +//! Atomic types present operations that, when used correctly, synchronize +//! updates between threads. +//! +//! Each method takes an `Ordering` which represents the strength of +//! the memory barrier for that operation. These orderings are the +//! same as [LLVM atomic orderings][1]. +//! +//! [1]: http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations +//! +//! Atomic variables are safe to share between threads (they implement `Sync`) +//! but they do not themselves provide the mechanism for sharing. The most +//! common way to share an atomic variable is to put it into an `Arc` (an +//! atomically-reference-counted shared pointer). +//! +//! Most atomic types may be stored in static variables, initialized using +//! the provided static initializers like `INIT_ATOMIC_BOOL`. Atomic statics +//! are often used for lazy global initialization. +//! +//! +//! # Examples +//! +//! A simple spinlock: +//! +//! ``` +//! use std::sync::Arc; +//! use std::sync::atomic::{AtomicUsize, Ordering}; +//! use std::thread; +//! +//! fn main() { +//! let spinlock = Arc::new(AtomicUsize::new(1)); +//! +//! let spinlock_clone = spinlock.clone(); +//! thread::spawn(move|| { +//! spinlock_clone.store(0, Ordering::SeqCst); +//! }); +//! +//! // Wait for the other thread to release the lock +//! while spinlock.load(Ordering::SeqCst) != 0 {} +//! } +//! ``` +//! +//! Keep a global count of live threads: +//! +//! ``` +//! use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; +//! +//! static GLOBAL_THREAD_COUNT: AtomicUsize = ATOMIC_USIZE_INIT; +//! +//! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::SeqCst); +//! println!("live threads: {}", old_thread_count + 1); +//! ``` + +#![stable(feature = "rust1", since = "1.0.0")] + +use self::Ordering::*; + +use marker::{Send, Sync}; + +use intrinsics; +use cell::UnsafeCell; + +use result::Result::{self, Ok, Err}; + +use default::Default; +use fmt; + +/// A boolean type which can be safely shared between threads. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct AtomicBool { + v: UnsafeCell<usize>, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for AtomicBool { + fn default() -> Self { + Self::new(Default::default()) + } +} + +// Send is implicitly implemented for AtomicBool. +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Sync for AtomicBool {} + +/// A signed integer type which can be safely shared between threads. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct AtomicIsize { + v: UnsafeCell<isize>, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for AtomicIsize { + fn default() -> Self { + Self::new(Default::default()) + } +} + +// Send is implicitly implemented for AtomicIsize. +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Sync for AtomicIsize {} + +/// An unsigned integer type which can be safely shared between threads. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct AtomicUsize { + v: UnsafeCell<usize>, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for AtomicUsize { + fn default() -> Self { + Self::new(Default::default()) + } +} + +// Send is implicitly implemented for AtomicUsize. +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Sync for AtomicUsize {} + +/// A raw pointer type which can be safely shared between threads. +#[stable(feature = "rust1", since = "1.0.0")] +pub struct AtomicPtr<T> { + p: UnsafeCell<*mut T>, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<T> Default for AtomicPtr<T> { + fn default() -> AtomicPtr<T> { + AtomicPtr::new(::ptr::null_mut()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<T> Send for AtomicPtr<T> {} +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<T> Sync for AtomicPtr<T> {} + +/// Atomic memory orderings +/// +/// Memory orderings limit the ways that both the compiler and CPU may reorder +/// instructions around atomic operations. At its most restrictive, +/// "sequentially consistent" atomics allow neither reads nor writes +/// to be moved either before or after the atomic operation; on the other end +/// "relaxed" atomics allow all reorderings. +/// +/// Rust's memory orderings are [the same as +/// LLVM's](http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations). +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Copy, Clone, Debug)] +pub enum Ordering { + /// No ordering constraints, only atomic operations. Corresponds to LLVM's + /// `Monotonic` ordering. + #[stable(feature = "rust1", since = "1.0.0")] + Relaxed, + /// When coupled with a store, all previous writes become visible + /// to another thread that performs a load with `Acquire` ordering + /// on the same value. + #[stable(feature = "rust1", since = "1.0.0")] + Release, + /// When coupled with a load, all subsequent loads will see data + /// written before a store with `Release` ordering on the same value + /// in another thread. + #[stable(feature = "rust1", since = "1.0.0")] + Acquire, + /// When coupled with a load, uses `Acquire` ordering, and with a store + /// `Release` ordering. + #[stable(feature = "rust1", since = "1.0.0")] + AcqRel, + /// Like `AcqRel` with the additional guarantee that all threads see all + /// sequentially consistent operations in the same order. + #[stable(feature = "rust1", since = "1.0.0")] + SeqCst, +} + +/// An `AtomicBool` initialized to `false`. +#[stable(feature = "rust1", since = "1.0.0")] +pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false); +/// An `AtomicIsize` initialized to `0`. +#[stable(feature = "rust1", since = "1.0.0")] +pub const ATOMIC_ISIZE_INIT: AtomicIsize = AtomicIsize::new(0); +/// An `AtomicUsize` initialized to `0`. +#[stable(feature = "rust1", since = "1.0.0")] +pub const ATOMIC_USIZE_INIT: AtomicUsize = AtomicUsize::new(0); + +// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly +const UINT_TRUE: usize = !0; + +impl AtomicBool { + /// Creates a new `AtomicBool`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::AtomicBool; + /// + /// let atomic_true = AtomicBool::new(true); + /// let atomic_false = AtomicBool::new(false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub const fn new(v: bool) -> AtomicBool { + AtomicBool { v: UnsafeCell::new(-(v as isize) as usize) } + } + + /// Loads a value from the bool. + /// + /// `load` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Panics + /// + /// Panics if `order` is `Release` or `AcqRel`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// assert_eq!(some_bool.load(Ordering::Relaxed), true); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn load(&self, order: Ordering) -> bool { + unsafe { atomic_load(self.v.get(), order) > 0 } + } + + /// Stores a value into the bool. + /// + /// `store` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// some_bool.store(false, Ordering::Relaxed); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// ``` + /// + /// # Panics + /// + /// Panics if `order` is `Acquire` or `AcqRel`. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn store(&self, val: bool, order: Ordering) { + let val = if val { UINT_TRUE } else { 0 }; + + unsafe { atomic_store(self.v.get(), val, order); } + } + + /// Stores a value into the bool, returning the old value. + /// + /// `swap` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// assert_eq!(some_bool.swap(false, Ordering::Relaxed), true); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn swap(&self, val: bool, order: Ordering) -> bool { + let val = if val { UINT_TRUE } else { 0 }; + + unsafe { atomic_swap(self.v.get(), val, order) > 0 } + } + + /// Stores a value into the `bool` if the current value is the same as the `current` value. + /// + /// The return value is always the previous value. If it is equal to `current`, then the value + /// was updated. + /// + /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of + /// this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// assert_eq!(some_bool.compare_and_swap(true, false, Ordering::Relaxed), true); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// + /// assert_eq!(some_bool.compare_and_swap(true, true, Ordering::Relaxed), false); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool { + match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } + } + + /// Stores a value into the `bool` if the current value is the same as the `current` value. + /// + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `new`. + /// + /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this + /// operation. The first describes the required ordering if the operation succeeds while the + /// second describes the required ordering when the operation fails. The failure ordering can't + /// be `Release` or `AcqRel` and must be equivalent or weaker than the success ordering. + /// + /// # Examples + /// + /// ``` + /// # #![feature(extended_compare_and_swap)] + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let some_bool = AtomicBool::new(true); + /// + /// assert_eq!(some_bool.compare_exchange(true, + /// false, + /// Ordering::Acquire, + /// Ordering::Relaxed), + /// Ok(true)); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// + /// assert_eq!(some_bool.compare_exchange(true, true, + /// Ordering::SeqCst, + /// Ordering::Acquire), + /// Err(false)); + /// assert_eq!(some_bool.load(Ordering::Relaxed), false); + /// ``` + #[inline] + #[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")] + pub fn compare_exchange(&self, + current: bool, + new: bool, + success: Ordering, + failure: Ordering) -> Result<bool, bool> { + let current = if current { UINT_TRUE } else { 0 }; + let new = if new { UINT_TRUE } else { 0 }; + + match unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } { + Ok(x) => Ok(x > 0), + Err(x) => Err(x > 0), + } + } + + /// Stores a value into the `bool` if the current value is the same as the `current` value. + /// + /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the + /// comparison succeeds, which can result in more efficient code on some platforms. The + /// return value is a result indicating whether the new value was written and containing the + /// previous value. + /// + /// `compare_exchange_weak` takes two `Ordering` arguments to describe the memory + /// ordering of this operation. The first describes the required ordering if the operation + /// succeeds while the second describes the required ordering when the operation fails. The + /// failure ordering can't be `Release` or `AcqRel` and must be equivalent or weaker than the + /// success ordering. + /// + /// # Examples + /// + /// ``` + /// # #![feature(extended_compare_and_swap)] + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let val = AtomicBool::new(false); + /// + /// let new = true; + /// let mut old = val.load(Ordering::Relaxed); + /// loop { + /// match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, + /// } + /// } + /// ``` + #[inline] + #[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")] + pub fn compare_exchange_weak(&self, + current: bool, + new: bool, + success: Ordering, + failure: Ordering) -> Result<bool, bool> { + let current = if current { UINT_TRUE } else { 0 }; + let new = if new { UINT_TRUE } else { 0 }; + + match unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, + success, failure) } { + Ok(x) => Ok(x > 0), + Err(x) => Err(x > 0), + } + } + + /// Logical "and" with a boolean value. + /// + /// Performs a logical "and" operation on the current value and the argument `val`, and sets + /// the new value to the result. + /// + /// Returns the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_and(true, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_and(false, Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { + let val = if val { UINT_TRUE } else { 0 }; + + unsafe { atomic_and(self.v.get(), val, order) > 0 } + } + + /// Logical "nand" with a boolean value. + /// + /// Performs a logical "nand" operation on the current value and the argument `val`, and sets + /// the new value to the result. + /// + /// Returns the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_nand(true, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst) as usize, 0); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_nand(false, Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool { + let val = if val { UINT_TRUE } else { 0 }; + + unsafe { atomic_nand(self.v.get(), val, order) > 0 } + } + + /// Logical "or" with a boolean value. + /// + /// Performs a logical "or" operation on the current value and the argument `val`, and sets the + /// new value to the result. + /// + /// Returns the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_or(true, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_or(false, Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { + let val = if val { UINT_TRUE } else { 0 }; + + unsafe { atomic_or(self.v.get(), val, order) > 0 } + } + + /// Logical "xor" with a boolean value. + /// + /// Performs a logical "xor" operation on the current value and the argument `val`, and sets + /// the new value to the result. + /// + /// Returns the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_xor(true, Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_xor(false, Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { + let val = if val { UINT_TRUE } else { 0 }; + + unsafe { atomic_xor(self.v.get(), val, order) > 0 } + } +} + +impl AtomicIsize { + /// Creates a new `AtomicIsize`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::AtomicIsize; + /// + /// let atomic_forty_two = AtomicIsize::new(42); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub const fn new(v: isize) -> AtomicIsize { + AtomicIsize {v: UnsafeCell::new(v)} + } + + /// Loads a value from the isize. + /// + /// `load` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Panics + /// + /// Panics if `order` is `Release` or `AcqRel`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let some_isize = AtomicIsize::new(5); + /// + /// assert_eq!(some_isize.load(Ordering::Relaxed), 5); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn load(&self, order: Ordering) -> isize { + unsafe { atomic_load(self.v.get(), order) } + } + + /// Stores a value into the isize. + /// + /// `store` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let some_isize = AtomicIsize::new(5); + /// + /// some_isize.store(10, Ordering::Relaxed); + /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); + /// ``` + /// + /// # Panics + /// + /// Panics if `order` is `Acquire` or `AcqRel`. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn store(&self, val: isize, order: Ordering) { + unsafe { atomic_store(self.v.get(), val, order); } + } + + /// Stores a value into the isize, returning the old value. + /// + /// `swap` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let some_isize = AtomicIsize::new(5); + /// + /// assert_eq!(some_isize.swap(10, Ordering::Relaxed), 5); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn swap(&self, val: isize, order: Ordering) -> isize { + unsafe { atomic_swap(self.v.get(), val, order) } + } + + /// Stores a value into the `isize` if the current value is the same as the `current` value. + /// + /// The return value is always the previous value. If it is equal to `current`, then the value + /// was updated. + /// + /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of + /// this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let some_isize = AtomicIsize::new(5); + /// + /// assert_eq!(some_isize.compare_and_swap(5, 10, Ordering::Relaxed), 5); + /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); + /// + /// assert_eq!(some_isize.compare_and_swap(6, 12, Ordering::Relaxed), 10); + /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn compare_and_swap(&self, current: isize, new: isize, order: Ordering) -> isize { + match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } + } + + /// Stores a value into the `isize` if the current value is the same as the `current` value. + /// + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `new`. + /// + /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this + /// operation. The first describes the required ordering if the operation succeeds while the + /// second describes the required ordering when the operation fails. The failure ordering can't + /// be `Release` or `AcqRel` and must be equivalent or weaker than the success ordering. + /// + /// # Examples + /// + /// ``` + /// # #![feature(extended_compare_and_swap)] + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let some_isize = AtomicIsize::new(5); + /// + /// assert_eq!(some_isize.compare_exchange(5, 10, + /// Ordering::Acquire, + /// Ordering::Relaxed), + /// Ok(5)); + /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); + /// + /// assert_eq!(some_isize.compare_exchange(6, 12, + /// Ordering::SeqCst, + /// Ordering::Acquire), + /// Err(10)); + /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); + /// ``` + #[inline] + #[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")] + pub fn compare_exchange(&self, + current: isize, + new: isize, + success: Ordering, + failure: Ordering) -> Result<isize, isize> { + unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } + } + + /// Stores a value into the `isize` if the current value is the same as the `current` value. + /// + /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the + /// comparison succeeds, which can result in more efficient code on some platforms. The + /// return value is a result indicating whether the new value was written and containing the + /// previous value. + /// + /// `compare_exchange_weak` takes two `Ordering` arguments to describe the memory + /// ordering of this operation. The first describes the required ordering if the operation + /// succeeds while the second describes the required ordering when the operation fails. The + /// failure ordering can't be `Release` or `AcqRel` and must be equivalent or weaker than the + /// success ordering. + /// + /// # Examples + /// + /// ``` + /// # #![feature(extended_compare_and_swap)] + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let val = AtomicIsize::new(4); + /// + /// let mut old = val.load(Ordering::Relaxed); + /// loop { + /// let new = old * 2; + /// match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, + /// } + /// } + /// ``` + #[inline] + #[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")] + pub fn compare_exchange_weak(&self, + current: isize, + new: isize, + success: Ordering, + failure: Ordering) -> Result<isize, isize> { + unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) } + } + + /// Add an isize to the current value, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let foo = AtomicIsize::new(0); + /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0); + /// assert_eq!(foo.load(Ordering::SeqCst), 10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_add(&self, val: isize, order: Ordering) -> isize { + unsafe { atomic_add(self.v.get(), val, order) } + } + + /// Subtract an isize from the current value, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let foo = AtomicIsize::new(0); + /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 0); + /// assert_eq!(foo.load(Ordering::SeqCst), -10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_sub(&self, val: isize, order: Ordering) -> isize { + unsafe { atomic_sub(self.v.get(), val, order) } + } + + /// Bitwise and with the current isize, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let foo = AtomicIsize::new(0b101101); + /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101); + /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001); + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_and(&self, val: isize, order: Ordering) -> isize { + unsafe { atomic_and(self.v.get(), val, order) } + } + + /// Bitwise or with the current isize, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let foo = AtomicIsize::new(0b101101); + /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101); + /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111); + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_or(&self, val: isize, order: Ordering) -> isize { + unsafe { atomic_or(self.v.get(), val, order) } + } + + /// Bitwise xor with the current isize, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let foo = AtomicIsize::new(0b101101); + /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101); + /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110); + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_xor(&self, val: isize, order: Ordering) -> isize { + unsafe { atomic_xor(self.v.get(), val, order) } + } +} + +impl AtomicUsize { + /// Creates a new `AtomicUsize`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::AtomicUsize; + /// + /// let atomic_forty_two = AtomicUsize::new(42); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub const fn new(v: usize) -> AtomicUsize { + AtomicUsize { v: UnsafeCell::new(v) } + } + + /// Loads a value from the usize. + /// + /// `load` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Panics + /// + /// Panics if `order` is `Release` or `AcqRel`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let some_usize = AtomicUsize::new(5); + /// + /// assert_eq!(some_usize.load(Ordering::Relaxed), 5); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn load(&self, order: Ordering) -> usize { + unsafe { atomic_load(self.v.get(), order) } + } + + /// Stores a value into the usize. + /// + /// `store` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let some_usize = AtomicUsize::new(5); + /// + /// some_usize.store(10, Ordering::Relaxed); + /// assert_eq!(some_usize.load(Ordering::Relaxed), 10); + /// ``` + /// + /// # Panics + /// + /// Panics if `order` is `Acquire` or `AcqRel`. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn store(&self, val: usize, order: Ordering) { + unsafe { atomic_store(self.v.get(), val, order); } + } + + /// Stores a value into the usize, returning the old value. + /// + /// `swap` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let some_usize = AtomicUsize::new(5); + /// + /// assert_eq!(some_usize.swap(10, Ordering::Relaxed), 5); + /// assert_eq!(some_usize.load(Ordering::Relaxed), 10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn swap(&self, val: usize, order: Ordering) -> usize { + unsafe { atomic_swap(self.v.get(), val, order) } + } + + /// Stores a value into the `usize` if the current value is the same as the `current` value. + /// + /// The return value is always the previous value. If it is equal to `current`, then the value + /// was updated. + /// + /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of + /// this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let some_usize = AtomicUsize::new(5); + /// + /// assert_eq!(some_usize.compare_and_swap(5, 10, Ordering::Relaxed), 5); + /// assert_eq!(some_usize.load(Ordering::Relaxed), 10); + /// + /// assert_eq!(some_usize.compare_and_swap(6, 12, Ordering::Relaxed), 10); + /// assert_eq!(some_usize.load(Ordering::Relaxed), 10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn compare_and_swap(&self, current: usize, new: usize, order: Ordering) -> usize { + match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } + } + + /// Stores a value into the `usize` if the current value is the same as the `current` value. + /// + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `new`. + /// + /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this + /// operation. The first describes the required ordering if the operation succeeds while the + /// second describes the required ordering when the operation fails. The failure ordering can't + /// be `Release` or `AcqRel` and must be equivalent or weaker than the success ordering. + /// + /// # Examples + /// + /// ``` + /// # #![feature(extended_compare_and_swap)] + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let some_isize = AtomicUsize::new(5); + /// + /// assert_eq!(some_isize.compare_exchange(5, 10, + /// Ordering::Acquire, + /// Ordering::Relaxed), + /// Ok(5)); + /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); + /// + /// assert_eq!(some_isize.compare_exchange(6, 12, + /// Ordering::SeqCst, + /// Ordering::Acquire), + /// Err(10)); + /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); + /// ``` + #[inline] + #[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")] + pub fn compare_exchange(&self, + current: usize, + new: usize, + success: Ordering, + failure: Ordering) -> Result<usize, usize> { + unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } + } + + /// Stores a value into the `usize` if the current value is the same as the `current` value. + /// + /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the + /// comparison succeeds, which can result in more efficient code on some platforms. The + /// return value is a result indicating whether the new value was written and containing the + /// previous value. + /// + /// `compare_exchange_weak` takes two `Ordering` arguments to describe the memory + /// ordering of this operation. The first describes the required ordering if the operation + /// succeeds while the second describes the required ordering when the operation fails. The + /// failure ordering can't be `Release` or `AcqRel` and must be equivalent or weaker than the + /// success ordering. + /// + /// # Examples + /// + /// ``` + /// # #![feature(extended_compare_and_swap)] + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let val = AtomicUsize::new(4); + /// + /// let mut old = val.load(Ordering::Relaxed); + /// loop { + /// let new = old * 2; + /// match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, + /// } + /// } + /// ``` + #[inline] + #[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")] + pub fn compare_exchange_weak(&self, + current: usize, + new: usize, + success: Ordering, + failure: Ordering) -> Result<usize, usize> { + unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) } + } + + /// Add to the current usize, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let foo = AtomicUsize::new(0); + /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0); + /// assert_eq!(foo.load(Ordering::SeqCst), 10); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_add(&self, val: usize, order: Ordering) -> usize { + unsafe { atomic_add(self.v.get(), val, order) } + } + + /// Subtract from the current usize, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let foo = AtomicUsize::new(10); + /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 10); + /// assert_eq!(foo.load(Ordering::SeqCst), 0); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_sub(&self, val: usize, order: Ordering) -> usize { + unsafe { atomic_sub(self.v.get(), val, order) } + } + + /// Bitwise and with the current usize, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let foo = AtomicUsize::new(0b101101); + /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101); + /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001); + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_and(&self, val: usize, order: Ordering) -> usize { + unsafe { atomic_and(self.v.get(), val, order) } + } + + /// Bitwise or with the current usize, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let foo = AtomicUsize::new(0b101101); + /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101); + /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111); + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_or(&self, val: usize, order: Ordering) -> usize { + unsafe { atomic_or(self.v.get(), val, order) } + } + + /// Bitwise xor with the current usize, returning the previous value. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicUsize, Ordering}; + /// + /// let foo = AtomicUsize::new(0b101101); + /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101); + /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110); + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn fetch_xor(&self, val: usize, order: Ordering) -> usize { + unsafe { atomic_xor(self.v.get(), val, order) } + } +} + +impl<T> AtomicPtr<T> { + /// Creates a new `AtomicPtr`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::AtomicPtr; + /// + /// let ptr = &mut 5; + /// let atomic_ptr = AtomicPtr::new(ptr); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub const fn new(p: *mut T) -> AtomicPtr<T> { + AtomicPtr { p: UnsafeCell::new(p) } + } + + /// Loads a value from the pointer. + /// + /// `load` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Panics + /// + /// Panics if `order` is `Release` or `AcqRel`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let value = some_ptr.load(Ordering::Relaxed); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn load(&self, order: Ordering) -> *mut T { + unsafe { + atomic_load(self.p.get() as *mut usize, order) as *mut T + } + } + + /// Stores a value into the pointer. + /// + /// `store` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10; + /// + /// some_ptr.store(other_ptr, Ordering::Relaxed); + /// ``` + /// + /// # Panics + /// + /// Panics if `order` is `Acquire` or `AcqRel`. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn store(&self, ptr: *mut T, order: Ordering) { + unsafe { atomic_store(self.p.get() as *mut usize, ptr as usize, order); } + } + + /// Stores a value into the pointer, returning the old value. + /// + /// `swap` takes an `Ordering` argument which describes the memory ordering of this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10; + /// + /// let value = some_ptr.swap(other_ptr, Ordering::Relaxed); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { + unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T } + } + + /// Stores a value into the pointer if the current value is the same as the `current` value. + /// + /// The return value is always the previous value. If it is equal to `current`, then the value + /// was updated. + /// + /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of + /// this operation. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10; + /// let another_ptr = &mut 10; + /// + /// let value = some_ptr.compare_and_swap(other_ptr, another_ptr, Ordering::Relaxed); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T { + match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } + } + + /// Stores a value into the pointer if the current value is the same as the `current` value. + /// + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `new`. + /// + /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this + /// operation. The first describes the required ordering if the operation succeeds while the + /// second describes the required ordering when the operation fails. The failure ordering can't + /// be `Release` or `AcqRel` and must be equivalent or weaker than the success ordering. + /// + /// # Examples + /// + /// ``` + /// # #![feature(extended_compare_and_swap)] + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let ptr = &mut 5; + /// let some_ptr = AtomicPtr::new(ptr); + /// + /// let other_ptr = &mut 10; + /// let another_ptr = &mut 10; + /// + /// let value = some_ptr.compare_exchange(other_ptr, another_ptr, + /// Ordering::SeqCst, Ordering::Relaxed); + /// ``` + #[inline] + #[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")] + pub fn compare_exchange(&self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering) -> Result<*mut T, *mut T> { + unsafe { + let res = atomic_compare_exchange(self.p.get() as *mut usize, + current as usize, + new as usize, + success, + failure); + match res { + Ok(x) => Ok(x as *mut T), + Err(x) => Err(x as *mut T), + } + } + } + + /// Stores a value into the pointer if the current value is the same as the `current` value. + /// + /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the + /// comparison succeeds, which can result in more efficient code on some platforms. The + /// return value is a result indicating whether the new value was written and containing the + /// previous value. + /// + /// `compare_exchange_weak` takes two `Ordering` arguments to describe the memory + /// ordering of this operation. The first describes the required ordering if the operation + /// succeeds while the second describes the required ordering when the operation fails. The + /// failure ordering can't be `Release` or `AcqRel` and must be equivalent or weaker than the + /// success ordering. + /// + /// # Examples + /// + /// ``` + /// # #![feature(extended_compare_and_swap)] + /// use std::sync::atomic::{AtomicPtr, Ordering}; + /// + /// let some_ptr = AtomicPtr::new(&mut 5); + /// + /// let new = &mut 10; + /// let mut old = some_ptr.load(Ordering::Relaxed); + /// loop { + /// match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, + /// } + /// } + /// ``` + #[inline] + #[unstable(feature = "extended_compare_and_swap", reason = "recently added", issue = "31767")] + pub fn compare_exchange_weak(&self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering) -> Result<*mut T, *mut T> { + unsafe { + let res = atomic_compare_exchange_weak(self.p.get() as *mut usize, + current as usize, + new as usize, + success, + failure); + match res { + Ok(x) => Ok(x as *mut T), + Err(x) => Err(x as *mut T), + } + } + } +} + +#[inline] +fn strongest_failure_ordering(order: Ordering) -> Ordering { + match order { + Release => Relaxed, + Relaxed => Relaxed, + SeqCst => SeqCst, + Acquire => Acquire, + AcqRel => Acquire, + } +} + +#[inline] +unsafe fn atomic_store<T>(dst: *mut T, val: T, order: Ordering) { + match order { + Release => intrinsics::atomic_store_rel(dst, val), + Relaxed => intrinsics::atomic_store_relaxed(dst, val), + SeqCst => intrinsics::atomic_store(dst, val), + Acquire => panic!("there is no such thing as an acquire store"), + AcqRel => panic!("there is no such thing as an acquire/release store"), + } +} + +#[inline] +unsafe fn atomic_load<T>(dst: *const T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_load_acq(dst), + Relaxed => intrinsics::atomic_load_relaxed(dst), + SeqCst => intrinsics::atomic_load(dst), + Release => panic!("there is no such thing as a release load"), + AcqRel => panic!("there is no such thing as an acquire/release load"), + } +} + +#[inline] +unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_xchg_acq(dst, val), + Release => intrinsics::atomic_xchg_rel(dst, val), + AcqRel => intrinsics::atomic_xchg_acqrel(dst, val), + Relaxed => intrinsics::atomic_xchg_relaxed(dst, val), + SeqCst => intrinsics::atomic_xchg(dst, val) + } +} + +/// Returns the old value (like __sync_fetch_and_add). +#[inline] +unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_xadd_acq(dst, val), + Release => intrinsics::atomic_xadd_rel(dst, val), + AcqRel => intrinsics::atomic_xadd_acqrel(dst, val), + Relaxed => intrinsics::atomic_xadd_relaxed(dst, val), + SeqCst => intrinsics::atomic_xadd(dst, val) + } +} + +/// Returns the old value (like __sync_fetch_and_sub). +#[inline] +unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_xsub_acq(dst, val), + Release => intrinsics::atomic_xsub_rel(dst, val), + AcqRel => intrinsics::atomic_xsub_acqrel(dst, val), + Relaxed => intrinsics::atomic_xsub_relaxed(dst, val), + SeqCst => intrinsics::atomic_xsub(dst, val) + } +} + +#[inline] +#[cfg(any(not(stage0), cargobuild))] +unsafe fn atomic_compare_exchange<T>(dst: *mut T, + old: T, + new: T, + success: Ordering, + failure: Ordering) -> Result<T, T> { + let (val, ok) = match (success, failure) { + (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new), + (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new), + (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new), + (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new), + (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new), + (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new), + (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new), + (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new), + (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new), + (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"), + (_, Release) => panic!("there is no such thing as a release failure ordering"), + _ => panic!("a failure ordering can't be stronger than a success ordering"), + }; + if ok { + Ok(val) + } else { + Err(val) + } +} + +#[inline] +#[cfg(all(stage0, not(cargobuild)))] +unsafe fn atomic_compare_exchange<T>(dst: *mut T, + old: T, + new: T, + success: Ordering, + _: Ordering) -> Result<T, T> + where T: ::cmp::Eq + ::marker::Copy +{ + let val = match success { + Acquire => intrinsics::atomic_cxchg_acq(dst, old, new), + Release => intrinsics::atomic_cxchg_rel(dst, old, new), + AcqRel => intrinsics::atomic_cxchg_acqrel(dst, old, new), + Relaxed => intrinsics::atomic_cxchg_relaxed(dst, old, new), + SeqCst => intrinsics::atomic_cxchg(dst, old, new), + }; + if val == old { + Ok(val) + } else { + Err(val) + } +} + +#[inline] +unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T, + old: T, + new: T, + success: Ordering, + failure: Ordering) -> Result<T, T> { + let (val, ok) = match (success, failure) { + (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new), + (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new), + (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new), + (Relaxed, Relaxed) => intrinsics::atomic_cxchgweak_relaxed(dst, old, new), + (SeqCst, SeqCst) => intrinsics::atomic_cxchgweak(dst, old, new), + (Acquire, Relaxed) => intrinsics::atomic_cxchgweak_acq_failrelaxed(dst, old, new), + (AcqRel, Relaxed) => intrinsics::atomic_cxchgweak_acqrel_failrelaxed(dst, old, new), + (SeqCst, Relaxed) => intrinsics::atomic_cxchgweak_failrelaxed(dst, old, new), + (SeqCst, Acquire) => intrinsics::atomic_cxchgweak_failacq(dst, old, new), + (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"), + (_, Release) => panic!("there is no such thing as a release failure ordering"), + _ => panic!("a failure ordering can't be stronger than a success ordering"), + }; + if ok { + Ok(val) + } else { + Err(val) + } +} + +#[inline] +unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_and_acq(dst, val), + Release => intrinsics::atomic_and_rel(dst, val), + AcqRel => intrinsics::atomic_and_acqrel(dst, val), + Relaxed => intrinsics::atomic_and_relaxed(dst, val), + SeqCst => intrinsics::atomic_and(dst, val) + } +} + +#[inline] +unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_nand_acq(dst, val), + Release => intrinsics::atomic_nand_rel(dst, val), + AcqRel => intrinsics::atomic_nand_acqrel(dst, val), + Relaxed => intrinsics::atomic_nand_relaxed(dst, val), + SeqCst => intrinsics::atomic_nand(dst, val) + } +} + + +#[inline] +unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_or_acq(dst, val), + Release => intrinsics::atomic_or_rel(dst, val), + AcqRel => intrinsics::atomic_or_acqrel(dst, val), + Relaxed => intrinsics::atomic_or_relaxed(dst, val), + SeqCst => intrinsics::atomic_or(dst, val) + } +} + + +#[inline] +unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_xor_acq(dst, val), + Release => intrinsics::atomic_xor_rel(dst, val), + AcqRel => intrinsics::atomic_xor_acqrel(dst, val), + Relaxed => intrinsics::atomic_xor_relaxed(dst, val), + SeqCst => intrinsics::atomic_xor(dst, val) + } +} + + +/// An atomic fence. +/// +/// A fence 'A' which has `Release` ordering semantics, synchronizes with a +/// fence 'B' with (at least) `Acquire` semantics, if and only if there exists +/// atomic operations X and Y, both operating on some atomic object 'M' such +/// that A is sequenced before X, Y is synchronized before B and Y observes +/// the change to M. This provides a happens-before dependence between A and B. +/// +/// Atomic operations with `Release` or `Acquire` semantics can also synchronize +/// with a fence. +/// +/// A fence which has `SeqCst` ordering, in addition to having both `Acquire` +/// and `Release` semantics, participates in the global program order of the +/// other `SeqCst` operations and/or fences. +/// +/// Accepts `Acquire`, `Release`, `AcqRel` and `SeqCst` orderings. +/// +/// # Panics +/// +/// Panics if `order` is `Relaxed`. +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn fence(order: Ordering) { + unsafe { + match order { + Acquire => intrinsics::atomic_fence_acq(), + Release => intrinsics::atomic_fence_rel(), + AcqRel => intrinsics::atomic_fence_acqrel(), + SeqCst => intrinsics::atomic_fence(), + Relaxed => panic!("there is no such thing as a relaxed fence") + } + } +} + +macro_rules! impl_Debug { + ($($t:ident)*) => ($( + #[stable(feature = "atomic_debug", since = "1.3.0")] + impl fmt::Debug for $t { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple(stringify!($t)).field(&self.load(Ordering::SeqCst)).finish() + } + } + )*); +} + +impl_Debug!{ AtomicUsize AtomicIsize AtomicBool } + +#[stable(feature = "atomic_debug", since = "1.3.0")] +impl<T> fmt::Debug for AtomicPtr<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("AtomicPtr").field(&self.load(Ordering::SeqCst)).finish() + } +} diff --git a/libcore/sync/mod.rs b/libcore/sync/mod.rs new file mode 100644 index 0000000..0080e0b --- /dev/null +++ b/libcore/sync/mod.rs @@ -0,0 +1,15 @@ +// Copyright 2015 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. + +//! Synchronization primitives + +#![stable(feature = "rust1", since = "1.0.0")] + +pub mod atomic; diff --git a/libcore/tuple.rs b/libcore/tuple.rs new file mode 100644 index 0000000..abaabfd --- /dev/null +++ b/libcore/tuple.rs @@ -0,0 +1,233 @@ +// Copyright 2012 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. + +// See src/libstd/primitive_docs.rs for documentation. + +use clone::Clone; +use cmp::*; +use cmp::Ordering::*; +use default::Default; +use option::Option; +use option::Option::Some; + +// FIXME(#19630) Remove this work-around +macro_rules! e { + ($e:expr) => { $e } +} + +// macro for implementing n-ary tuple functions and operations +macro_rules! tuple_impls { + ($( + $Tuple:ident { + $(($idx:tt) -> $T:ident)+ + } + )+) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T:Clone),+> Clone for ($($T,)+) { + fn clone(&self) -> ($($T,)+) { + ($(e!(self.$idx.clone()),)+) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T:PartialEq),+> PartialEq for ($($T,)+) { + #[inline] + fn eq(&self, other: &($($T,)+)) -> bool { + e!($(self.$idx == other.$idx)&&+) + } + #[inline] + fn ne(&self, other: &($($T,)+)) -> bool { + e!($(self.$idx != other.$idx)||+) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T:Eq),+> Eq for ($($T,)+) {} + + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) { + #[inline] + fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> { + lexical_partial_cmp!($(self.$idx, other.$idx),+) + } + #[inline] + fn lt(&self, other: &($($T,)+)) -> bool { + lexical_ord!(lt, $(self.$idx, other.$idx),+) + } + #[inline] + fn le(&self, other: &($($T,)+)) -> bool { + lexical_ord!(le, $(self.$idx, other.$idx),+) + } + #[inline] + fn ge(&self, other: &($($T,)+)) -> bool { + lexical_ord!(ge, $(self.$idx, other.$idx),+) + } + #[inline] + fn gt(&self, other: &($($T,)+)) -> bool { + lexical_ord!(gt, $(self.$idx, other.$idx),+) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T:Ord),+> Ord for ($($T,)+) { + #[inline] + fn cmp(&self, other: &($($T,)+)) -> Ordering { + lexical_cmp!($(self.$idx, other.$idx),+) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($T:Default),+> Default for ($($T,)+) { + #[inline] + fn default() -> ($($T,)+) { + ($({ let x: $T = Default::default(); x},)+) + } + } + )+ + } +} + +// Constructs an expression that performs a lexical ordering using method $rel. +// The values are interleaved, so the macro invocation for +// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2, +// a3, b3)` (and similarly for `lexical_cmp`) +macro_rules! lexical_ord { + ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => { + if $a != $b { lexical_ord!($rel, $a, $b) } + else { lexical_ord!($rel, $($rest_a, $rest_b),+) } + }; + ($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) }; +} + +macro_rules! lexical_partial_cmp { + ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => { + match ($a).partial_cmp(&$b) { + Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+), + ordering => ordering + } + }; + ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) }; +} + +macro_rules! lexical_cmp { + ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => { + match ($a).cmp(&$b) { + Equal => lexical_cmp!($($rest_a, $rest_b),+), + ordering => ordering + } + }; + ($a:expr, $b:expr) => { ($a).cmp(&$b) }; +} + +tuple_impls! { + Tuple1 { + (0) -> A + } + Tuple2 { + (0) -> A + (1) -> B + } + Tuple3 { + (0) -> A + (1) -> B + (2) -> C + } + Tuple4 { + (0) -> A + (1) -> B + (2) -> C + (3) -> D + } + Tuple5 { + (0) -> A + (1) -> B + (2) -> C + (3) -> D + (4) -> E + } + Tuple6 { + (0) -> A + (1) -> B + (2) -> C + (3) -> D + (4) -> E + (5) -> F + } + Tuple7 { + (0) -> A + (1) -> B + (2) -> C + (3) -> D + (4) -> E + (5) -> F + (6) -> G + } + Tuple8 { + (0) -> A + (1) -> B + (2) -> C + (3) -> D + (4) -> E + (5) -> F + (6) -> G + (7) -> H + } + Tuple9 { + (0) -> A + (1) -> B + (2) -> C + (3) -> D + (4) -> E + (5) -> F + (6) -> G + (7) -> H + (8) -> I + } + Tuple10 { + (0) -> A + (1) -> B + (2) -> C + (3) -> D + (4) -> E + (5) -> F + (6) -> G + (7) -> H + (8) -> I + (9) -> J + } + Tuple11 { + (0) -> A + (1) -> B + (2) -> C + (3) -> D + (4) -> E + (5) -> F + (6) -> G + (7) -> H + (8) -> I + (9) -> J + (10) -> K + } + Tuple12 { + (0) -> A + (1) -> B + (2) -> C + (3) -> D + (4) -> E + (5) -> F + (6) -> G + (7) -> H + (8) -> I + (9) -> J + (10) -> K + (11) -> L + } +} |