diff options
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/array.rs | 48 | ||||
| -rw-r--r-- | src/libcore/atomic.rs | 2 | ||||
| -rw-r--r-- | src/libcore/borrow.rs | 4 | ||||
| -rw-r--r-- | src/libcore/cell.rs | 27 | ||||
| -rw-r--r-- | src/libcore/char.rs | 5 | ||||
| -rw-r--r-- | src/libcore/clone.rs | 2 | ||||
| -rw-r--r-- | src/libcore/cmp.rs | 148 | ||||
| -rw-r--r-- | src/libcore/fmt/float.rs | 19 | ||||
| -rw-r--r-- | src/libcore/fmt/mod.rs | 93 | ||||
| -rw-r--r-- | src/libcore/fmt/num.rs | 2 | ||||
| -rw-r--r-- | src/libcore/hash/mod.rs | 2 | ||||
| -rw-r--r-- | src/libcore/hash/sip.rs | 4 | ||||
| -rw-r--r-- | src/libcore/iter.rs | 97 | ||||
| -rw-r--r-- | src/libcore/macros.rs | 65 | ||||
| -rw-r--r-- | src/libcore/ops.rs | 111 | ||||
| -rw-r--r-- | src/libcore/panicking.rs | 49 | ||||
| -rw-r--r-- | src/libcore/prelude.rs | 8 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 151 | ||||
| -rw-r--r-- | src/libcore/result.rs | 2 | ||||
| -rw-r--r-- | src/libcore/slice.rs | 365 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs (renamed from src/libcore/str.rs) | 259 | ||||
| -rw-r--r-- | src/libcore/tuple.rs | 8 | 
22 files changed, 716 insertions, 755 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs index e85a132ed36..28563a60b61 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -26,32 +26,33 @@ macro_rules! array_impls { ($($N:expr)+) => { $( #[stable] - impl<T:Copy> Clone for [T, ..$N] { - fn clone(&self) -> [T, ..$N] { + impl<T:Copy> Clone for [T; $N] { + fn clone(&self) -> [T; $N] { *self } } #[unstable = "waiting for Show to stabilize"] - impl<T:fmt::Show> fmt::Show for [T, ..$N] { + impl<T:fmt::Show> fmt::Show for [T; $N] { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Show::fmt(&self[], f) } } - #[unstable = "waiting for PartialEq to stabilize"] - impl<A, B> PartialEq<[B, ..$N]> for [A, ..$N] where A: PartialEq<B> { + #[stable] + impl<A, B> PartialEq<[B; $N]> for [A; $N] where A: PartialEq<B> { #[inline] - fn eq(&self, other: &[B, ..$N]) -> bool { + fn eq(&self, other: &[B; $N]) -> bool { self[] == other[] } #[inline] - fn ne(&self, other: &[B, ..$N]) -> bool { + fn ne(&self, other: &[B; $N]) -> bool { self[] != other[] } } - impl<'a, A, B, Rhs> PartialEq<Rhs> for [A, ..$N] where + #[stable] + impl<'a, A, B, Rhs> PartialEq<Rhs> for [A; $N] where A: PartialEq<B>, Rhs: Deref<[B]>, { @@ -61,47 +62,48 @@ macro_rules! array_impls { fn ne(&self, other: &Rhs) -> bool { PartialEq::ne(self[], &**other) } } - impl<'a, A, B, Lhs> PartialEq<[B, ..$N]> for Lhs where + #[stable] + impl<'a, A, B, Lhs> PartialEq<[B; $N]> for Lhs where A: PartialEq<B>, Lhs: Deref<[A]> { #[inline(always)] - fn eq(&self, other: &[B, ..$N]) -> bool { PartialEq::eq(&**self, other[]) } + fn eq(&self, other: &[B; $N]) -> bool { PartialEq::eq(&**self, other[]) } #[inline(always)] - fn ne(&self, other: &[B, ..$N]) -> bool { PartialEq::ne(&**self, other[]) } + fn ne(&self, other: &[B; $N]) -> bool { PartialEq::ne(&**self, other[]) } } - #[unstable = "waiting for Eq to stabilize"] - impl<T:Eq> Eq for [T, ..$N] { } + #[stable] + impl<T:Eq> Eq for [T; $N] { } - #[unstable = "waiting for PartialOrd to stabilize"] - impl<T:PartialOrd> PartialOrd for [T, ..$N] { + #[stable] + impl<T:PartialOrd> PartialOrd for [T; $N] { #[inline] - fn partial_cmp(&self, other: &[T, ..$N]) -> Option<Ordering> { + fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> { PartialOrd::partial_cmp(&self[], &other[]) } #[inline] - fn lt(&self, other: &[T, ..$N]) -> bool { + fn lt(&self, other: &[T; $N]) -> bool { PartialOrd::lt(&self[], &other[]) } #[inline] - fn le(&self, other: &[T, ..$N]) -> bool { + fn le(&self, other: &[T; $N]) -> bool { PartialOrd::le(&self[], &other[]) } #[inline] - fn ge(&self, other: &[T, ..$N]) -> bool { + fn ge(&self, other: &[T; $N]) -> bool { PartialOrd::ge(&self[], &other[]) } #[inline] - fn gt(&self, other: &[T, ..$N]) -> bool { + fn gt(&self, other: &[T; $N]) -> bool { PartialOrd::gt(&self[], &other[]) } } - #[unstable = "waiting for Ord to stabilize"] - impl<T:Ord> Ord for [T, ..$N] { + #[stable] + impl<T:Ord> Ord for [T; $N] { #[inline] - fn cmp(&self, other: &[T, ..$N]) -> Ordering { + fn cmp(&self, other: &[T; $N]) -> Ordering { Ord::cmp(&self[], &other[]) } } diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index 9452d0a64bf..6a40915f4dd 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -12,7 +12,7 @@ #![stable] -pub use self::Ordering::*; +use self::Ordering::*; use kinds::Sync; diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 9bbcf67773e..3a2cb8ea7d9 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -200,8 +200,10 @@ impl<'a, T, Sized? B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T> { } } +#[stable] impl<'a, T, Sized? B> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {} +#[stable] impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> { #[inline] fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering { @@ -209,6 +211,7 @@ impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> { } } +#[stable] impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where B: PartialEq<C> + ToOwned<T>, C: ToOwned<U>, @@ -219,6 +222,7 @@ impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B } } +#[stable] impl<'a, T, Sized? B> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> { #[inline] fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> { diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index b45424a5eed..4b246860006 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -158,7 +158,8 @@ use clone::Clone; use cmp::PartialEq; use default::Default; -use kinds::{marker, Copy}; +use fmt; +use kinds::{Copy, Send}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{None, Some}; @@ -167,7 +168,6 @@ use option::Option::{None, Some}; #[stable] pub struct Cell<T> { value: UnsafeCell<T>, - noshare: marker::NoSync, } impl<T:Copy> Cell<T> { @@ -176,7 +176,6 @@ impl<T:Copy> Cell<T> { pub fn new(value: T) -> Cell<T> { Cell { value: UnsafeCell::new(value), - noshare: marker::NoSync, } } @@ -209,6 +208,9 @@ impl<T:Copy> Cell<T> { } #[stable] +unsafe impl<T> Send for Cell<T> where T: Send {} + +#[stable] impl<T:Copy> Clone for Cell<T> { fn clone(&self) -> Cell<T> { Cell::new(self.get()) @@ -223,7 +225,7 @@ impl<T:Default + Copy> Default for Cell<T> { } } -#[unstable = "waiting for `PartialEq` trait to become stable"] +#[stable] impl<T:PartialEq + Copy> PartialEq for Cell<T> { fn eq(&self, other: &Cell<T>) -> bool { self.get() == other.get() @@ -235,7 +237,6 @@ impl<T:PartialEq + Copy> PartialEq for Cell<T> { pub struct RefCell<T> { value: UnsafeCell<T>, borrow: Cell<BorrowFlag>, - noshare: marker::NoSync, } // Values [1, MAX-1] represent the number of `Ref` active @@ -251,7 +252,6 @@ impl<T> RefCell<T> { RefCell { value: UnsafeCell::new(value), borrow: Cell::new(UNUSED), - noshare: marker::NoSync, } } @@ -342,6 +342,9 @@ impl<T> RefCell<T> { } #[stable] +unsafe impl<T> Send for RefCell<T> where T: Send {} + +#[stable] impl<T: Clone> Clone for RefCell<T> { fn clone(&self) -> RefCell<T> { RefCell::new(self.borrow().clone()) @@ -356,13 +359,23 @@ impl<T:Default> Default for RefCell<T> { } } -#[unstable = "waiting for `PartialEq` to become stable"] +#[stable] impl<T: PartialEq> PartialEq for RefCell<T> { fn eq(&self, other: &RefCell<T>) -> bool { *self.borrow() == *other.borrow() } } +#[unstable] +impl<T:fmt::Show> fmt::Show for RefCell<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.try_borrow() { + Some(val) => write!(f, "{}", val), + None => write!(f, "<borrowed RefCell>") + } + } +} + struct BorrowRef<'b> { _borrow: &'b Cell<BorrowFlag>, } diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 9c12b3f68d3..f0151dda8d7 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -430,11 +430,13 @@ impl Char for char { /// An iterator over the characters that represent a `char`, as escaped by /// Rust's unicode escaping rules. +#[deriving(Clone)] pub struct EscapeUnicode { c: char, state: EscapeUnicodeState } +#[deriving(Clone)] enum EscapeUnicodeState { Backslash, Type, @@ -486,10 +488,12 @@ impl Iterator<char> for EscapeUnicode { /// An iterator over the characters that represent a `char`, escaped /// for maximum portability. +#[deriving(Clone)] pub struct EscapeDefault { state: EscapeDefaultState } +#[deriving(Clone)] enum EscapeDefaultState { Backslash(char), Char(char), @@ -513,4 +517,3 @@ impl Iterator<char> for EscapeDefault { } } } - diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 686ccf6f1a2..5d84d0c7797 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -36,7 +36,7 @@ pub trait Clone { /// but can be overridden to reuse the resources of `a` to avoid unnecessary /// allocations. #[inline(always)] - #[unstable = "this function rarely unused"] + #[unstable = "this function is rarely used"] fn clone_from(&mut self, source: &Self) { *self = source.clone() } diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 4d72fb8ac92..38906892a33 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -46,27 +46,37 @@ use self::Ordering::*; use kinds::Sized; use option::Option::{mod, Some, None}; -/// Trait for values that can be compared for equality and inequality. +/// 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 an +/// 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`. -/// -/// Eventually, this will be implemented by default for types that implement -/// `Eq`. #[lang="eq"] -#[unstable = "Definition may change slightly after trait reform"] +#[stable] pub trait PartialEq<Sized? Rhs = Self> for Sized? { /// This method tests for `self` and `other` values to be equal, and is used by `==`. + #[stable] fn eq(&self, other: &Rhs) -> bool; /// This method tests for `!=`. #[inline] + #[stable] fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } } @@ -79,8 +89,8 @@ pub trait PartialEq<Sized? Rhs = Self> for Sized? { /// - reflexive: `a == a`; /// - symmetric: `a == b` implies `b == a`; and /// - transitive: `a == b` and `b == c` implies `a == c`. -#[unstable = "Definition may change slightly after trait reform"] -pub trait Eq<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> { +#[stable] +pub trait Eq for Sized?: 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 @@ -97,12 +107,15 @@ pub trait Eq<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> { #[deriving(Clone, Copy, PartialEq, Show)] #[stable] pub enum Ordering { - /// An ordering where a compared value is less [than another]. - Less = -1i, - /// An ordering where a compared value is equal [to another]. - Equal = 0i, - /// An ordering where a compared value is greater [than another]. - Greater = 1i, + /// An ordering where a compared value is less [than another]. + #[stable] + Less = -1i, + /// An ordering where a compared value is equal [to another]. + #[stable] + Equal = 0i, + /// An ordering where a compared value is greater [than another]. + #[stable] + Greater = 1i, } impl Ordering { @@ -127,7 +140,7 @@ impl Ordering { /// assert!(data == b); /// ``` #[inline] - #[experimental] + #[stable] pub fn reverse(self) -> Ordering { unsafe { // this compiles really nicely (to a single instruction); @@ -150,8 +163,8 @@ impl Ordering { /// true; and /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for /// both `==` and `>`. -#[unstable = "Definition may change slightly after trait reform"] -pub trait Ord<Sized? Rhs = Self> for Sized?: Eq<Rhs> + PartialOrd<Rhs> { +#[stable] +pub trait Ord for Sized?: Eq + PartialOrd<Self> { /// This method returns an ordering between `self` and `other` values. /// /// By convention, `self.cmp(&other)` returns the ordering matching @@ -164,23 +177,26 @@ pub trait Ord<Sized? Rhs = Self> for Sized?: Eq<Rhs> + PartialOrd<Rhs> { /// assert_eq!(10u.cmp(&5), Greater); // because 10 > 5 /// assert_eq!( 5u.cmp(&5), Equal); // because 5 == 5 /// ``` - fn cmp(&self, other: &Rhs) -> Ordering; + #[stable] + fn cmp(&self, other: &Self) -> Ordering; } -#[unstable = "Trait is unstable."] +#[stable] impl Eq for Ordering {} -#[unstable = "Trait is unstable."] +#[stable] impl Ord for Ordering { #[inline] + #[stable] fn cmp(&self, other: &Ordering) -> Ordering { (*self as int).cmp(&(*other as int)) } } -#[unstable = "Trait is unstable."] +#[stable] impl PartialOrd for Ordering { #[inline] + #[stable] fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> { (*self as int).partial_cmp(&(*other as int)) } @@ -188,6 +204,17 @@ impl PartialOrd for Ordering { /// 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)` and vice versa; 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. /// @@ -196,14 +223,16 @@ impl PartialOrd for Ordering { /// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section /// 5.11). #[lang="ord"] -#[unstable = "Definition may change slightly after trait reform"] +#[stable] pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> { /// This method returns an ordering between `self` and `other` values /// if one exists. + #[stable] fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>; /// This method tests less than (for `self` and `other`) and is used by the `<` operator. #[inline] + #[stable] fn lt(&self, other: &Rhs) -> bool { match self.partial_cmp(other) { Some(Less) => true, @@ -213,6 +242,7 @@ pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> { /// This method tests less than or equal to (`<=`). #[inline] + #[stable] fn le(&self, other: &Rhs) -> bool { match self.partial_cmp(other) { Some(Less) | Some(Equal) => true, @@ -222,6 +252,7 @@ pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> { /// This method tests greater than (`>`). #[inline] + #[stable] fn gt(&self, other: &Rhs) -> bool { match self.partial_cmp(other) { Some(Greater) => true, @@ -231,6 +262,7 @@ pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> { /// This method tests greater than or equal to (`>=`). #[inline] + #[stable] fn ge(&self, other: &Rhs) -> bool { match self.partial_cmp(other) { Some(Greater) | Some(Equal) => true, @@ -299,7 +331,7 @@ mod impls { macro_rules! partial_eq_impl { ($($t:ty)*) => ($( - #[unstable = "Trait is unstable."] + #[stable] impl PartialEq for $t { #[inline] fn eq(&self, other: &$t) -> bool { (*self) == (*other) } @@ -309,7 +341,7 @@ mod impls { )*) } - #[unstable = "Trait is unstable."] + #[stable] impl PartialEq for () { #[inline] fn eq(&self, _other: &()) -> bool { true } @@ -323,7 +355,7 @@ mod impls { macro_rules! eq_impl { ($($t:ty)*) => ($( - #[unstable = "Trait is unstable."] + #[stable] impl Eq for $t {} )*) } @@ -332,7 +364,7 @@ mod impls { macro_rules! partial_ord_impl { ($($t:ty)*) => ($( - #[unstable = "Trait is unstable."] + #[stable] impl PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &$t) -> Option<Ordering> { @@ -355,7 +387,7 @@ mod impls { )*) } - #[unstable = "Trait is unstable."] + #[stable] impl PartialOrd for () { #[inline] fn partial_cmp(&self, _: &()) -> Option<Ordering> { @@ -363,7 +395,7 @@ mod impls { } } - #[unstable = "Trait is unstable."] + #[stable] impl PartialOrd for bool { #[inline] fn partial_cmp(&self, other: &bool) -> Option<Ordering> { @@ -375,7 +407,7 @@ mod impls { macro_rules! ord_impl { ($($t:ty)*) => ($( - #[unstable = "Trait is unstable."] + #[stable] impl Ord for $t { #[inline] fn cmp(&self, other: &$t) -> Ordering { @@ -387,13 +419,13 @@ mod impls { )*) } - #[unstable = "Trait is unstable."] + #[stable] impl Ord for () { #[inline] fn cmp(&self, _other: &()) -> Ordering { Equal } } - #[unstable = "Trait is unstable."] + #[stable] impl Ord for bool { #[inline] fn cmp(&self, other: &bool) -> Ordering { @@ -405,68 +437,69 @@ mod impls { // & pointers - #[unstable = "Trait is unstable."] + #[stable] impl<'a, 'b, Sized? A, Sized? B> 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) } } - #[unstable = "Trait is unstable."] - impl<'a, Sized? T: PartialOrd> PartialOrd for &'a T { + #[stable] + impl<'a, 'b, Sized? A, Sized? B> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> { #[inline] - fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> { + fn partial_cmp(&self, other: &&'b B) -> Option<Ordering> { PartialOrd::partial_cmp(*self, *other) } #[inline] - fn lt(&self, other: & &'a T) -> bool { PartialOrd::lt(*self, *other) } + fn lt(&self, other: & &'b B) -> bool { PartialOrd::lt(*self, *other) } #[inline] - fn le(&self, other: & &'a T) -> bool { PartialOrd::le(*self, *other) } + fn le(&self, other: & &'b B) -> bool { PartialOrd::le(*self, *other) } #[inline] - fn ge(&self, other: & &'a T) -> bool { PartialOrd::ge(*self, *other) } + fn ge(&self, other: & &'b B) -> bool { PartialOrd::ge(*self, *other) } #[inline] - fn gt(&self, other: & &'a T) -> bool { PartialOrd::gt(*self, *other) } + fn gt(&self, other: & &'b B) -> bool { PartialOrd::gt(*self, *other) } } - #[unstable = "Trait is unstable."] - impl<'a, Sized? T: Ord> Ord for &'a T { + #[stable] + impl<'a, Sized? A> Ord for &'a A where A: Ord { #[inline] - fn cmp(&self, other: & &'a T) -> Ordering { Ord::cmp(*self, *other) } + fn cmp(&self, other: & &'a A) -> Ordering { Ord::cmp(*self, *other) } } - #[unstable = "Trait is unstable."] - impl<'a, Sized? T: Eq> Eq for &'a T {} + #[stable] + impl<'a, Sized? A> Eq for &'a A where A: Eq {} // &mut pointers - #[unstable = "Trait is unstable."] + #[stable] impl<'a, 'b, Sized? A, Sized? B> 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) } } - #[unstable = "Trait is unstable."] - impl<'a, Sized? T: PartialOrd> PartialOrd for &'a mut T { + #[stable] + impl<'a, 'b, Sized? A, Sized? B> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> { #[inline] - fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> { + fn partial_cmp(&self, other: &&'b mut B) -> Option<Ordering> { PartialOrd::partial_cmp(*self, *other) } #[inline] - fn lt(&self, other: &&'a mut T) -> bool { PartialOrd::lt(*self, *other) } + fn lt(&self, other: &&'b mut B) -> bool { PartialOrd::lt(*self, *other) } #[inline] - fn le(&self, other: &&'a mut T) -> bool { PartialOrd::le(*self, *other) } + fn le(&self, other: &&'b mut B) -> bool { PartialOrd::le(*self, *other) } #[inline] - fn ge(&self, other: &&'a mut T) -> bool { PartialOrd::ge(*self, *other) } + fn ge(&self, other: &&'b mut B) -> bool { PartialOrd::ge(*self, *other) } #[inline] - fn gt(&self, other: &&'a mut T) -> bool { PartialOrd::gt(*self, *other) } + fn gt(&self, other: &&'b mut B) -> bool { PartialOrd::gt(*self, *other) } } - #[unstable = "Trait is unstable."] - impl<'a, Sized? T: Ord> Ord for &'a mut T { + #[stable] + impl<'a, Sized? A> Ord for &'a mut A where A: Ord { #[inline] - fn cmp(&self, other: &&'a mut T) -> Ordering { Ord::cmp(*self, *other) } + fn cmp(&self, other: &&'a mut A) -> Ordering { Ord::cmp(*self, *other) } } - #[unstable = "Trait is unstable."] - impl<'a, Sized? T: Eq> Eq for &'a mut T {} + #[stable] + impl<'a, Sized? A> Eq for &'a mut A where A: Eq {} + #[stable] impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> { #[inline] fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) } @@ -474,6 +507,7 @@ mod impls { fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) } } + #[stable] impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> { #[inline] fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) } diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 47701ab8ffd..e1728d762ed 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -123,7 +123,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>( // For an f64 the exponent is in the range of [-1022, 1023] for base 2, so // we may have up to that many digits. Give ourselves some extra wiggle room // otherwise as well. - let mut buf = [0u8, ..1536]; + let mut buf = [0u8; 1536]; let mut end = 0; let radix_gen: T = cast(radix as int).unwrap(); @@ -179,7 +179,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>( _ => () } - buf[mut ..end].reverse(); + buf.slice_to_mut(end).reverse(); // Remember start of the fractional digits. // Points one beyond end of buf if none get generated, @@ -225,10 +225,10 @@ pub fn float_to_str_bytes_common<T: Float, U, F>( // cut off the one extra digit, and depending on its value // round the remaining ones. if limit_digits && dig == digit_count { - let ascii2value = |chr: u8| { + let ascii2value = |&: chr: u8| { (chr as char).to_digit(radix).unwrap() }; - let value2ascii = |val: uint| { + let value2ascii = |&: val: uint| { char::from_digit(val, radix).unwrap() as u8 }; @@ -316,7 +316,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>( impl<'a> fmt::FormatWriter for Filler<'a> { fn write(&mut self, bytes: &[u8]) -> fmt::Result { - slice::bytes::copy_memory(self.buf[mut *self.end..], + slice::bytes::copy_memory(self.buf.slice_from_mut(*self.end), bytes); *self.end += bytes.len(); Ok(()) @@ -325,18 +325,9 @@ pub fn float_to_str_bytes_common<T: Float, U, F>( let mut filler = Filler { buf: &mut buf, end: &mut end }; match sign { - // NOTE(stage0): Remove cfg after a snapshot - #[cfg(not(stage0))] SignNeg => { let _ = fmt::write(&mut filler, format_args!("{:-}", exp)); } - // NOTE(stage0): Remove match arm after a snapshot - #[cfg(stage0)] - SignNeg => { - let _ = format_args!(|args| { - fmt::write(&mut filler, args) - }, "{:-}", exp); - } } } } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index b050b98de2f..87fcb12e29f 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -70,21 +70,11 @@ pub trait FormatWriter { /// This function will return an instance of `FormatError` on error. fn write(&mut self, bytes: &[u8]) -> Result; - // NOTE(stage0): Remove cfg after a snapshot - #[cfg(not(stage0))] /// Glue for usage of the `write!` macro with implementers of this trait. /// /// This method should generally not be invoked manually, but rather through /// the `write!` macro itself. fn write_fmt(&mut self, args: Arguments) -> Result { write(self, args) } - - // NOTE(stage0): Remove method after a snapshot - #[cfg(stage0)] - /// Glue for usage of the `write!` macro with implementers of this trait. - /// - /// This method should generally not be invoked manually, but rather through - /// the `write!` macro itself. - fn write_fmt(&mut self, args: &Arguments) -> Result { write(self, args) } } /// A struct to represent both where to emit formatting strings to and how they @@ -204,17 +194,9 @@ pub struct Arguments<'a> { } impl<'a> Show for Arguments<'a> { - // NOTE(stage0): Remove cfg after a snapshot - #[cfg(not(stage0))] fn fmt(&self, fmt: &mut Formatter) -> Result { write(fmt.buf, *self) } - - // NOTE(stage0): Remove method after a snapshot - #[cfg(stage0)] - fn fmt(&self, fmt: &mut Formatter) -> Result { - write(fmt.buf, self) - } } /// When a format is not otherwise specified, types are formatted by ascribing @@ -287,8 +269,6 @@ static DEFAULT_ARGUMENT: rt::Argument<'static> = rt::Argument { } }; -// NOTE(stage0): Remove cfg after a snapshot -#[cfg(not(stage0))] /// 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. @@ -342,61 +322,6 @@ pub fn write(output: &mut FormatWriter, args: Arguments) -> Result { Ok(()) } -// NOTE(stage0): Remove function after a snapshot -#[cfg(stage0)] -/// 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!` -#[experimental = "libcore and I/O have yet to be reconciled, and this is an \ - implementation detail which should not otherwise be exported"] -pub fn write(output: &mut FormatWriter, args: &Arguments) -> Result { - let mut formatter = Formatter { - flags: 0, - width: None, - precision: None, - buf: output, - align: rt::AlignUnknown, - 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 _ in range(0, args.args.len()) { - try!(formatter.buf.write(pieces.next().unwrap().as_bytes())); - try!(formatter.run(&DEFAULT_ARGUMENT)); - } - } - 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()) { - try!(formatter.buf.write(piece.as_bytes())); - try!(formatter.run(arg)); - } - } - } - - // There can be only one trailing string piece left. - match pieces.next() { - Some(piece) => { - try!(formatter.buf.write(piece.as_bytes())); - } - None => {} - } - - Ok(()) -} - impl<'a> Formatter<'a> { // First up is the collection of functions used to execute a format string @@ -473,9 +398,9 @@ impl<'a> Formatter<'a> { } // Writes the sign if it exists, and then the prefix if it was requested - let write_prefix = |f: &mut Formatter| { + let write_prefix = |&: f: &mut Formatter| { for c in sign.into_iter() { - let mut b = [0, ..4]; + let mut b = [0; 4]; let n = c.encode_utf8(&mut b).unwrap_or(0); try!(f.buf.write(b[..n])); } @@ -580,7 +505,7 @@ impl<'a> Formatter<'a> { rt::AlignCenter => (padding / 2, (padding + 1) / 2), }; - let mut fill = [0u8, ..4]; + let mut fill = [0u8; 4]; let len = self.fill.encode_utf8(&mut fill).unwrap_or(0); for _ in range(0, pre_pad) { @@ -603,22 +528,12 @@ impl<'a> Formatter<'a> { self.buf.write(data) } - // NOTE(stage0): Remove cfg after a snapshot - #[cfg(not(stage0))] /// Writes some formatted information into this instance #[unstable = "reconciling core and I/O may alter this definition"] pub fn write_fmt(&mut self, fmt: Arguments) -> Result { write(self.buf, fmt) } - // NOTE(stage0): Remove method after a snapshot - #[cfg(stage0)] - /// Writes some formatted information into this instance - #[unstable = "reconciling core and I/O may alter this definition"] - pub fn write_fmt(&mut self, fmt: &Arguments) -> Result { - write(self.buf, fmt) - } - /// Flags for formatting (packed version of rt::Flag) #[experimental = "return type may change and method was just created"] pub fn flags(&self) -> uint { self.flags } @@ -691,7 +606,7 @@ impl Show for char { fn fmt(&self, f: &mut Formatter) -> Result { use char::Char; - let mut utf8 = [0u8, ..4]; + let mut utf8 = [0u8; 4]; let amt = self.encode_utf8(&mut utf8).unwrap_or(0); let s: &str = unsafe { mem::transmute(utf8[..amt]) }; Show::fmt(s, f) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index cd8f226172a..7de3e847dc6 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -37,7 +37,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = Int::zero(); let is_positive = x >= zero; - let mut buf = [0u8, ..64]; + let mut buf = [0u8; 64]; let mut curr = buf.len(); let base = cast(self.base()).unwrap(); if is_positive { diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index c1aa605a455..d4d241752f2 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -100,7 +100,7 @@ macro_rules! impl_hash { impl<S: Writer> Hash<S> for $ty { #[inline] fn hash(&self, state: &mut S) { - let a: [u8, ..::$ty::BYTES] = unsafe { + let a: [u8; ::$ty::BYTES] = unsafe { mem::transmute((*self as $uty).to_le() as $ty) }; state.write(a.as_slice()) diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index ab6b0986c68..51c0827186d 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -292,7 +292,7 @@ mod tests { #[test] #[allow(unused_must_use)] fn test_siphash() { - let vecs : [[u8, ..8], ..64] = [ + let vecs : [[u8; 8]; 64] = [ [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ], [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ], [ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ], @@ -366,7 +366,7 @@ mod tests { let mut state_inc = SipState::new_with_keys(k0, k1); let mut state_full = SipState::new_with_keys(k0, k1); - fn to_hex_str(r: &[u8, ..8]) -> String { + fn to_hex_str(r: &[u8; 8]) -> String { let mut s = String::new(); for b in r.iter() { s.push_str(format!("{}", fmt::radix(*b, 16)).as_slice()); diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 9c3e53a1ace..7c53503b1ce 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -59,6 +59,7 @@ pub use self::MinMaxResult::*; use clone::Clone; use cmp; use cmp::Ord; +use default::Default; use mem; use num::{ToPrimitive, Int}; use ops::{Add, Deref, FnMut}; @@ -68,20 +69,6 @@ use uint; #[deprecated = "renamed to Extend"] pub use self::Extend as Extendable; -/// Conversion from an `Iterator` -#[unstable = "may be replaced by a more general conversion trait"] -pub trait FromIterator<A> { - /// Build a container with elements from an external iterator. - fn from_iter<T: Iterator<A>>(iterator: T) -> Self; -} - -/// A type growable from an `Iterator` implementation -#[unstable = "just renamed as part of collections reform"] -pub trait Extend<A> { - /// Extend a container with the elements yielded by an arbitrary iterator - fn extend<T: Iterator<A>>(&mut self, iterator: T); -} - /// An interface for dealing with "external iterators". These types of iterators /// can be resumed at any time as all state is stored internally as opposed to /// being located on the call stack. @@ -106,6 +93,20 @@ pub trait Iterator<A> { fn size_hint(&self) -> (uint, Option<uint>) { (0, None) } } +/// Conversion from an `Iterator` +#[unstable = "may be replaced by a more general conversion trait"] +pub trait FromIterator<A> { + /// Build a container with elements from an external iterator. + fn from_iter<T: Iterator<A>>(iterator: T) -> Self; +} + +/// A type growable from an `Iterator` implementation +#[unstable = "just renamed as part of collections reform"] +pub trait Extend<A> { + /// Extend a container with the elements yielded by an arbitrary iterator + fn extend<T: Iterator<A>>(&mut self, iterator: T); +} + #[unstable = "new convention for extension traits"] /// An extension trait providing numerous methods applicable to all iterators. pub trait IteratorExt<A>: Iterator<A> { @@ -223,7 +224,6 @@ pub trait IteratorExt<A>: Iterator<A> { Enumerate{iter: self, count: 0} } - /// Creates an iterator that has a `.peek()` method /// that returns an optional reference to the next element. /// @@ -471,6 +471,35 @@ pub trait IteratorExt<A>: Iterator<A> { FromIterator::from_iter(self) } + /// Loops through the entire iterator, collecting all of the elements into + /// one of two containers, depending on a predicate. The elements of the + /// first container satisfy the predicate, while the elements of the second + /// do not. + /// + /// ``` + /// let vec = vec![1i, 2i, 3i, 4i]; + /// let (even, odd): (Vec<int>, Vec<int>) = vec.into_iter().partition(|&n| n % 2 == 0); + /// assert_eq!(even, vec![2, 4]); + /// assert_eq!(odd, vec![1, 3]); + /// ``` + #[unstable = "recently added as part of collections reform"] + fn partition<B, F>(mut self, mut f: F) -> (B, B) where + B: Default + Extend<A>, F: FnMut(&A) -> bool + { + let mut left: B = Default::default(); + let mut right: B = Default::default(); + + for x in self { + if f(&x) { + left.extend(Some(x).into_iter()) + } else { + right.extend(Some(x).into_iter()) + } + } + + (left, right) + } + /// Loops through `n` iterations, returning the `n`th element of the /// iterator. /// @@ -661,6 +690,42 @@ pub trait IteratorExt<A>: Iterator<A> { #[unstable = "trait is unstable"] impl<A, I> IteratorExt<A> for I where I: Iterator<A> {} +/// Extention trait for iterators of pairs. +#[unstable = "newly added trait, likely to be merged with IteratorExt"] +pub trait IteratorPairExt<A, B>: Iterator<(A, B)> { + /// Converts an iterator of pairs into a pair of containers. + /// + /// Loops through the entire iterator, collecting the first component of + /// each item into one new container, and the second component into another. + fn unzip<FromA, FromB>(mut self) -> (FromA, FromB) where + FromA: Default + Extend<A>, FromB: Default + Extend<B> + { + struct SizeHint<A>(uint, Option<uint>); + impl<A> Iterator<A> for SizeHint<A> { + fn next(&mut self) -> Option<A> { None } + fn size_hint(&self) -> (uint, Option<uint>) { + (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)); + us.extend(SizeHint(lo, hi)); + + for (t, u) in self { + ts.extend(Some(t).into_iter()); + us.extend(Some(u).into_iter()); + } + + (ts, us) + } +} + +impl<A, B, I> IteratorPairExt<A, B> for I where I: Iterator<(A, B)> {} + /// A range iterator able to yield elements from both ends /// /// A `DoubleEndedIterator` can be thought of as a deque in that `next()` and `next_back()` exhaust @@ -972,7 +1037,7 @@ pub trait IteratorOrdExt<A> { /// ```rust /// use std::iter::{NoElements, OneElement, MinMax}; /// - /// let v: [int, ..0] = []; + /// let v: [int; 0] = []; /// assert_eq!(v.iter().min_max(), NoElements); /// /// let v = [1i]; diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 2cd9e7c4509..e8fbd9d930f 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -10,8 +10,6 @@ #![macro_escape] -// NOTE(stage0): Remove cfg after a snapshot -#[cfg(not(stage0))] /// Entry point of task panic, for details, see std::macros #[macro_export] macro_rules! panic { @@ -32,44 +30,6 @@ macro_rules! panic { }); } -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -/// Entry point of task panic, for details, see std::macros -#[macro_export] -macro_rules! panic { - () => ( - panic!("{}", "explicit panic") - ); - ($msg:expr) => ({ - static _MSG_FILE_LINE: (&'static str, &'static str, uint) = ($msg, file!(), line!()); - ::core::panicking::panic(&_MSG_FILE_LINE) - }); - ($fmt:expr, $($arg:tt)*) => ({ - // a closure can't have return type !, so we need a full - // function to pass to format_args!, *and* we need the - // file and line numbers right here; so an inner bare fn - // is our only choice. - // - // LLVM doesn't tend to inline this, presumably because begin_unwind_fmt - // is #[cold] and #[inline(never)] and because this is flagged as cold - // as returning !. We really do want this to be inlined, however, - // because it's just a tiny wrapper. Small wins (156K to 149K in size) - // were seen when forcing this to be inlined, and that number just goes - // up with the number of calls to panic!() - // - // 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. - #[inline(always)] - fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! { - static _FILE_LINE: (&'static str, uint) = (file!(), line!()); - ::core::panicking::panic_fmt(fmt, &_FILE_LINE) - } - format_args!(_run_fmt, $fmt, $($arg)*) - }); -} - /// Runtime assertion, for details see std::macros #[macro_export] macro_rules! assert { @@ -85,16 +45,6 @@ macro_rules! assert { ); } -/// Runtime assertion, only without `--cfg ndebug` -#[macro_export] -macro_rules! debug_assert { - ($(a:tt)*) => ({ - if cfg!(not(ndebug)) { - assert!($($a)*); - } - }) -} - /// Runtime assertion for equality, for details see std::macros #[macro_export] macro_rules! assert_eq { @@ -117,7 +67,7 @@ macro_rules! debug_assert_eq { }) } -/// Runtime assertion, disableable at compile time +/// Runtime assertion, disableable at compile time with `--cfg ndebug` #[macro_export] macro_rules! debug_assert { ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); }) @@ -129,25 +79,12 @@ macro_rules! try { ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) }) } -// NOTE(stage0): Remove cfg after a snapshot -#[cfg(not(stage0))] /// Writing a formatted string into a writer #[macro_export] macro_rules! write { ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*))) } -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -/// Writing a formatted string into a writer -#[macro_export] -macro_rules! write { - ($dst:expr, $($arg:tt)*) => ({ - let dst = &mut *$dst; - format_args!(|args| { dst.write_fmt(args) }, $($arg)*) - }) -} - /// Writing a formatted string plus a newline into a writer #[macro_export] macro_rules! writeln { diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index a2ef8d484a7..15016562699 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -314,60 +314,6 @@ rem_float_impl! { f64, fmod } /// ``` /// use std::ops::Neg; /// -/// #[deriving(Copy)] -/// struct Foo; -/// -/// impl Neg<Foo> for Foo { -/// fn neg(&self) -> Foo { -/// println!("Negating!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// -Foo; -/// } -/// ``` -// NOTE(stage0): Remove trait after a snapshot -#[cfg(stage0)] -#[lang="neg"] -pub trait Neg<Result> for Sized? { - /// The method for the unary `-` operator - fn neg(&self) -> Result; -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! neg_impl { - ($($t:ty)*) => ($( - impl Neg<$t> for $t { - #[inline] - fn neg(&self) -> $t { -*self } - } - )*) -} - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! neg_uint_impl { - ($t:ty, $t_signed:ty) => { - impl Neg<$t> for $t { - #[inline] - fn neg(&self) -> $t { -(*self as $t_signed) as $t } - } - } -} - -/// The `Neg` trait is used to specify the functionality of unary `-`. -/// -/// # Example -/// -/// 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 Copy for Foo {} @@ -383,14 +329,12 @@ macro_rules! neg_uint_impl { /// -Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="neg"] pub trait Neg<Result> { /// The method for the unary `-` operator fn neg(self) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! neg_impl { ($($t:ty)*) => ($( impl Neg<$t> for $t { @@ -400,7 +344,6 @@ macro_rules! neg_impl { )*) } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! neg_uint_impl { ($t:ty, $t_signed:ty) => { impl Neg<$t> for $t { @@ -429,50 +372,6 @@ neg_uint_impl! { u64, i64 } /// ``` /// use std::ops::Not; /// -/// #[deriving(Copy)] -/// struct Foo; -/// -/// impl Not<Foo> for Foo { -/// fn not(&self) -> Foo { -/// println!("Not-ing!"); -/// *self -/// } -/// } -/// -/// fn main() { -/// !Foo; -/// } -/// ``` -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -#[lang="not"] -pub trait Not<Result> for Sized? { - /// The method for the unary `!` operator - fn not(&self) -> Result; -} - - -// NOTE(stage0): Remove macro after a snapshot -#[cfg(stage0)] -macro_rules! not_impl { - ($($t:ty)*) => ($( - impl Not<$t> for $t { - #[inline] - fn not(&self) -> $t { !*self } - } - )*) -} - -/// The `Not` trait is used to specify the functionality of unary `!`. -/// -/// # Example -/// -/// 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 Copy for Foo {} @@ -488,14 +387,12 @@ macro_rules! not_impl { /// !Foo; /// } /// ``` -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot #[lang="not"] pub trait Not<Result> { /// The method for the unary `!` operator fn not(self) -> Result; } -#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot macro_rules! not_impl { ($($t:ty)*) => ($( impl Not<$t> for $t { @@ -946,6 +843,14 @@ impl<Idx: Clone + Step> Iterator<Idx> for RangeFrom<Idx> { } } +/// A range which is only bounded above. +#[deriving(Copy)] +#[lang="range_to"] +pub struct RangeTo<Idx> { + /// The upper bound of the range (exclusive). + pub end: Idx, +} + /// The `Deref` trait is used to specify the functionality of dereferencing /// operations like `*v`. diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index 32f09a4c17f..61b4284e1dd 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -31,11 +31,7 @@ #![allow(dead_code, missing_docs)] use fmt; -// NOTE(stage0): Remove import after a snapshot -#[cfg(stage0)] use intrinsics; -// NOTE(stage0): Remove cfg after a snapshot -#[cfg(not(stage0))] #[cold] #[inline(never)] // this is the slow path, always #[lang="panic"] pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! { @@ -43,22 +39,6 @@ pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! { panic_fmt(format_args!("{}", expr), &(file, line)) } -// NOTE(stage0): Remove function after a snapshot -#[cfg(stage0)] -#[cold] #[inline(never)] // this is the slow path, always -#[lang="panic"] -pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! { - let (expr, file, line) = *expr_file_line; - let ref file_line = (file, line); - format_args!(|args| -> () { - panic_fmt(args, file_line); - }, "{}", expr); - - unsafe { intrinsics::abort() } -} - -// NOTE(stage0): Remove cfg after a snapshot -#[cfg(not(stage0))] #[cold] #[inline(never)] #[lang="panic_bounds_check"] fn panic_bounds_check(file_line: &(&'static str, uint), @@ -67,20 +47,6 @@ fn panic_bounds_check(file_line: &(&'static str, uint), len, index), file_line) } -// NOTE(stage0): Remove function after a snapshot -#[cfg(stage0)] -#[cold] #[inline(never)] -#[lang="panic_bounds_check"] -fn panic_bounds_check(file_line: &(&'static str, uint), - index: uint, len: uint) -> ! { - format_args!(|args| -> () { - panic_fmt(args, file_line); - }, "index out of bounds: the len is {} but the index is {}", len, index); - unsafe { intrinsics::abort() } -} - -// NOTE(stage0): Remove cfg after a snapshot -#[cfg(not(stage0))] #[cold] #[inline(never)] pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, uint)) -> ! { #[allow(improper_ctypes)] @@ -91,18 +57,3 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, uint)) -> ! { let (file, line) = *file_line; unsafe { panic_impl(fmt, file, line) } } - -// NOTE(stage0): Remove function after a snapshot -#[cfg(stage0)] -#[cold] #[inline(never)] -pub fn panic_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! { - #[allow(improper_ctypes)] - extern { - #[lang = "panic_fmt"] - fn panic_impl(fmt: &fmt::Arguments, file: &'static str, - line: uint) -> !; - - } - let (file, line) = *file_line; - unsafe { panic_impl(fmt, file, line) } -} diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 1fc377cda0a..210850be13a 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -44,10 +44,10 @@ pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; pub use iter::{Extend, IteratorExt}; pub use iter::{Iterator, DoubleEndedIterator, DoubleEndedIteratorExt}; pub use iter::{IteratorCloneExt, CloneIteratorExt}; -pub use iter::{IteratorOrdExt, ExactSizeIterator}; +pub use iter::{IteratorOrdExt, ExactSizeIterator, IteratorPairExt}; pub use option::Option::{mod, Some, None}; -pub use ptr::RawPtr; +pub use ptr::{PtrExt, MutPtrExt}; pub use result::Result::{mod, Ok, Err}; -pub use str::{Str, StrExt}; -pub use slice::{PartialEqSliceExt, OrdSliceExt}; pub use slice::{AsSlice, SliceExt}; +pub use slice::{PartialEqSliceExt, OrdSliceExt}; +pub use str::{Str, StrExt}; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 8c724b4d852..faf1d781465 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -16,11 +16,10 @@ //! typically limited to a few patterns. //! //! Use the [`null` function](fn.null.html) to create null pointers, -//! the [`is_null`](trait.RawPtr.html#tymethod.is_null) -//! and [`is_not_null`](trait.RawPtr.html#method.is_not_null) -//! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null. -//! The `RawPtr` trait is imported by the prelude, so `is_null` etc. -//! work everywhere. The `RawPtr` also defines the `offset` method, +//! the [`is_null`](trait.PtrExt.html#tymethod.is_null) +//! methods of the [`PtrExt` trait](trait.PtrExt.html) to check for null. +//! The `PtrExt` trait is imported by the prelude, so `is_null` etc. +//! work everywhere. The `PtrExt` also defines the `offset` method, //! for pointer math. //! //! # Common ways to create unsafe pointers @@ -87,16 +86,16 @@ //! but C APIs hand out a lot of pointers generally, so are a common source //! of unsafe pointers in Rust. +#![stable] + use mem; use clone::Clone; use intrinsics; +use option::Option::{mod, Some, None}; use kinds::{Send, Sync}; -use option::Option; -use option::Option::{Some, None}; use cmp::{PartialEq, Eq, Ord, PartialOrd, Equiv}; -use cmp::Ordering; -use cmp::Ordering::{Less, Equal, Greater}; +use cmp::Ordering::{mod, Less, Equal, Greater}; // FIXME #19649: instrinsic docs don't render, so these have no docs :( @@ -121,7 +120,7 @@ pub use intrinsics::set_memory; /// assert!(p.is_null()); /// ``` #[inline] -#[unstable = "may need a different name after pending changes to pointer types"] +#[stable] pub fn null<T>() -> *const T { 0 as *const T } /// Creates a null mutable raw pointer. @@ -135,31 +134,31 @@ pub fn null<T>() -> *const T { 0 as *const T } /// assert!(p.is_null()); /// ``` #[inline] -#[unstable = "may need a different name after pending changes to pointer types"] +#[stable] pub fn null_mut<T>() -> *mut T { 0 as *mut T } -/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`. `count` may be `0`. +/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`. `count` may be +/// `0`. /// /// # Safety /// -/// Beyond accepting a raw pointer, this is unsafe because it will not drop the contents of `dst`, -/// and may be used to create invalid instances of `T`. +/// Beyond accepting a raw pointer, this is unsafe because it will not drop the +/// contents of `dst`, and may be used to create invalid instances of `T`. #[inline] -#[experimental = "uncertain about naming and semantics"] -#[allow(experimental)] +#[unstable = "may play a larger role in std::ptr future extensions"] pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) { set_memory(dst, 0, count); } /// Swaps the values at two mutable locations of the same type, without -/// deinitialising either. They may overlap, unlike `mem::swap` which is otherwise -/// equivalent. +/// deinitialising either. They may overlap, unlike `mem::swap` which is +/// otherwise equivalent. /// /// # Safety /// /// This is only unsafe because it accepts a raw pointer. #[inline] -#[unstable] +#[stable] 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(); @@ -183,7 +182,7 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) { /// This is only unsafe because it accepts a raw pointer. /// Otherwise, this operation is identical to `mem::replace`. #[inline] -#[unstable] +#[stable] pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T { mem::swap(mem::transmute(dest), &mut src); // cannot overlap src @@ -201,7 +200,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T { /// `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)] -#[unstable] +#[stable] pub unsafe fn read<T>(src: *const T) -> T { let mut tmp: T = mem::uninitialized(); copy_nonoverlapping_memory(&mut tmp, src, 1); @@ -214,8 +213,7 @@ pub unsafe fn read<T>(src: *const T) -> T { /// /// This is unsafe for the same reasons that `read` is unsafe. #[inline(always)] -#[experimental] -#[allow(experimental)] +#[unstable = "may play a larger role in std::ptr future extensions"] pub unsafe fn read_and_zero<T>(dest: *mut T) -> T { // Copy the data out from `dest`: let tmp = read(&*dest); @@ -226,8 +224,8 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T { tmp } -/// Overwrites a memory location with the given value without reading or dropping -/// the old value. +/// Overwrites a memory location with the given value without reading or +/// dropping the old value. /// /// # Safety /// @@ -235,36 +233,44 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T { /// not drop the contents of `dst`. This 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 overwritting memory -/// that has previously been `read` from. +/// This is appropriate for initializing uninitialized memory, or overwritting +/// memory that has previously been `read` from. #[inline] -#[unstable] +#[stable] pub unsafe fn write<T>(dst: *mut T, src: T) { intrinsics::move_val_init(&mut *dst, src) } /// Methods on raw pointers -pub trait RawPtr<T> { - /// Returns a null raw pointer. +#[stable] +pub trait PtrExt<T> { + /// Returns the null pointer. + #[deprecated = "call ptr::null instead"] fn null() -> Self; /// Returns true if the pointer is null. - fn is_null(&self) -> bool; + #[stable] + fn is_null(self) -> bool; - /// Returns true if the pointer is not null. - fn is_not_null(&self) -> bool { !self.is_null() } + /// Returns true if the pointer is not equal to the null pointer. + #[deprecated = "use !p.is_null() instead"] + fn is_not_null(self) -> bool { !self.is_null() } - /// Returns the address of the pointer. - fn to_uint(&self) -> uint; + /// Returns true if the pointer is not null. + #[deprecated = "use `as uint` instead"] + fn to_uint(self) -> uint; - /// Returns `None` if the pointer is null, or else returns a reference to the - /// value wrapped in `Some`. + /// 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. + /// 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. + #[unstable = "Option is not clearly the right return type, and we may want \ + to tie the return lifetime to a borrow of the raw pointer"] unsafe fn as_ref<'a>(&self) -> Option<&'a T>; /// Calculates the offset from a pointer. `count` is in units of T; e.g. a @@ -272,39 +278,51 @@ pub trait RawPtr<T> { /// /// # Safety /// - /// The offset must be in-bounds of the object, or one-byte-past-the-end. Otherwise - /// `offset` invokes Undefined Behaviour, regardless of whether the pointer is used. + /// The offset must be in-bounds of the object, or one-byte-past-the-end. + /// Otherwise `offset` invokes Undefined Behaviour, regardless of whether + /// the pointer is used. + #[stable] unsafe fn offset(self, count: int) -> Self; } /// Methods on mutable raw pointers -pub trait RawMutPtr<T>{ - /// Returns `None` if the pointer is null, or else returns a mutable reference - /// to the value wrapped in `Some`. +#[stable] +pub trait MutPtrExt<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. + #[unstable = "Option is not clearly the right return type, and we may want \ + to tie the return lifetime to a borrow of the raw pointer"] unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>; } -impl<T> RawPtr<T> for *const T { +#[stable] +impl<T> PtrExt<T> for *const T { #[inline] + #[deprecated = "call ptr::null instead"] fn null() -> *const T { null() } #[inline] - fn is_null(&self) -> bool { *self == RawPtr::null() } + #[stable] + fn is_null(self) -> bool { self as uint == 0 } #[inline] - fn to_uint(&self) -> uint { *self as uint } + #[deprecated = "use `as uint` instead"] + fn to_uint(self) -> uint { self as uint } #[inline] + #[stable] unsafe fn offset(self, count: int) -> *const T { intrinsics::offset(self, count) } #[inline] + #[unstable = "return value does not necessarily convey all possible \ + information"] unsafe fn as_ref<'a>(&self) -> Option<&'a T> { if self.is_null() { None @@ -314,22 +332,29 @@ impl<T> RawPtr<T> for *const T { } } -impl<T> RawPtr<T> for *mut T { +#[stable] +impl<T> PtrExt<T> for *mut T { #[inline] + #[deprecated = "call ptr::null instead"] fn null() -> *mut T { null_mut() } #[inline] - fn is_null(&self) -> bool { *self == RawPtr::null() } + #[stable] + fn is_null(self) -> bool { self as uint == 0 } #[inline] - fn to_uint(&self) -> uint { *self as uint } + #[deprecated = "use `as uint` instead"] + fn to_uint(self) -> uint { self as uint } #[inline] + #[stable] unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *const T, count) as *mut T } #[inline] + #[unstable = "return value does not necessarily convey all possible \ + information"] unsafe fn as_ref<'a>(&self) -> Option<&'a T> { if self.is_null() { None @@ -339,8 +364,11 @@ impl<T> RawPtr<T> for *mut T { } } -impl<T> RawMutPtr<T> for *mut T { +#[stable] +impl<T> MutPtrExt<T> for *mut T { #[inline] + #[unstable = "return value does not necessarily convey all possible \ + information"] unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> { if self.is_null() { None @@ -351,6 +379,7 @@ impl<T> RawMutPtr<T> for *mut T { } // Equality for pointers +#[stable] impl<T> PartialEq for *const T { #[inline] fn eq(&self, other: &*const T) -> bool { @@ -360,8 +389,10 @@ impl<T> PartialEq for *const T { fn ne(&self, other: &*const T) -> bool { !self.eq(other) } } +#[stable] impl<T> Eq for *const T {} +#[stable] impl<T> PartialEq for *mut T { #[inline] fn eq(&self, other: &*mut T) -> bool { @@ -371,6 +402,7 @@ impl<T> PartialEq for *mut T { fn ne(&self, other: &*mut T) -> bool { !self.eq(other) } } +#[stable] impl<T> Eq for *mut T {} // Equivalence for pointers @@ -411,6 +443,7 @@ mod externfnpointers { use mem; use cmp::PartialEq; + #[stable] impl<_R> PartialEq for extern "C" fn() -> _R { #[inline] fn eq(&self, other: &extern "C" fn() -> _R) -> bool { @@ -421,6 +454,7 @@ mod externfnpointers { } macro_rules! fnptreq { ($($p:ident),*) => { + #[stable] impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R { #[inline] fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool { @@ -440,6 +474,7 @@ mod externfnpointers { } // Comparison for pointers +#[stable] impl<T> Ord for *const T { #[inline] fn cmp(&self, other: &*const T) -> Ordering { @@ -453,6 +488,7 @@ impl<T> Ord for *const T { } } +#[stable] impl<T> PartialOrd for *const T { #[inline] fn partial_cmp(&self, other: &*const T) -> Option<Ordering> { @@ -472,6 +508,7 @@ impl<T> PartialOrd for *const T { fn ge(&self, other: &*const T) -> bool { *self >= *other } } +#[stable] impl<T> Ord for *mut T { #[inline] fn cmp(&self, other: &*mut T) -> Ordering { @@ -485,6 +522,7 @@ impl<T> Ord for *mut T { } } +#[stable] impl<T> PartialOrd for *mut T { #[inline] fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> { @@ -510,28 +548,33 @@ impl<T> PartialOrd for *mut T { /// raw `*mut T` (which conveys no particular ownership semantics). /// Useful for building abstractions like `Vec<T>` or `Box<T>`, which /// internally use raw pointers to manage the memory that they own. +#[unstable = "recently added to this module"] pub struct Unique<T>(pub *mut 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 = "recently added to this module"] unsafe impl<T:Send> 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 = "recently added to this module"] unsafe impl<T:Sync> Sync for Unique<T> { } impl<T> Unique<T> { /// Returns a null Unique. + #[unstable = "recently added to this module"] pub fn null() -> Unique<T> { - Unique(RawPtr::null()) + Unique(null_mut()) } /// Return an (unsafe) pointer into the memory owned by `self`. + #[unstable = "recently added to this module"] pub unsafe fn offset(self, offset: int) -> *mut T { - (self.0 as *const T).offset(offset) as *mut T + self.0.offset(offset) } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index c738f61e20a..3ebe191930b 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -332,7 +332,7 @@ impl<T, E> Result<T, E> { /// Convert from `Result<T, E>` to `Option<E>` /// - /// Converts `self` into an `Option<T>`, consuming `self`, + /// Converts `self` into an `Option<E>`, consuming `self`, /// and discarding the value, if any. /// /// # Example diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 26684864c4c..7d894ac697b 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -46,8 +46,10 @@ use num::Int; use ops::{FnMut, mod}; use option::Option; use option::Option::{None, Some}; +use result::Result; +use result::Result::{Ok, Err}; use ptr; -use ptr::RawPtr; +use ptr::PtrExt; use mem; use mem::size_of; use kinds::{Sized, marker}; @@ -68,23 +70,23 @@ pub trait SliceExt<T> for Sized? { fn slice_to<'a>(&'a self, end: uint) -> &'a [T]; fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]); fn iter<'a>(&'a self) -> Iter<'a, T>; - fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> + fn split<'a, P>(&'a self, pred: P) -> Split<'a, T, P> where P: FnMut(&T) -> bool; - fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> + fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, T, P> where P: FnMut(&T) -> bool; - fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> + fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, T, P> where P: FnMut(&T) -> bool; fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>; fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>; fn get<'a>(&'a self, index: uint) -> Option<&'a T>; - fn head<'a>(&'a self) -> Option<&'a T>; + fn first<'a>(&'a self) -> Option<&'a T>; fn tail<'a>(&'a self) -> &'a [T]; fn init<'a>(&'a self) -> &'a [T]; fn last<'a>(&'a self) -> Option<&'a T>; - unsafe fn unsafe_get<'a>(&'a self, index: uint) -> &'a T; + unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a T; fn as_ptr(&self) -> *const T; - fn binary_search<F>(&self, f: F) -> BinarySearchResult - where F: FnMut(&T) -> Ordering; + fn binary_search_by<F>(&self, f: F) -> Result<uint, uint> where + F: FnMut(&T) -> Ordering; fn len(&self) -> uint; fn is_empty(&self) -> bool { self.len() == 0 } fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>; @@ -93,21 +95,21 @@ pub trait SliceExt<T> for Sized? { fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T]; fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T]; fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T>; - fn head_mut<'a>(&'a mut self) -> Option<&'a mut T>; + fn first_mut<'a>(&'a mut self) -> Option<&'a mut T>; fn tail_mut<'a>(&'a mut self) -> &'a mut [T]; fn init_mut<'a>(&'a mut self) -> &'a mut [T]; fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>; - fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> + fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> where P: FnMut(&T) -> bool; - fn splitn_mut<P>(&mut self, n: uint, pred: P) -> SplitsN<MutSplits<T, P>> + fn splitn_mut<P>(&mut self, n: uint, pred: P) -> SplitNMut<T, P> where P: FnMut(&T) -> bool; - fn rsplitn_mut<P>(&mut self, n: uint, pred: P) -> SplitsN<MutSplits<T, P>> + fn rsplitn_mut<P>(&mut self, n: uint, pred: P) -> RSplitNMut<T, P> where P: FnMut(&T) -> bool; - fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> MutChunks<'a, T>; + fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, T>; fn swap(&mut self, a: uint, b: uint); fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]); fn reverse(&mut self); - unsafe fn unsafe_mut<'a>(&'a mut self, index: uint) -> &'a mut T; + unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T; fn as_mut_ptr(&mut self) -> *mut T; } @@ -145,11 +147,11 @@ impl<T> SliceExt<T> for [T] { unsafe { let p = self.as_ptr(); if mem::size_of::<T>() == 0 { - Iter{ptr: p, + Iter {ptr: p, end: (p as uint + self.len()) as *const T, marker: marker::ContravariantLifetime::<'a>} } else { - Iter{ptr: p, + Iter {ptr: p, end: p.offset(self.len() as int), marker: marker::ContravariantLifetime::<'a>} } @@ -157,8 +159,8 @@ impl<T> SliceExt<T> for [T] { } #[inline] - fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> where P: FnMut(&T) -> bool { - Splits { + fn split<'a, P>(&'a self, pred: P) -> Split<'a, T, P> where P: FnMut(&T) -> bool { + Split { v: self, pred: pred, finished: false @@ -166,24 +168,28 @@ impl<T> SliceExt<T> for [T] { } #[inline] - fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where + fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, T, P> where P: FnMut(&T) -> bool, { - SplitsN { - iter: self.split(pred), - count: n, - invert: false + SplitN { + inner: GenericSplitN { + iter: self.split(pred), + count: n, + invert: false + } } } #[inline] - fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, T, P>> where + fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, T, P> where P: FnMut(&T) -> bool, { - SplitsN { - iter: self.split(pred), - count: n, - invert: true + RSplitN { + inner: GenericSplitN { + iter: self.split(pred), + count: n, + invert: true + } } } @@ -205,7 +211,7 @@ impl<T> SliceExt<T> for [T] { } #[inline] - fn head(&self) -> Option<&T> { + fn first(&self) -> Option<&T> { if self.len() == 0 { None } else { Some(&self[0]) } } @@ -223,7 +229,7 @@ impl<T> SliceExt<T> for [T] { } #[inline] - unsafe fn unsafe_get(&self, index: uint) -> &T { + unsafe fn get_unchecked(&self, index: uint) -> &T { transmute(self.repr().data.offset(index as int)) } @@ -233,14 +239,16 @@ impl<T> SliceExt<T> for [T] { } #[unstable] - fn binary_search<F>(&self, mut f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering { + fn binary_search_by<F>(&self, mut f: F) -> Result<uint, uint> where + F: FnMut(&T) -> Ordering + { let mut base : uint = 0; let mut lim : uint = self.len(); while lim != 0 { let ix = base + (lim >> 1); match f(&self[ix]) { - Equal => return BinarySearchResult::Found(ix), + Equal => return Ok(ix), Less => { base = ix + 1; lim -= 1; @@ -249,7 +257,7 @@ impl<T> SliceExt<T> for [T] { } lim >>= 1; } - return BinarySearchResult::NotFound(base); + Err(base) } #[inline] @@ -264,24 +272,26 @@ impl<T> SliceExt<T> for [T] { fn as_mut_slice(&mut self) -> &mut [T] { self } fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] { - self[mut start..end] + ops::SliceMut::slice_or_fail_mut(self, &start, &end) } #[inline] fn slice_from_mut(&mut self, start: uint) -> &mut [T] { - self[mut start..] + ops::SliceMut::slice_from_or_fail_mut(self, &start) } #[inline] fn slice_to_mut(&mut self, end: uint) -> &mut [T] { - self[mut ..end] + ops::SliceMut::slice_to_or_fail_mut(self, &end) } #[inline] fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) { unsafe { let self2: &mut [T] = mem::transmute_copy(&self); - (self[mut ..mid], self2[mut mid..]) + + (ops::SliceMut::slice_to_or_fail_mut(self, &mid), + ops::SliceMut::slice_from_or_fail_mut(self2, &mid)) } } @@ -290,11 +300,11 @@ impl<T> SliceExt<T> for [T] { unsafe { let p = self.as_mut_ptr(); if mem::size_of::<T>() == 0 { - IterMut{ptr: p, + IterMut {ptr: p, end: (p as uint + self.len()) as *mut T, marker: marker::ContravariantLifetime::<'a>} } else { - IterMut{ptr: p, + IterMut {ptr: p, end: p.offset(self.len() as int), marker: marker::ContravariantLifetime::<'a>} } @@ -309,53 +319,56 @@ impl<T> SliceExt<T> for [T] { } #[inline] - fn head_mut(&mut self) -> Option<&mut T> { + fn first_mut(&mut self) -> Option<&mut T> { if self.len() == 0 { None } else { Some(&mut self[0]) } } #[inline] fn tail_mut(&mut self) -> &mut [T] { - let len = self.len(); - self[mut 1..len] + self.slice_from_mut(1) } #[inline] fn init_mut(&mut self) -> &mut [T] { let len = self.len(); - self[mut 0..len - 1] + self.slice_to_mut(len-1) } #[inline] - fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> where P: FnMut(&T) -> bool { - MutSplits { v: self, pred: pred, finished: false } + fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> where P: FnMut(&T) -> bool { + SplitMut { v: self, pred: pred, finished: false } } #[inline] - fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where + fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitNMut<'a, T, P> where P: FnMut(&T) -> bool { - SplitsN { - iter: self.split_mut(pred), - count: n, - invert: false + SplitNMut { + inner: GenericSplitN { + iter: self.split_mut(pred), + count: n, + invert: false + } } } #[inline] - fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN<MutSplits<'a, T, P>> where + fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> RSplitNMut<'a, T, P> where P: FnMut(&T) -> bool, { - SplitsN { - iter: self.split_mut(pred), - count: n, - invert: true + RSplitNMut { + inner: GenericSplitN { + iter: self.split_mut(pred), + count: n, + invert: true + } } } #[inline] - fn chunks_mut(&mut self, chunk_size: uint) -> MutChunks<T> { + fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut<T> { assert!(chunk_size > 0); - MutChunks { v: self, chunk_size: chunk_size } + ChunksMut { v: self, chunk_size: chunk_size } } fn swap(&mut self, a: uint, b: uint) { @@ -374,8 +387,8 @@ impl<T> SliceExt<T> for [T] { while i < ln / 2 { // Unsafe swap to avoid the bounds check in safe swap. unsafe { - let pa: *mut T = self.unsafe_mut(i); - let pb: *mut T = self.unsafe_mut(ln - i - 1); + 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; @@ -383,7 +396,7 @@ impl<T> SliceExt<T> for [T] { } #[inline] - unsafe fn unsafe_mut(&mut self, index: uint) -> &mut T { + unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T { transmute((self.repr().data as *mut T).offset(index as int)) } @@ -467,21 +480,26 @@ impl<T> ops::SliceMut<uint, [T]> for [T] { } /// Extension methods for slices containing `PartialEq` elements. -#[unstable = "may merge with other traits"] +#[unstable = "may merge with SliceExt"] pub trait PartialEqSliceExt<T: PartialEq> for Sized? { /// Find the first index containing a matching value. + #[experimental] fn position_elem(&self, t: &T) -> Option<uint>; /// Find the last index containing a matching value. + #[experimental] fn rposition_elem(&self, t: &T) -> Option<uint>; /// Return true if the slice contains an element with the given value. + #[stable] fn contains(&self, x: &T) -> bool; /// Returns true if `needle` is a prefix of the slice. + #[stable] fn starts_with(&self, needle: &[T]) -> bool; /// Returns true if `needle` is a suffix of the slice. + #[stable] fn ends_with(&self, needle: &[T]) -> bool; } @@ -519,19 +537,16 @@ impl<T: PartialEq> PartialEqSliceExt<T> for [T] { #[unstable = "may merge with other traits"] #[allow(missing_docs)] // docs in libcollections pub trait OrdSliceExt<T: Ord> for Sized? { - #[unstable = "name likely to change"] - fn binary_search_elem(&self, x: &T) -> BinarySearchResult; - #[experimental] + fn binary_search(&self, x: &T) -> Result<uint, uint>; fn next_permutation(&mut self) -> bool; - #[experimental] fn prev_permutation(&mut self) -> bool; } #[unstable = "trait is unstable"] impl<T: Ord> OrdSliceExt<T> for [T] { #[unstable] - fn binary_search_elem(&self, x: &T) -> BinarySearchResult { - self.binary_search(|p| p.cmp(x)) + fn binary_search(&self, x: &T) -> Result<uint, uint> { + self.binary_search_by(|p| p.cmp(x)) } #[experimental] @@ -560,7 +575,7 @@ impl<T: Ord> OrdSliceExt<T> for [T] { self.swap(j, i-1); // Step 4: Reverse the (previously) weakly decreasing part - self[mut i..].reverse(); + self.slice_from_mut(i).reverse(); true } @@ -582,7 +597,7 @@ impl<T: Ord> OrdSliceExt<T> for [T] { } // Step 2: Reverse the weakly increasing part - self[mut i..].reverse(); + self.slice_from_mut(i).reverse(); // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1) let mut j = self.len() - 1; @@ -618,28 +633,30 @@ impl<T: Clone> CloneSliceExt<T> for [T] { } } -// +//////////////////////////////////////////////////////////////////////////////// // Common traits -// +//////////////////////////////////////////////////////////////////////////////// /// Data that is viewable as a slice. -#[unstable = "may merge with other traits"] +#[experimental = "will be replaced by slice syntax"] pub trait AsSlice<T> for Sized? { /// Work with `self` as a slice. fn as_slice<'a>(&'a self) -> &'a [T]; } -#[unstable = "trait is unstable"] +#[experimental = "trait is experimental"] impl<T> AsSlice<T> for [T] { #[inline(always)] fn as_slice<'a>(&'a self) -> &'a [T] { self } } +#[experimental = "trait is experimental"] impl<'a, T, Sized? U: AsSlice<T>> AsSlice<T> for &'a U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } } +#[experimental = "trait is experimental"] impl<'a, T, Sized? U: AsSlice<T>> AsSlice<T> for &'a mut U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } @@ -655,7 +672,7 @@ impl<'a, T> Default for &'a [T] { // Iterators // -// The shared definition of the `Item` and `IterMut` iterators +// The shared definition of the `Iter` and `IterMut` iterators macro_rules! iterator { (struct $name:ident -> $ptr:ty, $elem:ty) => { #[experimental = "needs review"] @@ -735,9 +752,8 @@ macro_rules! make_slice { }} } - /// Immutable slice iterator -#[experimental = "needs review"] +#[stable] pub struct Iter<'a, T: 'a> { ptr: *const T, end: *const T, @@ -812,7 +828,7 @@ impl<'a, T> RandomAccessIterator<&'a T> for Iter<'a, T> { } /// Mutable slice iterator. -#[experimental = "needs review"] +#[stable] pub struct IterMut<'a, T: 'a> { ptr: *mut T, end: *mut T, @@ -875,9 +891,9 @@ iterator!{struct IterMut -> *mut T, &'a mut T} #[experimental = "needs review"] impl<'a, T> ExactSizeIterator<&'a mut T> for IterMut<'a, T> {} -/// An abstraction over the splitting iterators, so that splitn, splitn_mut etc -/// can be implemented once. -trait SplitsIter<E>: DoubleEndedIterator<E> { +/// An internal abstraction over the splitting iterators, so that +/// splitn, splitn_mut etc can be implemented once. +trait SplitIter<E>: DoubleEndedIterator<E> { /// Mark the underlying iterator as complete, extracting the remaining /// portion of the slice. fn finish(&mut self) -> Option<E>; @@ -885,8 +901,8 @@ trait SplitsIter<E>: DoubleEndedIterator<E> { /// An iterator over subslices separated by elements that match a predicate /// function. -#[experimental = "needs review"] -pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool { +#[stable] +pub struct Split<'a, T:'a, P> where P: FnMut(&T) -> bool { v: &'a [T], pred: P, finished: bool @@ -894,9 +910,9 @@ pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool { // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` #[stable] -impl<'a, T, P> Clone for Splits<'a, T, P> where P: Clone + FnMut(&T) -> bool { - fn clone(&self) -> Splits<'a, T, P> { - Splits { +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, @@ -905,7 +921,7 @@ impl<'a, T, P> Clone for Splits<'a, T, P> where P: Clone + FnMut(&T) -> bool { } #[experimental = "needs review"] -impl<'a, T, P> Iterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator<&'a [T]> for Split<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn next(&mut self) -> Option<&'a [T]> { if self.finished { return None; } @@ -931,7 +947,7 @@ impl<'a, T, P> Iterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool } #[experimental = "needs review"] -impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Split<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn next_back(&mut self) -> Option<&'a [T]> { if self.finished { return None; } @@ -947,7 +963,7 @@ impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Splits<'a, T, P> where P: FnMut( } } -impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter<&'a [T]> 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) } @@ -956,14 +972,14 @@ impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bo /// An iterator over the subslices of the vector which are separated /// by elements that match `pred`. -#[experimental = "needs review"] -pub struct MutSplits<'a, T:'a, P> where P: FnMut(&T) -> bool { +#[stable] +pub struct SplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool { v: &'a mut [T], pred: P, finished: bool } -impl<'a, T, P> SplitsIter<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter<&'a mut [T]> for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn finish(&mut self) -> Option<&'a mut [T]> { if self.finished { @@ -976,7 +992,7 @@ impl<'a, T, P> SplitsIter<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T } #[experimental = "needs review"] -impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator<&'a mut [T]> for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn next(&mut self) -> Option<&'a mut [T]> { if self.finished { return None; } @@ -990,7 +1006,7 @@ impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) Some(idx) => { let tmp = mem::replace(&mut self.v, &mut []); let (head, tail) = tmp.split_at_mut(idx); - self.v = tail[mut 1..]; + self.v = tail.slice_from_mut(1); Some(head) } } @@ -1009,7 +1025,7 @@ impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) } #[experimental = "needs review"] -impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where +impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for SplitMut<'a, T, P> where P: FnMut(&T) -> bool, { #[inline] @@ -1026,23 +1042,23 @@ impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where let tmp = mem::replace(&mut self.v, &mut []); let (head, tail) = tmp.split_at_mut(idx); self.v = head; - Some(tail[mut 1..]) + Some(tail.slice_from_mut(1)) } } } } -/// An iterator over subslices separated by elements that match a predicate -/// function, splitting at most a fixed number of times. -#[experimental = "needs review"] -pub struct SplitsN<I> { +/// An private iterator over subslices separated by elements that +/// match a predicate function, splitting at most a fixed number of +/// times. +struct GenericSplitN<I> { iter: I, count: uint, invert: bool } #[experimental = "needs review"] -impl<E, I: SplitsIter<E>> Iterator<E> for SplitsN<I> { +impl<E, I: SplitIter<E>> Iterator<E> for GenericSplitN<I> { #[inline] fn next(&mut self) -> Option<E> { if self.count == 0 { @@ -1060,6 +1076,55 @@ impl<E, I: SplitsIter<E>> Iterator<E> for SplitsN<I> { } } +/// An iterator over subslices separated by elements that match a predicate +/// function, limited to a given number of splits. +pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN<Split<'a, T, P>> +} + +/// 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. +pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN<Split<'a, T, P>> +} + +/// An iterator over subslices separated by elements that match a predicate +/// function, limited to a given number of splits. +pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN<SplitMut<'a, T, P>> +} + +/// 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. +pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN<SplitMut<'a, T, P>> +} + +macro_rules! forward_iterator { + ($name:ident: $elem:ident, $iter_of:ty) => { + impl<'a, $elem, P> Iterator<$iter_of> for $name<'a, $elem, P> where + P: FnMut(&T) -> bool + { + #[inline] + fn next(&mut self) -> Option<$iter_of> { + self.inner.next() + } + + #[inline] + fn size_hint(&self) -> (uint, Option<uint>) { + 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`. #[deriving(Clone)] #[experimental = "needs review"] @@ -1171,13 +1236,13 @@ impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> { /// 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. #[experimental = "needs review"] -pub struct MutChunks<'a, T:'a> { +pub struct ChunksMut<'a, T:'a> { v: &'a mut [T], chunk_size: uint } #[experimental = "needs review"] -impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> { +impl<'a, T> Iterator<&'a mut [T]> for ChunksMut<'a, T> { #[inline] fn next(&mut self) -> Option<&'a mut [T]> { if self.v.len() == 0 { @@ -1205,7 +1270,7 @@ impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> { } #[experimental = "needs review"] -impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> { +impl<'a, T> DoubleEndedIterator<&'a mut [T]> for ChunksMut<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a mut [T]> { if self.v.len() == 0 { @@ -1223,51 +1288,12 @@ impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> { } - -/// The result of calling `binary_search`. -/// -/// `Found` means the search succeeded, and the contained value is the -/// index of the matching element. `NotFound` means the search -/// succeeded, and the contained value is an index where a matching -/// value could be inserted while maintaining sort order. -#[deriving(Copy, PartialEq, Show)] -#[experimental = "needs review"] -pub enum BinarySearchResult { - /// The index of the found value. - Found(uint), - /// The index where the value should have been found. - NotFound(uint) -} - -#[experimental = "needs review"] -impl BinarySearchResult { - /// Converts a `Found` to `Some`, `NotFound` to `None`. - /// Similar to `Result::ok`. - pub fn found(&self) -> Option<uint> { - match *self { - BinarySearchResult::Found(i) => Some(i), - BinarySearchResult::NotFound(_) => None - } - } - - /// Convert a `Found` to `None`, `NotFound` to `Some`. - /// Similar to `Result::err`. - pub fn not_found(&self) -> Option<uint> { - match *self { - BinarySearchResult::Found(_) => None, - BinarySearchResult::NotFound(i) => Some(i) - } - } -} - - - // // Free functions // /// Converts a pointer to A into a slice of length 1 (without copying). -#[unstable = "waiting for DST"] +#[unstable] pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] { unsafe { transmute(RawSlice { data: s, len: 1 }) @@ -1275,7 +1301,7 @@ pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] { } /// Converts a pointer to A into a slice of length 1 (without copying). -#[unstable = "waiting for DST"] +#[unstable] pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] { unsafe { let ptr: *const A = transmute(s); @@ -1309,7 +1335,7 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] { /// } /// ``` #[inline] -#[unstable = "just renamed from `mod raw`"] +#[unstable = "should be renamed to from_raw_parts"] pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] { transmute(RawSlice { data: *p, len: len }) } @@ -1321,7 +1347,7 @@ pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] { /// not being able to provide a non-aliasing guarantee of the returned mutable /// slice. #[inline] -#[unstable = "just renamed from `mod raw`"] +#[unstable = "jshould be renamed to from_raw_parts_mut"] pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] { transmute(RawSlice { data: *p as *const T, len: len }) } @@ -1334,7 +1360,7 @@ pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] { #[deprecated] pub mod raw { use mem::transmute; - use ptr::RawPtr; + use ptr::PtrExt; use raw::Slice; use ops::FnOnce; use option::Option; @@ -1436,7 +1462,7 @@ pub mod bytes { // Boilerplate traits // -#[unstable = "waiting for DST"] +#[stable] impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> { fn eq(&self, other: &[B]) -> bool { self.len() == other.len() && @@ -1448,7 +1474,7 @@ impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> { } } -#[unstable = "waiting for DST"] +#[stable] impl<T: Eq> Eq for [T] {} #[allow(deprecated)] @@ -1465,14 +1491,14 @@ impl<'a,T:PartialEq, Sized? V: AsSlice<T>> Equiv<V> for &'a mut [T] { fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } } -#[unstable = "waiting for DST"] +#[stable] impl<T: Ord> Ord for [T] { fn cmp(&self, other: &[T]) -> Ordering { order::cmp(self.iter(), other.iter()) } } -#[unstable = "waiting for DST"] +#[stable] impl<T: PartialOrd> PartialOrd for [T] { #[inline] fn partial_cmp(&self, other: &[T]) -> Option<Ordering> { @@ -1496,39 +1522,28 @@ impl<T: PartialOrd> PartialOrd for [T] { } } -/// Extension methods for immutable slices containing integers. +/// Extension methods for slices containing integers. #[experimental] -pub trait ImmutableIntSlice<U, S> for Sized? { +pub trait IntSliceExt<U, S> for Sized? { /// Converts the slice to an immutable slice of unsigned integers with the same width. fn as_unsigned<'a>(&'a self) -> &'a [U]; /// Converts the slice to an immutable slice of signed integers with the same width. fn as_signed<'a>(&'a self) -> &'a [S]; -} -/// Extension methods for mutable slices containing integers. -#[experimental] -pub trait MutableIntSlice<U, S> for Sized?: ImmutableIntSlice<U, S> { /// Converts the slice to a mutable slice of unsigned integers with the same width. fn as_unsigned_mut<'a>(&'a mut self) -> &'a mut [U]; /// Converts the slice to a mutable slice of signed integers with the same width. fn as_signed_mut<'a>(&'a mut self) -> &'a mut [S]; } -macro_rules! impl_immut_int_slice { +macro_rules! impl_int_slice { ($u:ty, $s:ty, $t:ty) => { #[experimental] - impl ImmutableIntSlice<$u, $s> for [$t] { + impl IntSliceExt<$u, $s> for [$t] { #[inline] fn as_unsigned(&self) -> &[$u] { unsafe { transmute(self) } } #[inline] fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } } - } - } -} -macro_rules! impl_mut_int_slice { - ($u:ty, $s:ty, $t:ty) => { - #[experimental] - impl MutableIntSlice<$u, $s> for [$t] { #[inline] fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute(self) } } #[inline] @@ -1537,17 +1552,15 @@ macro_rules! impl_mut_int_slice { } } -macro_rules! impl_int_slice { +macro_rules! impl_int_slices { ($u:ty, $s:ty) => { - impl_immut_int_slice! { $u, $s, $u } - impl_immut_int_slice! { $u, $s, $s } - impl_mut_int_slice! { $u, $s, $u } - impl_mut_int_slice! { $u, $s, $s } + impl_int_slice! { $u, $s, $u } + impl_int_slice! { $u, $s, $s } } } -impl_int_slice! { u8, i8 } -impl_int_slice! { u16, i16 } -impl_int_slice! { u32, i32 } -impl_int_slice! { u64, i64 } -impl_int_slice! { uint, int } +impl_int_slices! { u8, i8 } +impl_int_slices! { u16, i16 } +impl_int_slices! { u32, i32 } +impl_int_slices! { u64, i64 } +impl_int_slices! { uint, int } diff --git a/src/libcore/str.rs b/src/libcore/str/mod.rs index 204ffae6cbd..f4fe86a0d7e 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str/mod.rs @@ -18,7 +18,6 @@ use self::Searcher::{Naive, TwoWay, TwoWayLong}; -use clone::Clone; use cmp::{mod, Eq}; use default::Default; use iter::range; @@ -29,12 +28,76 @@ use mem; use num::Int; use ops::{Fn, FnMut}; use option::Option::{mod, None, Some}; -use ptr::RawPtr; +use ptr::PtrExt; use raw::{Repr, Slice}; use result::Result::{mod, Ok, Err}; use slice::{mod, SliceExt}; use uint; +macro_rules! delegate_iter { + (exact $te:ty in $ti:ty) => { + delegate_iter!{$te in $ti} + impl<'a> ExactSizeIterator<$te> for $ti { + #[inline] + fn rposition<P>(&mut self, predicate: P) -> Option<uint> where P: FnMut($te) -> bool{ + self.0.rposition(predicate) + } + #[inline] + fn len(&self) -> uint { + self.0.len() + } + } + }; + ($te:ty in $ti:ty) => { + impl<'a> Iterator<$te> for $ti { + #[inline] + fn next(&mut self) -> Option<$te> { + self.0.next() + } + #[inline] + fn size_hint(&self) -> (uint, Option<uint>) { + self.0.size_hint() + } + } + impl<'a> DoubleEndedIterator<$te> for $ti { + #[inline] + fn next_back(&mut self) -> Option<$te> { + self.0.next_back() + } + } + }; + (pattern $te:ty in $ti:ty) => { + impl<'a, P: CharEq> Iterator<$te> for $ti { + #[inline] + fn next(&mut self) -> Option<$te> { + self.0.next() + } + #[inline] + fn size_hint(&self) -> (uint, Option<uint>) { + self.0.size_hint() + } + } + impl<'a, P: CharEq> DoubleEndedIterator<$te> for $ti { + #[inline] + fn next_back(&mut self) -> Option<$te> { + self.0.next_back() + } + } + }; + (pattern forward $te:ty in $ti:ty) => { + impl<'a, P: CharEq> Iterator<$te> for $ti { + #[inline] + fn next(&mut self) -> Option<$te> { + self.0.next() + } + #[inline] + fn size_hint(&self) -> (uint, Option<uint>) { + self.0.size_hint() + } + } + } +} + /// A trait to abstract the idea of creating a new instance of a type from a /// string. // FIXME(#17307): there should be an `E` associated type for a `Result` return @@ -333,29 +396,28 @@ impl<'a> DoubleEndedIterator<(uint, char)> for CharIndices<'a> { /// External iterator for a string's bytes. /// Use with the `std::iter` module. +/// +/// Created with `StrExt::bytes` #[stable] #[deriving(Clone)] -pub struct Bytes<'a> { - inner: Map<&'a u8, u8, slice::Iter<'a, u8>, BytesFn>, -} +pub struct Bytes<'a>(Map<&'a u8, u8, slice::Iter<'a, u8>, BytesDeref>); +delegate_iter!{exact u8 in Bytes<'a>} -/// A temporary new type wrapper that ensures that the `Bytes` iterator +/// A temporary fn new type that ensures that the `Bytes` iterator /// is cloneable. -#[deriving(Copy)] -struct BytesFn(fn(&u8) -> u8); +#[deriving(Copy, Clone)] +struct BytesDeref; -impl<'a> Fn(&'a u8) -> u8 for BytesFn { +impl<'a> Fn(&'a u8) -> u8 for BytesDeref { + #[inline] extern "rust-call" fn call(&self, (ptr,): (&'a u8,)) -> u8 { - (self.0)(ptr) + *ptr } } -impl Clone for BytesFn { - fn clone(&self) -> BytesFn { *self } -} - /// An iterator over the substrings of a string, separated by `sep`. #[deriving(Clone)] +#[deprecated = "Type is now named `Split` or `SplitTerminator`"] pub struct CharSplits<'a, Sep> { /// The slice remaining to be iterated string: &'a str, @@ -369,6 +431,7 @@ pub struct CharSplits<'a, Sep> { /// An iterator over the substrings of a string, separated by `sep`, /// splitting at most `count` times. #[deriving(Clone)] +#[deprecated = "Type is now named `SplitN` or `RSplitN`"] pub struct CharSplitsN<'a, Sep> { iter: CharSplits<'a, Sep>, /// The number of splits remaining @@ -790,12 +853,17 @@ pub struct MatchIndices<'a> { /// An iterator over the substrings of a string separated by a given /// search string #[deriving(Clone)] -pub struct StrSplits<'a> { +#[unstable = "Type might get removed"] +pub struct SplitStr<'a> { it: MatchIndices<'a>, last_end: uint, finished: bool } +/// Deprecated +#[deprecated = "Type is now named `SplitStr`"] +pub type StrSplits<'a> = SplitStr<'a>; + impl<'a> Iterator<(uint, uint)> for MatchIndices<'a> { #[inline] fn next(&mut self) -> Option<(uint, uint)> { @@ -810,7 +878,7 @@ impl<'a> Iterator<(uint, uint)> for MatchIndices<'a> { } } -impl<'a> Iterator<&'a str> for StrSplits<'a> { +impl<'a> Iterator<&'a str> for SplitStr<'a> { #[inline] fn next(&mut self) -> Option<&'a str> { if self.finished { return None; } @@ -829,6 +897,7 @@ impl<'a> Iterator<&'a str> for StrSplits<'a> { } } + /* Section: Comparing strings */ @@ -958,7 +1027,7 @@ pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { } // https://tools.ietf.org/html/rfc3629 -static UTF8_CHAR_WIDTH: [u8, ..256] = [ +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, @@ -1004,7 +1073,7 @@ const TAG_CONT_U8: u8 = 0b1000_0000u8; /// Unsafe operations #[deprecated] pub mod raw { - use ptr::RawPtr; + use ptr::PtrExt; use raw::Slice; use slice::SliceExt; use str::StrExt; @@ -1074,6 +1143,7 @@ pub mod traits { use ops; use str::{Str, StrExt, eq_slice}; + #[stable] impl Ord for str { #[inline] fn cmp(&self, other: &str) -> Ordering { @@ -1089,6 +1159,7 @@ pub mod traits { } } + #[stable] impl PartialEq for str { #[inline] fn eq(&self, other: &str) -> bool { @@ -1098,8 +1169,10 @@ pub mod traits { fn ne(&self, other: &str) -> bool { !(*self).eq(other) } } + #[stable] impl Eq for str {} + #[stable] impl PartialOrd for str { #[inline] fn partial_cmp(&self, other: &str) -> Option<Ordering> { @@ -1158,23 +1231,47 @@ impl<'a, Sized? S> Str for &'a S where S: Str { fn as_slice(&self) -> &str { Str::as_slice(*self) } } +/// Return type of `StrExt::split` +#[deriving(Clone)] +#[stable] +pub struct Split<'a, P>(CharSplits<'a, P>); +delegate_iter!{pattern &'a str in Split<'a, P>} + +/// Return type of `StrExt::split_terminator` +#[deriving(Clone)] +#[unstable = "might get removed in favour of a constructor method on Split"] +pub struct SplitTerminator<'a, P>(CharSplits<'a, P>); +delegate_iter!{pattern &'a str in SplitTerminator<'a, P>} + +/// Return type of `StrExt::splitn` +#[deriving(Clone)] +#[stable] +pub struct SplitN<'a, P>(CharSplitsN<'a, P>); +delegate_iter!{pattern forward &'a str in SplitN<'a, P>} + +/// Return type of `StrExt::rsplitn` +#[deriving(Clone)] +#[stable] +pub struct RSplitN<'a, P>(CharSplitsN<'a, P>); +delegate_iter!{pattern forward &'a str in RSplitN<'a, P>} + /// Methods for string slices #[allow(missing_docs)] pub trait StrExt for Sized? { // NB there are no docs here are they're all located on the StrExt trait in // libcollections, not here. - fn contains(&self, needle: &str) -> bool; - fn contains_char(&self, needle: char) -> bool; + fn contains(&self, pat: &str) -> bool; + fn contains_char<P: CharEq>(&self, pat: P) -> bool; fn chars<'a>(&'a self) -> Chars<'a>; fn bytes<'a>(&'a self) -> Bytes<'a>; fn char_indices<'a>(&'a self) -> CharIndices<'a>; - fn split<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>; - fn splitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>; - fn split_terminator<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>; - fn rsplitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>; + fn split<'a, P: CharEq>(&'a self, pat: P) -> Split<'a, P>; + fn splitn<'a, P: CharEq>(&'a self, count: uint, pat: P) -> SplitN<'a, P>; + fn split_terminator<'a, P: CharEq>(&'a self, pat: P) -> SplitTerminator<'a, P>; + fn rsplitn<'a, P: CharEq>(&'a self, count: uint, pat: P) -> RSplitN<'a, P>; fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a>; - fn split_str<'a>(&'a self, &'a str) -> StrSplits<'a>; + fn split_str<'a>(&'a self, pat: &'a str) -> SplitStr<'a>; fn lines<'a>(&'a self) -> Lines<'a>; fn lines_any<'a>(&'a self) -> LinesAny<'a>; fn char_len(&self) -> uint; @@ -1183,20 +1280,20 @@ pub trait StrExt for Sized? { fn slice_to<'a>(&'a self, end: uint) -> &'a str; fn slice_chars<'a>(&'a self, begin: uint, end: uint) -> &'a str; unsafe fn slice_unchecked<'a>(&'a self, begin: uint, end: uint) -> &'a str; - fn starts_with(&self, needle: &str) -> bool; - fn ends_with(&self, needle: &str) -> bool; - fn trim_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str; - fn trim_left_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str; - fn trim_right_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str; + fn starts_with(&self, pat: &str) -> bool; + fn ends_with(&self, pat: &str) -> bool; + fn trim_matches<'a, P: CharEq>(&'a self, pat: P) -> &'a str; + fn trim_left_matches<'a, P: CharEq>(&'a self, pat: P) -> &'a str; + fn trim_right_matches<'a, P: CharEq>(&'a self, pat: P) -> &'a str; fn is_char_boundary(&self, index: uint) -> bool; fn char_range_at(&self, start: uint) -> CharRange; fn char_range_at_reverse(&self, start: uint) -> CharRange; fn char_at(&self, i: uint) -> char; fn char_at_reverse(&self, i: uint) -> char; fn as_bytes<'a>(&'a self) -> &'a [u8]; - fn find<C: CharEq>(&self, search: C) -> Option<uint>; - fn rfind<C: CharEq>(&self, search: C) -> Option<uint>; - fn find_str(&self, &str) -> Option<uint>; + fn find<P: CharEq>(&self, pat: P) -> Option<uint>; + fn rfind<P: CharEq>(&self, pat: P) -> Option<uint>; + fn find_str(&self, pat: &str) -> Option<uint>; fn slice_shift_char<'a>(&'a self) -> Option<(char, &'a str)>; fn subslice_offset(&self, inner: &str) -> uint; fn as_ptr(&self) -> *const u8; @@ -1218,8 +1315,8 @@ impl StrExt for str { } #[inline] - fn contains_char(&self, needle: char) -> bool { - self.find(needle).is_some() + fn contains_char<P: CharEq>(&self, pat: P) -> bool { + self.find(pat).is_some() } #[inline] @@ -1229,9 +1326,7 @@ impl StrExt for str { #[inline] fn bytes(&self) -> Bytes { - fn deref(&x: &u8) -> u8 { x } - - Bytes { inner: self.as_bytes().iter().map(BytesFn(deref)) } + Bytes(self.as_bytes().iter().map(BytesDeref)) } #[inline] @@ -1240,43 +1335,44 @@ impl StrExt for str { } #[inline] - fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<Sep> { - CharSplits { + #[allow(deprecated)] // For using CharSplits + fn split<P: CharEq>(&self, pat: P) -> Split<P> { + Split(CharSplits { string: self, - only_ascii: sep.only_ascii(), - sep: sep, + only_ascii: pat.only_ascii(), + sep: pat, allow_trailing_empty: true, finished: false, - } + }) } #[inline] - fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep) - -> CharSplitsN<Sep> { - CharSplitsN { - iter: self.split(sep), + #[allow(deprecated)] // For using CharSplitsN + fn splitn<P: CharEq>(&self, count: uint, pat: P) -> SplitN<P> { + SplitN(CharSplitsN { + iter: self.split(pat).0, count: count, invert: false, - } + }) } #[inline] - fn split_terminator<Sep: CharEq>(&self, sep: Sep) - -> CharSplits<Sep> { - CharSplits { + #[allow(deprecated)] // For using CharSplits + fn split_terminator<P: CharEq>(&self, pat: P) -> SplitTerminator<P> { + SplitTerminator(CharSplits { allow_trailing_empty: false, - ..self.split(sep) - } + ..self.split(pat).0 + }) } #[inline] - fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep) - -> CharSplitsN<Sep> { - CharSplitsN { - iter: self.split(sep), + #[allow(deprecated)] // For using CharSplitsN + fn rsplitn<P: CharEq>(&self, count: uint, pat: P) -> RSplitN<P> { + RSplitN(CharSplitsN { + iter: self.split(pat).0, count: count, invert: true, - } + }) } #[inline] @@ -1290,8 +1386,8 @@ impl StrExt for str { } #[inline] - fn split_str<'a>(&'a self, sep: &'a str) -> StrSplits<'a> { - StrSplits { + fn split_str<'a>(&'a self, sep: &'a str) -> SplitStr<'a> { + SplitStr { it: self.match_indices(sep), last_end: 0, finished: false @@ -1300,7 +1396,7 @@ impl StrExt for str { #[inline] fn lines(&self) -> Lines { - Lines { inner: self.split_terminator('\n') } + Lines { inner: self.split_terminator('\n').0 } } fn lines_any(&self) -> LinesAny { @@ -1393,12 +1489,12 @@ impl StrExt for str { } #[inline] - fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &str { - let cur = match self.find(|&mut: c: char| !to_trim.matches(c)) { + fn trim_matches<P: CharEq>(&self, mut pat: P) -> &str { + let cur = match self.find(|&mut: c: char| !pat.matches(c)) { None => "", Some(i) => unsafe { self.slice_unchecked(i, self.len()) } }; - match cur.rfind(|&mut: c: char| !to_trim.matches(c)) { + match cur.rfind(|&mut: c: char| !pat.matches(c)) { None => "", Some(i) => { let right = cur.char_range_at(i).next; @@ -1408,16 +1504,16 @@ impl StrExt for str { } #[inline] - fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &str { - match self.find(|&mut: c: char| !to_trim.matches(c)) { + fn trim_left_matches<P: CharEq>(&self, mut pat: P) -> &str { + match self.find(|&mut: c: char| !pat.matches(c)) { None => "", Some(first) => unsafe { self.slice_unchecked(first, self.len()) } } } #[inline] - fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &str { - match self.rfind(|&mut: c: char| !to_trim.matches(c)) { + fn trim_right_matches<P: CharEq>(&self, mut pat: P) -> &str { + match self.rfind(|&mut: c: char| !pat.matches(c)) { None => "", Some(last) => { let next = self.char_range_at(last).next; @@ -1504,23 +1600,23 @@ impl StrExt for str { unsafe { mem::transmute(self) } } - fn find<C: CharEq>(&self, mut search: C) -> Option<uint> { - if search.only_ascii() { - self.bytes().position(|b| search.matches(b as char)) + fn find<P: CharEq>(&self, mut pat: P) -> Option<uint> { + if pat.only_ascii() { + self.bytes().position(|b| pat.matches(b as char)) } else { for (index, c) in self.char_indices() { - if search.matches(c) { return Some(index); } + if pat.matches(c) { return Some(index); } } None } } - fn rfind<C: CharEq>(&self, mut search: C) -> Option<uint> { - if search.only_ascii() { - self.bytes().rposition(|b| search.matches(b as char)) + fn rfind<P: CharEq>(&self, mut pat: P) -> Option<uint> { + if pat.only_ascii() { + self.bytes().rposition(|b| pat.matches(b as char)) } else { for (index, c) in self.char_indices().rev() { - if search.matches(c) { return Some(index); } + if pat.matches(c) { return Some(index); } } None } @@ -1596,14 +1692,3 @@ impl<'a> DoubleEndedIterator<&'a str> for LinesAny<'a> { #[inline] fn next_back(&mut self) -> Option<&'a str> { self.inner.next_back() } } -impl<'a> Iterator<u8> for Bytes<'a> { - #[inline] - fn next(&mut self) -> Option<u8> { self.inner.next() } - #[inline] - fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() } -} -impl<'a> DoubleEndedIterator<u8> for Bytes<'a> { - #[inline] - fn next_back(&mut self) -> Option<u8> { self.inner.next_back() } -} -impl<'a> ExactSizeIterator<u8> for Bytes<'a> {} diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index 270c5c59058..ad2323296d9 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -103,7 +103,7 @@ macro_rules! tuple_impls { } } - #[unstable = "waiting for PartialEq to stabilize"] + #[stable] impl<$($T:PartialEq),+> PartialEq for ($($T,)+) { #[inline] fn eq(&self, other: &($($T,)+)) -> bool { @@ -115,10 +115,10 @@ macro_rules! tuple_impls { } } - #[unstable = "waiting for Eq to stabilize"] + #[stable] impl<$($T:Eq),+> Eq for ($($T,)+) {} - #[unstable = "waiting for PartialOrd to stabilize"] + #[stable] impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) { #[inline] fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> { @@ -142,7 +142,7 @@ macro_rules! tuple_impls { } } - #[unstable = "waiting for Ord to stabilize"] + #[stable] impl<$($T:Ord),+> Ord for ($($T,)+) { #[inline] fn cmp(&self, other: &($($T,)+)) -> Ordering {  | 
