diff options
| author | bors <bors@rust-lang.org> | 2015-03-24 17:38:09 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-03-24 17:38:09 +0000 |
| commit | ed810385045ab0db90303574ba3ea47dfa2a36d5 (patch) | |
| tree | 161242c800aca625a26c56551fa5adb446c0089f /src/libcore | |
| parent | 28a0b25f424090255966273994748a9f9901059f (diff) | |
| parent | d252d0ad5434bcf77076729ab766eeff98f20ead (diff) | |
| download | rust-ed810385045ab0db90303574ba3ea47dfa2a36d5.tar.gz rust-ed810385045ab0db90303574ba3ea47dfa2a36d5.zip | |
Auto merge of #23654 - alexcrichton:rollup, r=alexcrichton
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/array.rs | 2 | ||||
| -rw-r--r-- | src/libcore/cell.rs | 1 | ||||
| -rw-r--r-- | src/libcore/cmp.rs | 7 | ||||
| -rw-r--r-- | src/libcore/convert.rs | 113 | ||||
| -rw-r--r-- | src/libcore/error.rs | 16 | ||||
| -rw-r--r-- | src/libcore/finally.rs | 2 | ||||
| -rw-r--r-- | src/libcore/fmt/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/fmt/num.rs | 1 | ||||
| -rw-r--r-- | src/libcore/hash/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/intrinsics.rs | 36 | ||||
| -rw-r--r-- | src/libcore/iter.rs | 22 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 2 | ||||
| -rw-r--r-- | src/libcore/macros.rs | 1 | ||||
| -rw-r--r-- | src/libcore/marker.rs | 6 | ||||
| -rw-r--r-- | src/libcore/num/f32.rs | 3 | ||||
| -rw-r--r-- | src/libcore/num/f64.rs | 3 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 22 | ||||
| -rw-r--r-- | src/libcore/ops.rs | 18 | ||||
| -rw-r--r-- | src/libcore/option.rs | 21 | ||||
| -rw-r--r-- | src/libcore/prelude.rs | 1 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 31 | ||||
| -rw-r--r-- | src/libcore/raw.rs | 2 | ||||
| -rw-r--r-- | src/libcore/result.rs | 30 | ||||
| -rw-r--r-- | src/libcore/simd.rs | 2 | ||||
| -rw-r--r-- | src/libcore/slice.rs | 207 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 236 | ||||
| -rw-r--r-- | src/libcore/str/pattern.rs | 20 |
27 files changed, 725 insertions, 88 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs index edb11df5489..b2c23f051d5 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -14,6 +14,8 @@ #![unstable(feature = "core")] // not yet reviewed +#![doc(primitive = "array")] + use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use fmt; diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index e3a7f23851c..a9c5de23d94 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -220,6 +220,7 @@ impl<T:Copy> Cell<T> { /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::cell::Cell; /// /// let c = Cell::new(5); diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index b37bad5f754..9ab8ab8672d 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -19,7 +19,8 @@ //! could do the following: //! //! ``` -//! use core::num::SignedInt; +//! # #![feature(core)] +//! use std::num::SignedInt; //! //! struct FuzzyNum { //! num: i32, @@ -398,6 +399,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T { /// # Examples /// /// ``` +/// # #![feature(core)] /// use std::cmp; /// /// assert_eq!(Some(1), cmp::partial_min(1, 2)); @@ -407,6 +409,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T { /// When comparison is impossible: /// /// ``` +/// # #![feature(core)] /// use std::cmp; /// /// let result = cmp::partial_min(std::f64::NAN, 1.0); @@ -429,6 +432,7 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> { /// # Examples /// /// ``` +/// # #![feature(core)] /// use std::cmp; /// /// assert_eq!(Some(2), cmp::partial_max(1, 2)); @@ -438,6 +442,7 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> { /// When comparison is impossible: /// /// ``` +/// # #![feature(core)] /// use std::cmp; /// /// let result = cmp::partial_max(std::f64::NAN, 1.0); diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs new file mode 100644 index 00000000000..65a226d37cb --- /dev/null +++ b/src/libcore/convert.rs @@ -0,0 +1,113 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Traits for conversions between types. +//! +//! The traits in this module provide a general way to talk about +//! conversions from one type to another. They follow the standard +//! Rust conventions of `as`/`to`/`into`/`from`. + +#![unstable(feature = "convert", + reason = "recently added, experimental traits")] + +use marker::Sized; + +/// A cheap, reference-to-reference conversion. +pub trait AsRef<T: ?Sized> { + /// Perform the conversion. + fn as_ref(&self) -> &T; +} + +/// A cheap, mutable reference-to-mutable reference conversion. +pub trait AsMut<T: ?Sized> { + /// Perform the conversion. + fn as_mut(&mut self) -> &mut T; +} + +/// A conversion that consumes `self`, which may or may not be +/// expensive. +pub trait Into<T>: Sized { + /// Perform the conversion. + fn into(self) -> T; +} + +/// Construct `Self` via a conversion. +pub trait From<T> { + /// Perform the conversion. + fn from(T) -> Self; +} + +//////////////////////////////////////////////////////////////////////////////// +// GENERIC IMPLS +//////////////////////////////////////////////////////////////////////////////// + +// As implies Into +impl<'a, T: ?Sized, U: ?Sized> Into<&'a U> for &'a T where T: AsRef<U> { + fn into(self) -> &'a U { + self.as_ref() + } +} + +// As lifts over & +impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> { + fn as_ref(&self) -> &U { + <T as AsRef<U>>::as_ref(*self) + } +} + +// As lifts over &mut +impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> { + fn as_ref(&self) -> &U { + <T as AsRef<U>>::as_ref(*self) + } +} + +// AsMut implies Into +impl<'a, T: ?Sized, U: ?Sized> Into<&'a mut U> for &'a mut T where T: AsMut<U> { + fn into(self) -> &'a mut U { + (*self).as_mut() + } +} + +// AsMut lifts over &mut +impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> { + fn as_mut(&mut self) -> &mut U { + (*self).as_mut() + } +} + +// From implies Into +impl<T, U> Into<U> for T where U: From<T> { + fn into(self) -> U { + U::from(self) + } +} + +//////////////////////////////////////////////////////////////////////////////// +// CONCRETE IMPLS +//////////////////////////////////////////////////////////////////////////////// + +impl<T> AsRef<[T]> for [T] { + fn as_ref(&self) -> &[T] { + self + } +} + +impl<T> AsMut<[T]> for [T] { + fn as_mut(&mut self) -> &mut [T] { + self + } +} + +impl AsRef<str> for str { + fn as_ref(&self) -> &str { + self + } +} diff --git a/src/libcore/error.rs b/src/libcore/error.rs index 161f6c78921..d7b4c9411fb 100644 --- a/src/libcore/error.rs +++ b/src/libcore/error.rs @@ -48,6 +48,7 @@ //! For example, //! //! ``` +//! # #![feature(os, old_io, old_path)] //! use std::error::FromError; //! use std::old_io::{File, IoError}; //! use std::os::{MemoryMap, MapError}; @@ -82,16 +83,21 @@ #![stable(feature = "rust1", since = "1.0.0")] use prelude::*; -use fmt::Display; +use fmt::{Debug, Display}; /// Base functionality for all errors in Rust. -#[unstable(feature = "core", - reason = "the exact API of this trait may change")] -pub trait Error: Display { - /// A short description of the error; usually a static string. +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Error: Debug + Display + Send { + /// A short description of the error. + /// + /// The description should not contain newlines or sentence-ending + /// punctuation, to facilitate embedding in larger user-facing + /// strings. + #[stable(feature = "rust1", since = "1.0.0")] fn description(&self) -> &str; /// The lower-level cause of this error, if any. + #[stable(feature = "rust1", since = "1.0.0")] fn cause(&self) -> Option<&Error> { None } } diff --git a/src/libcore/finally.rs b/src/libcore/finally.rs index 19cd34cdb09..93a7d2bb17b 100644 --- a/src/libcore/finally.rs +++ b/src/libcore/finally.rs @@ -19,6 +19,7 @@ //! # Examples //! //! ``` +//! # #![feature(core)] //! # #![feature(unboxed_closures)] //! //! use std::finally::Finally; @@ -70,6 +71,7 @@ impl<T, F> Finally<T> for F where F: FnMut() -> T { /// # Examples /// /// ``` +/// # #![feature(core)] /// use std::finally::try_finally; /// /// struct State<'a> { buffer: &'a mut [u8], len: usize } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 741cf7b47fa..cf427c16588 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -624,6 +624,7 @@ impl<'a> Formatter<'a> { /// # Examples /// /// ```rust + /// # #![feature(debug_builders, core)] /// use std::fmt; /// /// struct Foo { @@ -655,6 +656,7 @@ impl<'a> Formatter<'a> { /// # Examples /// /// ```rust + /// # #![feature(debug_builders, core)] /// use std::fmt; /// /// struct Foo(i32, String); @@ -683,6 +685,7 @@ impl<'a> Formatter<'a> { /// # Examples /// /// ```rust + /// # #![feature(debug_builders, core)] /// use std::fmt; /// /// struct Foo(Vec<i32>); @@ -712,6 +715,7 @@ impl<'a> Formatter<'a> { /// # Examples /// /// ```rust + /// # #![feature(debug_builders, core)] /// use std::fmt; /// /// struct Foo(Vec<(String, i32)>); diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index fe22ee60da6..49da99b97cb 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -146,6 +146,7 @@ pub struct RadixFmt<T, R>(T, R); /// # Examples /// /// ``` +/// # #![feature(core)] /// use std::fmt::radix; /// assert_eq!(format!("{}", radix(55, 36)), "1j".to_string()); /// ``` diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index fdc0020dfcd..1d5e174a8dc 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -16,6 +16,7 @@ //! # Examples //! //! ```rust +//! # #![feature(hash)] //! use std::hash::{hash, Hash, SipHasher}; //! //! #[derive(Hash)] @@ -35,6 +36,7 @@ //! the trait `Hash`: //! //! ```rust +//! # #![feature(hash)] //! use std::hash::{hash, Hash, Hasher, SipHasher}; //! //! struct Person { @@ -90,7 +92,7 @@ pub trait Hash { #[stable(feature = "rust1", since = "1.0.0")] pub trait Hasher { /// Completes a round of hashing, producing the output hash generated. - #[unstable(feature = "hash", reason = "module was recently redesigned")] + #[stable(feature = "rust1", since = "1.0.0")] fn finish(&self) -> u64; /// Writes some data into this `Hasher` diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 1462d07652d..1f1044b0b21 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -44,6 +44,10 @@ use marker::Sized; +#[cfg(stage0)] pub use self::copy_memory as copy; +#[cfg(stage0)] pub use self::set_memory as write_bytes; +#[cfg(stage0)] pub use self::copy_nonoverlapping_memory as copy_nonoverlapping; + extern "rust-intrinsic" { // NB: These intrinsics take unsafe pointers because they mutate aliased @@ -246,7 +250,7 @@ extern "rust-intrinsic" { /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source /// and destination may *not* overlap. /// - /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`. + /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`. /// /// # Safety /// @@ -262,6 +266,7 @@ extern "rust-intrinsic" { /// A safe swap function: /// /// ``` + /// # #![feature(core)] /// use std::mem; /// use std::ptr; /// @@ -271,9 +276,9 @@ extern "rust-intrinsic" { /// let mut t: T = mem::uninitialized(); /// /// // Perform the swap, `&mut` pointers never alias - /// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1); - /// ptr::copy_nonoverlapping_memory(x, &*y, 1); - /// ptr::copy_nonoverlapping_memory(y, &t, 1); + /// ptr::copy_nonoverlapping(&mut t, &*x, 1); + /// ptr::copy_nonoverlapping(x, &*y, 1); + /// ptr::copy_nonoverlapping(y, &t, 1); /// /// // y and t now point to the same thing, but we need to completely forget `tmp` /// // because it's no longer relevant. @@ -282,12 +287,18 @@ extern "rust-intrinsic" { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] + pub fn copy_nonoverlapping<T>(dst: *mut T, src: *const T, count: usize); + + /// dox + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize); /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source /// and destination may overlap. /// - /// `copy_memory` is semantically equivalent to C's `memmove`. + /// `copy` is semantically equivalent to C's `memmove`. /// /// # Safety /// @@ -301,21 +312,34 @@ extern "rust-intrinsic" { /// Efficiently create a Rust vector from an unsafe buffer: /// /// ``` + /// # #![feature(core)] /// use std::ptr; /// /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> { /// let mut dst = Vec::with_capacity(elts); /// dst.set_len(elts); - /// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts); + /// ptr::copy(dst.as_mut_ptr(), ptr, elts); /// dst /// } /// ``` /// + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn copy<T>(dst: *mut T, src: *const T, count: usize); + + /// dox + #[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize); /// Invokes memset on the specified pointer, setting `count * size_of::<T>()` /// bytes of memory starting at `dst` to `c`. + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize); + + /// dox + #[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] pub fn set_memory<T>(dst: *mut T, val: u8, count: usize); diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 4f8b1c21ab2..5f5b8ef73ef 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -334,6 +334,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// let xs = [100, 200, 300]; /// let mut it = xs.iter().cloned().peekable(); /// assert_eq!(*it.peek().unwrap(), 100); @@ -465,6 +466,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// let xs = [2, 3]; /// let ys = [0, 1, 0, 1, 2]; /// let it = xs.iter().flat_map(|&x| std::iter::count(0, 1).take(x)); @@ -521,6 +523,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::iter::AdditiveIterator; /// /// let a = [1, 4, 2, 3, 8, 9, 6]; @@ -563,6 +566,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// let a = [1, 2, 3, 4, 5]; /// let b: Vec<_> = a.iter().cloned().collect(); /// assert_eq!(a, b); @@ -579,6 +583,7 @@ pub trait IteratorExt: Iterator + Sized { /// do not. /// /// ``` + /// # #![feature(core)] /// let vec = vec![1, 2, 3, 4]; /// let (even, odd): (Vec<_>, Vec<_>) = vec.into_iter().partition(|&n| n % 2 == 0); /// assert_eq!(even, [2, 4]); @@ -648,6 +653,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// let a = [1, 2, 3, 4, 5]; /// let mut it = a.iter(); /// assert!(it.any(|x| *x == 3)); @@ -668,6 +674,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// let a = [1, 2, 3, 4, 5]; /// let mut it = a.iter(); /// assert_eq!(it.find(|&x| *x == 3).unwrap(), &3); @@ -690,6 +697,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// let a = [1, 2, 3, 4, 5]; /// let mut it = a.iter(); /// assert_eq!(it.position(|x| *x == 3).unwrap(), 2); @@ -718,6 +726,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// let a = [1, 2, 2, 4, 5]; /// let mut it = a.iter(); /// assert_eq!(it.rposition(|x| *x == 2).unwrap(), 2); @@ -795,6 +804,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax}; /// /// let a: [i32; 0] = []; @@ -860,7 +870,8 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` - /// use core::num::SignedInt; + /// # #![feature(core)] + /// use std::num::SignedInt; /// /// let a = [-3, 0, 1, 5, -10]; /// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10); @@ -890,7 +901,8 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` - /// use core::num::SignedInt; + /// # #![feature(core)] + /// use std::num::SignedInt; /// /// let a = [-3, 0, 1, 5, -10]; /// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0); @@ -940,6 +952,7 @@ pub trait IteratorExt: Iterator + Sized { /// # Examples /// /// ``` + /// # #![feature(core)] /// let a = [(1, 2), (3, 4)]; /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip(); /// assert_eq!([1, 3], left); @@ -1146,6 +1159,7 @@ pub trait AdditiveIterator<A> { /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::iter::AdditiveIterator; /// /// let a = [1, 2, 3, 4, 5]; @@ -1188,6 +1202,7 @@ pub trait MultiplicativeIterator<A> { /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::iter::{count, MultiplicativeIterator}; /// /// fn factorial(n: usize) -> usize { @@ -1248,6 +1263,7 @@ impl<T: Clone> MinMaxResult<T> { /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::iter::MinMaxResult::{self, NoElements, OneElement, MinMax}; /// /// let r: MinMaxResult<i32> = NoElements; @@ -2292,6 +2308,7 @@ impl<I: RandomAccessIterator, F> RandomAccessIterator for Inspect<I, F> /// An iterator that yields sequential Fibonacci numbers, and stops on overflow. /// /// ``` +/// # #![feature(core)] /// use std::iter::Unfold; /// use std::num::Int; // For `.checked_add()` /// @@ -2693,6 +2710,7 @@ pub struct RangeStepInclusive<A> { /// # Examples /// /// ``` +/// # #![feature(core)] /// use std::iter::range_step_inclusive; /// /// for i in range_step_inclusive(0, 10, 2) { diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 29cc11d5a60..a2b13584270 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -56,6 +56,7 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] +#![doc(test(no_crate_inject))] #![feature(no_std)] #![no_std] @@ -125,6 +126,7 @@ pub mod ops; pub mod cmp; pub mod clone; pub mod default; +pub mod convert; /* Core types and methods on primitives */ diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index c647b037944..40e32f4171a 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -231,6 +231,7 @@ macro_rules! writeln { /// Iterators: /// /// ``` +/// # #![feature(core)] /// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3 /// for i in std::iter::count(0, 1) { /// if 3*i < i { panic!("u32 overflow"); } diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 1b866501b8e..88c10e3661e 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -39,6 +39,8 @@ pub unsafe trait Send : MarkerTrait { // empty. } +unsafe impl Send for .. { } + impl<T> !Send for *const T { } impl<T> !Send for *mut T { } impl !Send for Managed { } @@ -203,6 +205,8 @@ pub unsafe trait Sync : MarkerTrait { // Empty } +unsafe impl Sync for .. { } + impl<T> !Sync for *const T { } impl<T> !Sync for *mut T { } impl !Sync for Managed { } @@ -270,6 +274,7 @@ macro_rules! impls{ /// any methods, but instead is used to gate access to data. /// /// FIXME. Better documentation needed here! +#[stable(feature = "rust1", since = "1.0.0")] pub trait MarkerTrait : PhantomFn<Self,Self> { } // ~~~~~ <-- FIXME(#22806)? // @@ -319,6 +324,7 @@ impl<T:?Sized> MarkerTrait for T { } /// `MarkerTrait`: /// /// ``` +/// # #![feature(core)] /// use std::marker::MarkerTrait; /// trait Even : MarkerTrait { } /// ``` diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index ae1b5f65eeb..d211b0f9928 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -282,7 +282,8 @@ impl Float for f32 { /// The fractional part of the number, satisfying: /// /// ``` - /// use core::num::Float; + /// # #![feature(core)] + /// use std::num::Float; /// /// let x = 1.65f32; /// assert!(x == x.trunc() + x.fract()) diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 4a73c1e8fcf..1421fdd72f2 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -289,7 +289,8 @@ impl Float for f64 { /// The fractional part of the number, satisfying: /// /// ``` - /// use core::num::Float; + /// # #![feature(core)] + /// use std::num::Float; /// /// let x = 1.65f64; /// assert!(x == x.trunc() + x.fract()) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 17ef0ecb1c0..9ca7b48fbe5 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -85,6 +85,7 @@ pub trait Int /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b01001100u8; @@ -100,6 +101,7 @@ pub trait Int /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b01001100u8; @@ -119,6 +121,7 @@ pub trait Int /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b0101000u16; @@ -135,6 +138,7 @@ pub trait Int /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b0101000u16; @@ -151,6 +155,7 @@ pub trait Int /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0x0123456789ABCDEFu64; @@ -168,6 +173,7 @@ pub trait Int /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0x0123456789ABCDEFu64; @@ -392,6 +398,7 @@ pub trait Int /// # Examples /// /// ``` + /// # #![feature(core)] /// use std::num::Int; /// /// assert_eq!(2.pow(4), 16); @@ -787,6 +794,7 @@ macro_rules! int_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b01001100u8; @@ -803,6 +811,7 @@ macro_rules! int_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b01001100u8; @@ -822,6 +831,7 @@ macro_rules! int_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b0101000u16; @@ -841,6 +851,7 @@ macro_rules! int_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b0101000u16; @@ -860,6 +871,7 @@ macro_rules! int_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0x0123456789ABCDEFu64; @@ -881,6 +893,7 @@ macro_rules! int_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0x0123456789ABCDEFu64; @@ -1112,6 +1125,7 @@ macro_rules! int_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// assert_eq!(2.pow(4), 16); @@ -1277,6 +1291,7 @@ macro_rules! uint_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b01001100u8; @@ -1295,6 +1310,7 @@ macro_rules! uint_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b01001100u8; @@ -1314,6 +1330,7 @@ macro_rules! uint_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b0101000u16; @@ -1333,6 +1350,7 @@ macro_rules! uint_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0b0101000u16; @@ -1352,6 +1370,7 @@ macro_rules! uint_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0x0123456789ABCDEFu64; @@ -1375,6 +1394,7 @@ macro_rules! uint_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// let n = 0x0123456789ABCDEFu64; @@ -1606,6 +1626,7 @@ macro_rules! uint_impl { /// # Examples /// /// ```rust + /// # #![feature(core)] /// use std::num::Int; /// /// assert_eq!(2.pow(4), 16); @@ -2266,6 +2287,7 @@ impl_from_primitive! { f64, to_f64 } /// # Examples /// /// ``` +/// # #![feature(core)] /// use std::num; /// /// let twenty: f32 = num::cast(0x14).unwrap(); diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 6324e8fa874..6e6f97a7af7 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -898,7 +898,7 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize } /// impl Index<Bar> for Foo { /// type Output = Foo; /// -/// fn index<'a>(&'a self, _index: &Bar) -> &'a Foo { +/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo { /// println!("Indexing!"); /// self /// } @@ -917,8 +917,14 @@ pub trait Index<Idx: ?Sized> { type Output: ?Sized; /// The method for the indexing (`Foo[Bar]`) operation + #[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] fn index<'a>(&'a self, index: &Idx) -> &'a Self::Output; + + /// The method for the indexing (`Foo[Bar]`) operation + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + fn index<'a>(&'a self, index: Idx) -> &'a Self::Output; } /// The `IndexMut` trait is used to specify the functionality of indexing @@ -939,13 +945,13 @@ pub trait Index<Idx: ?Sized> { /// impl Index<Bar> for Foo { /// type Output = Foo; /// -/// fn index<'a>(&'a self, _index: &Bar) -> &'a Foo { +/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo { /// self /// } /// } /// /// impl IndexMut<Bar> for Foo { -/// fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo { +/// fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo { /// println!("Indexing!"); /// self /// } @@ -960,8 +966,14 @@ pub trait Index<Idx: ?Sized> { #[stable(feature = "rust1", since = "1.0.0")] pub trait IndexMut<Idx: ?Sized>: Index<Idx> { /// The method for the indexing (`Foo[Bar]`) operation + #[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] fn index_mut<'a>(&'a mut self, index: &Idx) -> &'a mut Self::Output; + + /// The method for the indexing (`Foo[Bar]`) operation + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + fn index_mut<'a>(&'a mut self, index: Idx) -> &'a mut Self::Output; } /// An unbounded range. diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 455c68d4319..a565b137cc8 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -154,6 +154,7 @@ use mem; use ops::{Deref, FnOnce}; use result::Result::{Ok, Err}; use result::Result; +#[allow(deprecated)] use slice::AsSlice; use slice; @@ -275,6 +276,7 @@ impl<T> Option<T> { /// # Examples /// /// ``` + /// # #![feature(core)] /// let mut x = Some("Diamonds"); /// { /// let v = x.as_mut_slice(); @@ -470,6 +472,7 @@ impl<T> Option<T> { /// # Examples /// /// ``` + /// # #![feature(core)] /// let x = Some("foo"); /// assert_eq!(x.ok_or(0), Ok("foo")); /// @@ -491,6 +494,7 @@ impl<T> Option<T> { /// # Examples /// /// ``` + /// # #![feature(core)] /// let x = Some("foo"); /// assert_eq!(x.ok_or_else(|| 0), Ok("foo")); /// @@ -532,6 +536,7 @@ impl<T> Option<T> { /// # Examples /// /// ``` + /// # #![feature(core)] /// let mut x = Some(4); /// match x.iter_mut().next() { /// Some(&mut ref mut v) => *v = 42, @@ -701,6 +706,19 @@ impl<T> Option<T> { pub fn take(&mut self) -> Option<T> { mem::replace(self, None) } + + /// Convert from `Option<T>` to `&[T]` (without copying) + #[inline] + #[unstable(feature = "as_slice", since = "unsure of the utility here")] + pub fn as_slice<'a>(&'a self) -> &'a [T] { + match *self { + Some(ref x) => slice::ref_slice(x), + None => { + let result: &[_] = &[]; + result + } + } + } } impl<'a, T: Clone, D: Deref<Target=T>> Option<D> { @@ -752,6 +770,9 @@ impl<T: Default> Option<T> { #[unstable(feature = "core", reason = "waiting on the stability of the trait itself")] +#[deprecated(since = "1.0.0", + reason = "use the inherent method instead")] +#[allow(deprecated)] impl<T> AsSlice<T> for Option<T> { /// Convert from `Option<T>` to `&[T]` (without copying) #[inline] diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 4bf7f85284c..424829939b9 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -36,6 +36,7 @@ pub use mem::drop; pub use char::CharExt; pub use clone::Clone; pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; +pub use convert::{AsRef, AsMut, Into, From}; pub use iter::{Extend, IteratorExt}; pub use iter::{Iterator, DoubleEndedIterator}; pub use iter::{ExactSizeIterator}; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 1cbea057e88..d92622eeb70 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -15,12 +15,9 @@ //! Working with unsafe pointers in Rust is uncommon, //! typically limited to a few patterns. //! -//! Use the [`null` function](fn.null.html) to create null pointers, -//! 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. +//! Use the [`null` function](fn.null.html) to create null pointers, and +//! the `is_null` method of the `*const T` type to check for null. +//! The `*const T` type also defines the `offset` method, for pointer math. //! //! # Common ways to create unsafe pointers //! @@ -52,6 +49,7 @@ //! the raw pointer. It doesn't destroy `T` or deallocate any memory. //! //! ``` +//! # #![feature(alloc)] //! use std::boxed; //! //! unsafe { @@ -70,6 +68,7 @@ //! ## 3. Get it from C. //! //! ``` +//! # #![feature(libc)] //! extern crate libc; //! //! use std::mem; @@ -105,27 +104,13 @@ use cmp::Ordering::{self, Less, Equal, Greater}; // FIXME #19649: intrinsic docs don't render, so these have no docs :( #[stable(feature = "rust1", since = "1.0.0")] -pub use intrinsics::copy_nonoverlapping_memory as copy_nonoverlapping; +pub use intrinsics::copy_nonoverlapping; #[stable(feature = "rust1", since = "1.0.0")] -pub use intrinsics::copy_memory as copy; +pub use intrinsics::copy; #[stable(feature = "rust1", since = "1.0.0")] -pub use intrinsics::set_memory as write_bytes; - -extern "rust-intrinsic" { - #[unstable(feature = "core")] - #[deprecated(since = "1.0.0", reason = "renamed to `copy_nonoverlapping`")] - pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize); - #[unstable(feature = "core")] - #[deprecated(since = "1.0.0", reason = "renamed to `copy`")] - pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize); - - #[unstable(feature = "core", - reason = "uncertain about naming and semantics")] - #[deprecated(since = "1.0.0", reason = "renamed to `write_bytes`")] - pub fn set_memory<T>(dst: *mut T, val: u8, count: usize); -} +pub use intrinsics::write_bytes; /// Creates a null raw pointer. /// diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index 35dfc762687..8502a9c53c4 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -48,6 +48,7 @@ use mem; /// # Examples /// /// ``` +/// # #![feature(core)] /// use std::raw::{self, Repr}; /// /// let slice: &[u16] = &[1, 2, 3, 4]; @@ -106,6 +107,7 @@ pub struct Closure { /// # Examples /// /// ``` +/// # #![feature(core)] /// use std::mem; /// use std::raw; /// diff --git a/src/libcore/result.rs b/src/libcore/result.rs index bc8d53e2a57..62e1bcd827a 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -95,6 +95,7 @@ //! by the [`Writer`](../io/trait.Writer.html) trait: //! //! ``` +//! # #![feature(old_io)] //! use std::old_io::IoError; //! //! trait Writer { @@ -110,6 +111,7 @@ //! something like this: //! //! ```{.ignore} +//! # #![feature(old_io)] //! use std::old_io::*; //! use std::old_path::Path; //! @@ -129,6 +131,7 @@ //! a marginally useful message indicating why: //! //! ```{.no_run} +//! # #![feature(old_io, old_path)] //! use std::old_io::*; //! use std::old_path::Path; //! @@ -140,6 +143,7 @@ //! You might also simply assert success: //! //! ```{.no_run} +//! # #![feature(old_io, old_path)] //! # use std::old_io::*; //! # use std::old_path::Path; //! @@ -151,6 +155,7 @@ //! Or propagate the error up the call stack with `try!`: //! //! ``` +//! # #![feature(old_io, old_path)] //! # use std::old_io::*; //! # use std::old_path::Path; //! fn write_message() -> Result<(), IoError> { @@ -171,6 +176,7 @@ //! It replaces this: //! //! ``` +//! # #![feature(old_io, old_path)] //! use std::old_io::*; //! use std::old_path::Path; //! @@ -196,6 +202,7 @@ //! With this: //! //! ``` +//! # #![feature(old_io, old_path)] //! use std::old_io::*; //! use std::old_path::Path; //! @@ -240,6 +247,7 @@ use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator}; use ops::{FnMut, FnOnce}; use option::Option::{self, None, Some}; +#[allow(deprecated)] use slice::AsSlice; use slice; @@ -408,9 +416,24 @@ impl<T, E> Result<T, E> { } } + /// Convert from `Result<T, E>` to `&[T]` (without copying) + #[inline] + #[unstable(feature = "as_slice", since = "unsure of the utility here")] + pub fn as_slice(&self) -> &[T] { + match *self { + Ok(ref x) => slice::ref_slice(x), + Err(_) => { + // work around lack of implicit coercion from fixed-size array to slice + let emp: &[_] = &[]; + emp + } + } + } + /// Convert from `Result<T, E>` to `&mut [T]` (without copying) /// /// ``` + /// # #![feature(core)] /// let mut x: Result<&str, u32> = Ok("Gold"); /// { /// let v = x.as_mut_slice(); @@ -452,6 +475,7 @@ impl<T, E> Result<T, E> { /// ignoring I/O and parse errors: /// /// ``` + /// # #![feature(old_io)] /// use std::old_io::*; /// /// let mut buffer: &[u8] = b"1\n2\n3\n4\n"; @@ -788,10 +812,14 @@ impl<T: fmt::Debug, E> Result<T, E> { // Trait implementations ///////////////////////////////////////////////////////////////////////////// +#[unstable(feature = "core", + reason = "waiting on the stability of the trait itself")] +#[deprecated(since = "1.0.0", + reason = "use inherent method instead")] +#[allow(deprecated)] impl<T, E> AsSlice<T> for Result<T, E> { /// Convert from `Result<T, E>` to `&[T]` (without copying) #[inline] - #[stable(feature = "rust1", since = "1.0.0")] fn as_slice<'a>(&'a self) -> &'a [T] { match *self { Ok(ref x) => slice::ref_slice(x), diff --git a/src/libcore/simd.rs b/src/libcore/simd.rs index 0058971faf0..21cff3021ab 100644 --- a/src/libcore/simd.rs +++ b/src/libcore/simd.rs @@ -19,7 +19,7 @@ //! provided beyond this module. //! //! ```rust -//! +//! # #![feature(core)] //! fn main() { //! use std::simd::f32x4; //! let a = f32x4(40.0, 41.0, 42.0, 43.0); diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 907b2eba80c..fce29abed73 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -263,6 +263,7 @@ impl<T> SliceExt for [T] { #[inline] fn as_mut_slice(&mut self) -> &mut [T] { self } + #[cfg(stage0)] #[inline] fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { unsafe { @@ -273,6 +274,17 @@ impl<T> SliceExt for [T] { } } + #[cfg(not(stage0))] + #[inline] + fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { + unsafe { + let self2: &mut [T] = mem::transmute_copy(&self); + + (ops::IndexMut::index_mut(self, ops::RangeTo { end: mid } ), + ops::IndexMut::index_mut(self2, ops::RangeFrom { start: mid } )) + } + } + #[inline] fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> { unsafe { @@ -495,25 +507,45 @@ impl<T> SliceExt for [T] { impl<T> ops::Index<usize> for [T] { type Output = T; + #[cfg(stage0)] fn index(&self, &index: &usize) -> &T { assert!(index < self.len()); unsafe { mem::transmute(self.repr().data.offset(index as isize)) } } + + #[cfg(not(stage0))] + fn index(&self, index: usize) -> &T { + assert!(index < self.len()); + + unsafe { mem::transmute(self.repr().data.offset(index as isize)) } + } } #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::IndexMut<usize> for [T] { + #[cfg(stage0)] + #[inline] fn index_mut(&mut self, &index: &usize) -> &mut T { assert!(index < self.len()); unsafe { mem::transmute(self.repr().data.offset(index as isize)) } } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: usize) -> &mut T { + assert!(index < self.len()); + + unsafe { mem::transmute(self.repr().data.offset(index as isize)) } + } } #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::Index<ops::Range<usize>> for [T] { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::Range<usize>) -> &[T] { assert!(index.start <= index.end); @@ -525,34 +557,72 @@ impl<T> ops::Index<ops::Range<usize>> for [T] { ) } } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::Range<usize>) -> &[T] { + assert!(index.start <= index.end); + assert!(index.end <= self.len()); + unsafe { + from_raw_parts ( + self.as_ptr().offset(index.start as isize), + index.end - index.start + ) + } + } } #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::Index<ops::RangeTo<usize>> for [T] { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo<usize>) -> &[T] { self.index(&ops::Range{ start: 0, end: index.end }) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo<usize>) -> &[T] { + self.index(ops::Range{ start: 0, end: index.end }) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::Index<ops::RangeFrom<usize>> for [T] { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] { self.index(&ops::Range{ start: index.start, end: self.len() }) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom<usize>) -> &[T] { + self.index(ops::Range{ start: index.start, end: self.len() }) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::Index<RangeFull> for [T] { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &RangeFull) -> &[T] { self } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: RangeFull) -> &[T] { + self + } } #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::IndexMut<ops::Range<usize>> for [T] { + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] { assert!(index.start <= index.end); @@ -564,28 +634,64 @@ impl<T> ops::IndexMut<ops::Range<usize>> for [T] { ) } } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] { + assert!(index.start <= index.end); + assert!(index.end <= self.len()); + unsafe { + from_raw_parts_mut( + self.as_mut_ptr().offset(index.start as isize), + index.end - index.start + ) + } + } } #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::IndexMut<ops::RangeTo<usize>> for [T] { + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] { self.index_mut(&ops::Range{ start: 0, end: index.end }) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] { + self.index_mut(ops::Range{ start: 0, end: index.end }) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::IndexMut<ops::RangeFrom<usize>> for [T] { + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] { let len = self.len(); self.index_mut(&ops::Range{ start: index.start, end: len }) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] { + let len = self.len(); + self.index_mut(ops::Range{ start: index.start, end: len }) + } } #[stable(feature = "rust1", since = "1.0.0")] impl<T> ops::IndexMut<RangeFull> for [T] { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] { self } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, _index: RangeFull) -> &mut [T] { + self + } } @@ -596,24 +702,29 @@ impl<T> ops::IndexMut<RangeFull> for [T] { /// Data that is viewable as a slice. #[unstable(feature = "core", reason = "will be replaced by slice syntax")] +#[deprecated(since = "1.0.0", + reason = "use std::convert::AsRef<[T]> instead")] pub trait AsSlice<T> { /// Work with `self` as a slice. fn as_slice<'a>(&'a self) -> &'a [T]; } #[unstable(feature = "core", reason = "trait is experimental")] +#[allow(deprecated)] impl<T> AsSlice<T> for [T] { #[inline(always)] fn as_slice<'a>(&'a self) -> &'a [T] { self } } #[unstable(feature = "core", reason = "trait is experimental")] +#[allow(deprecated)] impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } } #[unstable(feature = "core", reason = "trait is experimental")] +#[allow(deprecated)] impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a mut U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } @@ -763,37 +874,69 @@ unsafe impl<'a, T: Sync> Send for Iter<'a, T> {} #[unstable(feature = "core")] impl<'a, T> ops::Index<ops::Range<usize>> for Iter<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::Range<usize>) -> &[T] { self.as_slice().index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::Range<usize>) -> &[T] { + self.as_slice().index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index<ops::RangeTo<usize>> for Iter<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo<usize>) -> &[T] { self.as_slice().index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo<usize>) -> &[T] { + self.as_slice().index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index<ops::RangeFrom<usize>> for Iter<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] { self.as_slice().index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom<usize>) -> &[T] { + self.as_slice().index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index<RangeFull> for Iter<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &RangeFull) -> &[T] { self.as_slice() } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: RangeFull) -> &[T] { + self.as_slice() + } } impl<'a, T> Iter<'a, T> { @@ -856,63 +999,126 @@ unsafe impl<'a, T: Send> Send for IterMut<'a, T> {} #[unstable(feature = "core")] impl<'a, T> ops::Index<ops::Range<usize>> for IterMut<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::Range<usize>) -> &[T] { self.index(&RangeFull).index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::Range<usize>) -> &[T] { + self.index(RangeFull).index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index<ops::RangeTo<usize>> for IterMut<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo<usize>) -> &[T] { self.index(&RangeFull).index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo<usize>) -> &[T] { + self.index(RangeFull).index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index<ops::RangeFrom<usize>> for IterMut<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] { self.index(&RangeFull).index(index) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom<usize>) -> &[T] { + self.index(RangeFull).index(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::Index<RangeFull> for IterMut<'a, T> { type Output = [T]; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &RangeFull) -> &[T] { make_slice!(T => &[T]: self.ptr, self.end) } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: RangeFull) -> &[T] { + make_slice!(T => &[T]: self.ptr, self.end) + } } #[unstable(feature = "core")] impl<'a, T> ops::IndexMut<ops::Range<usize>> for IterMut<'a, T> { + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] { self.index_mut(&RangeFull).index_mut(index) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] { + self.index_mut(RangeFull).index_mut(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::IndexMut<ops::RangeTo<usize>> for IterMut<'a, T> { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] { self.index_mut(&RangeFull).index_mut(index) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] { + self.index_mut(RangeFull).index_mut(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::IndexMut<ops::RangeFrom<usize>> for IterMut<'a, T> { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] { self.index_mut(&RangeFull).index_mut(index) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] { + self.index_mut(RangeFull).index_mut(index) + } } #[unstable(feature = "core")] impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> { + + #[cfg(stage0)] #[inline] fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] { make_mut_slice!(T => &mut [T]: self.ptr, self.end) } + + #[cfg(not(stage0))] + #[inline] + fn index_mut(&mut self, _index: RangeFull) -> &mut [T] { + make_mut_slice!(T => &mut [T]: self.ptr, self.end) + } } @@ -1491,6 +1697,7 @@ pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] { /// # Examples /// /// ``` +/// #![feature(core)] /// use std::slice; /// /// // manifest a slice out of thin air! diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index e8181395b5c..b7285d30a73 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -111,7 +111,24 @@ macro_rules! delegate_iter { self.0.size_hint() } } - } + }; + (pattern reverse $te:ty : $ti:ty) => { + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, P: Pattern<'a>> Iterator for $ti + where P::Searcher: ReverseSearcher<'a> + { + type Item = $te; + + #[inline] + fn next(&mut self) -> Option<$te> { + self.0.next() + } + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.0.size_hint() + } + } + }; } /// A trait to abstract the idea of creating a new instance of a type from a @@ -550,7 +567,26 @@ struct CharSplitsN<'a, P: Pattern<'a>> { iter: CharSplits<'a, P>, /// The number of splits remaining count: usize, - invert: bool, +} + +/// An iterator over the substrings of a string, separated by a +/// pattern, in reverse order. +struct RCharSplits<'a, P: Pattern<'a>> { + /// The slice remaining to be iterated + start: usize, + end: usize, + matcher: P::Searcher, + /// Whether an empty string at the end of iteration is allowed + allow_final_empty: bool, + finished: bool, +} + +/// An iterator over the substrings of a string, separated by a +/// pattern, splitting at most `count` times, in reverse order. +struct RCharSplitsN<'a, P: Pattern<'a>> { + iter: RCharSplits<'a, P>, + /// The number of splits remaining + count: usize, } /// An iterator over the lines of a string, separated by `\n`. @@ -631,21 +667,74 @@ where P::Searcher: DoubleEndedSearcher<'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P> -where P::Searcher: DoubleEndedSearcher<'a> { +impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P> { type Item = &'a str; #[inline] fn next(&mut self) -> Option<&'a str> { if self.count != 0 { self.count -= 1; - if self.invert { self.iter.next_back() } else { self.iter.next() } + self.iter.next() } else { self.iter.get_end() } } } +impl<'a, P: Pattern<'a>> RCharSplits<'a, P> { + #[inline] + fn get_remainder(&mut self) -> Option<&'a str> { + if !self.finished && (self.allow_final_empty || self.end - self.start > 0) { + self.finished = true; + unsafe { + let string = self.matcher.haystack().slice_unchecked(self.start, self.end); + Some(string) + } + } else { + None + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, P: Pattern<'a>> Iterator for RCharSplits<'a, P> + where P::Searcher: ReverseSearcher<'a> +{ + type Item = &'a str; + + #[inline] + fn next(&mut self) -> Option<&'a str> { + if self.finished { return None } + + let haystack = self.matcher.haystack(); + match self.matcher.next_match_back() { + Some((a, b)) => unsafe { + let elt = haystack.slice_unchecked(b, self.end); + self.end = a; + Some(elt) + }, + None => self.get_remainder(), + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, P: Pattern<'a>> Iterator for RCharSplitsN<'a, P> + where P::Searcher: ReverseSearcher<'a> +{ + type Item = &'a str; + + #[inline] + fn next(&mut self) -> Option<&'a str> { + if self.count != 0 { + self.count -= 1; + self.iter.next() + } else { + self.iter.get_remainder() + } + } +} + /// The internal state of an iterator that searches for matches of a substring /// within a larger string using two-way search #[derive(Clone)] @@ -1203,6 +1292,7 @@ mod traits { /// // byte 100 is outside the string /// // &s[3 .. 100]; /// ``` + #[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index<ops::Range<usize>> for str { type Output = str; @@ -1219,6 +1309,49 @@ mod traits { } } + /// Returns a slice of the given string from the byte range + /// [`begin`..`end`). + /// + /// This operation is `O(1)`. + /// + /// Panics when `begin` and `end` do not point to valid characters + /// or point beyond the last character of the string. + /// + /// # Examples + /// + /// ``` + /// let s = "Löwe 老虎 Léopard"; + /// assert_eq!(&s[0 .. 1], "L"); + /// + /// assert_eq!(&s[1 .. 9], "öwe 老"); + /// + /// // these will panic: + /// // byte 2 lies within `ö`: + /// // &s[2 ..3]; + /// + /// // byte 8 lies within `老` + /// // &s[1 .. 8]; + /// + /// // byte 100 is outside the string + /// // &s[3 .. 100]; + /// ``` + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + impl ops::Index<ops::Range<usize>> for str { + type Output = str; + #[inline] + fn index(&self, index: ops::Range<usize>) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if index.start <= index.end && + self.is_char_boundary(index.start) && + self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(index.start, index.end) } + } else { + super::slice_error_fail(self, index.start, index.end) + } + } + } + /// Returns a slice of the string from the beginning to byte /// `end`. /// @@ -1229,6 +1362,8 @@ mod traits { #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index<ops::RangeTo<usize>> for str { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeTo<usize>) -> &str { // is_char_boundary checks that the index is in [0, .len()] @@ -1238,6 +1373,17 @@ mod traits { super::slice_error_fail(self, 0, index.end) } } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeTo<usize>) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.end) { + unsafe { self.slice_unchecked(0, index.end) } + } else { + super::slice_error_fail(self, 0, index.end) + } + } } /// Returns a slice of the string from `begin` to its end. @@ -1249,6 +1395,8 @@ mod traits { #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index<ops::RangeFrom<usize>> for str { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, index: &ops::RangeFrom<usize>) -> &str { // is_char_boundary checks that the index is in [0, .len()] @@ -1258,15 +1406,34 @@ mod traits { super::slice_error_fail(self, index.start, self.len()) } } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, index: ops::RangeFrom<usize>) -> &str { + // is_char_boundary checks that the index is in [0, .len()] + if self.is_char_boundary(index.start) { + unsafe { self.slice_unchecked(index.start, self.len()) } + } else { + super::slice_error_fail(self, index.start, self.len()) + } + } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index<ops::RangeFull> for str { type Output = str; + + #[cfg(stage0)] #[inline] fn index(&self, _index: &ops::RangeFull) -> &str { self } + + #[cfg(not(stage0))] + #[inline] + fn index(&self, _index: ops::RangeFull) -> &str { + self + } } } @@ -1275,16 +1442,20 @@ mod traits { reason = "Instead of taking this bound generically, this trait will be \ replaced with one of slicing syntax (&foo[..]), deref coercions, or \ a more generic conversion trait")] +#[deprecated(since = "1.0.0", + reason = "use std::convert::AsRef<str> instead")] pub trait Str { /// Work with `self` as a slice. fn as_slice<'a>(&'a self) -> &'a str; } +#[allow(deprecated)] impl Str for str { #[inline] fn as_slice<'a>(&'a self) -> &'a str { self } } +#[allow(deprecated)] impl<'a, S: ?Sized> Str for &'a S where S: Str { #[inline] fn as_slice(&self) -> &str { Str::as_slice(*self) } @@ -1293,23 +1464,7 @@ impl<'a, S: ?Sized> Str for &'a S where S: Str { /// Return type of `StrExt::split` #[stable(feature = "rust1", since = "1.0.0")] pub struct Split<'a, P: Pattern<'a>>(CharSplits<'a, P>); -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, P: Pattern<'a>> Iterator for Split<'a, P> { - type Item = &'a str; - - #[inline] - fn next(&mut self) -> Option<&'a str> { - self.0.next() - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, P: Pattern<'a>> DoubleEndedIterator for Split<'a, P> -where P::Searcher: DoubleEndedSearcher<'a> { - #[inline] - fn next_back(&mut self) -> Option<&'a str> { - self.0.next_back() - } -} +delegate_iter!{pattern &'a str : Split<'a, P>} /// Return type of `StrExt::split_terminator` #[stable(feature = "rust1", since = "1.0.0")] @@ -1321,10 +1476,15 @@ delegate_iter!{pattern &'a str : SplitTerminator<'a, P>} pub struct SplitN<'a, P: Pattern<'a>>(CharSplitsN<'a, P>); delegate_iter!{pattern forward &'a str : SplitN<'a, P>} +/// Return type of `StrExt::rsplit` +#[stable(feature = "rust1", since = "1.0.0")] +pub struct RSplit<'a, P: Pattern<'a>>(RCharSplits<'a, P>); +delegate_iter!{pattern reverse &'a str : RSplit<'a, P>} + /// Return type of `StrExt::rsplitn` #[stable(feature = "rust1", since = "1.0.0")] -pub struct RSplitN<'a, P: Pattern<'a>>(CharSplitsN<'a, P>); -delegate_iter!{pattern forward &'a str : RSplitN<'a, P>} +pub struct RSplitN<'a, P: Pattern<'a>>(RCharSplitsN<'a, P>); +delegate_iter!{pattern reverse &'a str : RSplitN<'a, P>} /// Methods for string slices #[allow(missing_docs)] @@ -1340,7 +1500,10 @@ pub trait StrExt { fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P>; fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P>; fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>; - fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>; + fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P> + where P::Searcher: ReverseSearcher<'a>; + fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> + where P::Searcher: ReverseSearcher<'a>; fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>; #[allow(deprecated) /* for SplitStr */] fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P>; @@ -1424,7 +1587,6 @@ impl StrExt for str { SplitN(CharSplitsN { iter: self.split(pat).0, count: count, - invert: false, }) } @@ -1437,11 +1599,25 @@ impl StrExt for str { } #[inline] - fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> { - RSplitN(CharSplitsN { - iter: self.split(pat).0, + fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P> + where P::Searcher: ReverseSearcher<'a> + { + RSplit(RCharSplits { + start: 0, + end: self.len(), + matcher: pat.into_searcher(self), + allow_final_empty: true, + finished: false, + }) + } + + #[inline] + fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> + where P::Searcher: ReverseSearcher<'a> + { + RSplitN(RCharSplitsN { + iter: self.rsplit(pat).0, count: count, - invert: true, }) } diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 7bf248917a5..98b6533980d 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -474,22 +474,16 @@ impl<'a, 'b> Pattern<'a> for &'b [char] { s, CharEqPattern(s)); } +/// A convenience impl that delegates to the impl for `&str` +impl<'a, 'b> Pattern<'a> for &'b &'b str { + type Searcher = <&'b str as Pattern<'a>>::Searcher; + associated_items!(<&'b str as Pattern<'a>>::Searcher, + s, (*s)); +} + /// Searches for chars that match the given predicate impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool { type Searcher = <CharEqPattern<Self> as Pattern<'a>>::Searcher; associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher, s, CharEqPattern(s)); } - -// Deref-forward impl - -use ops::Deref; - -/// Delegates to the next deref coercion of `Self` that implements `Pattern` -impl<'a, 'b, P: 'b + ?Sized, T: Deref<Target = P> + ?Sized> Pattern<'a> for &'b T - where &'b P: Pattern<'a> -{ - type Searcher = <&'b P as Pattern<'a>>::Searcher; - associated_items!(<&'b P as Pattern<'a>>::Searcher, - s, (&**s)); -} |
