Remove deprecated functionality

This removes a large array of deprecated functionality, regardless of how
recently it was deprecated. The purpose of this commit is to clean out the
standard libraries and compiler for the upcoming alpha release.

Some notable compiler changes were to enable warnings for all now-deprecated
command line arguments (previously the deprecated versions were silently
accepted) as well as removing deriving(Zero) entirely (the trait was removed).

The distribution no longer contains the libtime or libregex_macros crates. Both
of these have been deprecated for some time and are available externally.
This commit is contained in:
Alex Crichton 2015-01-01 23:53:35 -08:00
parent 470118f3e9
commit 7d8d06f86b
239 changed files with 1104 additions and 7460 deletions

View File

@ -50,12 +50,12 @@
################################################################################
TARGET_CRATES := libc std flate arena term \
serialize getopts collections test time rand \
serialize getopts collections test rand \
log regex graphviz core rbml alloc \
unicode
RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
rustc_trans rustc_back rustc_llvm
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc regex_macros fmt_macros
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc
@ -75,11 +75,11 @@ DEPS_rustc_typeck := rustc syntax
DEPS_rustc_borrowck := rustc log graphviz syntax
DEPS_rustc_resolve := rustc log syntax
DEPS_rustc := syntax flate arena serialize getopts rbml \
time log graphviz rustc_llvm rustc_back
log graphviz rustc_llvm rustc_back
DEPS_rustc_llvm := native:rustllvm libc std
DEPS_rustc_back := std syntax rustc_llvm flate log libc
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
test time
test
DEPS_flate := std native:miniz
DEPS_arena := std
DEPS_graphviz := std
@ -90,12 +90,10 @@ DEPS_term := std log
DEPS_getopts := std
DEPS_collections := core alloc unicode
DEPS_num := std
DEPS_test := std getopts serialize rbml term time regex native:rust_test_helpers
DEPS_time := std serialize
DEPS_test := std getopts serialize rbml term regex native:rust_test_helpers
DEPS_rand := core
DEPS_log := std regex
DEPS_regex := std
DEPS_regex_macros = rustc syntax std regex
DEPS_fmt_macros = std
TOOL_DEPS_compiletest := test getopts
@ -124,10 +122,8 @@ DOC_CRATES := $(filter-out rustc, \
$(filter-out rustc_driver, \
$(filter-out log, \
$(filter-out regex, \
$(filter-out regex_macros, \
$(filter-out getopts, \
$(filter-out time, \
$(filter-out syntax, $(CRATES)))))))))))))
$(filter-out syntax, $(CRATES)))))))))))
COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_resolve \
rustc_typeck rustc_driver syntax

View File

@ -37,7 +37,7 @@ $(BG)RustLexer.class: $(BG) $(SG)RustLexer.g4
check-build-lexer-verifier: $(BG)verify
ifeq ($(NO_REBUILD),)
VERIFY_DEPS := rustc-stage2-H-$(CFG_BUILD) $(LD)stamp.regex_macros $(LD)stamp.rustc
VERIFY_DEPS := rustc-stage2-H-$(CFG_BUILD) $(LD)stamp.rustc
else
VERIFY_DEPS :=
endif

View File

@ -373,15 +373,6 @@ TESTDEP_$(1)_$(2)_$(3)_$(4) = $$(SREQ$(1)_T_$(2)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate)) \
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4))
# The regex crate depends on the regex_macros crate during testing, but it
# notably depend on the *host* regex_macros crate, not the target version.
# Additionally, this is not a dependency in stage1, only in stage2.
ifeq ($(4),regex)
ifneq ($(1),1)
TESTDEP_$(1)_$(2)_$(3)_$(4) += $$(TLIB$(1)_T_$(3)_H_$(3))/stamp.regex_macros
endif
endif
else
TESTDEP_$(1)_$(2)_$(3)_$(4) = $$(RSINPUTS_$(4))
endif
@ -843,27 +834,8 @@ else
CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(RSINPUTS_$(4))
endif
# (Issues #13732, #13983, #14000) The doc for the regex crate includes
# uses of the `regex!` macro from the regex_macros crate. There is
# normally a dependence injected that makes the target's regex depend
# upon the host's regex_macros (see #13845), but that dependency
# injection is currently skipped for stage1 as a special case.
#
# Therefore, as a further special case, this conditional skips
# attempting to run the doc tests for the regex crate atop stage1,
# (since there is no regex_macros crate for the stage1 rustc to load).
#
# (Another approach for solving this would be to inject the desired
# dependence for stage1 as well, by setting things up to generate a
# regex_macros crate that was compatible with the stage1 rustc and
# thus re-enable our ability to run this test.)
ifeq (stage$(1)-crate-$(4),stage1-crate-regex)
check-stage$(1)-T-$(2)-H-$(3)-doc-crate-$(4)-exec:
@$$(call E, skipping doc-crate-$(4) as it uses macros and cannot run at stage$(1))
else
check-stage$(1)-T-$(2)-H-$(3)-doc-crate-$(4)-exec: \
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4))
endif
ifeq ($(2),$$(CFG_BUILD))
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4)): $$(CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4))

View File

@ -22,7 +22,7 @@ extern crate regex;
use std::os;
use std::io;
use std::io::fs;
use std::str::{FromStr, from_str};
use std::str::FromStr;
use std::thunk::Thunk;
use getopts::{optopt, optflag, reqopt};
use common::Config;

View File

@ -1478,11 +1478,11 @@ Constants should in general be preferred over statics, unless large amounts of
data are being stored, or single-address and mutability properties are required.
```
use std::sync::atomic;
use std::sync::atomic::{AtomicUint, Ordering, ATOMIC_UINT_INIT};;
// Note that ATOMIC_UINT_INIT is a *const*, but it may be used to initialize a
// static. This static can be modified, so it is not placed in read-only memory.
static COUNTER: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
static COUNTER: AtomicUint = ATOMIC_UINT_INIT;
// This table is a candidate to be placed in read-only memory.
static TABLE: &'static [uint] = &[1, 2, 3, /* ... */];
@ -1490,7 +1490,7 @@ static TABLE: &'static [uint] = &[1, 2, 3, /* ... */];
for slot in TABLE.iter() {
println!("{}", slot);
}
COUNTER.fetch_add(1, atomic::SeqCst);
COUNTER.fetch_add(1, Ordering::SeqCst);
```
#### Mutable statics

View File

@ -19,10 +19,9 @@ extern crate regex;
#[phase(link, plugin)]
extern crate log;
#[phase(plugin)] extern crate regex_macros;
use std::collections::HashMap;
use std::io::File;
use regex::Regex;
use syntax::parse;
use syntax::parse::lexer;
@ -168,9 +167,9 @@ fn count(lit: &str) -> uint {
}
fn parse_antlr_token(s: &str, tokens: &HashMap<String, token::Token>) -> TokenAndSpan {
let re = regex!(
let re = Regex::new(
r"\[@(?P<seq>\d+),(?P<start>\d+):(?P<end>\d+)='(?P<content>.+?)',<(?P<toknum>-?\d+)>,\d+:\d+]"
);
).unwrap();
let m = re.captures(s).expect(format!("The regex didn't match {}", s).as_slice());
let start = m.name("start").unwrap_or("");

View File

@ -600,11 +600,9 @@ mod tests {
use std::ops::Drop;
use std::option::Option;
use std::option::Option::{Some, None};
use std::str::Str;
use std::sync::atomic;
use std::sync::atomic::Ordering::{Acquire, SeqCst};
use std::task;
use std::kinds::Send;
use std::thread::Thread;
use std::vec::Vec;
use super::{Arc, Weak, weak_count, strong_count};
use std::sync::Mutex;
@ -631,7 +629,7 @@ mod tests {
let (tx, rx) = channel();
task::spawn(move || {
let _t = Thread::spawn(move || {
let arc_v: Arc<Vec<int>> = rx.recv().unwrap();
assert_eq!((*arc_v)[3], 4);
});

View File

@ -77,12 +77,6 @@ extern crate libc;
#[cfg(test)] #[phase(plugin, link)] extern crate std;
#[cfg(test)] #[phase(plugin, link)] extern crate log;
// The deprecated name of the boxed module
#[deprecated = "use boxed instead"]
#[cfg(not(test))]
pub use boxed as owned;
// Heaps provided for low-level allocation strategies
pub mod heap;

View File

@ -68,7 +68,8 @@ pub fn find_rand_n<M, T, I, F>(n: uint,
{
// setup
let mut rng = rand::weak_rng();
let mut keys = Vec::from_fn(n, |_| rng.gen::<uint>() % n);
let mut keys = range(0, n).map(|_| rng.gen::<uint>() % n)
.collect::<Vec<_>>();
for k in keys.iter() {
insert(map, *k);

View File

@ -685,12 +685,6 @@ impl Bitv {
).collect()
}
/// Deprecated: Use `iter().collect()`.
#[deprecated = "Use `iter().collect()`"]
pub fn to_bools(&self) -> Vec<bool> {
self.iter().collect()
}
/// Compares a `Bitv` to a slice of `bool`s.
/// Both the `Bitv` and slice must have the same length.
///
@ -935,18 +929,6 @@ impl Bitv {
}
}
/// Deprecated: Now a static method on Bitv.
#[deprecated = "Now a static method on Bitv"]
pub fn from_bytes(bytes: &[u8]) -> Bitv {
Bitv::from_bytes(bytes)
}
/// Deprecated: Now a static method on Bitv.
#[deprecated = "Now a static method on Bitv"]
pub fn from_fn<F>(len: uint, f: F) -> Bitv where F: FnMut(uint) -> bool {
Bitv::from_fn(len, f)
}
#[stable]
impl Default for Bitv {
#[inline]
@ -1907,14 +1889,9 @@ impl<'a> Iterator for SymmetricDifference<'a> {
#[cfg(test)]
mod tests {
use prelude::*;
use core::iter::range_step;
use core::u32;
use std::rand;
use std::rand::Rng;
use test::{Bencher, black_box};
use super::{Bitv, BitvSet, from_fn, from_bytes};
use bitv;
use super::Bitv;
#[test]
fn test_to_str() {
@ -1928,7 +1905,7 @@ mod tests {
#[test]
fn test_0_elements() {
let act = Bitv::new();
let exp = Vec::from_elem(0u, false);
let exp = Vec::new();
assert!(act.eq_vec(exp.as_slice()));
assert!(act.none() && act.all());
}
@ -2318,7 +2295,7 @@ mod tests {
assert_eq!(bitv.iter().collect::<Vec<bool>>(), bools);
let long = Vec::from_fn(10000, |i| i % 2 == 0);
let long = range(0, 10000).map(|i| i % 2 == 0).collect::<Vec<_>>();
let bitv: Bitv = long.iter().map(|n| *n).collect();
assert_eq!(bitv.iter().collect::<Vec<bool>>(), long)
}

View File

@ -187,12 +187,6 @@ impl<K: Ord, V> BTreeMap<K, V> {
for _ in mem::replace(self, BTreeMap::with_b(b)).into_iter() {};
}
/// Deprecated: renamed to `get`.
#[deprecated = "renamed to `get`"]
pub fn find(&self, key: &K) -> Option<&V> {
self.get(key)
}
// Searching in a B-Tree is pretty straightforward.
//
// Start at the root. Try to find the key in the current node. If we find it, return it.
@ -253,12 +247,6 @@ impl<K: Ord, V> BTreeMap<K, V> {
self.get(key).is_some()
}
/// Deprecated: renamed to `get_mut`.
#[deprecated = "renamed to `get_mut`"]
pub fn find_mut(&mut self, key: &K) -> Option<&mut V> {
self.get_mut(key)
}
/// Returns a mutable reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but the ordering
@ -297,12 +285,6 @@ impl<K: Ord, V> BTreeMap<K, V> {
}
}
/// Deprecated: renamed to `insert`.
#[deprecated = "renamed to `insert`"]
pub fn swap(&mut self, key: K, value: V) -> Option<V> {
self.insert(key, value)
}
// Insertion in a B-Tree is a bit complicated.
//
// First we do the same kind of search described in `find`. But we need to maintain a stack of
@ -438,12 +420,6 @@ impl<K: Ord, V> BTreeMap<K, V> {
// the underflow handling process on the parent. If merging merges the last two children
// of the root, then we replace the root with the merged node.
/// Deprecated: renamed to `remove`.
#[deprecated = "renamed to `remove`"]
pub fn pop(&mut self, key: &K) -> Option<V> {
self.remove(key)
}
/// Removes a key from the map, returning the value at the key if the key
/// was previously in the map.
///
@ -1506,7 +1482,7 @@ mod test {
let size = 10000u;
// Forwards
let mut map: BTreeMap<uint, uint> = Vec::from_fn(size, |i| (i, i)).into_iter().collect();
let mut map: BTreeMap<uint, uint> = range(0, size).map(|i| (i, i)).collect();
{
let mut iter = map.iter();
@ -1545,7 +1521,7 @@ mod test {
let size = 10000u;
// Forwards
let mut map: BTreeMap<uint, uint> = Vec::from_fn(size, |i| (i, i)).into_iter().collect();
let mut map: BTreeMap<uint, uint> = range(0, size).map(|i| (i, i)).collect();
{
let mut iter = map.iter().rev();

View File

@ -219,22 +219,6 @@ impl<T> DList<T> {
DList{list_head: None, list_tail: Rawlink::none(), length: 0}
}
/// Deprecated: Not clearly useful enough; use split and append when available.
#[deprecated = "Not clearly useful enough; use split and append when available"]
pub fn rotate_forward(&mut self) {
self.pop_back_node().map(|tail| {
self.push_front_node(tail)
});
}
/// Deprecated: Not clearly useful enough; use split and append when available.
#[deprecated = "Not clearly useful enough; use split and append when available"]
pub fn rotate_backward(&mut self) {
self.pop_front_node().map(|head| {
self.push_back_node(head)
});
}
/// Adds all elements from `other` to the end of the list.
///
/// This operation should compute in O(1) time.
@ -277,49 +261,6 @@ impl<T> DList<T> {
}
}
/// Deprecated: Use append and a swap instead.
#[deprecated = "Use append and a swap instead"]
pub fn prepend(&mut self, mut other: DList<T>) {
mem::swap(self, &mut other);
self.append(other);
}
/// Deprecated: Use custom methods on IterMut.
#[deprecated = "Use custom methods on IterMut"]
pub fn insert_when<F>(&mut self, elt: T, mut f: F) where F: FnMut(&T, &T) -> bool {
let mut it = self.iter_mut();
loop {
match it.peek_next() {
None => break,
Some(x) => if f(x, &elt) { break }
}
it.next();
}
it.insert_next(elt);
}
/// Deprecated: Use custom methods on IterMut.
#[deprecated = "Use custom methods on IterMut"]
pub fn merge<F>(&mut self, mut other: DList<T>, mut f: F) where F: FnMut(&T, &T) -> bool {
{
let mut it = self.iter_mut();
loop {
let take_a = match (it.peek_next(), other.front()) {
(_ , None) => return,
(None, _ ) => break,
(Some(ref mut x), Some(y)) => f(*x, y),
};
if take_a {
it.next();
} else {
it.insert_next_node(other.pop_front_node().unwrap());
}
}
}
self.append(other);
}
/// Provides a forward iterator.
#[inline]
#[stable]
@ -426,12 +367,6 @@ impl<T> DList<T> {
self.pop_front_node().map(|box Node{value, ..}| value)
}
/// Deprecated: Renamed to `push_back`.
#[deprecated = "Renamed to `push_back`"]
pub fn push(&mut self, elt: T) {
self.push_back(elt)
}
/// Appends an element to the back of a list
///
/// # Examples
@ -449,12 +384,6 @@ impl<T> DList<T> {
self.push_back_node(box Node::new(elt))
}
/// Deprecated: Renamed to `pop_back`.
#[deprecated = "Renamed to `pop_back`"]
pub fn pop(&mut self) -> Option<T> {
self.pop_back()
}
/// Removes the last element from a list and returns it, or `None` if
/// it is empty.
///
@ -475,15 +404,6 @@ impl<T> DList<T> {
}
}
impl<T: Ord> DList<T> {
/// Deprecated: Why are you maintaining a sorted DList?
#[deprecated = "Why are you maintaining a sorted DList?"]
#[allow(deprecated)]
pub fn insert_ordered(&mut self, elt: T) {
self.insert_when(elt, |a, b| a >= b)
}
}
#[unsafe_destructor]
#[stable]
impl<T> Drop for DList<T> {
@ -589,19 +509,6 @@ impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
#[stable]
impl<'a, A> ExactSizeIterator for IterMut<'a, A> {}
/// Allows mutating a `DList` while iterating.
#[deprecated = "Trait is deprecated, use inherent methods on the iterator instead"]
pub trait ListInsertion<A> {
/// Inserts `elt` just after to the element most recently returned by
/// `.next()`
///
/// The inserted element does not appear in the iteration.
fn insert_next(&mut self, elt: A);
/// Provides a reference to the next element, without changing the iterator
fn peek_next<'a>(&'a mut self) -> Option<&'a mut A>;
}
// private methods for IterMut
impl<'a, A> IterMut<'a, A> {
fn insert_next_node(&mut self, mut ins_node: Box<Node<A>>) {
@ -780,7 +687,7 @@ mod tests {
use prelude::*;
use std::rand;
use std::hash;
use std::task::spawn;
use std::thread::Thread;
use test::Bencher;
use test;
@ -868,88 +775,6 @@ mod tests {
v.iter().map(|x| (*x).clone()).collect()
}
#[test]
#[allow(deprecated)]
fn test_append() {
{
let mut m = DList::new();
let mut n = DList::new();
n.push_back(2i);
m.append(n);
assert_eq!(m.len(), 1);
assert_eq!(m.pop_back(), Some(2));
check_links(&m);
}
{
let mut m = DList::new();
let n = DList::new();
m.push_back(2i);
m.append(n);
assert_eq!(m.len(), 1);
assert_eq!(m.pop_back(), Some(2));
check_links(&m);
}
let v = vec![1i,2,3,4,5];
let u = vec![9i,8,1,2,3,4,5];
let mut m = list_from(v.as_slice());
m.append(list_from(u.as_slice()));
check_links(&m);
let mut sum = v;
sum.push_all(u.as_slice());
assert_eq!(sum.len(), m.len());
for elt in sum.into_iter() {
assert_eq!(m.pop_front(), Some(elt))
}
}
#[test]
fn test_prepend() {
{
let mut m = DList::new();
let mut n = DList::new();
n.push_back(2i);
m.prepend(n);
assert_eq!(m.len(), 1);
assert_eq!(m.pop_back(), Some(2));
check_links(&m);
}
let v = vec![1i,2,3,4,5];
let mut u = vec![9i,8,1,2,3,4,5];
let mut m = list_from(v.as_slice());
m.prepend(list_from(u.as_slice()));
check_links(&m);
u.extend(v.iter().map(|&b| b));
assert_eq!(u.len(), m.len());
for elt in u.into_iter() {
assert_eq!(m.pop_front(), Some(elt))
}
}
#[test]
fn test_rotate() {
let mut n: DList<int> = DList::new();
n.rotate_backward(); check_links(&n);
assert_eq!(n.len(), 0);
n.rotate_forward(); check_links(&n);
assert_eq!(n.len(), 0);
let v = vec![1i,2,3,4,5];
let mut m = list_from(v.as_slice());
m.rotate_backward(); check_links(&m);
m.rotate_forward(); check_links(&m);
assert_eq!(v.iter().collect::<Vec<&int>>(), m.iter().collect::<Vec<_>>());
m.rotate_forward(); check_links(&m);
m.rotate_forward(); check_links(&m);
m.pop_front(); check_links(&m);
m.rotate_forward(); check_links(&m);
m.rotate_backward(); check_links(&m);
m.push_front(9); check_links(&m);
m.rotate_forward(); check_links(&m);
assert_eq!(vec![3i,9,5,1,2], m.into_iter().collect::<Vec<_>>());
}
#[test]
fn test_iterator() {
let m = generate_test();
@ -1080,33 +905,6 @@ mod tests {
assert_eq!(m.into_iter().collect::<Vec<int>>(), vec![-2,0,1,2,3,4,5,6,7,8,9,0,1]);
}
#[test]
fn test_merge() {
let mut m = list_from(&[0i, 1, 3, 5, 6, 7, 2]);
let n = list_from(&[-1i, 0, 0, 7, 7, 9]);
let len = m.len() + n.len();
m.merge(n, |a, b| a <= b);
assert_eq!(m.len(), len);
check_links(&m);
let res = m.into_iter().collect::<Vec<int>>();
assert_eq!(res, vec![-1, 0, 0, 0, 1, 3, 5, 6, 7, 2, 7, 7, 9]);
}
#[test]
fn test_insert_ordered() {
let mut n = DList::new();
n.insert_ordered(1i);
assert_eq!(n.len(), 1);
assert_eq!(n.pop_front(), Some(1));
let mut m = DList::new();
m.push_back(2i);
m.push_back(4);
m.insert_ordered(3);
check_links(&m);
assert_eq!(vec![2,3,4], m.into_iter().collect::<Vec<int>>());
}
#[test]
fn test_mut_rev_iter() {
let mut m = generate_test();
@ -1124,11 +922,11 @@ mod tests {
#[test]
fn test_send() {
let n = list_from(&[1i,2,3]);
spawn(move || {
Thread::spawn(move || {
check_links(&n);
let a: &[_] = &[&1,&2,&3];
assert_eq!(a, n.iter().collect::<Vec<&int>>());
});
}).join().ok().unwrap();
}
#[test]
@ -1265,6 +1063,40 @@ mod tests {
assert_eq!(i, v.len());
}
#[allow(deprecated)]
fn test_append() {
{
let mut m = DList::new();
let mut n = DList::new();
n.push_back(2i);
m.append(n);
assert_eq!(m.len(), 1);
assert_eq!(m.pop_back(), Some(2));
check_links(&m);
}
{
let mut m = DList::new();
let n = DList::new();
m.push_back(2i);
m.append(n);
assert_eq!(m.len(), 1);
assert_eq!(m.pop_back(), Some(2));
check_links(&m);
}
let v = vec![1i,2,3,4,5];
let u = vec![9i,8,1,2,3,4,5];
let mut m = list_from(v.as_slice());
m.append(list_from(u.as_slice()));
check_links(&m);
let mut sum = v;
sum.push_all(u.as_slice());
assert_eq!(sum.len(), m.len());
for elt in sum.into_iter() {
assert_eq!(m.pop_front(), Some(elt))
}
}
#[bench]
fn bench_collect_into(b: &mut test::Bencher) {
let v = &[0i; 64];
@ -1307,26 +1139,6 @@ mod tests {
})
}
#[bench]
fn bench_rotate_forward(b: &mut test::Bencher) {
let mut m: DList<int> = DList::new();
m.push_front(0i);
m.push_front(1);
b.iter(|| {
m.rotate_forward();
})
}
#[bench]
fn bench_rotate_backward(b: &mut test::Bencher) {
let mut m: DList<int> = DList::new();
m.push_front(0i);
m.push_front(1);
b.iter(|| {
m.rotate_backward();
})
}
#[bench]
fn bench_iter(b: &mut test::Bencher) {
let v = &[0i; 128];

View File

@ -81,12 +81,6 @@ fn bit<E:CLike>(e: &E) -> uint {
}
impl<E:CLike> EnumSet<E> {
/// Deprecated: Renamed to `new`.
#[deprecated = "Renamed to `new`"]
pub fn empty() -> EnumSet<E> {
EnumSet::new()
}
/// Returns an empty `EnumSet`.
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn new() -> EnumSet<E> {
@ -109,13 +103,6 @@ impl<E:CLike> EnumSet<E> {
self.bits = 0;
}
/// Returns `true` if the `EnumSet` contains any enum of the given `EnumSet`.
/// Deprecated: Use `is_disjoint`.
#[deprecated = "Use `is_disjoint`"]
pub fn intersects(&self, e: EnumSet<E>) -> bool {
!self.is_disjoint(&e)
}
/// Returns `false` if the `EnumSet` contains any enum of the given `EnumSet`.
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn is_disjoint(&self, other: &EnumSet<E>) -> bool {
@ -144,12 +131,6 @@ impl<E:CLike> EnumSet<E> {
EnumSet {bits: self.bits & e.bits}
}
/// Deprecated: Use `insert`.
#[deprecated = "Use `insert`"]
pub fn add(&mut self, e: E) {
self.insert(e);
}
/// Adds an enum to the `EnumSet`, and returns `true` if it wasn't there before
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn insert(&mut self, e: E) -> bool {
@ -166,12 +147,6 @@ impl<E:CLike> EnumSet<E> {
result
}
/// Deprecated: use `contains`.
#[deprecated = "use `contains"]
pub fn contains_elem(&self, e: E) -> bool {
self.contains(&e)
}
/// Returns `true` if an `EnumSet` contains a given enum.
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn contains(&self, e: &E) -> bool {

View File

@ -66,7 +66,7 @@ pub mod vec;
pub mod vec_map;
pub mod bitv {
pub use bit::{Bitv, Iter, from_fn, from_bytes};
pub use bit::{Bitv, Iter};
}
pub mod bitv_set {
@ -105,7 +105,7 @@ mod prelude {
pub use core::borrow::IntoCow;
pub use core::char::Char;
pub use core::clone::Clone;
pub use core::cmp::{PartialEq, Eq, Equiv, PartialOrd, Ord};
pub use core::cmp::{PartialEq, Eq, PartialOrd, Ord};
pub use core::cmp::Ordering::{Less, Equal, Greater};
pub use core::iter::range;
pub use core::iter::{FromIterator, Extend, IteratorExt};
@ -123,7 +123,7 @@ mod prelude {
// in core and collections (may differ).
pub use slice::{AsSlice, SliceExt};
pub use str::{from_str, Str, StrExt};
pub use str::{Str, StrExt};
// from other crates.
pub use alloc::boxed::Box;
@ -131,7 +131,6 @@ mod prelude {
// from collections.
pub use slice::SliceConcatExt;
pub use str::IntoMaybeOwned;
pub use string::{String, ToString};
pub use vec::Vec;
}

View File

@ -681,12 +681,6 @@ impl<T> RingBuf<T> {
unsafe { self.buffer_write(tail, t); }
}
/// Deprecated: Renamed to `push_back`.
#[deprecated = "Renamed to `push_back`"]
pub fn push(&mut self, t: T) {
self.push_back(t)
}
/// Appends an element to the back of a buffer
///
/// # Examples
@ -711,12 +705,6 @@ impl<T> RingBuf<T> {
unsafe { self.buffer_write(head, t) }
}
/// Deprecated: Renamed to `pop_back`.
#[deprecated = "Renamed to `pop_back`"]
pub fn pop(&mut self) -> Option<T> {
self.pop_back()
}
/// Removes the last element from a buffer and returns it, or `None` if
/// it is empty.
///
@ -1452,7 +1440,6 @@ mod tests {
use self::Taggy::*;
use self::Taggypar::*;
use prelude::*;
use core::cmp;
use core::iter;
use std::fmt::Show;
use std::hash;

View File

@ -92,7 +92,7 @@ use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
use core::clone::Clone;
use core::cmp::Ordering::{self, Greater, Less};
use core::cmp::{self, Ord, PartialEq};
use core::iter::{Iterator, IteratorExt, IteratorCloneExt};
use core::iter::{Iterator, IteratorExt};
use core::iter::{range, range_step, MultiplicativeIterator};
use core::kinds::Sized;
use core::mem::size_of;
@ -114,12 +114,6 @@ pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
pub use core::slice::{bytes, mut_ref_slice, ref_slice};
pub use core::slice::{from_raw_buf, from_raw_mut_buf};
#[deprecated = "use Iter instead"]
pub type Items<'a, T:'a> = Iter<'a, T>;
#[deprecated = "use IterMut instead"]
pub type MutItems<'a, T:'a> = IterMut<'a, T>;
////////////////////////////////////////////////////////////////////////////////
// Basic slice extension methods
////////////////////////////////////////////////////////////////////////////////
@ -287,10 +281,6 @@ pub trait SliceExt for Sized? {
#[stable]
fn first(&self) -> Option<&Self::Item>;
/// Deprecated: renamed to `first`.
#[deprecated = "renamed to `first`"]
fn head(&self) -> Option<&Self::Item> { self.first() }
/// Returns all but the first element of a slice.
#[experimental = "likely to be renamed"]
fn tail(&self) -> &[Self::Item];
@ -308,12 +298,6 @@ pub trait SliceExt for Sized? {
#[stable]
unsafe fn get_unchecked(&self, index: uint) -> &Self::Item;
/// Deprecated: renamed to `get_unchecked`.
#[deprecated = "renamed to get_unchecked"]
unsafe fn unsafe_get(&self, index: uint) -> &Self::Item {
self.get_unchecked(index)
}
/// Returns an unsafe pointer to the slice's buffer
///
/// The caller must ensure that the slice outlives the pointer this
@ -425,12 +409,6 @@ pub trait SliceExt for Sized? {
#[stable]
fn first_mut(&mut self) -> Option<&mut Self::Item>;
/// Depreated: renamed to `first_mut`.
#[deprecated = "renamed to first_mut"]
fn head_mut(&mut self) -> Option<&mut Self::Item> {
self.first_mut()
}
/// Returns all but the first element of a mutable slice
#[experimental = "likely to be renamed or removed"]
fn tail_mut(&mut self) -> &mut [Self::Item];
@ -549,12 +527,6 @@ pub trait SliceExt for Sized? {
#[stable]
unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut Self::Item;
/// Deprecated: renamed to `get_unchecked_mut`.
#[deprecated = "renamed to get_unchecked_mut"]
unsafe fn unchecked_mut(&mut self, index: uint) -> &mut Self::Item {
self.get_unchecked_mut(index)
}
/// Return an unsafe mutable pointer to the slice's buffer.
///
/// The caller must ensure that the slice outlives the pointer this
@ -570,12 +542,6 @@ pub trait SliceExt for Sized? {
#[stable]
fn to_vec(&self) -> Vec<Self::Item> where Self::Item: Clone;
/// Deprecated: use `iter().cloned().partition(f)` instead.
#[deprecated = "use iter().cloned().partition(f) instead"]
fn partitioned<F>(&self, f: F) -> (Vec<Self::Item>, Vec<Self::Item>) where
Self::Item: Clone,
F: FnMut(&Self::Item) -> bool;
/// Creates an iterator that yields every possible permutation of the
/// vector in succession.
///
@ -960,12 +926,6 @@ impl<T> SliceExt for [T] {
vector
}
#[inline]
fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool, T: Clone {
self.iter().cloned().partition(f)
}
/// Returns an iterator over all permutations of a vector.
fn permutations(&self) -> Permutations<T> where T: Clone {
Permutations{
@ -1034,20 +994,10 @@ pub trait SliceConcatExt<Sized? T, U> for Sized? {
#[stable]
fn concat(&self) -> U;
#[deprecated = "renamed to concat"]
fn concat_vec(&self) -> U {
self.concat()
}
/// Flattens a slice of `T` into a single value `U`, placing a
/// given seperator between each.
#[stable]
fn connect(&self, sep: &T) -> U;
#[deprecated = "renamed to connect"]
fn connect_vec(&self, sep: &T) -> U {
self.connect(sep)
}
}
impl<T: Clone, V: AsSlice<T>> SliceConcatExt<T, Vec<T>> for [V] {
@ -1438,21 +1388,12 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
}
}
/// Deprecated, unsafe operations
#[deprecated]
pub mod raw {
pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
pub use core::slice::raw::{shift_ptr, pop_ptr};
}
#[cfg(test)]
mod tests {
use std::boxed::Box;
use prelude::{Some, None, range, Vec, ToString, Clone, Greater, Less, Equal};
use prelude::{SliceExt, Iterator, IteratorExt};
use prelude::AsSlice;
use prelude::{RandomAccessIterator, Ord, SliceConcatExt};
use core::cell::Cell;
use core::default::Default;
use core::mem;
use std::rand::{Rng, thread_rng};
@ -1466,7 +1407,7 @@ mod tests {
#[test]
fn test_from_fn() {
// Test on-stack from_fn.
let mut v = Vec::from_fn(3u, square);
let mut v = range(0, 3).map(square).collect::<Vec<_>>();
{
let v = v.as_slice();
assert_eq!(v.len(), 3u);
@ -1476,7 +1417,7 @@ mod tests {
}
// Test on-heap from_fn.
v = Vec::from_fn(5u, square);
v = range(0, 5).map(square).collect::<Vec<_>>();
{
let v = v.as_slice();
assert_eq!(v.len(), 5u);
@ -1491,7 +1432,7 @@ mod tests {
#[test]
fn test_from_elem() {
// Test on-stack from_elem.
let mut v = Vec::from_elem(2u, 10u);
let mut v = vec![10u, 10u];
{
let v = v.as_slice();
assert_eq!(v.len(), 2u);
@ -1500,7 +1441,7 @@ mod tests {
}
// Test on-heap from_elem.
v = Vec::from_elem(6u, 20u);
v = vec![20u, 20u, 20u, 20u, 20u, 20u];
{
let v = v.as_slice();
assert_eq!(v[0], 20u);
@ -1542,23 +1483,23 @@ mod tests {
}
#[test]
fn test_head() {
fn test_first() {
let mut a = vec![];
assert_eq!(a.as_slice().head(), None);
assert_eq!(a.as_slice().first(), None);
a = vec![11i];
assert_eq!(a.as_slice().head().unwrap(), &11);
assert_eq!(a.as_slice().first().unwrap(), &11);
a = vec![11i, 12];
assert_eq!(a.as_slice().head().unwrap(), &11);
assert_eq!(a.as_slice().first().unwrap(), &11);
}
#[test]
fn test_head_mut() {
fn test_first_mut() {
let mut a = vec![];
assert_eq!(a.head_mut(), None);
assert_eq!(a.first_mut(), None);
a = vec![11i];
assert_eq!(*a.head_mut().unwrap(), 11);
assert_eq!(*a.first_mut().unwrap(), 11);
a = vec![11i, 12];
assert_eq!(*a.head_mut().unwrap(), 11);
assert_eq!(*a.first_mut().unwrap(), 11);
}
#[test]
@ -1762,42 +1703,6 @@ mod tests {
assert_eq!(v.as_slice()[1], 2);
}
#[test]
fn test_grow() {
// Test on-stack grow().
let mut v = vec![];
v.grow(2u, 1i);
{
let v = v.as_slice();
assert_eq!(v.len(), 2u);
assert_eq!(v[0], 1);
assert_eq!(v[1], 1);
}
// Test on-heap grow().
v.grow(3u, 2i);
{
let v = v.as_slice();
assert_eq!(v.len(), 5u);
assert_eq!(v[0], 1);
assert_eq!(v[1], 1);
assert_eq!(v[2], 2);
assert_eq!(v[3], 2);
assert_eq!(v[4], 2);
}
}
#[test]
fn test_grow_fn() {
let mut v = vec![];
v.grow_fn(3u, square);
let v = v.as_slice();
assert_eq!(v.len(), 3u);
assert_eq!(v[0], 0u);
assert_eq!(v[1], 1u);
assert_eq!(v[2], 4u);
}
#[test]
fn test_truncate() {
let mut v = vec![box 6i,box 5,box 4];
@ -2130,22 +2035,6 @@ mod tests {
}
}
#[test]
fn test_partition() {
assert_eq!((vec![]).partition(|x: &int| *x < 3), (vec![], vec![]));
assert_eq!((vec![1i, 2, 3]).partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
assert_eq!((vec![1i, 2, 3]).partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
assert_eq!((vec![1i, 2, 3]).partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
}
#[test]
fn test_partitioned() {
assert_eq!(([]).partitioned(|x: &int| *x < 3), (vec![], vec![]));
assert_eq!(([1i, 2, 3]).partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
assert_eq!(([1i, 2, 3]).partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
assert_eq!(([1i, 2, 3]).partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
}
#[test]
fn test_concat() {
let v: [Vec<int>; 0] = [];
@ -2163,14 +2052,14 @@ mod tests {
#[test]
fn test_connect() {
let v: [Vec<int>; 0] = [];
assert_eq!(v.connect_vec(&0), vec![]);
assert_eq!([vec![1i], vec![2i, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
assert_eq!([vec![1i], vec![2i], vec![3i]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
assert_eq!(v.connect(&0), vec![]);
assert_eq!([vec![1i], vec![2i, 3]].connect(&0), vec![1, 0, 2, 3]);
assert_eq!([vec![1i], vec![2i], vec![3i]].connect(&0), vec![1, 0, 2, 0, 3]);
let v: [&[int]; 2] = [&[1], &[2, 3]];
assert_eq!(v.connect_vec(&0), vec![1, 0, 2, 3]);
assert_eq!(v.connect(&0), vec![1, 0, 2, 3]);
let v: [&[int]; 3] = [&[1], &[2], &[3]];
assert_eq!(v.connect_vec(&0), vec![1, 0, 2, 0, 3]);
assert_eq!(v.connect(&0), vec![1, 0, 2, 0, 3]);
}
#[test]
@ -2243,55 +2132,6 @@ mod tests {
assert_eq!(v[1], 3);
}
#[test]
#[should_fail]
fn test_from_fn_fail() {
Vec::from_fn(100, |v| {
if v == 50 { panic!() }
box 0i
});
}
#[test]
#[should_fail]
fn test_from_elem_fail() {
struct S {
f: Cell<int>,
boxes: (Box<int>, Rc<int>)
}
impl Clone for S {
fn clone(&self) -> S {
self.f.set(self.f.get() + 1);
if self.f.get() == 10 { panic!() }
S {
f: self.f.clone(),
boxes: self.boxes.clone(),
}
}
}
let s = S {
f: Cell::new(0),
boxes: (box 0, Rc::new(0)),
};
let _ = Vec::from_elem(100, s);
}
#[test]
#[should_fail]
fn test_grow_fn_fail() {
let mut v = vec![];
v.grow_fn(100, |i| {
if i == 50 {
panic!()
}
(box 0i, Rc::new(0i))
})
}
#[test]
#[should_fail]
fn test_permute_fail() {
@ -2880,6 +2720,7 @@ mod bench {
use prelude::*;
use core::mem;
use core::ptr;
use core::iter::repeat;
use std::rand::{weak_rng, Rng};
use test::{Bencher, black_box};
@ -2887,7 +2728,7 @@ mod bench {
fn iterator(b: &mut Bencher) {
// peculiar numbers to stop LLVM from optimising the summation
// out.
let v = Vec::from_fn(100, |i| i ^ (i << 1) ^ (i >> 1));
let v = range(0u, 100).map(|i| i ^ (i << 1) ^ (i >> 1)).collect::<Vec<_>>();
b.iter(|| {
let mut sum = 0;
@ -2901,7 +2742,7 @@ mod bench {
#[bench]
fn mut_iterator(b: &mut Bencher) {
let mut v = Vec::from_elem(100, 0i);
let mut v = repeat(0i).take(100).collect::<Vec<_>>();
b.iter(|| {
let mut i = 0i;
@ -2915,7 +2756,7 @@ mod bench {
#[bench]
fn concat(b: &mut Bencher) {
let xss: Vec<Vec<uint>> =
Vec::from_fn(100, |i| range(0u, i).collect());
range(0, 100u).map(|i| range(0, i).collect()).collect();
b.iter(|| {
xss.as_slice().concat();
});
@ -2924,9 +2765,9 @@ mod bench {
#[bench]
fn connect(b: &mut Bencher) {
let xss: Vec<Vec<uint>> =
Vec::from_fn(100, |i| range(0u, i).collect());
range(0, 100u).map(|i| range(0, i).collect()).collect();
b.iter(|| {
xss.as_slice().connect_vec(&0)
xss.as_slice().connect(&0)
});
}
@ -2941,7 +2782,7 @@ mod bench {
#[bench]
fn starts_with_same_vector(b: &mut Bencher) {
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
let vec: Vec<uint> = range(0, 100).collect();
b.iter(|| {
vec.as_slice().starts_with(vec.as_slice())
})
@ -2957,8 +2798,8 @@ mod bench {
#[bench]
fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
let mut match_vec: Vec<uint> = Vec::from_fn(99, |i| i);
let vec: Vec<uint> = range(0, 100).collect();
let mut match_vec: Vec<uint> = range(0, 99).collect();
match_vec.push(0);
b.iter(|| {
vec.as_slice().starts_with(match_vec.as_slice())
@ -2967,7 +2808,7 @@ mod bench {
#[bench]
fn ends_with_same_vector(b: &mut Bencher) {
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
let vec: Vec<uint> = range(0, 100).collect();
b.iter(|| {
vec.as_slice().ends_with(vec.as_slice())
})
@ -2983,8 +2824,8 @@ mod bench {
#[bench]
fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
let mut match_vec: Vec<uint> = Vec::from_fn(100, |i| i);
let vec: Vec<uint> = range(0, 100).collect();
let mut match_vec: Vec<uint> = range(0, 100).collect();
match_vec.as_mut_slice()[0] = 200;
b.iter(|| {
vec.as_slice().starts_with(match_vec.as_slice())
@ -2993,7 +2834,7 @@ mod bench {
#[bench]
fn contains_last_element(b: &mut Bencher) {
let vec: Vec<uint> = Vec::from_fn(100, |i| i);
let vec: Vec<uint> = range(0, 100).collect();
b.iter(|| {
vec.contains(&99u)
})
@ -3002,7 +2843,7 @@ mod bench {
#[bench]
fn zero_1kb_from_elem(b: &mut Bencher) {
b.iter(|| {
Vec::from_elem(1024, 0u8)
repeat(0u8).take(1024).collect::<Vec<_>>()
});
}
@ -3050,7 +2891,7 @@ mod bench {
fn random_inserts(b: &mut Bencher) {
let mut rng = weak_rng();
b.iter(|| {
let mut v = Vec::from_elem(30, (0u, 0u));
let mut v = repeat((0u, 0u)).take(30).collect::<Vec<_>>();
for _ in range(0u, 100) {
let l = v.len();
v.insert(rng.gen::<uint>() % (l + 1),
@ -3062,7 +2903,7 @@ mod bench {
fn random_removes(b: &mut Bencher) {
let mut rng = weak_rng();
b.iter(|| {
let mut v = Vec::from_elem(130, (0u, 0u));
let mut v = repeat((0u, 0u)).take(130).collect::<Vec<_>>();
for _ in range(0u, 100) {
let l = v.len();
v.remove(rng.gen::<uint>() % l);
@ -3102,7 +2943,7 @@ mod bench {
#[bench]
fn sort_sorted(b: &mut Bencher) {
let mut v = Vec::from_fn(10000, |i| i);
let mut v = range(0u, 10000).collect::<Vec<_>>();
b.iter(|| {
v.sort();
});
@ -3146,7 +2987,7 @@ mod bench {
#[bench]
fn sort_big_sorted(b: &mut Bencher) {
let mut v = Vec::from_fn(10000u, |i| (i, i, i, i));
let mut v = range(0, 10000u).map(|i| (i, i, i, i)).collect::<Vec<_>>();
b.iter(|| {
v.sort();
});

View File

@ -51,20 +51,14 @@
#![doc(primitive = "str")]
use self::MaybeOwned::*;
use self::RecompositionState::*;
use self::DecompositionType::*;
use core::borrow::{BorrowFrom, Cow, ToOwned};
use core::borrow::{BorrowFrom, ToOwned};
use core::char::Char;
use core::clone::Clone;
use core::cmp::{Equiv, PartialEq, Eq, PartialOrd, Ord, Ordering};
use core::cmp;
use core::default::Default;
use core::fmt;
use core::hash;
use core::iter::AdditiveIterator;
use core::iter::{self, range, Iterator, IteratorExt};
use core::iter::{range, Iterator, IteratorExt};
use core::kinds::Sized;
use core::ops;
use core::option::Option::{self, Some, None};
@ -79,16 +73,13 @@ use unicode;
use vec::Vec;
use slice::SliceConcatExt;
pub use core::str::{from_utf8, CharEq, Chars, CharIndices};
pub use core::str::{Bytes, CharSplits, is_utf8};
pub use core::str::{CharSplitsN, Lines, LinesAny, MatchIndices, StrSplits, SplitStr};
pub use core::str::{CharRange};
pub use core::str::{FromStr, from_str, Utf8Error};
pub use core::str::Str;
pub use core::str::{from_utf8_unchecked, from_c_str};
pub use unicode::str::{Words, Graphemes, GraphemeIndices};
pub use core::str::{FromStr, Utf8Error, Str};
pub use core::str::{Lines, LinesAny, MatchIndices, SplitStr, CharRange};
pub use core::str::{Split, SplitTerminator};
pub use core::str::{SplitN, RSplitN};
pub use core::str::{from_utf8, CharEq, Chars, CharIndices, Bytes};
pub use core::str::{from_utf8_unchecked, from_c_str};
pub use unicode::str::{Words, Graphemes, GraphemeIndices};
/*
Section: Creating a string
@ -371,32 +362,6 @@ impl<'a> Iterator for Utf16Units<'a> {
fn size_hint(&self) -> (uint, Option<uint>) { self.encoder.size_hint() }
}
/// Replaces all occurrences of one string with another.
///
/// # Arguments
///
/// * s - The string containing substrings to replace
/// * from - The string to replace
/// * to - The replacement string
///
/// # Return value
///
/// The original string with all occurrences of `from` replaced with `to`.
///
/// # Examples
///
/// ```rust
/// # #![allow(deprecated)]
/// use std::str;
/// let string = "orange";
/// let new_string = str::replace(string, "or", "str");
/// assert_eq!(new_string.as_slice(), "strange");
/// ```
#[deprecated = "call the inherent method instead"]
pub fn replace(s: &str, from: &str, to: &str) -> String {
s.replace(from, to)
}
/*
Section: Misc
*/
@ -413,215 +378,6 @@ macro_rules! utf8_acc_cont_byte {
($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32)
}
/*
Section: MaybeOwned
*/
/// A string type that can hold either a `String` or a `&str`.
/// This can be useful as an optimization when an allocation is sometimes
/// needed but not always.
#[deprecated = "use std::string::CowString"]
pub enum MaybeOwned<'a> {
/// A borrowed string.
Slice(&'a str),
/// An owned string.
Owned(String)
}
/// A specialization of `CowString` to be sendable.
#[deprecated = "use std::string::CowString<'static>"]
pub type SendStr = CowString<'static>;
#[deprecated = "use std::string::CowString"]
impl<'a> MaybeOwned<'a> {
/// Returns `true` if this `MaybeOwned` wraps an owned string.
///
/// # Examples
///
/// ``` ignore
/// let string = String::from_str("orange");
/// let maybe_owned_string = string.into_maybe_owned();
/// assert_eq!(true, maybe_owned_string.is_owned());
/// ```
#[inline]
pub fn is_owned(&self) -> bool {
match *self {
Slice(_) => false,
Owned(_) => true
}
}
/// Returns `true` if this `MaybeOwned` wraps a borrowed string.
///
/// # Examples
///
/// ``` ignore
/// let string = "orange";
/// let maybe_owned_string = string.as_slice().into_maybe_owned();
/// assert_eq!(true, maybe_owned_string.is_slice());
/// ```
#[inline]
pub fn is_slice(&self) -> bool {
match *self {
Slice(_) => true,
Owned(_) => false
}
}
/// Return the number of bytes in this string.
#[inline]
#[allow(deprecated)]
pub fn len(&self) -> uint { self.as_slice().len() }
/// Returns true if the string contains no bytes
#[allow(deprecated)]
#[inline]
pub fn is_empty(&self) -> bool { self.len() == 0 }
}
#[deprecated = "use std::borrow::IntoCow"]
/// Trait for moving into a `MaybeOwned`.
pub trait IntoMaybeOwned<'a> {
/// Moves `self` into a `MaybeOwned`.
fn into_maybe_owned(self) -> MaybeOwned<'a>;
}
#[deprecated = "use std::borrow::IntoCow"]
#[allow(deprecated)]
impl<'a> IntoMaybeOwned<'a> for String {
/// # Examples
///
/// ``` ignore
/// let owned_string = String::from_str("orange");
/// let maybe_owned_string = owned_string.into_maybe_owned();
/// assert_eq!(true, maybe_owned_string.is_owned());
/// ```
#[allow(deprecated)]
#[inline]
fn into_maybe_owned(self) -> MaybeOwned<'a> {
Owned(self)
}
}
#[deprecated = "use std::borrow::IntoCow"]
#[allow(deprecated)]
impl<'a> IntoMaybeOwned<'a> for &'a str {
/// # Examples
///
/// ``` ignore
/// let string = "orange";
/// let maybe_owned_str = string.as_slice().into_maybe_owned();
/// assert_eq!(false, maybe_owned_str.is_owned());
/// ```
#[allow(deprecated)]
#[inline]
fn into_maybe_owned(self) -> MaybeOwned<'a> { Slice(self) }
}
#[allow(deprecated)]
#[deprecated = "use std::borrow::IntoCow"]
impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> {
/// # Examples
///
/// ``` ignore
/// let str = "orange";
/// let maybe_owned_str = str.as_slice().into_maybe_owned();
/// let maybe_maybe_owned_str = maybe_owned_str.into_maybe_owned();
/// assert_eq!(false, maybe_maybe_owned_str.is_owned());
/// ```
#[inline]
fn into_maybe_owned(self) -> MaybeOwned<'a> { self }
}
#[deprecated = "use std::string::CowString"]
#[allow(deprecated)]
impl<'a> PartialEq for MaybeOwned<'a> {
#[inline]
fn eq(&self, other: &MaybeOwned) -> bool {
self.as_slice() == other.as_slice()
}
}
#[deprecated = "use std::string::CowString"]
impl<'a> Eq for MaybeOwned<'a> {}
#[deprecated = "use std::string::CowString"]
impl<'a> PartialOrd for MaybeOwned<'a> {
#[inline]
fn partial_cmp(&self, other: &MaybeOwned) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[deprecated = "use std::string::CowString"]
impl<'a> Ord for MaybeOwned<'a> {
#[inline]
#[allow(deprecated)]
fn cmp(&self, other: &MaybeOwned) -> Ordering {
self.as_slice().cmp(other.as_slice())
}
}
#[allow(deprecated)]
#[deprecated = "use std::string::CowString"]
impl<'a, S: Str> Equiv<S> for MaybeOwned<'a> {
#[inline]
fn equiv(&self, other: &S) -> bool {
self.as_slice() == other.as_slice()
}
}
#[deprecated = "use std::string::CowString"]
#[allow(deprecated)]
impl<'a> Str for MaybeOwned<'a> {
#[inline]
fn as_slice<'b>(&'b self) -> &'b str {
match *self {
Slice(s) => s,
Owned(ref s) => s.as_slice()
}
}
}
#[deprecated = "use std::string::CowString"]
impl<'a> Clone for MaybeOwned<'a> {
#[allow(deprecated)]
#[inline]
fn clone(&self) -> MaybeOwned<'a> {
match *self {
Slice(s) => Slice(s),
Owned(ref s) => Owned(String::from_str(s.as_slice()))
}
}
}
#[deprecated = "use std::string::CowString"]
impl<'a> Default for MaybeOwned<'a> {
#[allow(deprecated)]
#[inline]
fn default() -> MaybeOwned<'a> { Slice("") }
}
#[deprecated = "use std::string::CowString"]
#[allow(deprecated)]
impl<'a, H: hash::Writer> hash::Hash<H> for MaybeOwned<'a> {
#[inline]
fn hash(&self, hasher: &mut H) {
self.as_slice().hash(hasher)
}
}
#[deprecated = "use std::string::CowString"]
impl<'a> fmt::Show for MaybeOwned<'a> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Slice(ref s) => s.fmt(f),
Owned(ref s) => s.fmt(f)
}
}
}
#[unstable = "trait is unstable"]
impl BorrowFrom<String> for str {
fn borrow_from(owned: &String) -> &str { owned[] }
@ -636,21 +392,10 @@ impl ToOwned<String> for str {
}
}
/// Unsafe string operations.
#[deprecated]
pub mod raw {
pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
pub use core::str::raw::{slice_unchecked};
}
/*
Section: CowString
*/
/// A clone-on-write string
#[deprecated = "use std::string::CowString instead"]
pub type CowString<'a> = Cow<'a, String, str>;
/*
Section: Trait implementations
*/
@ -706,46 +451,6 @@ pub trait StrExt for Sized?: ops::Slice<uint, str> {
result
}
/// Given a string, makes a new string with repeated copies of it.
#[deprecated = "use repeat(self).take(n).collect() instead"]
fn repeat(&self, nn: uint) -> String {
iter::repeat(self[]).take(nn).collect()
}
/// Returns the Levenshtein Distance between two strings.
#[deprecated = "this function will be removed"]
fn lev_distance(&self, t: &str) -> uint {
let me = self[];
if me.is_empty() { return t.chars().count(); }
if t.is_empty() { return me.chars().count(); }
let mut dcol: Vec<_> = range(0, t.len() + 1).collect();
let mut t_last = 0;
for (i, sc) in me.chars().enumerate() {
let mut current = i;
dcol[0] = current + 1;
for (j, tc) in t.chars().enumerate() {
let next = dcol[j + 1];
if sc == tc {
dcol[j + 1] = current;
} else {
dcol[j + 1] = cmp::min(current, next);
dcol[j + 1] = cmp::min(dcol[j + 1], dcol[j]) + 1;
}
current = next;
t_last = j;
}
}
dcol[t_last + 1]
}
/// Returns an iterator over the string in Unicode Normalization Form D
/// (canonical decomposition).
#[inline]
@ -1002,7 +707,7 @@ pub trait StrExt for Sized?: ops::Slice<uint, str> {
/// assert_eq!(v, vec!["1", "", "2"]);
/// ```
#[unstable = "might get removed in the future in favor of a more generic split()"]
fn split_str<'a>(&'a self, pat: &'a str) -> StrSplits<'a> {
fn split_str<'a>(&'a self, pat: &'a str) -> SplitStr<'a> {
core_str::StrExt::split_str(self[], pat)
}
@ -1038,43 +743,6 @@ pub trait StrExt for Sized?: ops::Slice<uint, str> {
core_str::StrExt::lines_any(self[])
}
/// Returns the number of Unicode code points (`char`) that a
/// string holds.
///
/// This does not perform any normalization, and is `O(n)`, since
/// UTF-8 is a variable width encoding of code points.
///
/// *Warning*: The number of code points in a string does not directly
/// correspond to the number of visible characters or width of the
/// visible text due to composing characters, and double- and
/// zero-width ones.
///
/// See also `.len()` for the byte length.
///
/// # Example
///
/// ```rust
/// # #![allow(deprecated)]
/// // composed forms of `ö` and `é`
/// let c = "Löwe 老虎 Léopard"; // German, Simplified Chinese, French
/// // decomposed forms of `ö` and `é`
/// let d = "Lo\u{0308}we 老虎 Le\u{0301}opard";
///
/// assert_eq!(c.char_len(), 15);
/// assert_eq!(d.char_len(), 17);
///
/// assert_eq!(c.len(), 21);
/// assert_eq!(d.len(), 23);
///
/// // the two strings *look* the same
/// println!("{}", c);
/// println!("{}", d);
/// ```
#[deprecated = "call .chars().count() instead"]
fn char_len(&self) -> uint {
core_str::StrExt::char_len(self[])
}
/// Returns a slice of the given string from the byte range
/// [`begin`..`end`).
///
@ -1220,12 +888,6 @@ pub trait StrExt for Sized?: ops::Slice<uint, str> {
core_str::StrExt::trim_matches(self[], pat)
}
/// Deprecated
#[deprecated = "Replaced by `trim_matches`"]
fn trim_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str {
self.trim_matches(to_trim)
}
/// Returns a string with all prefixes that match
/// the pattern `pat` repeatedly removed.
///
@ -1246,12 +908,6 @@ pub trait StrExt for Sized?: ops::Slice<uint, str> {
core_str::StrExt::trim_left_matches(self[], pat)
}
/// Deprecated
#[deprecated = "Replaced by `trim_left_matches`"]
fn trim_left_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str {
self.trim_left_matches(to_trim)
}
/// Returns a string with all suffixes that match
/// the pattern `pat` repeatedly removed.
///
@ -1272,12 +928,6 @@ pub trait StrExt for Sized?: ops::Slice<uint, str> {
core_str::StrExt::trim_right_matches(self[], pat)
}
/// Deprecated
#[deprecated = "Replaced by `trim_right_matches`"]
fn trim_right_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str {
self.trim_right_matches(to_trim)
}
/// Check that `index`-th byte lies at the start and/or end of a
/// UTF-8 code point sequence.
///
@ -1599,7 +1249,7 @@ pub trait StrExt for Sized?: ops::Slice<uint, str> {
#[inline]
#[unstable = "this method was just created"]
fn parse<F: FromStr>(&self) -> Option<F> {
FromStr::from_str(self[])
core_str::StrExt::parse(self[])
}
/// Returns an iterator over the
@ -1657,43 +1307,6 @@ pub trait StrExt for Sized?: ops::Slice<uint, str> {
UnicodeStr::words(self[])
}
/// Returns true if the string contains only whitespace.
///
/// Whitespace characters are determined by `char::is_whitespace`.
///
/// # Example
///
/// ```rust
/// # #![allow(deprecated)]
/// assert!(" \t\n".is_whitespace());
/// assert!("".is_whitespace());
///
/// assert!( !"abc".is_whitespace());
/// ```
#[deprecated = "use .chars().all(|c| c.is_whitespace())"]
fn is_whitespace(&self) -> bool {
UnicodeStr::is_whitespace(self[])
}
/// Returns true if the string contains only alphanumeric code
/// points.
///
/// Alphanumeric characters are determined by `char::is_alphanumeric`.
///
/// # Example
///
/// ```rust
/// # #![allow(deprecated)]
/// assert!("Löwe老虎Léopard123".is_alphanumeric());
/// assert!("".is_alphanumeric());
///
/// assert!( !" &*~".is_alphanumeric());
/// ```
#[deprecated = "use .chars().all(|c| c.is_alphanumeric())"]
fn is_alphanumeric(&self) -> bool {
UnicodeStr::is_alphanumeric(self[])
}
/// Returns a string's displayed width in columns, treating control
/// characters as zero-width.
///
@ -1725,13 +1338,6 @@ pub trait StrExt for Sized?: ops::Slice<uint, str> {
fn trim_right(&self) -> &str {
UnicodeStr::trim_right(self[])
}
/// Deprecated, call `.to_owned()` instead from the `std::borrow::ToOwned`
/// trait.
#[deprecated = "call `.to_owned()` on `std::borrow::ToOwned` instead"]
fn into_string(&self) -> String {
self[].to_owned()
}
}
impl StrExt for str {}
@ -1740,10 +1346,8 @@ impl StrExt for str {}
mod tests {
use prelude::*;
use core::default::Default;
use core::iter::AdditiveIterator;
use super::{from_utf8, is_utf8, raw};
use super::MaybeOwned::{Owned, Slice};
use super::from_utf8;
use super::Utf8Error;
#[test]
@ -1764,14 +1368,14 @@ mod tests {
assert_eq!("\u{2620}".len(), 3u);
assert_eq!("\u{1d11e}".len(), 4u);
assert_eq!("".char_len(), 0u);
assert_eq!("hello world".char_len(), 11u);
assert_eq!("\x63".char_len(), 1u);
assert_eq!("\u{a2}".char_len(), 1u);
assert_eq!("\u{3c0}".char_len(), 1u);
assert_eq!("\u{2620}".char_len(), 1u);
assert_eq!("\u{1d11e}".char_len(), 1u);
assert_eq!("ประเทศไทย中华Việt Nam".char_len(), 19u);
assert_eq!("".chars().count(), 0u);
assert_eq!("hello world".chars().count(), 11u);
assert_eq!("\x63".chars().count(), 1u);
assert_eq!("\u{a2}".chars().count(), 1u);
assert_eq!("\u{3c0}".chars().count(), 1u);
assert_eq!("\u{2620}".chars().count(), 1u);
assert_eq!("\u{1d11e}".chars().count(), 1u);
assert_eq!("ประเทศไทย中华Việt Nam".chars().count(), 19u);
assert_eq!("".width(false), 10u);
assert_eq!("".width(true), 10u);
@ -1854,7 +1458,7 @@ mod tests {
#[test]
fn test_slice_chars() {
fn t(a: &str, b: &str, start: uint) {
assert_eq!(a.slice_chars(start, start + b.char_len()), b);
assert_eq!(a.slice_chars(start, start + b.chars().count()), b);
}
t("", "", 0);
t("hello", "llo", 2);
@ -1864,7 +1468,7 @@ mod tests {
assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
}
fn s(x: &str) -> String { x.into_string() }
fn s(x: &str) -> String { x.to_string() }
macro_rules! test_concat {
($expected: expr, $string: expr) => {
@ -1904,7 +1508,7 @@ mod tests {
#[test]
fn test_connect_for_different_types() {
test_connect!("a-b", ["a", "b"], "-");
let hyphen = "-".into_string();
let hyphen = "-".to_string();
test_connect!("a-b", [s("a"), s("b")], hyphen.as_slice());
test_connect!("a-b", vec!["a", "b"], hyphen.as_slice());
test_connect!("a-b", vec!["a", "b"].as_slice(), "-");
@ -1920,20 +1524,11 @@ mod tests {
test_connect!("-a-bc", ["", "a", "bc"], "-");
}
#[test]
fn test_repeat() {
assert_eq!("x".repeat(4), String::from_str("xxxx"));
assert_eq!("hi".repeat(4), String::from_str("hihihihi"));
assert_eq!("ไท华".repeat(3), String::from_str("ไท华ไท华ไท华"));
assert_eq!("".repeat(4), String::from_str(""));
assert_eq!("hi".repeat(0), String::from_str(""));
}
#[test]
fn test_unsafe_slice() {
assert_eq!("ab", unsafe {raw::slice_bytes("abc", 0, 2)});
assert_eq!("bc", unsafe {raw::slice_bytes("abc", 1, 3)});
assert_eq!("", unsafe {raw::slice_bytes("abc", 1, 1)});
assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
fn a_million_letter_a() -> String {
let mut i = 0u;
let mut rs = String::new();
@ -1954,7 +1549,7 @@ mod tests {
}
let letters = a_million_letter_a();
assert!(half_a_million_letter_a() ==
unsafe {String::from_str(raw::slice_bytes(letters.as_slice(),
unsafe {String::from_str(letters.slice_unchecked(
0u,
500000))});
}
@ -2120,48 +1715,48 @@ mod tests {
}
#[test]
fn test_trim_left_chars() {
fn test_trim_left_matches() {
let v: &[char] = &[];
assert_eq!(" *** foo *** ".trim_left_chars(v), " *** foo *** ");
assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
let chars: &[char] = &['*', ' '];
assert_eq!(" *** foo *** ".trim_left_chars(chars), "foo *** ");
assert_eq!(" *** *** ".trim_left_chars(chars), "");
assert_eq!("foo *** ".trim_left_chars(chars), "foo *** ");
assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
assert_eq!(" *** *** ".trim_left_matches(chars), "");
assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11");
assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
let chars: &[char] = &['1', '2'];
assert_eq!("12foo1bar12".trim_left_chars(chars), "foo1bar12");
assert_eq!("123foo1bar123".trim_left_chars(|&: c: char| c.is_numeric()), "foo1bar123");
assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
assert_eq!("123foo1bar123".trim_left_matches(|&: c: char| c.is_numeric()), "foo1bar123");
}
#[test]
fn test_trim_right_chars() {
fn test_trim_right_matches() {
let v: &[char] = &[];
assert_eq!(" *** foo *** ".trim_right_chars(v), " *** foo *** ");
assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
let chars: &[char] = &['*', ' '];
assert_eq!(" *** foo *** ".trim_right_chars(chars), " *** foo");
assert_eq!(" *** *** ".trim_right_chars(chars), "");
assert_eq!(" *** foo".trim_right_chars(chars), " *** foo");
assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
assert_eq!(" *** *** ".trim_right_matches(chars), "");
assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar");
assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
let chars: &[char] = &['1', '2'];
assert_eq!("12foo1bar12".trim_right_chars(chars), "12foo1bar");
assert_eq!("123foo1bar123".trim_right_chars(|&: c: char| c.is_numeric()), "123foo1bar");
assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
assert_eq!("123foo1bar123".trim_right_matches(|&: c: char| c.is_numeric()), "123foo1bar");
}
#[test]
fn test_trim_chars() {
fn test_trim_matches() {
let v: &[char] = &[];
assert_eq!(" *** foo *** ".trim_chars(v), " *** foo *** ");
assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
let chars: &[char] = &['*', ' '];
assert_eq!(" *** foo *** ".trim_chars(chars), "foo");
assert_eq!(" *** *** ".trim_chars(chars), "");
assert_eq!("foo".trim_chars(chars), "foo");
assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
assert_eq!(" *** *** ".trim_matches(chars), "");
assert_eq!("foo".trim_matches(chars), "foo");
assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar");
assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
let chars: &[char] = &['1', '2'];
assert_eq!("12foo1bar12".trim_chars(chars), "foo1bar");
assert_eq!("123foo1bar123".trim_chars(|&: c: char| c.is_numeric()), "foo1bar");
assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
assert_eq!("123foo1bar123".trim_matches(|&: c: char| c.is_numeric()), "foo1bar");
}
#[test]
@ -2196,11 +1791,11 @@ mod tests {
#[test]
fn test_is_whitespace() {
assert!("".is_whitespace());
assert!(" ".is_whitespace());
assert!("\u{2009}".is_whitespace()); // Thin space
assert!(" \n\t ".is_whitespace());
assert!(!" _ ".is_whitespace());
assert!("".chars().all(|c| c.is_whitespace()));
assert!(" ".chars().all(|c| c.is_whitespace()));
assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
assert!(" \n\t ".chars().all(|c| c.is_whitespace()));
assert!(!" _ ".chars().all(|c| c.is_whitespace()));
}
#[test]
@ -2218,26 +1813,26 @@ mod tests {
#[test]
fn test_is_utf8() {
// deny overlong encodings
assert!(!is_utf8(&[0xc0, 0x80]));
assert!(!is_utf8(&[0xc0, 0xae]));
assert!(!is_utf8(&[0xe0, 0x80, 0x80]));
assert!(!is_utf8(&[0xe0, 0x80, 0xaf]));
assert!(!is_utf8(&[0xe0, 0x81, 0x81]));
assert!(!is_utf8(&[0xf0, 0x82, 0x82, 0xac]));
assert!(!is_utf8(&[0xf4, 0x90, 0x80, 0x80]));
assert!(from_utf8(&[0xc0, 0x80]).is_err());
assert!(from_utf8(&[0xc0, 0xae]).is_err());
assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
// deny surrogates
assert!(!is_utf8(&[0xED, 0xA0, 0x80]));
assert!(!is_utf8(&[0xED, 0xBF, 0xBF]));
assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
assert!(is_utf8(&[0xC2, 0x80]));
assert!(is_utf8(&[0xDF, 0xBF]));
assert!(is_utf8(&[0xE0, 0xA0, 0x80]));
assert!(is_utf8(&[0xED, 0x9F, 0xBF]));
assert!(is_utf8(&[0xEE, 0x80, 0x80]));
assert!(is_utf8(&[0xEF, 0xBF, 0xBF]));
assert!(is_utf8(&[0xF0, 0x90, 0x80, 0x80]));
assert!(is_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]));
assert!(from_utf8(&[0xC2, 0x80]).is_ok());
assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
}
#[test]
@ -2411,7 +2006,7 @@ mod tests {
let mut pos = 0;
for ch in v.iter() {
assert!(s.char_at(pos) == *ch);
pos += String::from_char(1, *ch).len();
pos += ch.to_string().len();
}
}
@ -2422,7 +2017,7 @@ mod tests {
let mut pos = s.len();
for ch in v.iter().rev() {
assert!(s.char_at_reverse(pos) == *ch);
pos -= String::from_char(1, *ch).len();
pos -= ch.to_string().len();
}
}
@ -3213,66 +2808,6 @@ mod tests {
let xs = b"hello\xFF";
assert_eq!(from_utf8(xs), Err(Utf8Error::TooShort));
}
#[test]
fn test_maybe_owned_traits() {
let s = Slice("abcde");
assert_eq!(s.len(), 5);
assert_eq!(s.as_slice(), "abcde");
assert_eq!(String::from_str(s.as_slice()).as_slice(), "abcde");
assert_eq!(format!("{}", s).as_slice(), "abcde");
assert!(s.lt(&Owned(String::from_str("bcdef"))));
assert_eq!(Slice(""), Default::default());
let o = Owned(String::from_str("abcde"));
assert_eq!(o.len(), 5);
assert_eq!(o.as_slice(), "abcde");
assert_eq!(String::from_str(o.as_slice()).as_slice(), "abcde");
assert_eq!(format!("{}", o).as_slice(), "abcde");
assert!(o.lt(&Slice("bcdef")));
assert_eq!(Owned(String::from_str("")), Default::default());
assert!(s.cmp(&o) == Equal);
assert!(s.equiv(&o));
assert!(o.cmp(&s) == Equal);
assert!(o.equiv(&s));
}
#[test]
fn test_maybe_owned_methods() {
let s = Slice("abcde");
assert!(s.is_slice());
assert!(!s.is_owned());
let o = Owned(String::from_str("abcde"));
assert!(!o.is_slice());
assert!(o.is_owned());
}
#[test]
fn test_maybe_owned_clone() {
assert_eq!(Owned(String::from_str("abcde")), Slice("abcde").clone());
assert_eq!(Owned(String::from_str("abcde")), Owned(String::from_str("abcde")).clone());
assert_eq!(Slice("abcde"), Slice("abcde").clone());
assert_eq!(Slice("abcde"), Owned(String::from_str("abcde")).clone());
}
#[test]
fn test_maybe_owned_into_string() {
assert_eq!(Slice("abcde").to_string(), String::from_str("abcde"));
assert_eq!(Owned(String::from_str("abcde")).to_string(),
String::from_str("abcde"));
}
#[test]
fn test_into_maybe_owned() {
assert_eq!("abcde".into_maybe_owned(), Slice("abcde"));
assert_eq!((String::from_str("abcde")).into_maybe_owned(), Slice("abcde"));
assert_eq!("abcde".into_maybe_owned(), Owned(String::from_str("abcde")));
assert_eq!((String::from_str("abcde")).into_maybe_owned(),
Owned(String::from_str("abcde")));
}
}
#[cfg(test)]
@ -3329,7 +2864,7 @@ mod bench {
#[bench]
fn char_indicesator(b: &mut Bencher) {
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
let len = s.char_len();
let len = s.chars().count();
b.iter(|| assert_eq!(s.char_indices().count(), len));
}
@ -3337,7 +2872,7 @@ mod bench {
#[bench]
fn char_indicesator_rev(b: &mut Bencher) {
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
let len = s.char_len();
let len = s.chars().count();
b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
}
@ -3416,27 +2951,6 @@ mod bench {
b.iter(|| assert_eq!(s.split(c).count(), len));
}
#[bench]
fn is_utf8_100_ascii(b: &mut Bencher) {
let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
Lorem ipsum dolor sit amet, consectetur. ";
assert_eq!(100, s.len());
b.iter(|| {
is_utf8(s)
});
}
#[bench]
fn is_utf8_100_multibyte(b: &mut Bencher) {
let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
assert_eq!(100, s.len());
b.iter(|| {
is_utf8(s)
});
}
#[bench]
fn bench_connect(b: &mut Bencher) {
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";

View File

@ -17,7 +17,6 @@
use core::prelude::*;
use core::borrow::{Cow, IntoCow};
use core::cmp::Equiv;
use core::default::Default;
use core::fmt;
use core::hash;
@ -109,7 +108,6 @@ impl String {
/// # Examples
///
/// ```rust
/// # #![allow(deprecated)]
/// use std::str::Utf8Error;
///
/// let hello_vec = vec![104, 101, 108, 108, 111];
@ -309,22 +307,6 @@ impl String {
unicode_str::utf16_items(v).map(|c| c.to_char_lossy()).collect()
}
/// Convert a vector of `char`s to a `String`.
///
/// # Examples
///
/// ```rust
/// # #![allow(deprecated)]
/// let chars = &['h', 'e', 'l', 'l', 'o'];
/// let s = String::from_chars(chars);
/// assert_eq!(s.as_slice(), "hello");
/// ```
#[inline]
#[deprecated = "use .collect() instead"]
pub fn from_chars(chs: &[char]) -> String {
chs.iter().map(|c| *c).collect()
}
/// Creates a new `String` from a length, capacity, and pointer.
///
/// This is unsafe because:
@ -386,32 +368,6 @@ impl String {
self.vec
}
/// Creates a string buffer by repeating a character `length` times.
///
/// # Examples
///
/// ```
/// # #![allow(deprecated)]
/// let s = String::from_char(5, 'a');
/// assert_eq!(s.as_slice(), "aaaaa");
/// ```
#[inline]
#[deprecated = "use repeat(ch).take(length).collect() instead"]
pub fn from_char(length: uint, ch: char) -> String {
if length == 0 {
return String::new()
}
let mut buf = String::new();
buf.push(ch);
let size = buf.len() * (length - 1);
buf.reserve_exact(size);
for _ in range(1, length) {
buf.push(ch)
}
buf
}
/// Pushes the given string onto this string buffer.
///
/// # Examples
@ -427,24 +383,6 @@ impl String {
self.vec.push_all(string.as_bytes())
}
/// Pushes `ch` onto the given string `count` times.
///
/// # Examples
///
/// ```
/// # #![allow(deprecated)]
/// let mut s = String::from_str("foo");
/// s.grow(5, 'Z');
/// assert_eq!(s.as_slice(), "fooZZZZZ");
/// ```
#[inline]
#[deprecated = "deprecated in favor of .extend(repeat(ch).take(count))"]
pub fn grow(&mut self, count: uint, ch: char) {
for _ in range(0, count) {
self.push(ch)
}
}
/// Returns the number of bytes that this string buffer can hold without
/// reallocating.
///
@ -460,12 +398,6 @@ impl String {
self.vec.capacity()
}
/// Deprecated: Renamed to `reserve`.
#[deprecated = "Renamed to `reserve`"]
pub fn reserve_additional(&mut self, extra: uint) {
self.vec.reserve(extra)
}
/// Reserves capacity for at least `additional` more bytes to be inserted
/// in the given `String`. The collection may reserve more space to avoid
/// frequent reallocations.
@ -869,7 +801,6 @@ impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
}
#[experimental = "waiting on Str stabilization"]
#[allow(deprecated)]
impl Str for String {
#[inline]
#[stable]
@ -901,15 +832,6 @@ impl<H: hash::Writer> hash::Hash<H> for String {
}
}
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<'a, S: Str> Equiv<S> for String {
#[inline]
fn equiv(&self, other: &S) -> bool {
self.as_slice() == other.as_slice()
}
}
#[experimental = "waiting on Add stabilization"]
impl<'a> Add<&'a str> for String {
type Output = String;
@ -991,13 +913,6 @@ impl FromStr for String {
}
}
/// Trait for converting a type to a string, consuming it in the process.
#[deprecated = "trait will be removed"]
pub trait IntoString {
/// Consume and convert to a string.
fn into_string(self) -> String;
}
/// A generic trait for converting a value to a string
pub trait ToString {
/// Converts the value of `self` to an owned string
@ -1026,59 +941,10 @@ impl<'a> IntoCow<'a, String, str> for &'a str {
}
}
/// Unsafe operations
#[deprecated]
pub mod raw {
use super::String;
use vec::Vec;
/// Creates a new `String` from a length, capacity, and pointer.
///
/// This is unsafe because:
/// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
/// * We assume that the `Vec` contains valid UTF-8.
#[inline]
#[deprecated = "renamed to String::from_raw_parts"]
pub unsafe fn from_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
String::from_raw_parts(buf, length, capacity)
}
/// Creates a `String` from a `*const u8` buffer of the given length.
///
/// This function is unsafe because of two reasons:
///
/// * A raw pointer is dereferenced and transmuted to `&[u8]`;
/// * The slice is not checked to see whether it contains valid UTF-8.
#[deprecated = "renamed to String::from_raw_buf_len"]
pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String {
String::from_raw_buf_len(buf, len)
}
/// Creates a `String` from a null-terminated `*const u8` buffer.
///
/// This function is unsafe because we dereference memory until we find the NUL character,
/// which is not guaranteed to be present. Additionally, the slice is not checked to see
/// whether it contains valid UTF-8
#[deprecated = "renamed to String::from_raw_buf"]
pub unsafe fn from_buf(buf: *const u8) -> String {
String::from_raw_buf(buf)
}
/// Converts a vector of bytes to a new `String` without checking if
/// it contains valid UTF-8. This is unsafe because it assumes that
/// the UTF-8-ness of the vector has already been validated.
#[inline]
#[deprecated = "renamed to String::from_utf8_unchecked"]
pub unsafe fn from_utf8(bytes: Vec<u8>) -> String {
String::from_utf8_unchecked(bytes)
}
}
/// A clone-on-write string
#[stable]
pub type CowString<'a> = Cow<'a, String, str>;
#[allow(deprecated)]
impl<'a> Str for CowString<'a> {
#[inline]
fn as_slice<'b>(&'b self) -> &'b str {
@ -1099,8 +965,8 @@ mod tests {
use test::Bencher;
use str::Utf8Error;
use str;
use super::as_string;
use core::iter::repeat;
use super::{as_string, CowString};
#[test]
fn test_as_string() {
@ -1110,7 +976,7 @@ mod tests {
#[test]
fn test_from_str() {
let owned: Option<::std::string::String> = from_str("string");
let owned: Option<::std::string::String> = "string".parse();
assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
}
@ -1133,11 +999,11 @@ mod tests {
#[test]
fn test_from_utf8_lossy() {
let xs = b"hello";
let ys: str::CowString = "hello".into_cow();
let ys: CowString = "hello".into_cow();
assert_eq!(String::from_utf8_lossy(xs), ys);
let xs = "ศไทย中华Việt Nam".as_bytes();
let ys: str::CowString = "ศไทย中华Việt Nam".into_cow();
let ys: CowString = "ศไทย中华Việt Nam".into_cow();
assert_eq!(String::from_utf8_lossy(xs), ys);
let xs = b"Hello\xC2 There\xFF Goodbye";
@ -1264,7 +1130,7 @@ mod tests {
fn test_from_buf_len() {
unsafe {
let a = vec![65u8, 65, 65, 65, 65, 65, 65, 0];
assert_eq!(super::raw::from_buf_len(a.as_ptr(), 3), String::from_str("AAA"));
assert_eq!(String::from_raw_buf_len(a.as_ptr(), 3), String::from_str("AAA"));
}
}
@ -1273,7 +1139,7 @@ mod tests {
unsafe {
let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
let b = a.as_ptr();
let c = super::raw::from_buf(b);
let c = String::from_raw_buf(b);
assert_eq!(c, String::from_str("AAAAAAA"));
}
}
@ -1530,7 +1396,7 @@ mod tests {
#[bench]
fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
let s = Vec::from_elem(100, 0xF5u8);
let s = repeat(0xf5u8).take(100).collect::<Vec<_>>();
b.iter(|| {
let _ = String::from_utf8_lossy(s.as_slice());
});

View File

@ -50,7 +50,7 @@ use alloc::boxed::Box;
use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
use core::borrow::{Cow, IntoCow};
use core::cmp::max;
use core::cmp::{Equiv, Ordering};
use core::cmp::{Ordering};
use core::default::Default;
use core::fmt;
use core::hash::{self, Hash};
@ -207,13 +207,6 @@ impl<T> Vec<T> {
}
}
/// Deprecated: use `iter::range(0, length).map(op).collect()` instead
#[inline]
#[deprecated = "use iter::range(0, length).map(op).collect() instead"]
pub fn from_fn<F>(length: uint, op: F) -> Vec<T> where F: FnMut(uint) -> T {
range(0, length).map(op).collect()
}
/// Creates a `Vec<T>` directly from the raw components of another vector.
///
/// This is highly unsafe, due to the number of invariants that aren't checked.
@ -268,13 +261,6 @@ impl<T> Vec<T> {
dst
}
/// Deprecated: use `into_iter().partition(f)` instead.
#[inline]
#[deprecated = "use into_iter().partition(f) instead"]
pub fn partition<F>(self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
self.into_iter().partition(f)
}
/// Returns the number of elements the vector can hold without
/// reallocating.
///
@ -290,12 +276,6 @@ impl<T> Vec<T> {
self.cap
}
/// Deprecated: Renamed to `reserve`.
#[deprecated = "Renamed to `reserve`"]
pub fn reserve_additional(&mut self, extra: uint) {
self.reserve(extra)
}
/// Reserves capacity for at least `additional` more elements to be inserted in the given
/// `Vec<T>`. The collection may reserve more space to avoid frequent reallocations.
///
@ -635,12 +615,6 @@ impl<T> Vec<T> {
}
}
/// Deprecated: use `extend(range(0, n).map(f))` instead.
#[deprecated = "use extend(range(0, n).map(f)) instead"]
pub fn grow_fn<F>(&mut self, n: uint, f: F) where F: FnMut(uint) -> T {
self.extend(range(0, n).map(f));
}
/// Appends an element to the back of a collection.
///
/// # Panics
@ -979,13 +953,6 @@ impl<T> Vec<T> {
}
impl<T: Clone> Vec<T> {
/// Deprecated: use `repeat(value).take(length).collect()` instead.
#[inline]
#[deprecated = "use repeat(value).take(length).collect() instead"]
pub fn from_elem(length: uint, value: T) -> Vec<T> {
repeat(value).take(length).collect()
}
/// Resizes the `Vec` in-place so that `len()` is equal to `new_len`.
///
/// Calls either `extend()` or `truncate()` depending on whether `new_len`
@ -1044,18 +1011,6 @@ impl<T: Clone> Vec<T> {
}
}
}
/// Deprecated: use `extend(repeat(value).take(n))` instead
#[deprecated = "use extend(repeat(value).take(n)) instead"]
pub fn grow(&mut self, n: uint, value: T) {
self.extend(repeat(value).take(n))
}
/// Deprecated: use `iter().cloned().partition(f)` instead.
#[deprecated = "use iter().cloned().partition(f) instead"]
pub fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
self.iter().cloned().partition(f)
}
}
impl<T: PartialEq> Vec<T> {
@ -1158,16 +1113,6 @@ impl<T: PartialEq> Vec<T> {
}
}
////////////////////////////////////////////////////////////////////////////////
// Public free fns
////////////////////////////////////////////////////////////////////////////////
/// Deprecated: use `unzip` directly on the iterator instead.
#[deprecated = "use unzip directly on the iterator instead"]
pub fn unzip<T, U, V: Iterator<Item=(T, U)>>(iter: V) -> (Vec<T>, Vec<U>) {
iter.unzip()
}
////////////////////////////////////////////////////////////////////////////////
// Internal methods and functions
////////////////////////////////////////////////////////////////////////////////
@ -1438,13 +1383,6 @@ impl<T: PartialOrd> PartialOrd for Vec<T> {
#[unstable = "waiting on Eq stability"]
impl<T: Eq> Eq for Vec<T> {}
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for Vec<T> {
#[inline]
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}
#[unstable = "waiting on Ord stability"]
impl<T: Ord> Ord for Vec<T> {
#[inline]
@ -1563,9 +1501,6 @@ pub struct IntoIter<T> {
end: *const T
}
#[deprecated = "use IntoIter instead"]
pub type MoveItems<T> = IntoIter<T>;
impl<T> IntoIter<T> {
#[inline]
/// Drops all items that have not yet been moved and returns the empty vector.
@ -1578,10 +1513,6 @@ impl<T> IntoIter<T> {
Vec { ptr: NonZero::new(allocation), cap: cap, len: 0 }
}
}
/// Deprecated, use .into_inner() instead
#[deprecated = "use .into_inner() instead"]
pub fn unwrap(self) -> Vec<T> { self.into_inner() }
}
impl<T> Iterator for IntoIter<T> {
@ -1780,26 +1711,6 @@ pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
}
}
////////////////////////////////////////////////////////////////////////////////
// Raw module (deprecated)
////////////////////////////////////////////////////////////////////////////////
/// Unsafe vector operations.
#[deprecated]
pub mod raw {
use super::Vec;
/// Constructs a vector from an unsafe pointer to a buffer.
///
/// The elements of the buffer are copied into the vector without cloning,
/// as if `ptr::read()` were called on them.
#[inline]
#[deprecated = "renamed to Vec::from_raw_buf"]
pub unsafe fn from_buf<T>(ptr: *const T, elts: uint) -> Vec<T> {
Vec::from_raw_buf(ptr, elts)
}
}
////////////////////////////////////////////////////////////////////////////////
// Partial vec, used for map_in_place
////////////////////////////////////////////////////////////////////////////////
@ -1879,8 +1790,9 @@ impl<T,U> Drop for PartialVecZeroSized<T,U> {
mod tests {
use prelude::*;
use core::mem::size_of;
use core::iter::repeat;
use test::Bencher;
use super::{as_vec, unzip, raw};
use super::as_vec;
struct DropCounter<'a> {
count: &'a mut int
@ -2069,13 +1981,6 @@ mod tests {
assert_eq!(v, three)
}
#[test]
fn test_grow_fn() {
let mut v = vec![0u, 1];
v.grow_fn(3, |i| i);
assert!(v == vec![0u, 1, 0, 1, 2]);
}
#[test]
fn test_retain() {
let mut vec = vec![1u, 2, 3, 4];
@ -2116,25 +2021,17 @@ mod tests {
#[test]
fn test_partition() {
assert_eq!(vec![].partition(|x: &int| *x < 3), (vec![], vec![]));
assert_eq!(vec![1i, 2, 3].partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
assert_eq!(vec![1i, 2, 3].partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
assert_eq!(vec![1i, 2, 3].partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
}
#[test]
fn test_partitioned() {
assert_eq!(vec![].partitioned(|x: &int| *x < 3), (vec![], vec![]));
assert_eq!(vec![1i, 2, 3].partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
assert_eq!(vec![1i, 2, 3].partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
assert_eq!(vec![1i, 2, 3].partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
assert_eq!(vec![].into_iter().partition(|x: &int| *x < 3), (vec![], vec![]));
assert_eq!(vec![1i, 2, 3].into_iter().partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
assert_eq!(vec![1i, 2, 3].into_iter().partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
assert_eq!(vec![1i, 2, 3].into_iter().partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
}
#[test]
fn test_zip_unzip() {
let z1 = vec![(1i, 4i), (2, 5), (3, 6)];
let (left, right) = unzip(z1.iter().map(|&x| x));
let (left, right): (Vec<_>, Vec<_>) = z1.iter().map(|&x| x).unzip();
assert_eq!((1, 4), (left[0], right[0]));
assert_eq!((2, 5), (left[1], right[1]));
@ -2147,13 +2044,13 @@ mod tests {
// Test on-stack copy-from-buf.
let a = [1i, 2, 3];
let ptr = a.as_ptr();
let b = raw::from_buf(ptr, 3u);
let b = Vec::from_raw_buf(ptr, 3u);
assert_eq!(b, vec![1, 2, 3]);
// Test on-heap copy-from-buf.
let c = vec![1i, 2, 3, 4, 5];
let ptr = c.as_ptr();
let d = raw::from_buf(ptr, 5u);
let d = Vec::from_raw_buf(ptr, 5u);
assert_eq!(d, vec![1, 2, 3, 4, 5]);
}
}
@ -2254,7 +2151,7 @@ mod tests {
vec.push(1);
vec.push(2);
let ptr = vec.as_ptr();
vec = vec.into_iter().unwrap();
vec = vec.into_iter().into_inner();
assert_eq!(vec.as_ptr(), ptr);
assert_eq!(vec.capacity(), 7);
assert_eq!(vec.len(), 0);
@ -2283,8 +2180,7 @@ mod tests {
#[test]
fn test_map_in_place_zero_drop_count() {
use std::sync::atomic;
use std::sync::atomic::AtomicUint;
use std::sync::atomic::{AtomicUint, Ordering, ATOMIC_UINT_INIT};
#[derive(Clone, PartialEq, Show)]
struct Nothing;
@ -2294,20 +2190,20 @@ mod tests {
struct ZeroSized;
impl Drop for ZeroSized {
fn drop(&mut self) {
DROP_COUNTER.fetch_add(1, atomic::Relaxed);
DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
}
}
const NUM_ELEMENTS: uint = 2;
static DROP_COUNTER: AtomicUint = atomic::ATOMIC_UINT_INIT;
static DROP_COUNTER: AtomicUint = ATOMIC_UINT_INIT;
let v = Vec::from_elem(NUM_ELEMENTS, Nothing);
let v = repeat(Nothing).take(NUM_ELEMENTS).collect::<Vec<_>>();
DROP_COUNTER.store(0, atomic::Relaxed);
DROP_COUNTER.store(0, Ordering::Relaxed);
let v = v.map_in_place(|_| ZeroSized);
assert_eq!(DROP_COUNTER.load(atomic::Relaxed), 0);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
drop(v);
assert_eq!(DROP_COUNTER.load(atomic::Relaxed), NUM_ELEMENTS);
assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), NUM_ELEMENTS);
}
#[test]
@ -2423,7 +2319,7 @@ mod tests {
b.bytes = src_len as u64;
b.iter(|| {
let dst = Vec::from_fn(src_len, |i| i);
let dst = range(0, src_len).collect::<Vec<_>>();
assert_eq!(dst.len(), src_len);
assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
})
@ -2453,7 +2349,7 @@ mod tests {
b.bytes = src_len as u64;
b.iter(|| {
let dst: Vec<uint> = Vec::from_elem(src_len, 5);
let dst: Vec<uint> = repeat(5).take(src_len).collect();
assert_eq!(dst.len(), src_len);
assert!(dst.iter().all(|x| *x == 5));
})

View File

@ -343,12 +343,6 @@ impl<V> VecMap<V> {
#[stable]
pub fn clear(&mut self) { self.v.clear() }
/// Deprecated: Renamed to `get`.
#[deprecated = "Renamed to `get`"]
pub fn find(&self, key: &uint) -> Option<&V> {
self.get(key)
}
/// Returns a reference to the value corresponding to the key.
///
/// # Examples
@ -391,12 +385,6 @@ impl<V> VecMap<V> {
self.get(key).is_some()
}
/// Deprecated: Renamed to `get_mut`.
#[deprecated = "Renamed to `get_mut`"]
pub fn find_mut(&mut self, key: &uint) -> Option<&mut V> {
self.get_mut(key)
}
/// Returns a mutable reference to the value corresponding to the key.
///
/// # Examples
@ -424,12 +412,6 @@ impl<V> VecMap<V> {
}
}
/// Deprecated: Renamed to `insert`.
#[deprecated = "Renamed to `insert`"]
pub fn swap(&mut self, key: uint, value: V) -> Option<V> {
self.insert(key, value)
}
/// Inserts a key-value pair from the map. If the key already had a value
/// present in the map, that value is returned. Otherwise, `None` is returned.
///
@ -455,12 +437,6 @@ impl<V> VecMap<V> {
replace(&mut self.v[key], Some(value))
}
/// Deprecated: Renamed to `remove`.
#[deprecated = "Renamed to `remove`"]
pub fn pop(&mut self, key: &uint) -> Option<V> {
self.remove(key)
}
/// Removes a key from the map, returning the value at the key if the key
/// was previously in the map.
///
@ -483,27 +459,6 @@ impl<V> VecMap<V> {
}
}
impl<V:Clone> VecMap<V> {
/// Deprecated: Use the entry API when available; shouldn't matter anyway, access is cheap.
#[deprecated = "Use the entry API when available; shouldn't matter anyway, access is cheap"]
#[allow(deprecated)]
pub fn update<F>(&mut self, key: uint, newval: V, ff: F) -> bool where F: FnOnce(V, V) -> V {
self.update_with_key(key, newval, move |_k, v, v1| ff(v,v1))
}
/// Deprecated: Use the entry API when available; shouldn't matter anyway, access is cheap.
#[deprecated = "Use the entry API when available; shouldn't matter anyway, access is cheap"]
pub fn update_with_key<F>(&mut self, key: uint, val: V, ff: F) -> bool where
F: FnOnce(uint, V, V) -> V
{
let new_val = match self.get(&key) {
None => val,
Some(orig) => ff(key, (*orig).clone(), val)
};
self.insert(key, new_val).is_none()
}
}
#[stable]
impl<V: PartialEq> PartialEq for VecMap<V> {
fn eq(&self, other: &VecMap<V>) -> bool {
@ -824,36 +779,6 @@ mod test_map {
assert!(map.get(&14).is_none());
}
#[test]
fn test_insert_with_key() {
let mut map = VecMap::new();
// given a new key, initialize it with this new count,
// given an existing key, add more to its count
fn add_more_to_count(_k: uint, v0: uint, v1: uint) -> uint {
v0 + v1
}
fn add_more_to_count_simple(v0: uint, v1: uint) -> uint {
v0 + v1
}
// count integers
map.update(3, 1, add_more_to_count_simple);
map.update_with_key(9, 1, add_more_to_count);
map.update(3, 7, add_more_to_count_simple);
map.update_with_key(5, 3, add_more_to_count);
map.update_with_key(3, 2, add_more_to_count);
// check the total counts
assert_eq!(map.get(&3).unwrap(), &10);
assert_eq!(map.get(&5).unwrap(), &3);
assert_eq!(map.get(&9).unwrap(), &1);
// sadly, no sevens were counted
assert!(map.get(&7).is_none());
}
#[test]
fn test_insert() {
let mut m = VecMap::new();

View File

@ -8,7 +8,65 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Core atomic primitives
//! Atomic types
//!
//! Atomic types provide primitive shared-memory communication between
//! threads, and are the building blocks of other concurrent
//! types.
//!
//! This module defines atomic versions of a select number of primitive
//! types, including `AtomicBool`, `AtomicInt`, `AtomicUint`, and `AtomicOption`.
//! Atomic types present operations that, when used correctly, synchronize
//! updates between threads.
//!
//! Each method takes an `Ordering` which represents the strength of
//! the memory barrier for that operation. These orderings are the
//! same as [C++11 atomic orderings][1].
//!
//! [1]: http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
//!
//! Atomic variables are safe to share between threads (they implement `Sync`)
//! but they do not themselves provide the mechanism for sharing. The most
//! common way to share an atomic variable is to put it into an `Arc` (an
//! atomically-reference-counted shared pointer).
//!
//! Most atomic types may be stored in static variables, initialized using
//! the provided static initializers like `INIT_ATOMIC_BOOL`. Atomic statics
//! are often used for lazy global initialization.
//!
//!
//! # Examples
//!
//! A simple spinlock:
//!
//! ```
//! use std::sync::Arc;
//! use std::sync::atomic::{AtomicUint, Ordering};
//! use std::thread::Thread;
//!
//! fn main() {
//! let spinlock = Arc::new(AtomicUint::new(1));
//!
//! let spinlock_clone = spinlock.clone();
//! Thread::spawn(move|| {
//! spinlock_clone.store(0, Ordering::SeqCst);
//! }).detach();
//!
//! // Wait for the other task to release the lock
//! while spinlock.load(Ordering::SeqCst) != 0 {}
//! }
//! ```
//!
//! Keep a global count of live tasks:
//!
//! ```
//! use std::sync::atomic::{AtomicUint, Ordering, ATOMIC_UINT_INIT};
//!
//! static GLOBAL_TASK_COUNT: AtomicUint = ATOMIC_UINT_INIT;
//!
//! let old_task_count = GLOBAL_TASK_COUNT.fetch_add(1, Ordering::SeqCst);
//! println!("live tasks: {}", old_task_count + 1);
//! ```
#![stable]
@ -235,19 +293,19 @@ impl AtomicBool {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicBool, SeqCst};
/// use std::sync::atomic::{AtomicBool, Ordering};
///
/// let foo = AtomicBool::new(true);
/// assert_eq!(true, foo.fetch_and(false, SeqCst));
/// assert_eq!(false, foo.load(SeqCst));
/// assert_eq!(true, foo.fetch_and(false, Ordering::SeqCst));
/// assert_eq!(false, foo.load(Ordering::SeqCst));
///
/// let foo = AtomicBool::new(true);
/// assert_eq!(true, foo.fetch_and(true, SeqCst));
/// assert_eq!(true, foo.load(SeqCst));
/// assert_eq!(true, foo.fetch_and(true, Ordering::SeqCst));
/// assert_eq!(true, foo.load(Ordering::SeqCst));
///
/// let foo = AtomicBool::new(false);
/// assert_eq!(false, foo.fetch_and(false, SeqCst));
/// assert_eq!(false, foo.load(SeqCst));
/// assert_eq!(false, foo.fetch_and(false, Ordering::SeqCst));
/// assert_eq!(false, foo.load(Ordering::SeqCst));
/// ```
#[inline]
#[stable]
@ -267,20 +325,20 @@ impl AtomicBool {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicBool, SeqCst};
/// use std::sync::atomic::{AtomicBool, Ordering};
///
/// let foo = AtomicBool::new(true);
/// assert_eq!(true, foo.fetch_nand(false, SeqCst));
/// assert_eq!(true, foo.load(SeqCst));
/// assert_eq!(true, foo.fetch_nand(false, Ordering::SeqCst));
/// assert_eq!(true, foo.load(Ordering::SeqCst));
///
/// let foo = AtomicBool::new(true);
/// assert_eq!(true, foo.fetch_nand(true, SeqCst));
/// assert_eq!(0, foo.load(SeqCst) as int);
/// assert_eq!(false, foo.load(SeqCst));
/// assert_eq!(true, foo.fetch_nand(true, Ordering::SeqCst));
/// assert_eq!(0, foo.load(Ordering::SeqCst) as int);
/// assert_eq!(false, foo.load(Ordering::SeqCst));
///
/// let foo = AtomicBool::new(false);
/// assert_eq!(false, foo.fetch_nand(false, SeqCst));
/// assert_eq!(true, foo.load(SeqCst));
/// assert_eq!(false, foo.fetch_nand(false, Ordering::SeqCst));
/// assert_eq!(true, foo.load(Ordering::SeqCst));
/// ```
#[inline]
#[stable]
@ -300,19 +358,19 @@ impl AtomicBool {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicBool, SeqCst};
/// use std::sync::atomic::{AtomicBool, Ordering};
///
/// let foo = AtomicBool::new(true);
/// assert_eq!(true, foo.fetch_or(false, SeqCst));
/// assert_eq!(true, foo.load(SeqCst));
/// assert_eq!(true, foo.fetch_or(false, Ordering::SeqCst));
/// assert_eq!(true, foo.load(Ordering::SeqCst));
///
/// let foo = AtomicBool::new(true);
/// assert_eq!(true, foo.fetch_or(true, SeqCst));
/// assert_eq!(true, foo.load(SeqCst));
/// assert_eq!(true, foo.fetch_or(true, Ordering::SeqCst));
/// assert_eq!(true, foo.load(Ordering::SeqCst));
///
/// let foo = AtomicBool::new(false);
/// assert_eq!(false, foo.fetch_or(false, SeqCst));
/// assert_eq!(false, foo.load(SeqCst));
/// assert_eq!(false, foo.fetch_or(false, Ordering::SeqCst));
/// assert_eq!(false, foo.load(Ordering::SeqCst));
/// ```
#[inline]
#[stable]
@ -332,19 +390,19 @@ impl AtomicBool {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicBool, SeqCst};
/// use std::sync::atomic::{AtomicBool, Ordering};
///
/// let foo = AtomicBool::new(true);
/// assert_eq!(true, foo.fetch_xor(false, SeqCst));
/// assert_eq!(true, foo.load(SeqCst));
/// assert_eq!(true, foo.fetch_xor(false, Ordering::SeqCst));
/// assert_eq!(true, foo.load(Ordering::SeqCst));
///
/// let foo = AtomicBool::new(true);
/// assert_eq!(true, foo.fetch_xor(true, SeqCst));
/// assert_eq!(false, foo.load(SeqCst));
/// assert_eq!(true, foo.fetch_xor(true, Ordering::SeqCst));
/// assert_eq!(false, foo.load(Ordering::SeqCst));
///
/// let foo = AtomicBool::new(false);
/// assert_eq!(false, foo.fetch_xor(false, SeqCst));
/// assert_eq!(false, foo.load(SeqCst));
/// assert_eq!(false, foo.fetch_xor(false, Ordering::SeqCst));
/// assert_eq!(false, foo.load(Ordering::SeqCst));
/// ```
#[inline]
#[stable]
@ -463,11 +521,11 @@ impl AtomicInt {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicInt, SeqCst};
/// use std::sync::atomic::{AtomicInt, Ordering};
///
/// let foo = AtomicInt::new(0);
/// assert_eq!(0, foo.fetch_add(10, SeqCst));
/// assert_eq!(10, foo.load(SeqCst));
/// assert_eq!(0, foo.fetch_add(10, Ordering::SeqCst));
/// assert_eq!(10, foo.load(Ordering::SeqCst));
/// ```
#[inline]
#[stable]
@ -480,11 +538,11 @@ impl AtomicInt {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicInt, SeqCst};
/// use std::sync::atomic::{AtomicInt, Ordering};
///
/// let foo = AtomicInt::new(0);
/// assert_eq!(0, foo.fetch_sub(10, SeqCst));
/// assert_eq!(-10, foo.load(SeqCst));
/// assert_eq!(0, foo.fetch_sub(10, Ordering::SeqCst));
/// assert_eq!(-10, foo.load(Ordering::SeqCst));
/// ```
#[inline]
#[stable]
@ -497,11 +555,11 @@ impl AtomicInt {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicInt, SeqCst};
/// use std::sync::atomic::{AtomicInt, Ordering};
///
/// let foo = AtomicInt::new(0b101101);
/// assert_eq!(0b101101, foo.fetch_and(0b110011, SeqCst));
/// assert_eq!(0b100001, foo.load(SeqCst));
/// assert_eq!(0b101101, foo.fetch_and(0b110011, Ordering::SeqCst));
/// assert_eq!(0b100001, foo.load(Ordering::SeqCst));
#[inline]
#[stable]
pub fn fetch_and(&self, val: int, order: Ordering) -> int {
@ -513,11 +571,11 @@ impl AtomicInt {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicInt, SeqCst};
/// use std::sync::atomic::{AtomicInt, Ordering};
///
/// let foo = AtomicInt::new(0b101101);
/// assert_eq!(0b101101, foo.fetch_or(0b110011, SeqCst));
/// assert_eq!(0b111111, foo.load(SeqCst));
/// assert_eq!(0b101101, foo.fetch_or(0b110011, Ordering::SeqCst));
/// assert_eq!(0b111111, foo.load(Ordering::SeqCst));
#[inline]
#[stable]
pub fn fetch_or(&self, val: int, order: Ordering) -> int {
@ -529,11 +587,11 @@ impl AtomicInt {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicInt, SeqCst};
/// use std::sync::atomic::{AtomicInt, Ordering};
///
/// let foo = AtomicInt::new(0b101101);
/// assert_eq!(0b101101, foo.fetch_xor(0b110011, SeqCst));
/// assert_eq!(0b011110, foo.load(SeqCst));
/// assert_eq!(0b101101, foo.fetch_xor(0b110011, Ordering::SeqCst));
/// assert_eq!(0b011110, foo.load(Ordering::SeqCst));
#[inline]
#[stable]
pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
@ -649,11 +707,11 @@ impl AtomicUint {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicUint, SeqCst};
/// use std::sync::atomic::{AtomicUint, Ordering};
///
/// let foo = AtomicUint::new(0);
/// assert_eq!(0, foo.fetch_add(10, SeqCst));
/// assert_eq!(10, foo.load(SeqCst));
/// assert_eq!(0, foo.fetch_add(10, Ordering::SeqCst));
/// assert_eq!(10, foo.load(Ordering::SeqCst));
/// ```
#[inline]
#[stable]
@ -666,11 +724,11 @@ impl AtomicUint {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicUint, SeqCst};
/// use std::sync::atomic::{AtomicUint, Ordering};
///
/// let foo = AtomicUint::new(10);
/// assert_eq!(10, foo.fetch_sub(10, SeqCst));
/// assert_eq!(0, foo.load(SeqCst));
/// assert_eq!(10, foo.fetch_sub(10, Ordering::SeqCst));
/// assert_eq!(0, foo.load(Ordering::SeqCst));
/// ```
#[inline]
#[stable]
@ -683,11 +741,11 @@ impl AtomicUint {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicUint, SeqCst};
/// use std::sync::atomic::{AtomicUint, Ordering};
///
/// let foo = AtomicUint::new(0b101101);
/// assert_eq!(0b101101, foo.fetch_and(0b110011, SeqCst));
/// assert_eq!(0b100001, foo.load(SeqCst));
/// assert_eq!(0b101101, foo.fetch_and(0b110011, Ordering::SeqCst));
/// assert_eq!(0b100001, foo.load(Ordering::SeqCst));
#[inline]
#[stable]
pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
@ -699,11 +757,11 @@ impl AtomicUint {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicUint, SeqCst};
/// use std::sync::atomic::{AtomicUint, Ordering};
///
/// let foo = AtomicUint::new(0b101101);
/// assert_eq!(0b101101, foo.fetch_or(0b110011, SeqCst));
/// assert_eq!(0b111111, foo.load(SeqCst));
/// assert_eq!(0b101101, foo.fetch_or(0b110011, Ordering::SeqCst));
/// assert_eq!(0b111111, foo.load(Ordering::SeqCst));
#[inline]
#[stable]
pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
@ -715,11 +773,11 @@ impl AtomicUint {
/// # Examples
///
/// ```
/// use std::sync::atomic::{AtomicUint, SeqCst};
/// use std::sync::atomic::{AtomicUint, Ordering};
///
/// let foo = AtomicUint::new(0b101101);
/// assert_eq!(0b101101, foo.fetch_xor(0b110011, SeqCst));
/// assert_eq!(0b011110, foo.load(SeqCst));
/// assert_eq!(0b101101, foo.fetch_xor(0b110011, Ordering::SeqCst));
/// assert_eq!(0b011110, foo.load(Ordering::SeqCst));
#[inline]
#[stable]
pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {

View File

@ -267,10 +267,6 @@ impl<T> RefCell<T> {
unsafe { self.value.into_inner() }
}
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> T { self.into_inner() }
/// Attempts to immutably borrow the wrapped value.
///
/// The borrow lasts until the returned `Ref` exits scope. Multiple
@ -569,8 +565,4 @@ impl<T> UnsafeCell<T> {
#[inline]
#[stable]
pub unsafe fn into_inner(self) -> T { self.value }
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub unsafe fn unwrap(self) -> T { self.into_inner() }
}

View File

@ -17,7 +17,6 @@
use iter::Iterator;
use mem::transmute;
use ops::FnMut;
use option::Option::{None, Some};
use option::Option;
use slice::SliceExt;
@ -80,51 +79,6 @@ pub fn from_u32(i: u32) -> Option<char> {
}
}
///
/// Checks if a `char` parses as a numeric digit in the given radix
///
/// Compared to `is_numeric()`, this function only recognizes the
/// characters `0-9`, `a-z` and `A-Z`.
///
/// # Return value
///
/// Returns `true` if `c` is a valid digit under `radix`, and `false`
/// otherwise.
///
/// # Panics
///
/// Panics if given a `radix` > 36.
///
/// # Note
///
/// This just wraps `to_digit()`.
///
#[inline]
#[deprecated = "use the Char::is_digit method"]
pub fn is_digit_radix(c: char, radix: uint) -> bool {
c.is_digit(radix)
}
///
/// Converts a `char` to the corresponding digit
///
/// # Return value
///
/// If `c` is between '0' and '9', the corresponding value
/// between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is
/// 'b' or 'B', 11, etc. Returns none if the `char` does not
/// refer to a digit in the given radix.
///
/// # Panics
///
/// Panics if given a `radix` outside the range `[0..36]`.
///
#[inline]
#[deprecated = "use the Char::to_digit method"]
pub fn to_digit(c: char, radix: uint) -> Option<uint> {
c.to_digit(radix)
}
///
/// Converts a number to the character representing it
///
@ -156,48 +110,9 @@ pub fn from_digit(num: uint, radix: uint) -> Option<char> {
}
}
/// Deprecated, call the escape_unicode method instead.
#[deprecated = "use the Char::escape_unicode method"]
pub fn escape_unicode<F>(c: char, mut f: F) where F: FnMut(char) {
for char in c.escape_unicode() {
f(char);
}
}
/// Deprecated, call the escape_default method instead.
#[deprecated = "use the Char::escape_default method"]
pub fn escape_default<F>(c: char, mut f: F) where F: FnMut(char) {
for c in c.escape_default() {
f(c);
}
}
/// Returns the amount of bytes this `char` would need if encoded in UTF-8
#[inline]
#[deprecated = "use the Char::len_utf8 method"]
pub fn len_utf8_bytes(c: char) -> uint {
c.len_utf8()
}
/// Basic `char` manipulations.
#[experimental = "trait organization may change"]
pub trait Char {
/// Checks if a `char` parses as a numeric digit in the given radix.
///
/// Compared to `is_numeric()`, this function only recognizes the characters
/// `0-9`, `a-z` and `A-Z`.
///
/// # Return value
///
/// Returns `true` if `c` is a valid digit under `radix`, and `false`
/// otherwise.
///
/// # Panics
///
/// Panics if given a radix > 36.
#[deprecated = "use is_digit"]
fn is_digit_radix(self, radix: uint) -> bool;
/// Checks if a `char` parses as a numeric digit in the given radix.
///
/// Compared to `is_numeric()`, this function only recognizes the characters
@ -228,23 +143,6 @@ pub trait Char {
#[unstable = "pending error conventions, trait organization"]
fn to_digit(self, radix: uint) -> Option<uint>;
/// Converts a number to the character representing it.
///
/// # Return value
///
/// Returns `Some(char)` if `num` represents one digit under `radix`,
/// using one character of `0-9` or `a-z`, or `None` if it doesn't.
///
/// # Panics
///
/// Panics if given a radix > 36.
#[deprecated = "use the char::from_digit free function"]
fn from_digit(num: uint, radix: uint) -> Option<Self>;
/// Converts from `u32` to a `char`
#[deprecated = "use the char::from_u32 free function"]
fn from_u32(i: u32) -> Option<char>;
/// Returns an iterator that yields the hexadecimal Unicode escape
/// of a character, as `char`s.
///
@ -269,11 +167,6 @@ pub trait Char {
#[unstable = "pending error conventions, trait organization"]
fn escape_default(self) -> EscapeDefault;
/// Returns the amount of bytes this character would need if encoded in
/// UTF-8.
#[deprecated = "use len_utf8"]
fn len_utf8_bytes(self) -> uint;
/// Returns the amount of bytes this character would need if encoded in
/// UTF-8.
#[unstable = "pending trait organization"]
@ -303,9 +196,6 @@ pub trait Char {
#[experimental = "trait is experimental"]
impl Char for char {
#[deprecated = "use is_digit"]
fn is_digit_radix(self, radix: uint) -> bool { self.is_digit(radix) }
#[unstable = "pending trait organization"]
fn is_digit(self, radix: uint) -> bool {
match self.to_digit(radix) {
@ -329,13 +219,6 @@ impl Char for char {
else { None }
}
#[deprecated = "use the char::from_digit free function"]
fn from_digit(num: uint, radix: uint) -> Option<char> { from_digit(num, radix) }
#[inline]
#[deprecated = "use the char::from_u32 free function"]
fn from_u32(i: u32) -> Option<char> { from_u32(i) }
#[unstable = "pending error conventions, trait organization"]
fn escape_unicode(self) -> EscapeUnicode {
EscapeUnicode { c: self, state: EscapeUnicodeState::Backslash }
@ -356,10 +239,6 @@ impl Char for char {
EscapeDefault { state: init_state }
}
#[inline]
#[deprecated = "use len_utf8"]
fn len_utf8_bytes(self) -> uint { self.len_utf8() }
#[inline]
#[unstable = "pending trait organization"]
fn len_utf8(self) -> uint {

View File

@ -271,16 +271,6 @@ pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
}
}
/// The equivalence relation. Two values may be equivalent even if they are
/// of different types. The most common use case for this relation is
/// container types; e.g. it is often desirable to be able to use `&str`
/// values to look up entries in a container with `String` keys.
#[deprecated = "Use overloaded core::cmp::PartialEq"]
pub trait Equiv<Sized? T> for Sized? {
/// Implement this function to decide equivalent values.
fn equiv(&self, other: &T) -> bool;
}
/// Compare and return the minimum of two values.
#[inline]
#[stable]

View File

@ -68,8 +68,6 @@ use option::Option::{Some, None};
use std::kinds::Sized;
use uint;
#[deprecated = "renamed to Extend"] pub use self::Extend as Extendable;
/// 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.
@ -2781,15 +2779,6 @@ pub struct Repeat<A> {
element: A
}
impl<A: Clone> Repeat<A> {
/// Create a new `Repeat` that endlessly repeats the element `elt`.
#[inline]
#[deprecated = "use iter::repeat instead"]
pub fn new(elt: A) -> Repeat<A> {
Repeat{element: elt}
}
}
#[unstable = "trait is unstable"]
impl<A: Clone> Iterator for Repeat<A> {
type Item = A;

View File

@ -20,7 +20,6 @@ use intrinsics;
use mem;
use num::Float;
use num::FpCategory as Fp;
use num::from_str_radix;
use option::Option;
#[stable]
@ -314,14 +313,6 @@ impl Float for f32 {
unsafe { intrinsics::powf32(self, n) }
}
/// sqrt(2.0)
#[inline]
fn sqrt2() -> f32 { consts::SQRT2 }
/// 1.0 / sqrt(2.0)
#[inline]
fn frac_1_sqrt2() -> f32 { consts::FRAC_1_SQRT2 }
#[inline]
fn sqrt(self) -> f32 {
if self < 0.0 {
@ -334,66 +325,6 @@ impl Float for f32 {
#[inline]
fn rsqrt(self) -> f32 { self.sqrt().recip() }
/// Archimedes' constant
#[inline]
fn pi() -> f32 { consts::PI }
/// 2.0 * pi
#[inline]
fn two_pi() -> f32 { consts::PI_2 }
/// pi / 2.0
#[inline]
fn frac_pi_2() -> f32 { consts::FRAC_PI_2 }
/// pi / 3.0
#[inline]
fn frac_pi_3() -> f32 { consts::FRAC_PI_3 }
/// pi / 4.0
#[inline]
fn frac_pi_4() -> f32 { consts::FRAC_PI_4 }
/// pi / 6.0
#[inline]
fn frac_pi_6() -> f32 { consts::FRAC_PI_6 }
/// pi / 8.0
#[inline]
fn frac_pi_8() -> f32 { consts::FRAC_PI_8 }
/// 1.0 / pi
#[inline]
fn frac_1_pi() -> f32 { consts::FRAC_1_PI }
/// 2.0 / pi
#[inline]
fn frac_2_pi() -> f32 { consts::FRAC_2_PI }
/// 2.0 / sqrt(pi)
#[inline]
fn frac_2_sqrtpi() -> f32 { consts::FRAC_2_SQRTPI }
/// Euler's number
#[inline]
fn e() -> f32 { consts::E }
/// log2(e)
#[inline]
fn log2_e() -> f32 { consts::LOG2_E }
/// log10(e)
#[inline]
fn log10_e() -> f32 { consts::LOG10_E }
/// ln(2.0)
#[inline]
fn ln_2() -> f32 { consts::LN_2 }
/// ln(10.0)
#[inline]
fn ln_10() -> f32 { consts::LN_10 }
/// Returns the exponential of the number.
#[inline]
fn exp(self) -> f32 {
@ -439,10 +370,3 @@ impl Float for f32 {
self * (value / 180.0f32)
}
}
#[inline]
#[allow(missing_docs)]
#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
pub fn from_str_hex(src: &str) -> Option<f32> {
from_str_radix(src, 16)
}

View File

@ -20,7 +20,6 @@ use intrinsics;
use mem;
use num::Float;
use num::FpCategory as Fp;
use num::from_str_radix;
use option::Option;
// FIXME(#5527): These constants should be deprecated once associated
@ -322,14 +321,6 @@ impl Float for f64 {
unsafe { intrinsics::powif64(self, n) }
}
/// sqrt(2.0)
#[inline]
fn sqrt2() -> f64 { consts::SQRT2 }
/// 1.0 / sqrt(2.0)
#[inline]
fn frac_1_sqrt2() -> f64 { consts::FRAC_1_SQRT2 }
#[inline]
fn sqrt(self) -> f64 {
if self < 0.0 {
@ -342,66 +333,6 @@ impl Float for f64 {
#[inline]
fn rsqrt(self) -> f64 { self.sqrt().recip() }
/// Archimedes' constant
#[inline]
fn pi() -> f64 { consts::PI }
/// 2.0 * pi
#[inline]
fn two_pi() -> f64 { consts::PI_2 }
/// pi / 2.0
#[inline]
fn frac_pi_2() -> f64 { consts::FRAC_PI_2 }
/// pi / 3.0
#[inline]
fn frac_pi_3() -> f64 { consts::FRAC_PI_3 }
/// pi / 4.0
#[inline]
fn frac_pi_4() -> f64 { consts::FRAC_PI_4 }
/// pi / 6.0
#[inline]
fn frac_pi_6() -> f64 { consts::FRAC_PI_6 }
/// pi / 8.0
#[inline]
fn frac_pi_8() -> f64 { consts::FRAC_PI_8 }
/// 1.0 / pi
#[inline]
fn frac_1_pi() -> f64 { consts::FRAC_1_PI }
/// 2.0 / pi
#[inline]
fn frac_2_pi() -> f64 { consts::FRAC_2_PI }
/// 2.0 / sqrt(pi)
#[inline]
fn frac_2_sqrtpi() -> f64 { consts::FRAC_2_SQRTPI }
/// Euler's number
#[inline]
fn e() -> f64 { consts::E }
/// log2(e)
#[inline]
fn log2_e() -> f64 { consts::LOG2_E }
/// log10(e)
#[inline]
fn log10_e() -> f64 { consts::LOG10_E }
/// ln(2.0)
#[inline]
fn ln_2() -> f64 { consts::LN_2 }
/// ln(10.0)
#[inline]
fn ln_10() -> f64 { consts::LN_10 }
/// Returns the exponential of the number.
#[inline]
fn exp(self) -> f64 {
@ -447,10 +378,3 @@ impl Float for f64 {
self * (value / 180.0)
}
}
#[inline]
#[allow(missing_docs)]
#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
pub fn from_str_hex(src: &str) -> Option<f64> {
from_str_radix(src, 16)
}

View File

@ -15,9 +15,6 @@
#![stable]
#![allow(missing_docs)]
use {int, i8, i16, i32, i64};
use {uint, u8, u16, u32, u64};
use {f32, f64};
use char::Char;
use clone::Clone;
use cmp::{PartialEq, Eq};
@ -30,21 +27,7 @@ use ops::{Add, Sub, Mul, Div, Rem, Neg};
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use option::Option;
use option::Option::{Some, None};
use str::{FromStr, from_str, StrExt};
/// Simultaneous division and remainder
#[inline]
#[deprecated = "use division and remainder directly"]
pub fn div_rem<T: Clone + Div<Output=T> + Rem<Output=T>>(x: T, y: T) -> (T, T) {
(x.clone() / y.clone(), x % y)
}
/// Raises a `base` to the power of `exp`, using exponentiation by squaring.
#[inline]
#[deprecated = "Use Int::pow() instead, as in 2i.pow(4)"]
pub fn pow<T: Int>(base: T, exp: uint) -> T {
base.pow(exp)
}
use str::{FromStr, StrExt};
/// A built-in signed or unsigned integer.
#[unstable = "recently settled as part of numerics reform"]
@ -1345,11 +1328,6 @@ pub trait Float
/// Raise a number to a floating point power.
fn powf(self, n: Self) -> Self;
/// sqrt(2.0).
fn sqrt2() -> Self;
/// 1.0 / sqrt(2.0).
fn frac_1_sqrt2() -> Self;
/// Take the square root of a number.
///
/// Returns NaN if `self` is a negative number.
@ -1357,53 +1335,6 @@ pub trait Float
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
fn rsqrt(self) -> Self;
/// Archimedes' constant.
#[deprecated = "use f32::consts or f64::consts instead"]
fn pi() -> Self;
/// 2.0 * pi.
#[deprecated = "use f32::consts or f64::consts instead"]
fn two_pi() -> Self;
/// pi / 2.0.
#[deprecated = "use f32::consts or f64::consts instead"]
fn frac_pi_2() -> Self;
/// pi / 3.0.
#[deprecated = "use f32::consts or f64::consts instead"]
fn frac_pi_3() -> Self;
/// pi / 4.0.
#[deprecated = "use f32::consts or f64::consts instead"]
fn frac_pi_4() -> Self;
/// pi / 6.0.
#[deprecated = "use f32::consts or f64::consts instead"]
fn frac_pi_6() -> Self;
/// pi / 8.0.
#[deprecated = "use f32::consts or f64::consts instead"]
fn frac_pi_8() -> Self;
/// 1.0 / pi.
#[deprecated = "use f32::consts or f64::consts instead"]
fn frac_1_pi() -> Self;
/// 2.0 / pi.
#[deprecated = "use f32::consts or f64::consts instead"]
fn frac_2_pi() -> Self;
/// 2.0 / sqrt(pi).
#[deprecated = "use f32::consts or f64::consts instead"]
fn frac_2_sqrtpi() -> Self;
/// Euler's number.
#[deprecated = "use f32::consts or f64::consts instead"]
fn e() -> Self;
/// log2(e).
#[deprecated = "use f32::consts or f64::consts instead"]
fn log2_e() -> Self;
/// log10(e).
#[deprecated = "use f32::consts or f64::consts instead"]
fn log10_e() -> Self;
/// ln(2.0).
#[deprecated = "use f32::consts or f64::consts instead"]
fn ln_2() -> Self;
/// ln(10.0).
#[deprecated = "use f32::consts or f64::consts instead"]
fn ln_10() -> Self;
/// Returns `e^(self)`, (the exponential function).
fn exp(self) -> Self;
/// Returns 2 raised to the power of the number, `2^(self)`.
@ -1609,9 +1540,9 @@ macro_rules! from_str_radix_float_impl {
// Parse the exponent as decimal integer
let src = src[offset..];
let (is_positive, exp) = match src.slice_shift_char() {
Some(('-', src)) => (false, from_str::<uint>(src)),
Some(('+', src)) => (true, from_str::<uint>(src)),
Some((_, _)) => (true, from_str::<uint>(src)),
Some(('-', src)) => (false, src.parse::<uint>()),
Some(('+', src)) => (true, src.parse::<uint>()),
Some((_, _)) => (true, src.parse::<uint>()),
None => return None,
};
@ -1706,135 +1637,3 @@ from_str_radix_int_impl! { u8 }
from_str_radix_int_impl! { u16 }
from_str_radix_int_impl! { u32 }
from_str_radix_int_impl! { u64 }
// DEPRECATED
macro_rules! trait_impl {
($name:ident for $($t:ty)*) => {
$(#[allow(deprecated)] impl $name for $t {})*
};
}
#[deprecated = "Generalised numbers are no longer supported"]
#[allow(deprecated)]
pub trait Num: PartialEq + Zero + One
+ Neg<Output=Self>
+ Add<Output=Self>
+ Sub<Output=Self>
+ Mul<Output=Self>
+ Div<Output=Self>
+ Rem<Output=Self> {}
trait_impl! { Num for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
#[deprecated = "Generalised unsigned numbers are no longer supported"]
#[allow(deprecated)]
pub trait Unsigned: Num {}
trait_impl! { Unsigned for uint u8 u16 u32 u64 }
#[deprecated = "Use `Float` or `Int`"]
#[allow(deprecated)]
pub trait Primitive: Copy + Clone + Num + NumCast + PartialOrd {}
trait_impl! { Primitive for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
#[deprecated = "The generic `Zero` trait will be removed soon."]
pub trait Zero: Add<Output=Self> {
#[deprecated = "Use `Int::zero()` or `Float::zero()`."]
fn zero() -> Self;
#[deprecated = "Use `x == Int::zero()` or `x == Float::zero()`."]
fn is_zero(&self) -> bool;
}
#[deprecated = "Use `Int::zero()` or `Float::zero()`."]
#[allow(deprecated)]
pub fn zero<T: Zero>() -> T { Zero::zero() }
macro_rules! zero_impl {
($t:ty, $v:expr) => {
impl Zero for $t {
fn zero() -> $t { $v }
fn is_zero(&self) -> bool { *self == $v }
}
}
}
zero_impl! { uint, 0u }
zero_impl! { u8, 0u8 }
zero_impl! { u16, 0u16 }
zero_impl! { u32, 0u32 }
zero_impl! { u64, 0u64 }
zero_impl! { int, 0i }
zero_impl! { i8, 0i8 }
zero_impl! { i16, 0i16 }
zero_impl! { i32, 0i32 }
zero_impl! { i64, 0i64 }
zero_impl! { f32, 0.0f32 }
zero_impl! { f64, 0.0f64 }
#[deprecated = "The generic `One` trait will be removed soon."]
pub trait One: Mul<Output=Self> {
#[deprecated = "Use `Int::one()` or `Float::one()`."]
fn one() -> Self;
}
#[deprecated = "Use `Int::one()` or `Float::one()`."]
#[allow(deprecated)]
pub fn one<T: One>() -> T { One::one() }
macro_rules! one_impl {
($t:ty, $v:expr) => {
impl One for $t {
fn one() -> $t { $v }
}
}
}
one_impl! { uint, 1u }
one_impl! { u8, 1u8 }
one_impl! { u16, 1u16 }
one_impl! { u32, 1u32 }
one_impl! { u64, 1u64 }
one_impl! { int, 1i }
one_impl! { i8, 1i8 }
one_impl! { i16, 1i16 }
one_impl! { i32, 1i32 }
one_impl! { i64, 1i64 }
one_impl! { f32, 1.0f32 }
one_impl! { f64, 1.0f64 }
#[deprecated = "Use `UnsignedInt::next_power_of_two`"]
pub fn next_power_of_two<T: UnsignedInt>(n: T) -> T {
n.next_power_of_two()
}
#[deprecated = "Use `UnsignedInt::is_power_of_two`"]
pub fn is_power_of_two<T: UnsignedInt>(n: T) -> bool {
n.is_power_of_two()
}
#[deprecated = "Use `UnsignedInt::checked_next_power_of_two`"]
pub fn checked_next_power_of_two<T: UnsignedInt>(n: T) -> Option<T> {
n.checked_next_power_of_two()
}
#[deprecated = "Generalised bounded values are no longer supported"]
pub trait Bounded {
#[deprecated = "Use `Int::min_value` or `Float::min_value`"]
fn min_value() -> Self;
#[deprecated = "Use `Int::max_value` or `Float::max_value`"]
fn max_value() -> Self;
}
macro_rules! bounded_impl {
($T:ty, $min:expr, $max:expr) => {
impl Bounded for $T {
#[inline]
fn min_value() -> $T { $min }
#[inline]
fn max_value() -> $T { $max }
}
};
}
bounded_impl! { uint, uint::MIN, uint::MAX }
bounded_impl! { u8, u8::MIN, u8::MAX }
bounded_impl! { u16, u16::MIN, u16::MAX }
bounded_impl! { u32, u32::MIN, u32::MAX }
bounded_impl! { u64, u64::MIN, u64::MAX }
bounded_impl! { int, int::MIN, int::MAX }
bounded_impl! { i8, i8::MIN, i8::MAX }
bounded_impl! { i16, i16::MIN, i16::MAX }
bounded_impl! { i32, i32::MIN, i32::MAX }
bounded_impl! { i64, i64::MIN, i64::MAX }
bounded_impl! { f32, f32::MIN_VALUE, f32::MAX_VALUE }
bounded_impl! { f64, f64::MIN_VALUE, f64::MAX_VALUE }

View File

@ -94,7 +94,7 @@ use intrinsics;
use option::Option::{self, Some, None};
use kinds::{Send, Sized, Sync};
use cmp::{PartialEq, Eq, Ord, PartialOrd, Equiv};
use cmp::{PartialEq, Eq, Ord, PartialOrd};
use cmp::Ordering::{self, Less, Equal, Greater};
// FIXME #19649: instrinsic docs don't render, so these have no docs :(
@ -246,22 +246,10 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
pub trait PtrExt: Sized {
type Target;
/// Returns the null pointer.
#[deprecated = "call ptr::null instead"]
fn null() -> Self;
/// Returns true if the pointer is null.
#[stable]
fn is_null(self) -> bool;
/// 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 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`.
///
@ -308,18 +296,10 @@ pub trait MutPtrExt {
impl<T> PtrExt for *const T {
type Target = T;
#[inline]
#[deprecated = "call ptr::null instead"]
fn null() -> *const T { null() }
#[inline]
#[stable]
fn is_null(self) -> bool { self as uint == 0 }
#[inline]
#[deprecated = "use `as uint` instead"]
fn to_uint(self) -> uint { self as uint }
#[inline]
#[stable]
unsafe fn offset(self, count: int) -> *const T {
@ -342,18 +322,10 @@ impl<T> PtrExt for *const T {
impl<T> PtrExt for *mut T {
type Target = T;
#[inline]
#[deprecated = "call ptr::null instead"]
fn null() -> *mut T { null_mut() }
#[inline]
#[stable]
fn is_null(self) -> bool { self as uint == 0 }
#[inline]
#[deprecated = "use `as uint` instead"]
fn to_uint(self) -> uint { self as uint }
#[inline]
#[stable]
unsafe fn offset(self, count: int) -> *mut T {
@ -415,23 +387,6 @@ impl<T> PartialEq for *mut T {
#[stable]
impl<T> Eq for *mut T {}
// Equivalence for pointers
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T> Equiv<*mut T> for *const T {
fn equiv(&self, other: &*mut T) -> bool {
self.to_uint() == other.to_uint()
}
}
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T> Equiv<*const T> for *mut T {
fn equiv(&self, other: &*const T) -> bool {
self.to_uint() == other.to_uint()
}
}
#[stable]
impl<T> Clone for *const T {
#[inline]

View File

@ -36,7 +36,7 @@
use mem::transmute;
use clone::Clone;
use cmp::{Ordering, PartialEq, PartialOrd, Eq, Ord, Equiv};
use cmp::{Ordering, PartialEq, PartialOrd, Eq, Ord};
use cmp::Ordering::{Less, Equal, Greater};
use cmp;
use default::Default;
@ -1369,68 +1369,6 @@ pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] {
// Submodules
//
/// Unsafe operations
#[deprecated]
pub mod raw {
use mem::transmute;
use ptr::PtrExt;
use raw::Slice;
use ops::FnOnce;
use option::Option;
use option::Option::{None, Some};
/// Form a slice from a pointer and length (as a number of units,
/// not bytes).
#[inline]
#[deprecated = "renamed to slice::from_raw_buf"]
pub unsafe fn buf_as_slice<T, U, F>(p: *const T, len: uint, f: F) -> U where
F: FnOnce(&[T]) -> U,
{
f(transmute(Slice {
data: p,
len: len
}))
}
/// Form a slice from a pointer and length (as a number of units,
/// not bytes).
#[inline]
#[deprecated = "renamed to slice::from_raw_mut_buf"]
pub unsafe fn mut_buf_as_slice<T, U, F>(p: *mut T, len: uint, f: F) -> U where
F: FnOnce(&mut [T]) -> U,
{
f(transmute(Slice {
data: p as *const T,
len: len
}))
}
/// Returns a pointer to first element in slice and adjusts
/// slice so it no longer contains that element. Returns None
/// if the slice is empty. O(1).
#[inline]
#[deprecated = "inspect `Slice::{data, len}` manually (increment data by 1)"]
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
if slice.len == 0 { return None; }
let head: *const T = slice.data;
slice.data = slice.data.offset(1);
slice.len -= 1;
Some(head)
}
/// Returns a pointer to last element in slice and adjusts
/// slice so it no longer contains that element. Returns None
/// if the slice is empty. O(1).
#[inline]
#[deprecated = "inspect `Slice::{data, len}` manually (decrement len by 1)"]
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
if slice.len == 0 { return None; }
let tail: *const T = slice.data.offset((slice.len - 1) as int);
slice.len -= 1;
Some(tail)
}
}
/// Operations on `[u8]`.
#[experimental = "needs review"]
pub mod bytes {
@ -1490,20 +1428,6 @@ impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
#[stable]
impl<T: Eq> Eq for [T] {}
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for [T] {
#[inline]
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<'a,T:PartialEq, Sized? V: AsSlice<T>> Equiv<V> for &'a mut [T] {
#[inline]
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}
#[stable]
impl<T: Ord> Ord for [T] {
fn cmp(&self, other: &[T]) -> Ordering {

View File

@ -114,12 +114,6 @@ pub trait FromStr {
fn from_str(s: &str) -> Option<Self>;
}
/// A utility function that just calls FromStr::from_str
#[deprecated = "call the .parse() method on the string instead"]
pub fn from_str<A: FromStr>(s: &str) -> Option<A> {
FromStr::from_str(s)
}
impl FromStr for bool {
/// Parse a `bool` from a string.
///
@ -427,8 +421,7 @@ impl<'a> Fn(&'a u8) -> u8 for BytesDeref {
/// An iterator over the substrings of a string, separated by `sep`.
#[derive(Clone)]
#[deprecated = "Type is now named `Split` or `SplitTerminator`"]
pub struct CharSplits<'a, Sep> {
struct CharSplits<'a, Sep> {
/// The slice remaining to be iterated
string: &'a str,
sep: Sep,
@ -441,8 +434,7 @@ pub struct CharSplits<'a, Sep> {
/// An iterator over the substrings of a string, separated by `sep`,
/// splitting at most `count` times.
#[derive(Clone)]
#[deprecated = "Type is now named `SplitN` or `RSplitN`"]
pub struct CharSplitsN<'a, Sep> {
struct CharSplitsN<'a, Sep> {
iter: CharSplits<'a, Sep>,
/// The number of splits remaining
count: uint,
@ -873,10 +865,6 @@ pub struct SplitStr<'a> {
finished: bool
}
/// Deprecated
#[deprecated = "Type is now named `SplitStr`"]
pub type StrSplits<'a> = SplitStr<'a>;
impl<'a> Iterator for MatchIndices<'a> {
type Item = (uint, uint);
@ -1027,22 +1015,6 @@ fn run_utf8_validation_iterator(iter: &mut slice::Iter<u8>)
}
}
/// Determines if a vector of bytes contains valid UTF-8.
#[deprecated = "call from_utf8 instead"]
pub fn is_utf8(v: &[u8]) -> bool {
run_utf8_validation_iterator(&mut v.iter()).is_ok()
}
/// Deprecated function
#[deprecated = "this function will be removed"]
pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
match v.iter().position(|c| *c == 0) {
// don't include the 0
Some(i) => v[..i],
None => v
}
}
// https://tools.ietf.org/html/rfc3629
static UTF8_CHAR_WIDTH: [u8; 256] = [
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
@ -1063,13 +1035,6 @@ static UTF8_CHAR_WIDTH: [u8; 256] = [
4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
];
/// Given a first byte, determine how many bytes are in this UTF-8 character
#[inline]
#[deprecated = "this function has moved to libunicode"]
pub fn utf8_char_width(b: u8) -> uint {
return UTF8_CHAR_WIDTH[b as uint] as uint;
}
/// Struct that contains a `char` and the index of the first byte of
/// the next `char` in a string. This can be used as a data structure
/// for iterating over the UTF-8 bytes of a string.
@ -1087,78 +1052,19 @@ const CONT_MASK: u8 = 0b0011_1111u8;
/// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte
const TAG_CONT_U8: u8 = 0b1000_0000u8;
/// Unsafe operations
#[deprecated]
pub mod raw {
use ptr::PtrExt;
use raw::Slice;
use slice::SliceExt;
use str::StrExt;
/// Converts a slice of bytes to a string slice without checking
/// that the string contains valid UTF-8.
#[deprecated = "renamed to str::from_utf8_unchecked"]
pub unsafe fn from_utf8<'a>(v: &'a [u8]) -> &'a str {
super::from_utf8_unchecked(v)
}
/// Form a slice from a C string. Unsafe because the caller must ensure the
/// C string has the static lifetime, or else the return value may be
/// invalidated later.
#[deprecated = "renamed to str::from_c_str"]
pub unsafe fn c_str_to_static_slice(s: *const i8) -> &'static str {
let s = s as *const u8;
let mut curr = s;
let mut len = 0u;
while *curr != 0u8 {
len += 1u;
curr = s.offset(len as int);
}
let v = Slice { data: s, len: len };
super::from_utf8(::mem::transmute(v)).unwrap()
}
/// Takes a bytewise (not UTF-8) slice from a string.
///
/// Returns the substring from [`begin`..`end`).
///
/// # Panics
///
/// If begin is greater than end.
/// If end is greater than the length of the string.
#[inline]
#[deprecated = "call the slice_unchecked method instead"]
pub unsafe fn slice_bytes<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
assert!(begin <= end);
assert!(end <= s.len());
s.slice_unchecked(begin, end)
}
/// Takes a bytewise (not UTF-8) slice from a string.
///
/// Returns the substring from [`begin`..`end`).
///
/// Caller must check slice boundaries!
#[inline]
#[deprecated = "this has moved to a method on `str` directly"]
pub unsafe fn slice_unchecked<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
s.slice_unchecked(begin, end)
}
}
/*
Section: Trait implementations
*/
#[allow(missing_docs)]
pub mod traits {
use cmp::{Ordering, Ord, PartialEq, PartialOrd, Equiv, Eq};
use cmp::{Ordering, Ord, PartialEq, PartialOrd, Eq};
use cmp::Ordering::{Less, Equal, Greater};
use iter::IteratorExt;
use option::Option;
use option::Option::Some;
use ops;
use str::{Str, StrExt, eq_slice};
use str::{StrExt, eq_slice};
#[stable]
impl Ord for str {
@ -1197,13 +1103,6 @@ pub mod traits {
}
}
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<S: Str> Equiv<S> for str {
#[inline]
fn equiv(&self, other: &S) -> bool { eq_slice(self, other.as_slice()) }
}
impl ops::Slice<uint, str> for str {
#[inline]
fn as_slice_<'a>(&'a self) -> &'a str {
@ -1236,13 +1135,11 @@ pub trait Str for Sized? {
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, Sized? S> Str for &'a S where S: Str {
#[inline]
fn as_slice(&self) -> &str { Str::as_slice(*self) }
@ -1316,6 +1213,7 @@ pub trait StrExt for Sized? {
fn as_ptr(&self) -> *const u8;
fn len(&self) -> uint;
fn is_empty(&self) -> bool;
fn parse<T: FromStr>(&self) -> Option<T>;
}
#[inline(never)]
@ -1352,7 +1250,6 @@ impl StrExt for str {
}
#[inline]
#[allow(deprecated)] // For using CharSplits
fn split<P: CharEq>(&self, pat: P) -> Split<P> {
Split(CharSplits {
string: self,
@ -1364,7 +1261,6 @@ impl StrExt for str {
}
#[inline]
#[allow(deprecated)] // For using CharSplitsN
fn splitn<P: CharEq>(&self, count: uint, pat: P) -> SplitN<P> {
SplitN(CharSplitsN {
iter: self.split(pat).0,
@ -1374,7 +1270,6 @@ impl StrExt for str {
}
#[inline]
#[allow(deprecated)] // For using CharSplits
fn split_terminator<P: CharEq>(&self, pat: P) -> SplitTerminator<P> {
SplitTerminator(CharSplits {
allow_trailing_empty: false,
@ -1383,7 +1278,6 @@ impl StrExt for str {
}
#[inline]
#[allow(deprecated)] // For using CharSplitsN
fn rsplitn<P: CharEq>(&self, count: uint, pat: P) -> RSplitN<P> {
RSplitN(CharSplitsN {
iter: self.split(pat).0,
@ -1681,6 +1575,9 @@ impl StrExt for str {
#[inline]
fn is_empty(&self) -> bool { self.len() == 0 }
#[inline]
fn parse<T: FromStr>(&self) -> Option<T> { FromStr::from_str(self) }
}
#[stable]

View File

@ -58,44 +58,6 @@ macro_rules! tuple_impls {
}
)+) => {
$(
#[allow(missing_docs)]
#[deprecated]
pub trait $Tuple<$($T),+> {
$(
#[deprecated = "use tuple indexing: `tuple.N`"]
fn $valN(self) -> $T;
#[deprecated = "use tuple indexing: `&tuple.N`"]
fn $refN<'a>(&'a self) -> &'a $T;
#[deprecated = "use tuple indexing: `&mut tuple.N`"]
fn $mutN<'a>(&'a mut self) -> &'a mut $T;
)+
}
impl<$($T),+> $Tuple<$($T),+> for ($($T,)+) {
$(
#[inline]
#[allow(unused_variables)]
#[deprecated = "use tuple indexing: `tuple.N`"]
fn $valN(self) -> $T {
e!(self.$idx)
}
#[inline]
#[allow(unused_variables)]
#[deprecated = "use tuple indexing: `&tuple.N`"]
fn $refN<'a>(&'a self) -> &'a $T {
e!(&self.$idx)
}
#[inline]
#[allow(unused_variables)]
#[deprecated = "use tuple indexing: &mut tuple.N"]
fn $mutN<'a>(&'a mut self) -> &'a mut $T {
e!(&mut self.$idx)
}
)+
}
#[stable]
impl<$($T:Clone),+> Clone for ($($T,)+) {
fn clone(&self) -> ($($T,)+) {

View File

@ -10,8 +10,6 @@
//
// ignore-lexer-test FIXME #15679
use core::char::{escape_unicode, escape_default};
#[test]
fn test_is_lowercase() {
assert!('a'.is_lowercase());
@ -33,12 +31,12 @@ fn test_is_uppercase() {
#[test]
fn test_is_whitespace() {
assert!(' '.is_whitespace());
assert!('\u2007'.is_whitespace());
assert!('\u{2007}'.is_whitespace());
assert!('\t'.is_whitespace());
assert!('\n'.is_whitespace());
assert!(!'a'.is_whitespace());
assert!(!'_'.is_whitespace());
assert!(!'\u0000'.is_whitespace());
assert!(!'\u{0}'.is_whitespace());
}
#[test]
@ -92,15 +90,15 @@ fn test_to_uppercase() {
#[test]
fn test_is_control() {
assert!('\u0000'.is_control());
assert!('\u0003'.is_control());
assert!('\u0006'.is_control());
assert!('\u0009'.is_control());
assert!('\u007f'.is_control());
assert!('\u0092'.is_control());
assert!(!'\u0020'.is_control());
assert!(!'\u0055'.is_control());
assert!(!'\u0068'.is_control());
assert!('\u{0}'.is_control());
assert!('\u{3}'.is_control());
assert!('\u{6}'.is_control());
assert!('\u{9}'.is_control());
assert!('\u{7f}'.is_control());
assert!('\u{92}'.is_control());
assert!(!'\u{20}'.is_control());
assert!(!'\u{55}'.is_control());
assert!(!'\u{68}'.is_control());
}
#[test]
@ -116,9 +114,7 @@ fn test_is_digit() {
#[test]
fn test_escape_default() {
fn string(c: char) -> String {
let mut result = String::new();
escape_default(c, |c| { result.push(c); });
return result;
c.escape_default().collect()
}
let s = string('\n');
assert_eq!(s, "\\n");
@ -175,9 +171,9 @@ fn test_encode_utf8() {
}
check('x', &[0x78]);
check('\u00e9', &[0xc3, 0xa9]);
check('\ua66e', &[0xea, 0x99, 0xae]);
check('\U0001f4a9', &[0xf0, 0x9f, 0x92, 0xa9]);
check('\u{e9}', &[0xc3, 0xa9]);
check('\u{a66e}', &[0xea, 0x99, 0xae]);
check('\u{1f4a9}', &[0xf0, 0x9f, 0x92, 0xa9]);
}
#[test]
@ -189,17 +185,17 @@ fn test_encode_utf16() {
}
check('x', &[0x0078]);
check('\u00e9', &[0x00e9]);
check('\ua66e', &[0xa66e]);
check('\U0001f4a9', &[0xd83d, 0xdca9]);
check('\u{e9}', &[0x00e9]);
check('\u{a66e}', &[0xa66e]);
check('\u{1f4a9}', &[0xd83d, 0xdca9]);
}
#[test]
fn test_len_utf16() {
assert!('x'.len_utf16() == 1);
assert!('\u00e9'.len_utf16() == 1);
assert!('\ua66e'.len_utf16() == 1);
assert!('\U0001f4a9'.len_utf16() == 2);
assert!('\u{e9}'.len_utf16() == 1);
assert!('\u{a66e}'.len_utf16() == 1);
assert!('\u{1f4a9}'.len_utf16() == 2);
}
#[test]
@ -216,15 +212,15 @@ fn test_width() {
assert_eq!(''.width(false),Some(2));
assert_eq!(''.width(true),Some(2));
assert_eq!('\u00AD'.width(false),Some(1));
assert_eq!('\u00AD'.width(true),Some(1));
assert_eq!('\u{AD}'.width(false),Some(1));
assert_eq!('\u{AD}'.width(true),Some(1));
assert_eq!('\u1160'.width(false),Some(0));
assert_eq!('\u1160'.width(true),Some(0));
assert_eq!('\u{1160}'.width(false),Some(0));
assert_eq!('\u{1160}'.width(true),Some(0));
assert_eq!('\u00a1'.width(false),Some(1));
assert_eq!('\u00a1'.width(true),Some(2));
assert_eq!('\u{a1}'.width(false),Some(1));
assert_eq!('\u{a1}'.width(true),Some(2));
assert_eq!('\u0300'.width(false),Some(0));
assert_eq!('\u0300'.width(true),Some(0));
assert_eq!('\u{300}'.width(false),Some(0));
assert_eq!('\u{300}'.width(true),Some(0));
}

View File

@ -103,7 +103,7 @@ fn test_iterator_chain() {
#[test]
fn test_filter_map() {
let mut it = count(0u, 1u).take(10)
let it = count(0u, 1u).take(10)
.filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
assert!(it.collect::<Vec<uint>>() == vec![0*0, 2*2, 4*4, 6*6, 8*8]);
}

View File

@ -92,7 +92,7 @@ fn test_match_option_empty_string() {
#[test]
fn test_match_option_string() {
let five = "Five".into_string();
let five = "Five".to_string();
match Some(five) {
Some(s) => assert_eq!(s, "Five"),
None => panic!("unexpected None while matching on Some(String { ... })")

View File

@ -16,7 +16,6 @@ mod tests {
use core::$T_i::*;
use core::int;
use core::num::{FromStrRadix, Int, SignedInt};
use core::str::from_str;
use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
use num;
@ -161,6 +160,9 @@ mod tests {
#[test]
fn test_from_str() {
fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
::std::str::FromStr::from_str(t)
}
assert_eq!(from_str::<$T>("0"), Some(0 as $T));
assert_eq!(from_str::<$T>("3"), Some(3 as $T));
assert_eq!(from_str::<$T>("10"), Some(10 as $T));

View File

@ -13,7 +13,6 @@ use core::fmt::Show;
use core::num::{NumCast, cast};
use core::ops::{Add, Sub, Mul, Div, Rem};
use core::kinds::Copy;
use std::str::from_str;
mod int_macros;
mod i8;
@ -55,7 +54,6 @@ mod test {
use core::option::Option::{Some, None};
use core::num::Float;
use core::num::from_str_radix;
use core::str::from_str;
#[test]
fn from_str_issue7588() {
@ -88,35 +86,35 @@ mod test {
#[test]
fn test_int_from_str_overflow() {
let mut i8_val: i8 = 127_i8;
assert_eq!(from_str::<i8>("127"), Some(i8_val));
assert_eq!(from_str::<i8>("128"), None);
assert_eq!("127".parse::<i8>(), Some(i8_val));
assert_eq!("128".parse::<i8>(), None);
i8_val += 1 as i8;
assert_eq!(from_str::<i8>("-128"), Some(i8_val));
assert_eq!(from_str::<i8>("-129"), None);
assert_eq!("-128".parse::<i8>(), Some(i8_val));
assert_eq!("-129".parse::<i8>(), None);
let mut i16_val: i16 = 32_767_i16;
assert_eq!(from_str::<i16>("32767"), Some(i16_val));
assert_eq!(from_str::<i16>("32768"), None);
assert_eq!("32767".parse::<i16>(), Some(i16_val));
assert_eq!("32768".parse::<i16>(), None);
i16_val += 1 as i16;
assert_eq!(from_str::<i16>("-32768"), Some(i16_val));
assert_eq!(from_str::<i16>("-32769"), None);
assert_eq!("-32768".parse::<i16>(), Some(i16_val));
assert_eq!("-32769".parse::<i16>(), None);
let mut i32_val: i32 = 2_147_483_647_i32;
assert_eq!(from_str::<i32>("2147483647"), Some(i32_val));
assert_eq!(from_str::<i32>("2147483648"), None);
assert_eq!("2147483647".parse::<i32>(), Some(i32_val));
assert_eq!("2147483648".parse::<i32>(), None);
i32_val += 1 as i32;
assert_eq!(from_str::<i32>("-2147483648"), Some(i32_val));
assert_eq!(from_str::<i32>("-2147483649"), None);
assert_eq!("-2147483648".parse::<i32>(), Some(i32_val));
assert_eq!("-2147483649".parse::<i32>(), None);
let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
assert_eq!(from_str::<i64>("9223372036854775807"), Some(i64_val));
assert_eq!(from_str::<i64>("9223372036854775808"), None);
assert_eq!("9223372036854775807".parse::<i64>(), Some(i64_val));
assert_eq!("9223372036854775808".parse::<i64>(), None);
i64_val += 1 as i64;
assert_eq!(from_str::<i64>("-9223372036854775808"), Some(i64_val));
assert_eq!(from_str::<i64>("-9223372036854775809"), None);
assert_eq!("-9223372036854775808".parse::<i64>(), Some(i64_val));
assert_eq!("-9223372036854775809".parse::<i64>(), None);
}
}

View File

@ -10,6 +10,7 @@
use core::ptr::*;
use core::mem;
use std::iter::repeat;
#[test]
fn test() {
@ -56,19 +57,15 @@ fn test() {
fn test_is_null() {
let p: *const int = null();
assert!(p.is_null());
assert!(!p.is_not_null());
let q = unsafe { p.offset(1) };
assert!(!q.is_null());
assert!(q.is_not_null());
let mp: *mut int = null_mut();
assert!(mp.is_null());
assert!(!mp.is_not_null());
let mq = unsafe { mp.offset(1) };
assert!(!mq.is_null());
assert!(mq.is_not_null());
}
#[test]
@ -116,7 +113,7 @@ fn test_as_mut() {
#[test]
fn test_ptr_addition() {
unsafe {
let xs = Vec::from_elem(16, 5i);
let xs = repeat(5i).take(16).collect::<Vec<_>>();
let mut ptr = xs.as_ptr();
let end = ptr.offset(16);
@ -134,7 +131,7 @@ fn test_ptr_addition() {
m_ptr = m_ptr.offset(1);
}
assert!(xs_mut == Vec::from_elem(16, 10i));
assert!(xs_mut == repeat(10i).take(16).collect::<Vec<_>>());
}
}

View File

@ -8,13 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::str::from_str;
#[test]
fn test_bool_from_str() {
assert_eq!(from_str::<bool>("true"), Some(true));
assert_eq!(from_str::<bool>("false"), Some(false));
assert_eq!(from_str::<bool>("not even a boolean"), None);
assert_eq!("true".parse(), Some(true));
assert_eq!("false".parse(), Some(false));
assert_eq!("not even a boolean".parse::<bool>(), None);
}
fn check_contains_all_substrings(s: &str) {
@ -120,6 +118,6 @@ fn test_rev_split_char_iterator_no_trailing() {
#[test]
fn test_utf16_code_units() {
use unicode::str::Utf16Encoder;
assert_eq!(Utf16Encoder::new(vec!['é', '\U0001F4A9'].into_iter()).collect::<Vec<u16>>(),
assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
vec![0xE9, 0xD83D, 0xDCA9])
}

View File

@ -278,7 +278,7 @@ pub use self::LabelText::*;
use std::borrow::IntoCow;
use std::io;
use std::str::CowString;
use std::string::CowString;
use std::vec::CowVec;
pub mod maybe_owned_vec;
@ -589,8 +589,8 @@ mod tests {
use super::{Id, LabelText, LabelStr, EscStr, Labeller};
use super::{Nodes, Edges, GraphWalk, render};
use std::io::IoResult;
use std::str;
use std::borrow::IntoCow;
use std::iter::repeat;
/// each node is an index in a vector in the graph.
type Node = uint;
@ -638,7 +638,7 @@ mod tests {
fn to_opt_strs(self) -> Vec<Option<&'static str>> {
match self {
UnlabelledNodes(len)
=> Vec::from_elem(len, None).into_iter().collect(),
=> repeat(None).take(len).collect(),
AllNodesLabelled(lbls)
=> lbls.into_iter().map(
|l|Some(l)).collect(),

View File

@ -12,7 +12,7 @@
pub use self::MaybeOwnedVector::*;
use std::cmp::{Equiv, Ordering};
use std::cmp::Ordering;
use std::default::Default;
use std::fmt;
use std::iter::FromIterator;
@ -97,13 +97,6 @@ impl<'a, T: Ord> Ord for MaybeOwnedVector<'a, T> {
}
}
#[allow(deprecated)]
impl<'a, T: PartialEq> Equiv<[T]> for MaybeOwnedVector<'a, T> {
fn equiv(&self, other: &[T]) -> bool {
self.as_slice() == other
}
}
// The `Vector` trait is provided in the prelude and is implemented on
// both `&'a [T]` and `Vec<T>`, so it makes sense to try to support it
// seamlessly. The other vector related traits from the prelude do

View File

@ -249,14 +249,14 @@ mod test {
let seed : &[_] = &[0u32; 8];
let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
let v = Vec::from_fn(16, |_| ra.next_u32());
let v = range(0, 16).map(|_| ra.next_u32()).collect::<Vec<_>>();
assert_eq!(v,
vec!(0xade0b876, 0x903df1a0, 0xe56a5d40, 0x28bd8653,
0xb819d2bd, 0x1aed8da0, 0xccef36a8, 0xc70d778b,
0x7c5941da, 0x8d485751, 0x3fe02477, 0x374ad8b8,
0xf4b8436a, 0x1ca11815, 0x69b687c3, 0x8665eeb2));
let v = Vec::from_fn(16, |_| ra.next_u32());
let v = range(0, 16).map(|_| ra.next_u32()).collect::<Vec<_>>();
assert_eq!(v,
vec!(0xbee7079f, 0x7a385155, 0x7c97ba98, 0x0d082d73,
0xa0290fcb, 0x6965e348, 0x3e53c612, 0xed7aee32,

View File

@ -555,7 +555,7 @@ mod test {
let seed: &[_] = &[1, 23, 456, 7890, 12345];
let mut ra: IsaacRng = SeedableRng::from_seed(seed);
// Regression test that isaac is actually using the above vector
let v = Vec::from_fn(10, |_| ra.next_u32());
let v = range(0, 10).map(|_| ra.next_u32()).collect::<Vec<_>>();
assert_eq!(v,
vec!(2558573138, 873787463, 263499565, 2103644246, 3595684709,
4203127393, 264982119, 2765226902, 2737944514, 3900253796));
@ -565,7 +565,7 @@ mod test {
// skip forward to the 10000th number
for _ in range(0u, 10000) { rb.next_u32(); }
let v = Vec::from_fn(10, |_| rb.next_u32());
let v = range(0, 10).map(|_| rb.next_u32()).collect::<Vec<_>>();
assert_eq!(v,
vec!(3676831399, 3183332890, 2834741178, 3854698763, 2717568474,
1576568959, 3507990155, 179069555, 141456972, 2478885421));
@ -575,7 +575,7 @@ mod test {
let seed: &[_] = &[1, 23, 456, 7890, 12345];
let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
// Regression test that isaac is actually using the above vector
let v = Vec::from_fn(10, |_| ra.next_u64());
let v = range(0, 10).map(|_| ra.next_u64()).collect::<Vec<_>>();
assert_eq!(v,
vec!(547121783600835980, 14377643087320773276, 17351601304698403469,
1238879483818134882, 11952566807690396487, 13970131091560099343,
@ -587,7 +587,7 @@ mod test {
// skip forward to the 10000th number
for _ in range(0u, 10000) { rb.next_u64(); }
let v = Vec::from_fn(10, |_| rb.next_u64());
let v = range(0, 10).map(|_| rb.next_u64()).collect::<Vec<_>>();
assert_eq!(v,
vec!(18143823860592706164, 8491801882678285927, 2699425367717515619,
17196852593171130876, 2606123525235546165, 15790932315217671084,

View File

@ -151,7 +151,7 @@ impl Default for ReseedWithDefault {
mod test {
use std::prelude::v1::*;
use core::iter::order;
use core::iter::{order, repeat};
use super::{ReseedingRng, ReseedWithDefault};
use std::default::Default;
use {SeedableRng, Rng};
@ -215,7 +215,7 @@ mod test {
static FILL_BYTES_V_LEN: uint = 13579;
#[test]
fn test_rng_fill_bytes() {
let mut v = Vec::from_elem(FILL_BYTES_V_LEN, 0u8);
let mut v = repeat(0u8).take(FILL_BYTES_V_LEN).collect::<Vec<_>>();
::test::rng().fill_bytes(v.as_mut_slice());
// Sanity test: if we've gotten here, `fill_bytes` has not infinitely

View File

@ -133,6 +133,7 @@ mod tests {
extern crate test;
use super::SeekableMemWriter;
use std::io;
use std::iter::repeat;
use test::Bencher;
#[test]
@ -183,7 +184,7 @@ mod tests {
}
fn do_bench_seekable_mem_writer(b: &mut Bencher, times: uint, len: uint) {
let src: Vec<u8> = Vec::from_elem(len, 5);
let src: Vec<u8> = repeat(5).take(len).collect();
b.bytes = (times * len) as u64;
b.iter(|| {

View File

@ -1165,12 +1165,12 @@ mod bench {
#[bench]
pub fn vuint_at_A_aligned(b: &mut Bencher) {
let data = Vec::from_fn(4*100, |i| {
let data = range(0, 4*100).map(|i| {
match i % 2 {
0 => 0x80u8,
_ => i as u8,
}
});
}).collect::<Vec<_>>();
let mut sum = 0u;
b.iter(|| {
let mut i = 0;
@ -1183,12 +1183,12 @@ mod bench {
#[bench]
pub fn vuint_at_A_unaligned(b: &mut Bencher) {
let data = Vec::from_fn(4*100+1, |i| {
let data = range(0, 4*100+1).map(|i| {
match i % 2 {
1 => 0x80u8,
_ => i as u8
}
});
}).collect::<Vec<_>>();
let mut sum = 0u;
b.iter(|| {
let mut i = 1;
@ -1201,13 +1201,13 @@ mod bench {
#[bench]
pub fn vuint_at_D_aligned(b: &mut Bencher) {
let data = Vec::from_fn(4*100, |i| {
let data = range(0, 4*100).map(|i| {
match i % 4 {
0 => 0x10u8,
3 => i as u8,
_ => 0u8
}
});
}).collect::<Vec<_>>();
let mut sum = 0u;
b.iter(|| {
let mut i = 0;
@ -1220,13 +1220,13 @@ mod bench {
#[bench]
pub fn vuint_at_D_unaligned(b: &mut Bencher) {
let data = Vec::from_fn(4*100+1, |i| {
let data = range(0, 4*100+1).map(|i| {
match i % 4 {
1 => 0x10u8,
0 => i as u8,
_ => 0u8
}
});
}).collect::<Vec<_>>();
let mut sum = 0u;
b.iter(|| {
let mut i = 1;

View File

@ -10,356 +10,9 @@
//
// ignore-lexer-test FIXME #15679
//! This crate provides a native implementation of regular expressions that is
//! heavily based on RE2 both in syntax and in implementation. Notably,
//! backreferences and arbitrary lookahead/lookbehind assertions are not
//! provided. In return, regular expression searching provided by this package
//! has excellent worst case performance. The specific syntax supported is
//! documented further down.
//! Regular expressions implemented in Rust
//!
//! This crate's documentation provides some simple examples, describes Unicode
//! support and exhaustively lists the supported syntax. For more specific
//! details on the API, please see the documentation for the `Regex` type.
//!
//! # First example: find a date
//!
//! General use of regular expressions in this package involves compiling an
//! expression and then using it to search, split or replace text. For example,
//! to confirm that some text resembles a date:
//!
//! ```rust
//! use regex::Regex;
//! let re = match Regex::new(r"^\d{4}-\d{2}-\d{2}$") {
//! Ok(re) => re,
//! Err(err) => panic!("{}", err),
//! };
//! assert_eq!(re.is_match("2014-01-01"), true);
//! ```
//!
//! Notice the use of the `^` and `$` anchors. In this crate, every expression
//! is executed with an implicit `.*?` at the beginning and end, which allows
//! it to match anywhere in the text. Anchors can be used to ensure that the
//! full text matches an expression.
//!
//! This example also demonstrates the utility of [raw
//! strings](../reference.html#character-and-string-literals) in Rust, which
//! are just like regular strings except they are prefixed with an `r` and do
//! not process any escape sequences. For example, `"\\d"` is the same
//! expression as `r"\d"`.
//!
//! # The `regex!` macro
//!
//! Rust's compile time meta-programming facilities provide a way to write a
//! `regex!` macro which compiles regular expressions *when your program
//! compiles*. Said differently, if you only use `regex!` to build regular
//! expressions in your program, then your program cannot compile with an
//! invalid regular expression. Moreover, the `regex!` macro compiles the
//! given expression to native Rust code, which makes it much faster for
//! searching text.
//!
//! Since `regex!` provides compiled regular expressions that are both safer
//! and faster to use, you should use them whenever possible. The only
//! requirement for using them is that you have a string literal corresponding
//! to your expression. Otherwise, it is indistinguishable from an expression
//! compiled at runtime with `Regex::new`.
//!
//! To use the `regex!` macro, you must enable the `phase` feature and import
//! the `regex_macros` crate as a syntax extension:
//!
//! ```rust
//! #![feature(phase)]
//! #[phase(plugin)]
//! extern crate regex_macros;
//! extern crate regex;
//!
//! fn main() {
//! let re = regex!(r"^\d{4}-\d{2}-\d{2}$");
//! assert_eq!(re.is_match("2014-01-01"), true);
//! }
//! ```
//!
//! There are a few things worth mentioning about using the `regex!` macro.
//! Firstly, the `regex!` macro *only* accepts string *literals*.
//! Secondly, the `regex` crate *must* be linked with the name `regex` since
//! the generated code depends on finding symbols in the `regex` crate.
//!
//! The only downside of using the `regex!` macro is that it can increase the
//! size of your program's binary since it generates specialized Rust code.
//! The extra size probably won't be significant for a small number of
//! expressions, but 100+ calls to `regex!` will probably result in a
//! noticeably bigger binary.
//!
//! # Example: iterating over capture groups
//!
//! This crate provides convenient iterators for matching an expression
//! repeatedly against a search string to find successive non-overlapping
//! matches. For example, to find all dates in a string and be able to access
//! them by their component pieces:
//!
//! ```rust
//! # #![feature(phase)]
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
//! # fn main() {
//! let re = regex!(r"(\d{4})-(\d{2})-(\d{2})");
//! let text = "2012-03-14, 2013-01-01 and 2014-07-05";
//! for cap in re.captures_iter(text) {
//! println!("Month: {} Day: {} Year: {}",
//! cap.at(2).unwrap_or(""), cap.at(3).unwrap_or(""),
//! cap.at(1).unwrap_or(""));
//! }
//! // Output:
//! // Month: 03 Day: 14 Year: 2012
//! // Month: 01 Day: 01 Year: 2013
//! // Month: 07 Day: 05 Year: 2014
//! # }
//! ```
//!
//! Notice that the year is in the capture group indexed at `1`. This is
//! because the *entire match* is stored in the capture group at index `0`.
//!
//! # Example: replacement with named capture groups
//!
//! Building on the previous example, perhaps we'd like to rearrange the date
//! formats. This can be done with text replacement. But to make the code
//! clearer, we can *name* our capture groups and use those names as variables
//! in our replacement text:
//!
//! ```rust
//! # #![feature(phase)]
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
//! # fn main() {
//! let re = regex!(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})");
//! let before = "2012-03-14, 2013-01-01 and 2014-07-05";
//! let after = re.replace_all(before, "$m/$d/$y");
//! assert_eq!(after.as_slice(), "03/14/2012, 01/01/2013 and 07/05/2014");
//! # }
//! ```
//!
//! The `replace` methods are actually polymorphic in the replacement, which
//! provides more flexibility than is seen here. (See the documentation for
//! `Regex::replace` for more details.)
//!
//! # Pay for what you use
//!
//! With respect to searching text with a regular expression, there are three
//! questions that can be asked:
//!
//! 1. Does the text match this expression?
//! 2. If so, where does it match?
//! 3. Where are the submatches?
//!
//! Generally speaking, this crate could provide a function to answer only #3,
//! which would subsume #1 and #2 automatically. However, it can be
//! significantly more expensive to compute the location of submatches, so it's
//! best not to do it if you don't need to.
//!
//! Therefore, only use what you need. For example, don't use `find` if you
//! only need to test if an expression matches a string. (Use `is_match`
//! instead.)
//!
//! # Unicode
//!
//! This implementation executes regular expressions **only** on sequences of
//! Unicode code points while exposing match locations as byte indices into the
//! search string.
//!
//! Currently, only naive case folding is supported. Namely, when matching
//! case insensitively, the characters are first converted to their uppercase
//! forms and then compared.
//!
//! Regular expressions themselves are also **only** interpreted as a sequence
//! of Unicode code points. This means you can use Unicode characters
//! directly in your expression:
//!
//! ```rust
//! # #![feature(phase)]
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
//! # fn main() {
//! let re = regex!(r"(?i)Δ+");
//! assert_eq!(re.find("ΔδΔ"), Some((0, 6)));
//! # }
//! ```
//!
//! Finally, Unicode general categories and scripts are available as character
//! classes. For example, you can match a sequence of numerals, Greek or
//! Cherokee letters:
//!
//! ```rust
//! # #![feature(phase)]
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
//! # fn main() {
//! let re = regex!(r"[\pN\p{Greek}\p{Cherokee}]+");
//! assert_eq!(re.find("abcΔβγδⅡxyz"), Some((3, 23)));
//! # }
//! ```
//!
//! # Syntax
//!
//! The syntax supported in this crate is almost in an exact correspondence
//! with the syntax supported by RE2.
//!
//! ## Matching one character
//!
//! <pre class="rust">
//! . any character except new line (includes new line with s flag)
//! [xyz] A character class matching either x, y or z.
//! [^xyz] A character class matching any character except x, y and z.
//! [a-z] A character class matching any character in range a-z.
//! \d Perl character class ([0-9])
//! \D Negated Perl character class ([^0-9])
//! [:alpha:] ASCII character class ([A-Za-z])
//! [:^alpha:] Negated ASCII character class ([^A-Za-z])
//! \pN One letter name Unicode character class
//! \p{Greek} Unicode character class (general category or script)
//! \PN Negated one letter name Unicode character class
//! \P{Greek} negated Unicode character class (general category or script)
//! </pre>
//!
//! Any named character class may appear inside a bracketed `[...]` character
//! class. For example, `[\p{Greek}\pN]` matches any Greek or numeral
//! character.
//!
//! ## Composites
//!
//! <pre class="rust">
//! xy concatenation (x followed by y)
//! x|y alternation (x or y, prefer x)
//! </pre>
//!
//! ## Repetitions
//!
//! <pre class="rust">
//! x* zero or more of x (greedy)
//! x+ one or more of x (greedy)
//! x? zero or one of x (greedy)
//! x*? zero or more of x (ungreedy)
//! x+? one or more of x (ungreedy)
//! x?? zero or one of x (ungreedy)
//! x{n,m} at least n x and at most m x (greedy)
//! x{n,} at least n x (greedy)
//! x{n} exactly n x
//! x{n,m}? at least n x and at most m x (ungreedy)
//! x{n,}? at least n x (ungreedy)
//! x{n}? exactly n x
//! </pre>
//!
//! ## Empty matches
//!
//! <pre class="rust">
//! ^ the beginning of text (or start-of-line with multi-line mode)
//! $ the end of text (or end-of-line with multi-line mode)
//! \A only the beginning of text (even with multi-line mode enabled)
//! \z only the end of text (even with multi-line mode enabled)
//! \b a Unicode word boundary (\w on one side and \W, \A, or \z on other)
//! \B not a Unicode word boundary
//! </pre>
//!
//! ## Grouping and flags
//!
//! <pre class="rust">
//! (exp) numbered capture group (indexed by opening parenthesis)
//! (?P&lt;name&gt;exp) named (also numbered) capture group (allowed chars: [_0-9a-zA-Z])
//! (?:exp) non-capturing group
//! (?flags) set flags within current group
//! (?flags:exp) set flags for exp (non-capturing)
//! </pre>
//!
//! Flags are each a single character. For example, `(?x)` sets the flag `x`
//! and `(?-x)` clears the flag `x`. Multiple flags can be set or cleared at
//! the same time: `(?xy)` sets both the `x` and `y` flags and `(?x-y)` sets
//! the `x` flag and clears the `y` flag.
//!
//! All flags are by default disabled. They are:
//!
//! <pre class="rust">
//! i case insensitive
//! m multi-line mode: ^ and $ match begin/end of line
//! s allow . to match \n
//! U swap the meaning of x* and x*?
//! </pre>
//!
//! Here's an example that matches case insensitively for only part of the
//! expression:
//!
//! ```rust
//! # #![feature(phase)]
//! # extern crate regex; #[phase(plugin)] extern crate regex_macros;
//! # fn main() {
//! let re = regex!(r"(?i)a+(?-i)b+");
//! let cap = re.captures("AaAaAbbBBBb").unwrap();
//! assert_eq!(cap.at(0), Some("AaAaAbb"));
//! # }
//! ```
//!
//! Notice that the `a+` matches either `a` or `A`, but the `b+` only matches
//! `b`.
//!
//! ## Escape sequences
//!
//! <pre class="rust">
//! \* literal *, works for any punctuation character: \.+*?()|[]{}^$
//! \a bell (\x07)
//! \f form feed (\x0C)
//! \t horizontal tab
//! \n new line
//! \r carriage return
//! \v vertical tab (\x0B)
//! \123 octal character code (up to three digits)
//! \x7F hex character code (exactly two digits)
//! \x{10FFFF} any hex character code corresponding to a Unicode code point
//! </pre>
//!
//! ## Perl character classes (Unicode friendly)
//!
//! These classes are based on the definitions provided in
//! [UTS#18](http://www.unicode.org/reports/tr18/#Compatibility_Properties):
//!
//! <pre class="rust">
//! \d digit (\p{Nd})
//! \D not digit
//! \s whitespace (\p{White_Space})
//! \S not whitespace
//! \w word character (\p{Alphabetic} + \p{M} + \d + \p{Pc} + \p{Join_Control})
//! \W not word character
//! </pre>
//!
//! ## ASCII character classes
//!
//! <pre class="rust">
//! [:alnum:] alphanumeric ([0-9A-Za-z])
//! [:alpha:] alphabetic ([A-Za-z])
//! [:ascii:] ASCII ([\x00-\x7F])
//! [:blank:] blank ([\t ])
//! [:cntrl:] control ([\x00-\x1F\x7F])
//! [:digit:] digits ([0-9])
//! [:graph:] graphical ([!-~])
//! [:lower:] lower case ([a-z])
//! [:print:] printable ([ -~])
//! [:punct:] punctuation ([!-/:-@[-`{-~])
//! [:space:] whitespace ([\t\n\v\f\r ])
//! [:upper:] upper case ([A-Z])
//! [:word:] word characters ([0-9A-Za-z_])
//! [:xdigit:] hex digit ([0-9A-Fa-f])
//! </pre>
//!
//! # Untrusted input
//!
//! There are two factors to consider here: untrusted regular expressions and
//! untrusted search text.
//!
//! Currently, there are no counter-measures in place to prevent a malicious
//! user from writing an expression that may use a lot of resources. One such
//! example is to repeat counted repetitions: `((a{100}){100}){100}` will try
//! to repeat the `a` instruction `100^3` times. Essentially, this means it's
//! very easy for an attacker to exhaust your system's memory if they are
//! allowed to execute arbitrary regular expressions. A possible solution to
//! this is to impose a hard limit on the size of a compiled expression, but it
//! does not yet exist.
//!
//! The story is a bit better with untrusted search text, since this crate's
//! implementation provides `O(nm)` search where `n` is the number of
//! characters in the search text and `m` is the number of instructions in a
//! compiled expression.
//! For official documentation, see the rust-lang/regex crate
#![crate_name = "regex"]
#![crate_type = "rlib"]

View File

@ -14,7 +14,7 @@ pub use self::Regex::*;
use std::borrow::IntoCow;
use std::collections::HashMap;
use std::fmt;
use std::str::CowString;
use std::string::CowString;
use compile::Program;
use parse;
@ -51,59 +51,6 @@ pub fn is_match(regex: &str, text: &str) -> Result<bool, parse::Error> {
}
/// A compiled regular expression
///
/// It is represented as either a sequence of bytecode instructions (dynamic)
/// or as a specialized Rust function (native). It can be used to search, split
/// or replace text. All searching is done with an implicit `.*?` at the
/// beginning and end of an expression. To force an expression to match the
/// whole string (or a prefix or a suffix), you must use an anchor like `^` or
/// `$` (or `\A` and `\z`).
///
/// While this crate will handle Unicode strings (whether in the regular
/// expression or in the search text), all positions returned are **byte
/// indices**. Every byte index is guaranteed to be at a Unicode code point
/// boundary.
///
/// The lifetimes `'r` and `'t` in this crate correspond to the lifetime of a
/// compiled regular expression and text to search, respectively.
///
/// The only methods that allocate new strings are the string replacement
/// methods. All other methods (searching and splitting) return borrowed
/// pointers into the string given.
///
/// # Examples
///
/// Find the location of a US phone number:
///
/// ```rust
/// # use regex::Regex;
/// let re = match Regex::new("[0-9]{3}-[0-9]{3}-[0-9]{4}") {
/// Ok(re) => re,
/// Err(err) => panic!("{}", err),
/// };
/// assert_eq!(re.find("phone: 111-222-3333"), Some((7, 19)));
/// ```
///
/// You can also use the `regex!` macro to compile a regular expression when
/// you compile your program:
///
/// ```rust
/// #![feature(phase)]
/// extern crate regex;
/// #[phase(plugin)] extern crate regex_macros;
///
/// fn main() {
/// let re = regex!(r"\d+");
/// assert_eq!(re.find("123 abc"), Some((0, 3)));
/// }
/// ```
///
/// Given an incorrect regular expression, `regex!` will cause the Rust
/// compiler to produce a compile time error.
/// Note that `regex!` will compile the expression to native Rust code, which
/// makes it much faster when searching text.
/// More details about the `regex!` macro can be found in the `regex` crate
/// documentation.
#[derive(Clone)]
pub enum Regex {
// The representation of `Regex` is exported to support the `regex!`
@ -169,46 +116,12 @@ impl Regex {
}
/// Returns true if and only if the regex matches the string given.
///
/// # Example
///
/// Test if some text contains at least one word with exactly 13
/// characters:
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let text = "I categorically deny having triskaidekaphobia.";
/// let matched = regex!(r"\b\w{13}\b").is_match(text);
/// assert!(matched);
/// # }
/// ```
pub fn is_match(&self, text: &str) -> bool {
has_match(&exec(self, Exists, text))
}
/// Returns the start and end byte range of the leftmost-first match in
/// `text`. If no match exists, then `None` is returned.
///
/// Note that this should only be used if you want to discover the position
/// of the match. Testing the existence of a match is faster if you use
/// `is_match`.
///
/// # Example
///
/// Find the start and end location of the first word with exactly 13
/// characters:
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let text = "I categorically deny having triskaidekaphobia.";
/// let pos = regex!(r"\b\w{13}\b").find(text);
/// assert_eq!(pos, Some((2, 15)));
/// # }
/// ```
pub fn find(&self, text: &str) -> Option<(uint, uint)> {
let caps = exec(self, Location, text);
if has_match(&caps) {
@ -221,27 +134,6 @@ impl Regex {
/// Returns an iterator for each successive non-overlapping match in
/// `text`, returning the start and end byte indices with respect to
/// `text`.
///
/// # Example
///
/// Find the start and end location of every word with exactly 13
/// characters:
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let text = "Retroactively relinquishing remunerations is reprehensible.";
/// for pos in regex!(r"\b\w{13}\b").find_iter(text) {
/// println!("{}", pos);
/// }
/// // Output:
/// // (0, 13)
/// // (14, 27)
/// // (28, 41)
/// // (45, 58)
/// # }
/// ```
pub fn find_iter<'r, 't>(&'r self, text: &'t str) -> FindMatches<'r, 't> {
FindMatches {
re: self,
@ -258,51 +150,6 @@ impl Regex {
/// You should only use `captures` if you need access to submatches.
/// Otherwise, `find` is faster for discovering the location of the overall
/// match.
///
/// # Examples
///
/// Say you have some text with movie names and their release years,
/// like "'Citizen Kane' (1941)". It'd be nice if we could search for text
/// looking like that, while also extracting the movie name and its release
/// year separately.
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let re = regex!(r"'([^']+)'\s+\((\d{4})\)");
/// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
/// let caps = re.captures(text).unwrap();
/// assert_eq!(caps.at(1), Some("Citizen Kane"));
/// assert_eq!(caps.at(2), Some("1941"));
/// assert_eq!(caps.at(0), Some("'Citizen Kane' (1941)"));
/// # }
/// ```
///
/// Note that the full match is at capture group `0`. Each subsequent
/// capture group is indexed by the order of its opening `(`.
///
/// We can make this example a bit clearer by using *named* capture groups:
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let re = regex!(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)");
/// let text = "Not my favorite movie: 'Citizen Kane' (1941).";
/// let caps = re.captures(text).unwrap();
/// assert_eq!(caps.name("title"), Some("Citizen Kane"));
/// assert_eq!(caps.name("year"), Some("1941"));
/// assert_eq!(caps.at(0), Some("'Citizen Kane' (1941)"));
/// # }
/// ```
///
/// Here we name the capture groups, which we can access with the `name`
/// method. Note that the named capture groups are still accessible with
/// `at`.
///
/// The `0`th capture group is always unnamed, so it must always be
/// accessed with `at(0)`.
pub fn captures<'t>(&self, text: &'t str) -> Option<Captures<'t>> {
let caps = exec(self, Submatches, text);
Captures::new(self, text, caps)
@ -311,27 +158,6 @@ impl Regex {
/// Returns an iterator over all the non-overlapping capture groups matched
/// in `text`. This is operationally the same as `find_iter` (except it
/// yields information about submatches).
///
/// # Example
///
/// We can use this to find all movie titles and their release years in
/// some text, where the movie is formatted like "'Title' (xxxx)":
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let re = regex!(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)");
/// let text = "'Citizen Kane' (1941), 'The Wizard of Oz' (1939), 'M' (1931).";
/// for caps in re.captures_iter(text) {
/// println!("Movie: {}, Released: {}", caps.name("title"), caps.name("year"));
/// }
/// // Output:
/// // Movie: Citizen Kane, Released: 1941
/// // Movie: The Wizard of Oz, Released: 1939
/// // Movie: M, Released: 1931
/// # }
/// ```
pub fn captures_iter<'r, 't>(&'r self, text: &'t str)
-> FindCaptures<'r, 't> {
FindCaptures {
@ -348,20 +174,6 @@ impl Regex {
/// matched by the regular expression.
///
/// This method will *not* copy the text given.
///
/// # Example
///
/// To split a string delimited by arbitrary amounts of spaces or tabs:
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let re = regex!(r"[ \t]+");
/// let fields: Vec<&str> = re.split("a b \t c\td e").collect();
/// assert_eq!(fields, vec!("a", "b", "c", "d", "e"));
/// # }
/// ```
pub fn split<'r, 't>(&'r self, text: &'t str) -> RegexSplits<'r, 't> {
RegexSplits {
finder: self.find_iter(text),
@ -378,20 +190,6 @@ impl Regex {
/// in the iterator.
///
/// This method will *not* copy the text given.
///
/// # Example
///
/// Get the first two words in some text:
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let re = regex!(r"\W+");
/// let fields: Vec<&str> = re.splitn("Hey! How are you?", 3).collect();
/// assert_eq!(fields, vec!("Hey", "How", "are you?"));
/// # }
/// ```
pub fn splitn<'r, 't>(&'r self, text: &'t str, limit: uint)
-> RegexSplitsN<'r, 't> {
RegexSplitsN {
@ -407,72 +205,6 @@ impl Regex {
/// `Captures` and returns the replaced string.
///
/// If no match is found, then a copy of the string is returned unchanged.
///
/// # Examples
///
/// Note that this function is polymorphic with respect to the replacement.
/// In typical usage, this can just be a normal string:
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let re = regex!("[^01]+");
/// assert_eq!(re.replace("1078910", ""), "1010");
/// # }
/// ```
///
/// But anything satisfying the `Replacer` trait will work. For example,
/// a closure of type `|&Captures| -> String` provides direct access to the
/// captures corresponding to a match. This allows one to access
/// submatches easily:
///
/// ```rust
/// # #![feature(phase)]
/// # #![feature(unboxed_closures)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # use regex::Captures; fn main() {
/// let re = regex!(r"([^,\s]+),\s+(\S+)");
/// let result = re.replace("Springsteen, Bruce", |&: caps: &Captures| {
/// format!("{} {}", caps.at(2).unwrap_or(""), caps.at(1).unwrap_or(""))
/// });
/// assert_eq!(result, "Bruce Springsteen");
/// # }
/// ```
///
/// But this is a bit cumbersome to use all the time. Instead, a simple
/// syntax is supported that expands `$name` into the corresponding capture
/// group. Here's the last example, but using this expansion technique
/// with named capture groups:
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// let re = regex!(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)");
/// let result = re.replace("Springsteen, Bruce", "$first $last");
/// assert_eq!(result, "Bruce Springsteen");
/// # }
/// ```
///
/// Note that using `$2` instead of `$first` or `$1` instead of `$last`
/// would produce the same result. To write a literal `$` use `$$`.
///
/// Finally, sometimes you just want to replace a literal string with no
/// submatch expansion. This can be done by wrapping a string with
/// `NoExpand`:
///
/// ```rust
/// # #![feature(phase)]
/// # extern crate regex; #[phase(plugin)] extern crate regex_macros;
/// # fn main() {
/// use regex::NoExpand;
///
/// let re = regex!(r"(?P<last>[^,\s]+),\s+(\S+)");
/// let result = re.replace("Springsteen, Bruce", NoExpand("$2 $last"));
/// assert_eq!(result, "$2 $last");
/// # }
/// ```
pub fn replace<R: Replacer>(&self, text: &str, rep: R) -> String {
self.replacen(text, 1, rep)
}

View File

@ -8,24 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[cfg(not(stage1))]
#[phase(plugin)]
extern crate regex_macros;
#[cfg(not(stage1))]
#[path = "bench.rs"]
mod native_bench;
#[cfg(not(stage1))]
#[path = "tests.rs"]
mod native_tests;
#[cfg(not(stage1))]
mod native_static;
// Due to macro scoping rules, this definition only applies for the modules
// defined below. Effectively, it allows us to use the same tests for both
// native and dynamic regexes.
macro_rules! regex {
($re:expr) => (
match ::regex::Regex::new($re) {

View File

@ -1,643 +0,0 @@
// 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.
//! This crate provides the `regex!` macro. Its use is documented in the
//! `regex` crate.
#![crate_name = "regex_macros"]
#![crate_type = "dylib"]
#![experimental = "use the crates.io `regex_macros` library instead"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![feature(plugin_registrar, quote)]
#![feature(unboxed_closures)]
extern crate regex;
extern crate syntax;
extern crate rustc;
use std::rc::Rc;
use syntax::ast;
use syntax::codemap;
use syntax::ext::build::AstBuilder;
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr, DummyResult};
use syntax::parse::token;
use syntax::print::pprust;
use syntax::fold::Folder;
use syntax::ptr::P;
use rustc::plugin::Registry;
use regex::Regex;
use regex::native::{
OneChar, CharClass, Any, Save, Jump, Split,
Match, EmptyBegin, EmptyEnd, EmptyWordBoundary,
Program, Dynamic, ExDynamic, Native,
FLAG_NOCASE, FLAG_MULTI, FLAG_DOTNL, FLAG_NEGATED,
};
/// For the `regex!` syntax extension. Do not use.
#[plugin_registrar]
#[doc(hidden)]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_macro("regex", native);
}
/// Generates specialized code for the Pike VM for a particular regular
/// expression.
///
/// There are two primary differences between the code generated here and the
/// general code in vm.rs.
///
/// 1. All heap allocation is removed. Sized vector types are used instead.
/// Care must be taken to make sure that these vectors are not copied
/// gratuitously. (If you're not sure, run the benchmarks. They will yell
/// at you if you do.)
/// 2. The main `match instruction { ... }` expressions are replaced with more
/// direct `match pc { ... }`. The generators can be found in
/// `step_insts` and `add_insts`.
///
/// Other more minor changes include eliding code when possible (although this
/// isn't completely thorough at the moment), and translating character class
/// matching from using a binary search to a simple `match` expression (see
/// `match_class`).
///
/// It is strongly recommended to read the dynamic implementation in vm.rs
/// first before trying to understand the code generator. The implementation
/// strategy is identical and vm.rs has comments and will be easier to follow.
#[allow(experimental)]
fn native(cx: &mut ExtCtxt, sp: codemap::Span, tts: &[ast::TokenTree])
-> Box<MacResult+'static> {
let regex = match parse(cx, tts) {
Some(r) => r,
// error is logged in 'parse' with cx.span_err
None => return DummyResult::any(sp),
};
let re = match Regex::new(regex.as_slice()) {
Ok(re) => re,
Err(err) => {
cx.span_err(sp, err.to_string().as_slice());
return DummyResult::any(sp)
}
};
let prog = match re {
Dynamic(ExDynamic { ref prog, .. }) => prog.clone(),
Native(_) => unreachable!(),
};
let mut gen = NfaGen {
cx: &*cx, sp: sp, prog: prog,
names: re.names_iter().collect(), original: re.as_str().to_string(),
};
MacExpr::new(gen.code())
}
struct NfaGen<'a> {
cx: &'a ExtCtxt<'a>,
sp: codemap::Span,
prog: Program,
names: Vec<Option<String>>,
original: String,
}
impl<'a> NfaGen<'a> {
fn code(&mut self) -> P<ast::Expr> {
// Most or all of the following things are used in the quasiquoted
// expression returned.
let num_cap_locs = 2 * self.prog.num_captures();
let num_insts = self.prog.insts.len();
let cap_names = self.vec_expr(self.names.iter(),
|cx, name| match *name {
Some(ref name) => {
let name = name.as_slice();
quote_expr!(cx, Some($name))
}
None => cx.expr_none(self.sp),
}
);
let prefix_anchor =
match self.prog.insts[1] {
EmptyBegin(flags) if flags & FLAG_MULTI == 0 => true,
_ => false,
};
let init_groups = self.vec_expr(range(0, num_cap_locs),
|cx, _| cx.expr_none(self.sp));
let prefix_lit = Rc::new(self.prog.prefix.as_bytes().to_vec());
let prefix_bytes = self.cx.expr_lit(self.sp, ast::LitBinary(prefix_lit));
let check_prefix = self.check_prefix();
let step_insts = self.step_insts();
let add_insts = self.add_insts();
let regex = self.original.as_slice();
quote_expr!(self.cx, {
// When `regex!` is bound to a name that is not used, we have to make sure
// that dead_code warnings don't bubble up to the user from the generated
// code. Therefore, we suppress them by allowing dead_code. The effect is that
// the user is only warned about *their* unused variable/code, and not the
// unused code generated by regex!. See #14185 for an example.
#[allow(dead_code)]
static CAP_NAMES: &'static [Option<&'static str>] = &$cap_names;
#[allow(dead_code)]
fn exec<'t>(which: ::regex::native::MatchKind, input: &'t str,
start: uint, end: uint) -> Vec<Option<uint>> {
#![allow(unused_imports)]
#![allow(unused_mut)]
use regex::native::{
MatchKind, Exists, Location, Submatches,
StepState, StepMatchEarlyReturn, StepMatch, StepContinue,
CharReader, find_prefix,
};
return Nfa {
which: which,
input: input,
ic: 0,
chars: CharReader::new(input),
}.run(start, end);
type Captures = [Option<uint>; $num_cap_locs];
struct Nfa<'t> {
which: MatchKind,
input: &'t str,
ic: uint,
chars: CharReader<'t>,
}
impl<'t> Nfa<'t> {
#[allow(unused_variables)]
fn run(&mut self, start: uint, end: uint) -> Vec<Option<uint>> {
let mut matched = false;
let prefix_bytes: &[u8] = $prefix_bytes;
let mut clist = &mut Threads::new(self.which);
let mut nlist = &mut Threads::new(self.which);
let mut groups = $init_groups;
self.ic = start;
let mut next_ic = self.chars.set(start);
while self.ic <= end {
if clist.size == 0 {
if matched {
break
}
$check_prefix
}
if clist.size == 0 || (!$prefix_anchor && !matched) {
self.add(clist, 0, &mut groups)
}
self.ic = next_ic;
next_ic = self.chars.advance();
for i in range(0, clist.size) {
let pc = clist.pc(i);
let step_state = self.step(&mut groups, nlist,
clist.groups(i), pc);
match step_state {
StepMatchEarlyReturn =>
return vec![Some(0u), Some(0u)],
StepMatch => { matched = true; break },
StepContinue => {},
}
}
::std::mem::swap(&mut clist, &mut nlist);
nlist.empty();
}
match self.which {
Exists if matched => vec![Some(0u), Some(0u)],
Exists => vec![None, None],
Location | Submatches => groups.iter().map(|x| *x).collect(),
}
}
// Sometimes `nlist` is never used (for empty regexes).
#[allow(unused_variables)]
#[inline]
fn step(&self, groups: &mut Captures, nlist: &mut Threads,
caps: &mut Captures, pc: uint) -> StepState {
$step_insts
StepContinue
}
fn add(&self, nlist: &mut Threads, pc: uint,
groups: &mut Captures) {
if nlist.contains(pc) {
return
}
$add_insts
}
}
struct Thread {
pc: uint,
groups: Captures,
}
struct Threads {
which: MatchKind,
queue: [Thread; $num_insts],
sparse: [uint; $num_insts],
size: uint,
}
impl Threads {
fn new(which: MatchKind) -> Threads {
Threads {
which: which,
// These unsafe blocks are used for performance reasons, as it
// gives us a zero-cost initialization of a sparse set. The
// trick is described in more detail here:
// http://research.swtch.com/sparse
// The idea here is to avoid initializing threads that never
// need to be initialized, particularly for larger regexs with
// a lot of instructions.
queue: unsafe { ::std::mem::uninitialized() },
sparse: unsafe { ::std::mem::uninitialized() },
size: 0,
}
}
#[inline]
fn add(&mut self, pc: uint, groups: &Captures) {
let t = &mut self.queue[self.size];
t.pc = pc;
match self.which {
Exists => {},
Location => {
t.groups[0] = groups[0];
t.groups[1] = groups[1];
}
Submatches => {
for (slot, val) in t.groups.iter_mut().zip(groups.iter()) {
*slot = *val;
}
}
}
self.sparse[pc] = self.size;
self.size += 1;
}
#[inline]
fn add_empty(&mut self, pc: uint) {
self.queue[self.size].pc = pc;
self.sparse[pc] = self.size;
self.size += 1;
}
#[inline]
fn contains(&self, pc: uint) -> bool {
let s = self.sparse[pc];
s < self.size && self.queue[s].pc == pc
}
#[inline]
fn empty(&mut self) {
self.size = 0;
}
#[inline]
fn pc(&self, i: uint) -> uint {
self.queue[i].pc
}
#[inline]
fn groups<'r>(&'r mut self, i: uint) -> &'r mut Captures {
&mut self.queue[i].groups
}
}
}
::regex::native::Native(::regex::native::ExNative {
original: $regex,
names: &CAP_NAMES,
prog: exec,
})
})
}
// Generates code for the `add` method, which is responsible for adding
// zero-width states to the next queue of states to visit.
fn add_insts(&self) -> P<ast::Expr> {
let arms = self.prog.insts.iter().enumerate().map(|(pc, inst)| {
let nextpc = pc + 1;
let body = match *inst {
EmptyBegin(flags) => {
let cond =
if flags & FLAG_MULTI > 0 {
quote_expr!(self.cx,
self.chars.is_begin()
|| self.chars.prev == Some('\n')
)
} else {
quote_expr!(self.cx, self.chars.is_begin())
};
quote_expr!(self.cx, {
nlist.add_empty($pc);
if $cond { self.add(nlist, $nextpc, &mut *groups) }
})
}
EmptyEnd(flags) => {
let cond =
if flags & FLAG_MULTI > 0 {
quote_expr!(self.cx,
self.chars.is_end()
|| self.chars.cur == Some('\n')
)
} else {
quote_expr!(self.cx, self.chars.is_end())
};
quote_expr!(self.cx, {
nlist.add_empty($pc);
if $cond { self.add(nlist, $nextpc, &mut *groups) }
})
}
EmptyWordBoundary(flags) => {
let cond =
if flags & FLAG_NEGATED > 0 {
quote_expr!(self.cx, !self.chars.is_word_boundary())
} else {
quote_expr!(self.cx, self.chars.is_word_boundary())
};
quote_expr!(self.cx, {
nlist.add_empty($pc);
if $cond { self.add(nlist, $nextpc, &mut *groups) }
})
}
Save(slot) => {
let save = quote_expr!(self.cx, {
let old = groups[$slot];
groups[$slot] = Some(self.ic);
self.add(nlist, $nextpc, &mut *groups);
groups[$slot] = old;
});
let add = quote_expr!(self.cx, {
self.add(nlist, $nextpc, &mut *groups);
});
// If this is saving a submatch location but we request
// existence or only full match location, then we can skip
// right over it every time.
if slot > 1 {
quote_expr!(self.cx, {
nlist.add_empty($pc);
match self.which {
Submatches => $save,
Exists | Location => $add,
}
})
} else {
quote_expr!(self.cx, {
nlist.add_empty($pc);
match self.which {
Submatches | Location => $save,
Exists => $add,
}
})
}
}
Jump(to) => {
quote_expr!(self.cx, {
nlist.add_empty($pc);
self.add(nlist, $to, &mut *groups);
})
}
Split(x, y) => {
quote_expr!(self.cx, {
nlist.add_empty($pc);
self.add(nlist, $x, &mut *groups);
self.add(nlist, $y, &mut *groups);
})
}
// For Match, OneChar, CharClass, Any
_ => quote_expr!(self.cx, nlist.add($pc, &*groups)),
};
self.arm_inst(pc, body)
}).collect::<Vec<ast::Arm>>();
self.match_insts(arms)
}
// Generates the code for the `step` method, which processes all states
// in the current queue that consume a single character.
fn step_insts(&self) -> P<ast::Expr> {
let arms = self.prog.insts.iter().enumerate().map(|(pc, inst)| {
let nextpc = pc + 1;
let body = match *inst {
Match => {
quote_expr!(self.cx, {
match self.which {
Exists => {
return StepMatchEarlyReturn
}
Location => {
groups[0] = caps[0];
groups[1] = caps[1];
return StepMatch
}
Submatches => {
for (slot, val) in groups.iter_mut().zip(caps.iter()) {
*slot = *val;
}
return StepMatch
}
}
})
}
OneChar(c, flags) => {
if flags & FLAG_NOCASE > 0 {
let upc = c.to_uppercase();
quote_expr!(self.cx, {
let upc = self.chars.prev.map(|c| c.to_uppercase());
if upc == Some($upc) {
self.add(nlist, $nextpc, caps);
}
})
} else {
quote_expr!(self.cx, {
if self.chars.prev == Some($c) {
self.add(nlist, $nextpc, caps);
}
})
}
}
CharClass(ref ranges, flags) => {
let negate = flags & FLAG_NEGATED > 0;
let casei = flags & FLAG_NOCASE > 0;
let get_char =
if casei {
quote_expr!(self.cx, self.chars.prev.unwrap().to_uppercase())
} else {
quote_expr!(self.cx, self.chars.prev.unwrap())
};
let negcond =
if negate {
quote_expr!(self.cx, !found)
} else {
quote_expr!(self.cx, found)
};
let mranges = self.match_class(casei, ranges.as_slice());
quote_expr!(self.cx, {
if self.chars.prev.is_some() {
let c = $get_char;
let found = $mranges;
if $negcond {
self.add(nlist, $nextpc, caps);
}
}
})
}
Any(flags) => {
if flags & FLAG_DOTNL > 0 {
quote_expr!(self.cx, self.add(nlist, $nextpc, caps))
} else {
quote_expr!(self.cx, {
if self.chars.prev != Some('\n') {
self.add(nlist, $nextpc, caps)
}
()
})
}
}
// EmptyBegin, EmptyEnd, EmptyWordBoundary, Save, Jump, Split
_ => self.empty_block(),
};
self.arm_inst(pc, body)
}).collect::<Vec<ast::Arm>>();
self.match_insts(arms)
}
// Translates a character class into a match expression.
// This avoids a binary search (and is hopefully replaced by a jump
// table).
fn match_class(&self, casei: bool, ranges: &[(char, char)]) -> P<ast::Expr> {
let mut arms = ranges.iter().map(|&(mut start, mut end)| {
if casei {
start = start.to_uppercase();
end = end.to_uppercase();
}
let pat = self.cx.pat(self.sp, ast::PatRange(quote_expr!(self.cx, $start),
quote_expr!(self.cx, $end)));
self.cx.arm(self.sp, vec!(pat), quote_expr!(self.cx, true))
}).collect::<Vec<ast::Arm>>();
arms.push(self.wild_arm_expr(quote_expr!(self.cx, false)));
let match_on = quote_expr!(self.cx, c);
self.cx.expr_match(self.sp, match_on, arms)
}
// Generates code for checking a literal prefix of the search string.
// The code is only generated if the regex *has* a literal prefix.
// Otherwise, a no-op is returned.
fn check_prefix(&self) -> P<ast::Expr> {
if self.prog.prefix.len() == 0 {
self.empty_block()
} else {
quote_expr!(self.cx,
if clist.size == 0 {
let haystack = self.input.as_bytes()[self.ic..];
match find_prefix(prefix_bytes, haystack) {
None => break,
Some(i) => {
self.ic += i;
next_ic = self.chars.set(self.ic);
}
}
}
)
}
}
// Builds a `match pc { ... }` expression from a list of arms, specifically
// for matching the current program counter with an instruction.
// A wild-card arm is automatically added that executes a no-op. It will
// never be used, but is added to satisfy the compiler complaining about
// non-exhaustive patterns.
fn match_insts(&self, mut arms: Vec<ast::Arm>) -> P<ast::Expr> {
arms.push(self.wild_arm_expr(self.empty_block()));
self.cx.expr_match(self.sp, quote_expr!(self.cx, pc), arms)
}
fn empty_block(&self) -> P<ast::Expr> {
quote_expr!(self.cx, {})
}
// Creates a match arm for the instruction at `pc` with the expression
// `body`.
fn arm_inst(&self, pc: uint, body: P<ast::Expr>) -> ast::Arm {
let pc_pat = self.cx.pat_lit(self.sp, quote_expr!(self.cx, $pc));
self.cx.arm(self.sp, vec!(pc_pat), body)
}
// Creates a wild-card match arm with the expression `body`.
fn wild_arm_expr(&self, body: P<ast::Expr>) -> ast::Arm {
ast::Arm {
attrs: vec!(),
pats: vec!(P(ast::Pat{
id: ast::DUMMY_NODE_ID,
span: self.sp,
node: ast::PatWild(ast::PatWildSingle),
})),
guard: None,
body: body,
}
}
// Converts `xs` to a `[x1, x2, .., xN]` expression by calling `to_expr`
// on each element in `xs`.
fn vec_expr<T, It, F>(&self, xs: It, mut to_expr: F) -> P<ast::Expr> where
It: Iterator<Item=T>,
F: FnMut(&ExtCtxt, T) -> P<ast::Expr>,
{
let exprs = xs.map(|x| to_expr(self.cx, x)).collect();
self.cx.expr_vec(self.sp, exprs)
}
}
/// Looks for a single string literal and returns it.
/// Otherwise, logs an error with cx.span_err and returns None.
fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
let mut parser = cx.new_parser_from_tts(tts);
let entry = cx.expander().fold_expr(parser.parse_expr());
let regex = match entry.node {
ast::ExprLit(ref lit) => {
match lit.node {
ast::LitStr(ref s, _) => s.to_string(),
_ => {
cx.span_err(entry.span, format!(
"expected string literal but got `{}`",
pprust::lit_to_string(&**lit)).as_slice());
return None
}
}
}
_ => {
cx.span_err(entry.span, format!(
"expected string literal but got `{}`",
pprust::expr_to_string(&*entry)).as_slice());
return None
}
};
if !parser.eat(&token::Eof) {
cx.span_err(parser.span, "only one string literal allowed");
return None;
}
Some(regex)
}

View File

@ -29,7 +29,7 @@ use util::ppaux::Repr;
use std::collections::hash_map::Entry::Vacant;
use std::io::{self, File};
use std::os;
use std::sync::atomic;
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
use syntax::ast;
fn print_help_message() {
@ -73,10 +73,10 @@ pub fn maybe_print_constraints_for<'a, 'tcx>(region_vars: &RegionVarBindings<'a,
let output_path = {
let output_template = match requested_output {
Some(ref s) if s.as_slice() == "help" => {
static PRINTED_YET : atomic::AtomicBool = atomic::ATOMIC_BOOL_INIT;
if !PRINTED_YET.load(atomic::SeqCst) {
static PRINTED_YET: AtomicBool = ATOMIC_BOOL_INIT;
if !PRINTED_YET.load(Ordering::SeqCst) {
print_help_message();
PRINTED_YET.store(true, atomic::SeqCst);
PRINTED_YET.store(true, Ordering::SeqCst);
}
return;
}

View File

@ -18,7 +18,7 @@ pub use self::OptLevel::*;
pub use self::OutputType::*;
pub use self::DebugInfoLevel::*;
use session::{early_error, Session};
use session::{early_error, early_warn, Session};
use session::search_paths::SearchPaths;
use rustc_back::target::Target;
@ -394,7 +394,6 @@ macro_rules! cgoptions {
mod cgsetters {
use super::{CodegenOptions, Passes, SomePasses, AllPasses};
use std::str::from_str;
$(
pub fn $opt(cg: &mut CodegenOptions, v: Option<&str>) -> bool {
@ -456,7 +455,7 @@ macro_rules! cgoptions {
}
fn parse_uint(slot: &mut uint, v: Option<&str>) -> bool {
match v.and_then(from_str) {
match v.and_then(|s| s.parse()) {
Some(i) => { *slot = i; true },
None => false
}
@ -464,7 +463,7 @@ macro_rules! cgoptions {
fn parse_opt_uint(slot: &mut Option<uint>, v: Option<&str>) -> bool {
match v {
Some(s) => { *slot = from_str(s); slot.is_some() }
Some(s) => { *slot = s.parse(); slot.is_some() }
None => { *slot = None; true }
}
}
@ -879,22 +878,22 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
let parse_only = if matches.opt_present("parse-only") {
// FIXME(acrichto) uncomment deprecation warning
// early_warn("--parse-only is deprecated in favor of -Z parse-only");
// FIXME(acrichto) remove this eventually
early_warn("--parse-only is deprecated in favor of -Z parse-only");
true
} else {
debugging_opts & PARSE_ONLY != 0
};
let no_trans = if matches.opt_present("no-trans") {
// FIXME(acrichto) uncomment deprecation warning
// early_warn("--no-trans is deprecated in favor of -Z no-trans");
// FIXME(acrichto) remove this eventually
early_warn("--no-trans is deprecated in favor of -Z no-trans");
true
} else {
debugging_opts & NO_TRANS != 0
};
let no_analysis = if matches.opt_present("no-analysis") {
// FIXME(acrichto) uncomment deprecation warning
// early_warn("--no-analysis is deprecated in favor of -Z no-analysis");
// FIXME(acrichto) remove this eventually
early_warn("--no-analysis is deprecated in favor of -Z no-analysis");
true
} else {
debugging_opts & NO_ANALYSIS != 0
@ -946,8 +945,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
Default
} else if matches.opt_present("opt-level") {
// FIXME(acrichto) uncomment deprecation warning
// early_warn("--opt-level=N is deprecated in favor of -C opt-level=N");
// FIXME(acrichto) remove this eventually
early_warn("--opt-level=N is deprecated in favor of -C opt-level=N");
match matches.opt_str("opt-level").as_ref().map(|s| s.as_slice()) {
None |
Some("0") => No,
@ -985,8 +984,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
FullDebugInfo
} else if matches.opt_present("debuginfo") {
// FIXME(acrichto) uncomment deprecation warning
// early_warn("--debuginfo=N is deprecated in favor of -C debuginfo=N");
// FIXME(acrichto) remove this eventually
early_warn("--debuginfo=N is deprecated in favor of -C debuginfo=N");
match matches.opt_str("debuginfo").as_ref().map(|s| s.as_slice()) {
Some("0") => NoDebugInfo,
Some("1") => LimitedDebugInfo,
@ -1054,8 +1053,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
let test = matches.opt_present("test");
let write_dependency_info = if matches.opt_present("dep-info") {
// FIXME(acrichto) uncomment deprecation warning
// early_warn("--dep-info has been deprecated in favor of --emit");
// FIXME(acrichto) remove this eventually
early_warn("--dep-info has been deprecated in favor of --emit");
(true, matches.opt_str("dep-info").map(|p| Path::new(p)))
} else {
(output_types.contains(&OutputTypeDepInfo), None)
@ -1072,22 +1071,21 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
}).collect::<Vec<_>>();
if matches.opt_present("print-crate-name") {
// FIXME(acrichto) uncomment deprecation warning
// early_warn("--print-crate-name has been deprecated in favor of \
// --print crate-name");
// FIXME(acrichto) remove this eventually
early_warn("--print-crate-name has been deprecated in favor of \
--print crate-name");
prints.push(PrintRequest::CrateName);
}
if matches.opt_present("print-file-name") {
// FIXME(acrichto) uncomment deprecation warning
// early_warn("--print-file-name has been deprecated in favor of \
// --print file-names");
// FIXME(acrichto) remove this eventually
early_warn("--print-file-name has been deprecated in favor of \
--print file-names");
prints.push(PrintRequest::FileNames);
}
if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
// FIXME(acrichto) uncomment deprecation warning
// early_warn("-C remark will not show source locations without \
// --debuginfo");
early_warn("-C remark will not show source locations without \
--debuginfo");
}
let color = match matches.opt_str("color").as_ref().map(|s| s[]) {

View File

@ -47,7 +47,7 @@ fn test_lev_distance() {
// Test bytelength agnosticity
for c in range(0u32, MAX as u32)
.filter_map(|i| from_u32(i))
.map(|i| String::from_char(1, i)) {
.map(|i| i.to_string()) {
assert_eq!(lev_distance(c[], c[]), 0);
}

View File

@ -14,7 +14,6 @@
//! module's count includes its children's.
use std::cmp::Ordering;
use std::num::Zero;
use std::ops::Add;
use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
@ -26,7 +25,7 @@ use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem, Stability};
use html::render::cache;
#[derive(Zero, RustcEncodable, RustcDecodable, PartialEq, Eq)]
#[derive(RustcEncodable, RustcDecodable, PartialEq, Eq)]
/// The counts for each stability level.
#[derive(Copy)]
pub struct Counts {

View File

@ -396,7 +396,7 @@ mod tests {
for _ in range(0u, 1000) {
let times = thread_rng().gen_range(1u, 100);
let v = Vec::from_fn(times, |_| random::<u8>());
let v = thread_rng().gen_iter::<u8>().take(times).collect::<Vec<_>>();
assert_eq!(v.to_base64(STANDARD)
.from_base64()
.unwrap(),

View File

@ -2052,7 +2052,7 @@ macro_rules! read_primitive {
Json::F64(f) => Err(ExpectedError("Integer".to_string(), format!("{}", f))),
// re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
// is going to have a string here, as per JSON spec.
Json::String(s) => match std::str::from_str(s.as_slice()) {
Json::String(s) => match s.parse() {
Some(f) => Ok(f),
None => Err(ExpectedError("Number".to_string(), s)),
},

View File

@ -13,7 +13,6 @@
//! Operations on ASCII strings and characters
#![unstable = "unsure about placement and naming"]
#![allow(deprecated)]
use core::kinds::Sized;
use iter::IteratorExt;

View File

@ -266,10 +266,6 @@ impl CString {
self.buf
}
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub unsafe fn unwrap(self) -> *const libc::c_char { self.into_inner() }
/// Return the number of bytes in the CString (not including the NUL
/// terminator).
#[inline]

View File

@ -150,10 +150,6 @@ impl<T> CVec<T> {
self.base
}
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub unsafe fn unwrap(self) -> *mut T { self.into_inner() }
/// Returns the number of items in this vector.
pub fn len(&self) -> uint { self.len }

View File

@ -16,7 +16,7 @@ use self::VacantEntryState::*;
use borrow::BorrowFrom;
use clone::Clone;
use cmp::{max, Eq, Equiv, PartialEq};
use cmp::{max, Eq, PartialEq};
use default::Default;
use fmt::{self, Show};
use hash::{Hash, Hasher, RandomSipHasher};
@ -444,20 +444,6 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
table::make_hash(&self.hasher, x)
}
#[allow(deprecated)]
fn search_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, q: &Q)
-> Option<FullBucketImm<'a, K, V>> {
let hash = self.make_hash(q);
search_hashed(&self.table, hash, |k| q.equiv(k)).into_option()
}
#[allow(deprecated)]
fn search_equiv_mut<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a mut self, q: &Q)
-> Option<FullBucketMut<'a, K, V>> {
let hash = self.make_hash(q);
search_hashed(&mut self.table, hash, |k| q.equiv(k)).into_option()
}
/// Search for a key, yielding the index if it's found in the hashtable.
/// If you already have the hash for the key lying around, use
/// search_hashed.
@ -807,30 +793,6 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
}
}
/// Deprecated: use `contains_key` and `BorrowFrom` instead.
#[deprecated = "use contains_key and BorrowFrom instead"]
pub fn contains_key_equiv<Sized? Q: Hash<S> + Equiv<K>>(&self, key: &Q) -> bool {
self.search_equiv(key).is_some()
}
/// Deprecated: use `get` and `BorrowFrom` instead.
#[deprecated = "use get and BorrowFrom instead"]
pub fn find_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
self.search_equiv(k).map(|bucket| bucket.into_refs().1)
}
/// Deprecated: use `remove` and `BorrowFrom` instead.
#[deprecated = "use remove and BorrowFrom instead"]
pub fn pop_equiv<Sized? Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
if self.table.size() == 0 {
return None
}
self.reserve(1);
self.search_equiv_mut(k).map(|bucket| pop_internal(bucket).1)
}
/// An iterator visiting all keys in arbitrary order.
/// Iterator element type is `&'a K`.
///
@ -1047,12 +1009,6 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
self.drain();
}
/// Deprecated: Renamed to `get`.
#[deprecated = "Renamed to `get`"]
pub fn find(&self, k: &K) -> Option<&V> {
self.get(k)
}
/// Returns a reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but
@ -1099,12 +1055,6 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
self.search(k).is_some()
}
/// Deprecated: Renamed to `get_mut`.
#[deprecated = "Renamed to `get_mut`"]
pub fn find_mut(&mut self, k: &K) -> Option<&mut V> {
self.get_mut(k)
}
/// Returns a mutable reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but
@ -1131,12 +1081,6 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
}
/// Deprecated: Renamed to `insert`.
#[deprecated = "Renamed to `insert`"]
pub fn swap(&mut self, k: K, v: V) -> Option<V> {
self.insert(k, v)
}
/// Inserts a key-value pair from the map. If the key already had a value
/// present in the map, that value is returned. Otherwise, `None` is returned.
///
@ -1165,12 +1109,6 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
retval
}
/// Deprecated: Renamed to `remove`.
#[deprecated = "Renamed to `remove`"]
pub fn pop(&mut self, k: &K) -> Option<V> {
self.remove(k)
}
/// Removes a key from the map, returning the value at the key if the key
/// was previously in the map.
///
@ -1246,24 +1184,6 @@ fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHas
}
}
impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
/// Deprecated: Use `map.get(k).cloned()`.
///
/// Return a copy of the value corresponding to the key.
#[deprecated = "Use `map.get(k).cloned()`"]
pub fn find_copy(&self, k: &K) -> Option<V> {
self.get(k).cloned()
}
/// Deprecated: Use `map[k].clone()`.
///
/// Return a copy of the value corresponding to the key.
#[deprecated = "Use `map[k].clone()`"]
pub fn get_copy(&self, k: &K) -> V {
self[*k].clone()
}
}
#[stable]
impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> {
fn eq(&self, other: &HashMap<K, V, H>) -> bool {
@ -1574,30 +1494,12 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extend<(K, V)> for HashMap<K
mod test_map {
use prelude::v1::*;
use cmp::Equiv;
use super::HashMap;
use super::Entry::{Occupied, Vacant};
use hash;
use iter::{range_inclusive, range_step_inclusive};
use iter::{range_inclusive, range_step_inclusive, repeat};
use cell::RefCell;
use rand::{weak_rng, Rng};
struct KindaIntLike(int);
#[allow(deprecated)]
impl Equiv<int> for KindaIntLike {
fn equiv(&self, other: &int) -> bool {
let KindaIntLike(this) = *self;
this == *other
}
}
impl<S: hash::Writer> hash::Hash<S> for KindaIntLike {
fn hash(&self, state: &mut S) {
let KindaIntLike(this) = *self;
this.hash(state)
}
}
#[test]
fn test_create_capacity_zero() {
let mut m = HashMap::with_capacity(0);
@ -1654,7 +1556,7 @@ mod test_map {
#[test]
fn test_drops() {
DROP_VECTOR.with(|slot| {
*slot.borrow_mut() = Vec::from_elem(200, 0i);
*slot.borrow_mut() = repeat(0i).take(200).collect();
});
{
@ -1713,7 +1615,7 @@ mod test_map {
#[test]
fn test_move_iter_drops() {
DROP_VECTOR.with(|v| {
*v.borrow_mut() = Vec::from_elem(200, 0i);
*v.borrow_mut() = repeat(0).take(200).collect();
});
let hm = {
@ -1911,15 +1813,6 @@ mod test_map {
assert_eq!(m.remove(&1), None);
}
#[test]
#[allow(deprecated)]
fn test_pop_equiv() {
let mut m = HashMap::new();
m.insert(1i, 2i);
assert_eq!(m.pop_equiv(&KindaIntLike(1)), Some(2));
assert_eq!(m.pop_equiv(&KindaIntLike(1)), None);
}
#[test]
fn test_iterate() {
let mut m = HashMap::with_capacity(4);
@ -1970,27 +1863,6 @@ mod test_map {
}
}
#[test]
#[allow(deprecated)]
fn test_find_copy() {
let mut m = HashMap::new();
assert!(m.get(&1i).is_none());
for i in range(1i, 10000) {
m.insert(i, i + 7);
match m.find_copy(&i) {
None => panic!(),
Some(v) => assert_eq!(v, i + 7)
}
for j in range(1i, i/100) {
match m.find_copy(&j) {
None => panic!(),
Some(v) => assert_eq!(v, j + 7)
}
}
}
}
#[test]
fn test_eq() {
let mut m1 = HashMap::new();

View File

@ -12,7 +12,7 @@
use borrow::BorrowFrom;
use clone::Clone;
use cmp::{Eq, Equiv, PartialEq};
use cmp::{Eq, PartialEq};
use core::kinds::Sized;
use default::Default;
use fmt::Show;
@ -228,13 +228,6 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
self.map.shrink_to_fit()
}
/// Deprecated: use `contains` and `BorrowFrom`.
#[deprecated = "use contains and BorrowFrom"]
#[allow(deprecated)]
pub fn contains_equiv<Sized? Q: Hash<S> + Equiv<T>>(&self, value: &Q) -> bool {
self.map.contains_key_equiv(value)
}
/// An iterator visiting all elements in arbitrary order.
/// Iterator element type is &'a T.
///

View File

@ -314,17 +314,9 @@
pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet};
pub use core_collections::{DList, RingBuf, VecMap};
/// Deprecated: Moved to collect-rs: https://github.com/Gankro/collect-rs/
#[deprecated = "Moved to collect-rs: https://github.com/Gankro/collect-rs/"]
pub use core_collections::EnumSet;
pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set};
pub use core_collections::{dlist, ring_buf, vec_map};
/// Deprecated: Moved to collect-rs: https://github.com/Gankro/collect-rs/
#[deprecated = "Moved to collect-rs: https://github.com/Gankro/collect-rs/"]
pub use core_collections::enum_set;
pub use self::hash_map::HashMap;
pub use self::hash_set::HashSet;

View File

@ -89,10 +89,6 @@ impl<R: Reader> BufferedReader<R> {
///
/// Note that any leftover data in the internal buffer is lost.
pub fn into_inner(self) -> R { self.inner }
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> R { self.into_inner() }
}
impl<R: Reader> Buffer for BufferedReader<R> {
@ -198,10 +194,6 @@ impl<W: Writer> BufferedWriter<W> {
self.flush_buf().unwrap();
self.inner.take().unwrap()
}
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> W { self.into_inner() }
}
impl<W: Writer> Writer for BufferedWriter<W> {
@ -262,10 +254,6 @@ impl<W: Writer> LineBufferedWriter<W> {
///
/// The internal buffer is flushed before returning the writer.
pub fn into_inner(self) -> W { self.inner.into_inner() }
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> W { self.into_inner() }
}
impl<W: Writer> Writer for LineBufferedWriter<W> {
@ -374,10 +362,6 @@ impl<S: Stream> BufferedStream<S> {
let InternalBufferedWriter(w) = self.inner.inner;
w.into_inner()
}
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> S { self.into_inner() }
}
impl<S: Stream> Buffer for BufferedStream<S> {

View File

@ -518,7 +518,7 @@ mod bench {
({
use super::u64_from_be_bytes;
let data = Vec::from_fn($stride*100+$start_index, |i| i as u8);
let data = range(0u8, $stride*100+$start_index).collect::<Vec<_>>();
let mut sum = 0u64;
$b.iter(|| {
let mut i = $start_index;

View File

@ -12,8 +12,6 @@
//! Readers and Writers for in-memory buffers
#![allow(deprecated)]
use cmp::min;
use option::Option::None;
use result::Result::{Err, Ok};
@ -70,6 +68,7 @@ pub struct MemWriter {
buf: Vec<u8>,
}
#[allow(deprecated)]
impl MemWriter {
/// Create a new `MemWriter`.
#[inline]
@ -96,10 +95,6 @@ impl MemWriter {
/// Unwraps this `MemWriter`, returning the underlying buffer
#[inline]
pub fn into_inner(self) -> Vec<u8> { self.buf }
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> Vec<u8> { self.into_inner() }
}
impl Writer for MemWriter {
@ -155,10 +150,6 @@ impl MemReader {
/// Unwraps this `MemReader`, returning the underlying buffer
#[inline]
pub fn into_inner(self) -> Vec<u8> { self.buf }
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> Vec<u8> { self.into_inner() }
}
impl Reader for MemReader {
@ -401,10 +392,11 @@ mod test {
extern crate "test" as test_crate;
use prelude::v1::*;
use super::*;
use io::{SeekSet, SeekCur, SeekEnd};
use io;
use iter::repeat;
use self::test_crate::Bencher;
use super::*;
#[test]
fn test_vec_writer() {
@ -664,7 +656,7 @@ mod test {
}
fn do_bench_mem_writer(b: &mut Bencher, times: uint, len: uint) {
let src: Vec<u8> = Vec::from_elem(len, 5);
let src: Vec<u8> = repeat(5).take(len).collect();
b.bytes = (times * len) as u64;
b.iter(|| {
@ -673,7 +665,7 @@ mod test {
wr.write(src.as_slice()).unwrap();
}
let v = wr.unwrap();
let v = wr.into_inner();
assert_eq!(v.len(), times * len);
assert!(v.iter().all(|x| *x == 5));
});

View File

@ -263,7 +263,6 @@ pub use self::timer::Timer;
pub use self::net::ip::IpAddr;
pub use self::net::tcp::TcpListener;
pub use self::net::tcp::TcpStream;
pub use self::net::udp::UdpStream;
pub use self::pipe::PipeStream;
pub use self::process::{Process, Command};
pub use self::tempfile::TempDir;
@ -862,23 +861,6 @@ pub trait Reader {
}
}
/// A reader which can be converted to a RefReader.
#[deprecated = "use ByRefReader instead"]
pub trait AsRefReader {
/// Creates a wrapper around a mutable reference to the reader.
///
/// This is useful to allow applying adaptors while still
/// retaining ownership of the original value.
fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self>;
}
#[allow(deprecated)]
impl<T: Reader> AsRefReader for T {
fn by_ref<'a>(&'a mut self) -> RefReader<'a, T> {
RefReader { inner: self }
}
}
/// A reader which can be converted to a RefReader.
pub trait ByRefReader {
/// Creates a wrapper around a mutable reference to the reader.
@ -1242,24 +1224,6 @@ pub trait Writer {
}
}
/// A writer which can be converted to a RefWriter.
#[deprecated = "use ByRefWriter instead"]
pub trait AsRefWriter {
/// Creates a wrapper around a mutable reference to the writer.
///
/// This is useful to allow applying wrappers while still
/// retaining ownership of the original value.
#[inline]
fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self>;
}
#[allow(deprecated)]
impl<T: Writer> AsRefWriter for T {
fn by_ref<'a>(&'a mut self) -> RefWriter<'a, T> {
RefWriter { inner: self }
}
}
/// A writer which can be converted to a RefWriter.
pub trait ByRefWriter {
/// Creates a wrapper around a mutable reference to the writer.
@ -1847,64 +1811,6 @@ bitflags! {
#[doc = "All possible permissions enabled."]
const ALL_PERMISSIONS = USER_RWX.bits | GROUP_RWX.bits | OTHER_RWX.bits,
// Deprecated names
#[allow(non_upper_case_globals)]
#[deprecated = "use USER_READ instead"]
const UserRead = USER_READ.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use USER_WRITE instead"]
const UserWrite = USER_WRITE.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use USER_EXECUTE instead"]
const UserExecute = USER_EXECUTE.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use GROUP_READ instead"]
const GroupRead = GROUP_READ.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use GROUP_WRITE instead"]
const GroupWrite = GROUP_WRITE.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use GROUP_EXECUTE instead"]
const GroupExecute = GROUP_EXECUTE.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use OTHER_READ instead"]
const OtherRead = OTHER_READ.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use OTHER_WRITE instead"]
const OtherWrite = OTHER_WRITE.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use OTHER_EXECUTE instead"]
const OtherExecute = OTHER_EXECUTE.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use USER_RWX instead"]
const UserRWX = USER_RWX.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use GROUP_RWX instead"]
const GroupRWX = GROUP_RWX.bits,
#[allow(non_upper_case_globals)]
#[deprecated = "use OTHER_RWX instead"]
const OtherRWX = OTHER_RWX.bits,
#[doc = "Deprecated: use `USER_FILE` instead."]
#[allow(non_upper_case_globals)]
#[deprecated = "use USER_FILE instead"]
const UserFile = USER_FILE.bits,
#[doc = "Deprecated: use `USER_DIR` instead."]
#[allow(non_upper_case_globals)]
#[deprecated = "use USER_DIR instead"]
const UserDir = USER_DIR.bits,
#[doc = "Deprecated: use `USER_EXEC` instead."]
#[allow(non_upper_case_globals)]
#[deprecated = "use USER_EXEC instead"]
const UserExec = USER_EXEC.bits,
#[doc = "Deprecated: use `ALL_PERMISSIONS` instead"]
#[allow(non_upper_case_globals)]
#[deprecated = "use ALL_PERMISSIONS instead"]
const AllPermissions = ALL_PERMISSIONS.bits,
}
}

View File

@ -17,10 +17,8 @@
use clone::Clone;
use io::net::ip::{SocketAddr, IpAddr, ToSocketAddr};
use io::{Reader, Writer, IoResult};
use ops::FnOnce;
use io::IoResult;
use option::Option;
use result::Result::{Ok, Err};
use sys::udp::UdpSocket as UdpSocketImp;
use sys_common;
@ -88,21 +86,6 @@ impl UdpSocket {
super::with_addresses(addr, |addr| self.inner.send_to(buf, addr))
}
/// Creates a `UdpStream`, which allows use of the `Reader` and `Writer`
/// traits to receive and send data from the same address. This transfers
/// ownership of the socket to the stream.
///
/// Note that this call does not perform any actual network communication,
/// because UDP is a datagram protocol.
#[deprecated = "`UdpStream` has been deprecated"]
#[allow(deprecated)]
pub fn connect(self, other: SocketAddr) -> UdpStream {
UdpStream {
socket: self,
connected_to: other,
}
}
/// Returns the socket address that this socket was created from.
pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
self.inner.socket_name()
@ -192,59 +175,6 @@ impl sys_common::AsInner<UdpSocketImp> for UdpSocket {
}
}
/// A type that allows convenient usage of a UDP stream connected to one
/// address via the `Reader` and `Writer` traits.
///
/// # Note
///
/// This structure has been deprecated because `Reader` is a stream-oriented API but UDP
/// is a packet-oriented protocol. Every `Reader` method will read a whole packet and
/// throw all superfluous bytes away so that they are no longer available for further
/// method calls.
#[deprecated]
pub struct UdpStream {
socket: UdpSocket,
connected_to: SocketAddr
}
impl UdpStream {
/// Allows access to the underlying UDP socket owned by this stream. This
/// is useful to, for example, use the socket to send data to hosts other
/// than the one that this stream is connected to.
pub fn as_socket<T, F>(&mut self, f: F) -> T where
F: FnOnce(&mut UdpSocket) -> T,
{
f(&mut self.socket)
}
/// Consumes this UDP stream and returns out the underlying socket.
pub fn disconnect(self) -> UdpSocket {
self.socket
}
}
impl Reader for UdpStream {
/// Returns the next non-empty message from the specified address.
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
let peer = self.connected_to;
self.as_socket(|sock| {
loop {
let (nread, src) = try!(sock.recv_from(buf));
if nread > 0 && src == peer {
return Ok(nread);
}
}
})
}
}
impl Writer for UdpStream {
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
let connected_to = self.connected_to;
self.as_socket(|sock| sock.send_to(buf, connected_to))
}
}
#[cfg(test)]
#[allow(experimental)]
mod test {
@ -337,91 +267,6 @@ mod test {
}
}
#[test]
#[allow(deprecated)]
fn stream_smoke_test_ip4() {
let server_ip = next_test_ip4();
let client_ip = next_test_ip4();
let dummy_ip = next_test_ip4();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
let _t = Thread::spawn(move|| {
let send_as = |&:ip, val: &[u8]| {
match UdpSocket::bind(ip) {
Ok(client) => {
let client = box client;
let mut stream = client.connect(server_ip);
stream.write(val).unwrap();
}
Err(..) => panic!()
}
};
rx1.recv().unwrap();
send_as(dummy_ip, &[98]);
send_as(client_ip, &[99]);
tx2.send(()).unwrap();
});
match UdpSocket::bind(server_ip) {
Ok(server) => {
let server = box server;
let mut stream = server.connect(client_ip);
tx1.send(()).unwrap();
let mut buf = [0];
match stream.read(&mut buf) {
Ok(nread) => {
assert_eq!(nread, 1);
assert_eq!(buf[0], 99);
}
Err(..) => panic!(),
}
}
Err(..) => panic!()
}
rx2.recv().unwrap();
}
#[test]
#[allow(deprecated)]
fn stream_smoke_test_ip6() {
let server_ip = next_test_ip6();
let client_ip = next_test_ip6();
let (tx1, rx1) = channel();
let (tx2, rx2) = channel();
let _t = Thread::spawn(move|| {
match UdpSocket::bind(client_ip) {
Ok(client) => {
let client = box client;
let mut stream = client.connect(server_ip);
rx1.recv().unwrap();
stream.write(&[99]).unwrap();
}
Err(..) => panic!()
}
tx2.send(()).unwrap();
});
match UdpSocket::bind(server_ip) {
Ok(server) => {
let server = box server;
let mut stream = server.connect(client_ip);
tx1.send(()).unwrap();
let mut buf = [0];
match stream.read(&mut buf) {
Ok(nread) => {
assert_eq!(nread, 1);
assert_eq!(buf[0], 99);
}
Err(..) => panic!()
}
}
Err(..) => panic!()
}
rx2.recv().unwrap();
}
pub fn socket_name(addr: SocketAddr) {
let server = UdpSocket::bind(addr);

View File

@ -19,7 +19,7 @@ use option::Option::{None, Some};
use os;
use path::{Path, GenericPath};
use result::Result::{Ok, Err};
use sync::atomic;
use sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
/// A wrapper for a path to temporary directory implementing automatic
/// scope-based deletion.
@ -90,14 +90,14 @@ impl TempDir {
return TempDir::new_in(&abs_tmpdir, suffix);
}
static CNT: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
static CNT: AtomicUint = ATOMIC_UINT_INIT;
let mut attempts = 0u;
loop {
let filename =
format!("rs-{}-{}-{}",
unsafe { libc::getpid() },
CNT.fetch_add(1, atomic::SeqCst),
CNT.fetch_add(1, Ordering::SeqCst),
suffix);
let p = tmpdir.join(filename);
match fs::mkdir(&p, io::USER_RWX) {
@ -129,10 +129,6 @@ impl TempDir {
tmpdir.path.take().unwrap()
}
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> Path { self.into_inner() }
/// Access the wrapped `std::path::Path` to the temporary directory.
pub fn path<'a>(&'a self) -> &'a Path {
self.path.as_ref().unwrap()

View File

@ -17,12 +17,12 @@ use prelude::v1::*;
use libc;
use os;
use std::io::net::ip::*;
use sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Relaxed};
use sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
/// Get a port number, starting at 9600, for use in tests
pub fn next_test_port() -> u16 {
static NEXT_OFFSET: AtomicUint = ATOMIC_UINT_INIT;
base_port() + NEXT_OFFSET.fetch_add(1, Relaxed) as u16
base_port() + NEXT_OFFSET.fetch_add(1, Ordering::Relaxed) as u16
}
/// Get a temporary path which could be the location of a unix socket
@ -34,7 +34,7 @@ pub fn next_test_unix() -> Path {
let string = format!("rust-test-unix-path-{}-{}-{}",
base_port(),
unsafe {libc::getpid()},
COUNT.fetch_add(1, Relaxed));
COUNT.fetch_add(1, Ordering::Relaxed));
if cfg!(unix) {
os::tmpdir().join(string)
} else {

View File

@ -30,10 +30,6 @@ impl<R: Reader> LimitReader<R> {
/// Consumes the `LimitReader`, returning the underlying `Reader`.
pub fn into_inner(self) -> R { self.inner }
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner"]
pub fn unwrap(self) -> R { self.into_inner() }
/// Returns the number of bytes that can be read before the `LimitReader`
/// will return EOF.
///
@ -219,10 +215,6 @@ impl<R: Reader, W: Writer> TeeReader<R, W> {
let TeeReader { reader, writer } = self;
(reader, writer)
}
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner"]
pub fn unwrap(self) -> (R, W) { self.into_inner() }
}
impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {

View File

@ -226,7 +226,6 @@ pub mod hash;
/* Threads and communication */
pub mod task;
pub mod thread;
pub mod sync;

View File

@ -21,12 +21,8 @@
#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
#[cfg(test)] use kinds::Copy;
pub use core::num::{Num, div_rem, Zero, zero, One, one};
pub use core::num::{Unsigned, pow, Bounded};
pub use core::num::{Primitive, Int, SignedInt, UnsignedInt};
pub use core::num::{Int, SignedInt, UnsignedInt};
pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
pub use core::num::{next_power_of_two, is_power_of_two};
pub use core::num::{checked_next_power_of_two};
pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
pub use core::num::{from_f32, from_f64};
@ -118,11 +114,6 @@ pub trait FloatMath: Float {
// DEPRECATED
#[deprecated = "Use `FloatMath::abs_sub`"]
pub fn abs_sub<T: FloatMath>(x: T, y: T) -> T {
x.abs_sub(y)
}
/// Helper function for testing numeric operations
#[cfg(test)]
pub fn test_num<T>(ten: T, two: T) where
@ -804,7 +795,7 @@ mod bench {
#[bench]
fn bench_pow_function(b: &mut Bencher) {
let v = Vec::from_fn(1024u, |n| n);
let v = range(0, 1024u).collect::<Vec<_>>();
b.iter(|| {v.iter().fold(0u, |old, new| old.pow(*new));});
}
}

View File

@ -15,6 +15,4 @@
pub use core::u16::{BITS, BYTES, MIN, MAX};
use ops::FnOnce;
uint_module! { u16 }

View File

@ -15,6 +15,4 @@
pub use core::u32::{BITS, BYTES, MIN, MAX};
use ops::FnOnce;
uint_module! { u32 }

View File

@ -15,6 +15,4 @@
pub use core::u64::{BITS, BYTES, MIN, MAX};
use ops::FnOnce;
uint_module! { u64 }

View File

@ -15,6 +15,4 @@
pub use core::u8::{BITS, BYTES, MIN, MAX};
use ops::FnOnce;
uint_module! { u8 }

View File

@ -15,6 +15,4 @@
pub use core::uint::{BITS, BYTES, MIN, MAX};
use ops::FnOnce;
uint_module! { uint }

View File

@ -17,41 +17,14 @@ macro_rules! uint_module { ($T:ty) => (
// String conversion functions and impl num -> str
/// Convert to a string as a byte slice in a given base.
///
/// Use in place of x.to_string() when you do not need to store the string permanently
///
/// # Examples
///
/// ```
/// #![allow(deprecated)]
///
/// std::uint::to_str_bytes(123, 10, |v| {
/// assert!(v == "123".as_bytes());
/// });
/// ```
#[inline]
#[deprecated = "just use .to_string(), or a BufWriter with write! if you mustn't allocate"]
pub fn to_str_bytes<U, F>(n: $T, radix: uint, f: F) -> U where
F: FnOnce(&[u8]) -> U,
{
use io::{Writer, Seek};
// The radix can be as low as 2, so we need at least 64 characters for a
// base 2 number, and then we need another for a possible '-' character.
let mut buf = [0u8; 65];
let amt = {
let mut wr = ::io::BufWriter::new(&mut buf);
(write!(&mut wr, "{}", ::fmt::radix(n, radix as u8))).unwrap();
wr.tell().unwrap() as uint
};
f(buf[..amt])
}
#[cfg(test)]
mod tests {
use prelude::v1::*;
use num::FromStrRadix;
use str::from_str;
fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> {
::str::FromStr::from_str(t)
}
#[test]
pub fn test_from_str() {

View File

@ -54,7 +54,7 @@ use result::Result::{Err, Ok};
use slice::{AsSlice, SliceExt};
use str::{Str, StrExt};
use string::{String, ToString};
use sync::atomic::{AtomicInt, ATOMIC_INT_INIT, SeqCst};
use sync::atomic::{AtomicInt, ATOMIC_INT_INIT, Ordering};
use vec::Vec;
#[cfg(unix)] use c_str::ToCStr;
@ -606,13 +606,13 @@ static EXIT_STATUS: AtomicInt = ATOMIC_INT_INIT;
///
/// Note that this is not synchronized against modifications of other threads.
pub fn set_exit_status(code: int) {
EXIT_STATUS.store(code, SeqCst)
EXIT_STATUS.store(code, Ordering::SeqCst)
}
/// Fetches the process's current exit code. This defaults to 0 and can change
/// by calling `set_exit_status`.
pub fn get_exit_status() -> int {
EXIT_STATUS.load(SeqCst)
EXIT_STATUS.load(Ordering::SeqCst)
}
#[cfg(target_os = "macos")]

View File

@ -69,9 +69,9 @@ use iter::IteratorExt;
use option::Option;
use option::Option::{None, Some};
use str;
use str::{CowString, MaybeOwned, Str, StrExt};
use string::String;
use slice::{AsSlice, SliceExt};
use str::StrExt;
use string::{String, CowString};
use slice::SliceExt;
use vec::Vec;
/// Typedef for POSIX file paths.
@ -896,20 +896,6 @@ impl BytesContainer for CString {
}
}
#[allow(deprecated)]
impl<'a> BytesContainer for str::MaybeOwned<'a> {
#[inline]
fn container_as_bytes<'b>(&'b self) -> &'b [u8] {
self.as_slice().as_bytes()
}
#[inline]
fn container_as_str<'b>(&'b self) -> Option<&'b str> {
Some(self.as_slice())
}
#[inline]
fn is_str(_: Option<&str::MaybeOwned>) -> bool { true }
}
impl<'a, Sized? T: BytesContainer> BytesContainer for &'a T {
#[inline]
fn container_as_bytes(&self) -> &[u8] {

View File

@ -421,7 +421,7 @@ pub fn sample<T, I: Iterator<Item=T>, R: Rng>(rng: &mut R,
mod test {
use prelude::v1::*;
use super::{Rng, thread_rng, random, SeedableRng, StdRng, sample};
use iter::order;
use iter::{order, repeat};
struct ConstRng { i: u64 }
impl Rng for ConstRng {
@ -439,7 +439,7 @@ mod test {
let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
80, 81, 82, 83, 84, 85, 86, 87];
for &n in lengths.iter() {
let mut v = Vec::from_elem(n, 0u8);
let mut v = repeat(0u8).take(n).collect::<Vec<_>>();
r.fill_bytes(v.as_mut_slice());
// use this to get nicer error messages.

View File

@ -93,12 +93,12 @@ mod imp {
target_arch = "arm",
target_arch = "aarch64")))]
fn is_getrandom_available() -> bool {
use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Relaxed};
use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
static GETRANDOM_CHECKED: AtomicBool = ATOMIC_BOOL_INIT;
static GETRANDOM_AVAILABLE: AtomicBool = ATOMIC_BOOL_INIT;
if !GETRANDOM_CHECKED.load(Relaxed) {
if !GETRANDOM_CHECKED.load(Ordering::Relaxed) {
let mut buf: [u8; 0] = [];
let result = getrandom(&mut buf);
let available = if result == -1 {
@ -107,11 +107,11 @@ mod imp {
} else {
true
};
GETRANDOM_AVAILABLE.store(available, Relaxed);
GETRANDOM_CHECKED.store(true, Relaxed);
GETRANDOM_AVAILABLE.store(available, Ordering::Relaxed);
GETRANDOM_CHECKED.store(true, Ordering::Relaxed);
available
} else {
GETRANDOM_AVAILABLE.load(Relaxed)
GETRANDOM_AVAILABLE.load(Ordering::Relaxed)
}
}

View File

@ -15,7 +15,7 @@
use prelude::v1::*;
use os;
use sync::atomic;
use sync::atomic::{mod, Ordering};
pub use sys::backtrace::write;
@ -23,7 +23,7 @@ pub use sys::backtrace::write;
// whether the magical environment variable is present to see if it's turned on.
pub fn log_enabled() -> bool {
static ENABLED: atomic::AtomicInt = atomic::ATOMIC_INT_INIT;
match ENABLED.load(atomic::SeqCst) {
match ENABLED.load(Ordering::SeqCst) {
1 => return false,
2 => return true,
_ => {}
@ -33,7 +33,7 @@ pub fn log_enabled() -> bool {
Some(..) => 2,
None => 1,
};
ENABLED.store(val, atomic::SeqCst);
ENABLED.store(val, Ordering::SeqCst);
val == 2
}

View File

@ -67,7 +67,7 @@ use fmt;
use intrinsics;
use libc::c_void;
use mem;
use sync::atomic;
use sync::atomic::{mod, Ordering};
use sync::{Once, ONCE_INIT};
use rt::libunwind as uw;
@ -543,11 +543,11 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
// callback. Additionally, CALLBACK_CNT may briefly be higher than
// MAX_CALLBACKS, so we're sure to clamp it as necessary.
let callbacks = {
let amt = CALLBACK_CNT.load(atomic::SeqCst);
let amt = CALLBACK_CNT.load(Ordering::SeqCst);
CALLBACKS[..cmp::min(amt, MAX_CALLBACKS)]
};
for cb in callbacks.iter() {
match cb.load(atomic::SeqCst) {
match cb.load(Ordering::SeqCst) {
0 => {}
n => {
let f: Callback = unsafe { mem::transmute(n) };
@ -584,18 +584,18 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
/// currently possible to unregister a callback once it has been registered.
#[experimental]
pub unsafe fn register(f: Callback) -> bool {
match CALLBACK_CNT.fetch_add(1, atomic::SeqCst) {
match CALLBACK_CNT.fetch_add(1, Ordering::SeqCst) {
// The invocation code has knowledge of this window where the count has
// been incremented, but the callback has not been stored. We're
// guaranteed that the slot we're storing into is 0.
n if n < MAX_CALLBACKS => {
let prev = CALLBACKS[n].swap(mem::transmute(f), atomic::SeqCst);
let prev = CALLBACKS[n].swap(mem::transmute(f), Ordering::SeqCst);
rtassert!(prev == 0);
true
}
// If we accidentally bumped the count too high, pull it back.
_ => {
CALLBACK_CNT.store(MAX_CALLBACKS, atomic::SeqCst);
CALLBACK_CNT.store(MAX_CALLBACKS, Ordering::SeqCst);
false
}
}

View File

@ -19,7 +19,7 @@ use libc::{self, uintptr_t};
use os;
use slice;
use str;
use sync::atomic;
use sync::atomic::{mod, Ordering};
/// Dynamically inquire about whether we're running under V.
/// You should usually not use this unless your test definitely
@ -47,7 +47,7 @@ pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
pub fn min_stack() -> uint {
static MIN: atomic::AtomicUint = atomic::ATOMIC_UINT_INIT;
match MIN.load(atomic::SeqCst) {
match MIN.load(Ordering::SeqCst) {
0 => {}
n => return n - 1,
}
@ -55,7 +55,7 @@ pub fn min_stack() -> uint {
let amt = amt.unwrap_or(2 * 1024 * 1024);
// 0 is our sentinel value, so ensure that we'll never see 0 after
// initialization has run
MIN.store(amt + 1, atomic::SeqCst);
MIN.store(amt + 1, Ordering::SeqCst);
return amt;
}

View File

@ -1,227 +0,0 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Atomic types
//!
//! Atomic types provide primitive shared-memory communication between
//! threads, and are the building blocks of other concurrent
//! types.
//!
//! This module defines atomic versions of a select number of primitive
//! types, including `AtomicBool`, `AtomicInt`, `AtomicUint`, and `AtomicOption`.
//! Atomic types present operations that, when used correctly, synchronize
//! updates between threads.
//!
//! Each method takes an `Ordering` which represents the strength of
//! the memory barrier for that operation. These orderings are the
//! same as [C++11 atomic orderings][1].
//!
//! [1]: http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
//!
//! Atomic variables are safe to share between threads (they implement `Sync`)
//! but they do not themselves provide the mechanism for sharing. The most
//! common way to share an atomic variable is to put it into an `Arc` (an
//! atomically-reference-counted shared pointer).
//!
//! Most atomic types may be stored in static variables, initialized using
//! the provided static initializers like `INIT_ATOMIC_BOOL`. Atomic statics
//! are often used for lazy global initialization.
//!
//!
//! # Examples
//!
//! A simple spinlock:
//!
//! ```
//! use std::sync::Arc;
//! use std::sync::atomic::{AtomicUint, SeqCst};
//! use std::thread::Thread;
//!
//! fn main() {
//! let spinlock = Arc::new(AtomicUint::new(1));
//!
//! let spinlock_clone = spinlock.clone();
//! Thread::spawn(move|| {
//! spinlock_clone.store(0, SeqCst);
//! }).detach();
//!
//! // Wait for the other task to release the lock
//! while spinlock.load(SeqCst) != 0 {}
//! }
//! ```
//!
//! Transferring a heap object with `AtomicOption`:
//!
//! ```
//! use std::sync::Arc;
//! use std::sync::atomic::{AtomicOption, SeqCst};
//! use std::thread::Thread;
//!
//! fn main() {
//! struct BigObject;
//!
//! let shared_big_object = Arc::new(AtomicOption::empty());
//!
//! let shared_big_object_clone = shared_big_object.clone();
//! Thread::spawn(move|| {
//! let unwrapped_big_object = shared_big_object_clone.take(SeqCst);
//! if unwrapped_big_object.is_some() {
//! println!("got a big object from another task");
//! } else {
//! println!("other task hasn't sent big object yet");
//! }
//! }).detach();
//!
//! shared_big_object.swap(box BigObject, SeqCst);
//! }
//! ```
//!
//! Keep a global count of live tasks:
//!
//! ```
//! use std::sync::atomic::{AtomicUint, SeqCst, ATOMIC_UINT_INIT};
//!
//! static GLOBAL_TASK_COUNT: AtomicUint = ATOMIC_UINT_INIT;
//!
//! let old_task_count = GLOBAL_TASK_COUNT.fetch_add(1, SeqCst);
//! println!("live tasks: {}", old_task_count + 1);
//! ```
#![stable]
use alloc::boxed::Box;
use core::mem;
use core::prelude::{Send, Drop, None, Option, Some};
pub use core::atomic::{AtomicBool, AtomicInt, AtomicUint, AtomicPtr};
pub use core::atomic::{INIT_ATOMIC_BOOL, INIT_ATOMIC_INT, INIT_ATOMIC_UINT};
pub use core::atomic::{ATOMIC_BOOL_INIT, ATOMIC_INT_INIT, ATOMIC_UINT_INIT};
pub use core::atomic::fence;
pub use core::atomic::Ordering::{self, Relaxed, Release, Acquire, AcqRel, SeqCst};
/// An atomic, nullable unique pointer
///
/// This can be used as the concurrency primitive for operations that transfer
/// owned heap objects across tasks.
#[unsafe_no_drop_flag]
#[deprecated = "no longer used; will eventually be replaced by a higher-level\
concept like MVar"]
pub struct AtomicOption<T> {
p: AtomicUint,
}
#[allow(deprecated)]
impl<T: Send> AtomicOption<T> {
/// Create a new `AtomicOption`
pub fn new(p: Box<T>) -> AtomicOption<T> {
unsafe { AtomicOption { p: AtomicUint::new(mem::transmute(p)) } }
}
/// Create a new `AtomicOption` that doesn't contain a value
pub fn empty() -> AtomicOption<T> { AtomicOption { p: AtomicUint::new(0) } }
/// Store a value, returning the old value
#[inline]
pub fn swap(&self, val: Box<T>, order: Ordering) -> Option<Box<T>> {
let val = unsafe { mem::transmute(val) };
match self.p.swap(val, order) {
0 => None,
n => Some(unsafe { mem::transmute(n) }),
}
}
/// Remove the value, leaving the `AtomicOption` empty.
#[inline]
pub fn take(&self, order: Ordering) -> Option<Box<T>> {
unsafe { self.swap(mem::transmute(0u), order) }
}
/// Replace an empty value with a non-empty value.
///
/// Succeeds if the option is `None` and returns `None` if so. If
/// the option was already `Some`, returns `Some` of the rejected
/// value.
#[inline]
pub fn fill(&self, val: Box<T>, order: Ordering) -> Option<Box<T>> {
unsafe {
let val = mem::transmute(val);
let expected = mem::transmute(0u);
let oldval = self.p.compare_and_swap(expected, val, order);
if oldval == expected {
None
} else {
Some(mem::transmute(val))
}
}
}
/// Returns `true` if the `AtomicOption` is empty.
///
/// Be careful: The caller must have some external method of ensuring the
/// result does not get invalidated by another task after this returns.
#[inline]
pub fn is_empty(&self, order: Ordering) -> bool {
self.p.load(order) as uint == 0
}
}
#[unsafe_destructor]
impl<T: Send> Drop for AtomicOption<T> {
fn drop(&mut self) {
let _ = self.take(SeqCst);
}
}
#[cfg(test)]
mod test {
use prelude::v1::*;
use super::*;
#[test]
fn option_empty() {
let option: AtomicOption<()> = AtomicOption::empty();
assert!(option.is_empty(SeqCst));
}
#[test]
fn option_swap() {
let p = AtomicOption::new(box 1i);
let a = box 2i;
let b = p.swap(a, SeqCst);
assert!(b == Some(box 1));
assert!(p.take(SeqCst) == Some(box 2));
}
#[test]
fn option_take() {
let p = AtomicOption::new(box 1i);
assert!(p.take(SeqCst) == Some(box 1));
assert!(p.take(SeqCst) == None);
let p2 = box 2i;
p.swap(p2, SeqCst);
assert!(p.take(SeqCst) == Some(box 2));
}
#[test]
fn option_fill() {
let p = AtomicOption::new(box 1i);
assert!(p.fill(box 2i, SeqCst).is_some()); // should fail; shouldn't leak!
assert!(p.take(SeqCst) == Some(box 1));
assert!(p.fill(box 2i, SeqCst).is_none()); // shouldn't fail
assert!(p.take(SeqCst) == Some(box 2));
}
}

View File

@ -10,7 +10,7 @@
use prelude::v1::*;
use sync::atomic::{self, AtomicUint};
use sync::atomic::{AtomicUint, Ordering, ATOMIC_UINT_INIT};
use sync::poison::{self, LockResult};
use sys_common::condvar as sys;
use sys_common::mutex as sys_mutex;
@ -88,7 +88,7 @@ unsafe impl Sync for StaticCondvar {}
#[unstable = "may be merged with Condvar in the future"]
pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
inner: sys::CONDVAR_INIT,
mutex: atomic::ATOMIC_UINT_INIT,
mutex: ATOMIC_UINT_INIT,
};
impl Condvar {
@ -260,7 +260,7 @@ impl StaticCondvar {
fn verify(&self, mutex: &sys_mutex::Mutex) {
let addr = mutex as *const _ as uint;
match self.mutex.compare_and_swap(0, addr, atomic::SeqCst) {
match self.mutex.compare_and_swap(0, addr, Ordering::SeqCst) {
// If we got out 0, then we have successfully bound the mutex to
// this cvar.
0 => {}

View File

@ -65,10 +65,6 @@ impl<A> Future<A> {
}
}
/// Deprecated, use into_inner() instead
#[deprecated = "renamed to into_inner()"]
pub fn unwrap(self) -> A { self.into_inner() }
pub fn get_ref<'a>(&'a mut self) -> &'a A {
/*!
* Executes the future's closure and then returns a reference

View File

@ -18,6 +18,7 @@
#![experimental]
pub use alloc::arc::{Arc, Weak};
pub use core::atomic;
pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
pub use self::mutex::MUTEX_INIT;
@ -32,7 +33,6 @@ pub use self::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
pub use self::future::Future;
pub use self::task_pool::TaskPool;
pub mod atomic;
pub mod mpsc;
mod barrier;

View File

@ -48,7 +48,7 @@ use alloc::boxed::Box;
use core::mem;
use core::cell::UnsafeCell;
use sync::atomic::{AtomicPtr, Release, Acquire, AcqRel, Relaxed};
use sync::atomic::{AtomicPtr, Ordering};
/// A result of the `pop` function.
pub enum PopResult<T> {
@ -103,8 +103,8 @@ impl<T: Send> Queue<T> {
pub fn push(&self, t: T) {
unsafe {
let n = Node::new(Some(t));
let prev = self.head.swap(n, AcqRel);
(*prev).next.store(n, Release);
let prev = self.head.swap(n, Ordering::AcqRel);
(*prev).next.store(n, Ordering::Release);
}
}
@ -121,7 +121,7 @@ impl<T: Send> Queue<T> {
pub fn pop(&self) -> PopResult<T> {
unsafe {
let tail = *self.tail.get();
let next = (*tail).next.load(Acquire);
let next = (*tail).next.load(Ordering::Acquire);
if !next.is_null() {
*self.tail.get() = next;
@ -132,7 +132,7 @@ impl<T: Send> Queue<T> {
return Data(ret);
}
if self.head.load(Acquire) == tail {Empty} else {Inconsistent}
if self.head.load(Ordering::Acquire) == tail {Empty} else {Inconsistent}
}
}
}
@ -143,7 +143,7 @@ impl<T: Send> Drop for Queue<T> {
unsafe {
let mut cur = *self.tail.get();
while !cur.is_null() {
let next = (*cur).next.load(Relaxed);
let next = (*cur).next.load(Ordering::Relaxed);
let _: Box<Node<T>> = mem::transmute(cur);
cur = next;
}

View File

@ -42,7 +42,7 @@ use core::prelude::*;
use sync::mpsc::Receiver;
use sync::mpsc::blocking::{self, SignalToken};
use core::mem;
use sync::atomic;
use sync::atomic::{AtomicUint, Ordering};
// Various states you can find a port in.
const EMPTY: uint = 0; // initial state: no data, no blocked reciever
@ -56,7 +56,7 @@ const DISCONNECTED: uint = 2; // channel is disconnected OR upgraded
pub struct Packet<T> {
// Internal state of the chan/port pair (stores the blocked task as well)
state: atomic::AtomicUint,
state: AtomicUint,
// One-shot data slot location
data: Option<T>,
// when used for the second time, a oneshot channel must be upgraded, and
@ -93,7 +93,7 @@ impl<T: Send> Packet<T> {
Packet {
data: None,
upgrade: NothingSent,
state: atomic::AtomicUint::new(EMPTY),
state: AtomicUint::new(EMPTY),
}
}
@ -107,7 +107,7 @@ impl<T: Send> Packet<T> {
self.data = Some(t);
self.upgrade = SendUsed;
match self.state.swap(DATA, atomic::SeqCst) {
match self.state.swap(DATA, Ordering::SeqCst) {
// Sent the data, no one was waiting
EMPTY => Ok(()),
@ -141,14 +141,14 @@ impl<T: Send> Packet<T> {
pub fn recv(&mut self) -> Result<T, Failure<T>> {
// Attempt to not block the task (it's a little expensive). If it looks
// like we're not empty, then immediately go through to `try_recv`.
if self.state.load(atomic::SeqCst) == EMPTY {
if self.state.load(Ordering::SeqCst) == EMPTY {
let (wait_token, signal_token) = blocking::tokens();
let ptr = unsafe { signal_token.cast_to_uint() };
// race with senders to enter the blocking state
if self.state.compare_and_swap(EMPTY, ptr, atomic::SeqCst) == EMPTY {
if self.state.compare_and_swap(EMPTY, ptr, Ordering::SeqCst) == EMPTY {
wait_token.wait();
debug_assert!(self.state.load(atomic::SeqCst) != EMPTY);
debug_assert!(self.state.load(Ordering::SeqCst) != EMPTY);
} else {
// drop the signal token, since we never blocked
drop(unsafe { SignalToken::cast_from_uint(ptr) });
@ -159,7 +159,7 @@ impl<T: Send> Packet<T> {
}
pub fn try_recv(&mut self) -> Result<T, Failure<T>> {
match self.state.load(atomic::SeqCst) {
match self.state.load(Ordering::SeqCst) {
EMPTY => Err(Empty),
// We saw some data on the channel, but the channel can be used
@ -169,7 +169,7 @@ impl<T: Send> Packet<T> {
// the state changes under our feet we'd rather just see that state
// change.
DATA => {
self.state.compare_and_swap(DATA, EMPTY, atomic::SeqCst);
self.state.compare_and_swap(DATA, EMPTY, Ordering::SeqCst);
match self.data.take() {
Some(data) => Ok(data),
None => unreachable!(),
@ -209,7 +209,7 @@ impl<T: Send> Packet<T> {
};
self.upgrade = GoUp(up);
match self.state.swap(DISCONNECTED, atomic::SeqCst) {
match self.state.swap(DISCONNECTED, Ordering::SeqCst) {
// If the channel is empty or has data on it, then we're good to go.
// Senders will check the data before the upgrade (in case we
// plastered over the DATA state).
@ -225,7 +225,7 @@ impl<T: Send> Packet<T> {
}
pub fn drop_chan(&mut self) {
match self.state.swap(DISCONNECTED, atomic::SeqCst) {
match self.state.swap(DISCONNECTED, Ordering::SeqCst) {
DATA | DISCONNECTED | EMPTY => {}
// If someone's waiting, we gotta wake them up
@ -236,7 +236,7 @@ impl<T: Send> Packet<T> {
}
pub fn drop_port(&mut self) {
match self.state.swap(DISCONNECTED, atomic::SeqCst) {
match self.state.swap(DISCONNECTED, Ordering::SeqCst) {
// An empty channel has nothing to do, and a remotely disconnected
// channel also has nothing to do b/c we're about to run the drop
// glue
@ -259,7 +259,7 @@ impl<T: Send> Packet<T> {
// If Ok, the value is whether this port has data, if Err, then the upgraded
// port needs to be checked instead of this one.
pub fn can_recv(&mut self) -> Result<bool, Receiver<T>> {
match self.state.load(atomic::SeqCst) {
match self.state.load(Ordering::SeqCst) {
EMPTY => Ok(false), // Welp, we tried
DATA => Ok(true), // we have some un-acquired data
DISCONNECTED if self.data.is_some() => Ok(true), // we have data
@ -284,7 +284,7 @@ impl<T: Send> Packet<T> {
// because there is data, or fail because there is an upgrade pending.
pub fn start_selection(&mut self, token: SignalToken) -> SelectionResult<T> {
let ptr = unsafe { token.cast_to_uint() };
match self.state.compare_and_swap(EMPTY, ptr, atomic::SeqCst) {
match self.state.compare_and_swap(EMPTY, ptr, Ordering::SeqCst) {
EMPTY => SelSuccess,
DATA => {
drop(unsafe { SignalToken::cast_from_uint(ptr) });
@ -322,7 +322,7 @@ impl<T: Send> Packet<T> {
//
// The return value indicates whether there's data on this port.
pub fn abort_selection(&mut self) -> Result<bool, Receiver<T>> {
let state = match self.state.load(atomic::SeqCst) {
let state = match self.state.load(Ordering::SeqCst) {
// Each of these states means that no further activity will happen
// with regard to abortion selection
s @ EMPTY |
@ -331,7 +331,7 @@ impl<T: Send> Packet<T> {
// If we've got a blocked task, then use an atomic to gain ownership
// of it (may fail)
ptr => self.state.compare_and_swap(ptr, EMPTY, atomic::SeqCst)
ptr => self.state.compare_and_swap(ptr, EMPTY, Ordering::SeqCst)
};
// Now that we've got ownership of our state, figure out what to do
@ -370,6 +370,6 @@ impl<T: Send> Packet<T> {
#[unsafe_destructor]
impl<T: Send> Drop for Packet<T> {
fn drop(&mut self) {
assert_eq!(self.state.load(atomic::SeqCst), DISCONNECTED);
assert_eq!(self.state.load(Ordering::SeqCst), DISCONNECTED);
}
}

View File

@ -25,11 +25,12 @@ use core::prelude::*;
use core::cmp;
use core::int;
use sync::{atomic, Mutex, MutexGuard};
use sync::mpsc::mpsc_queue as mpsc;
use sync::atomic::{AtomicUint, AtomicInt, AtomicBool, Ordering};
use sync::mpsc::blocking::{self, SignalToken};
use sync::mpsc::select::StartResult;
use sync::mpsc::mpsc_queue as mpsc;
use sync::mpsc::select::StartResult::*;
use sync::mpsc::select::StartResult;
use sync::{Mutex, MutexGuard};
use thread::Thread;
const DISCONNECTED: int = int::MIN;
@ -41,17 +42,17 @@ const MAX_STEALS: int = 1 << 20;
pub struct Packet<T> {
queue: mpsc::Queue<T>,
cnt: atomic::AtomicInt, // How many items are on this channel
cnt: AtomicInt, // How many items are on this channel
steals: int, // How many times has a port received without blocking?
to_wake: atomic::AtomicUint, // SignalToken for wake up
to_wake: AtomicUint, // SignalToken for wake up
// The number of channels which are currently using this packet.
channels: atomic::AtomicInt,
channels: AtomicInt,
// See the discussion in Port::drop and the channel send methods for what
// these are used for
port_dropped: atomic::AtomicBool,
sender_drain: atomic::AtomicInt,
port_dropped: AtomicBool,
sender_drain: AtomicInt,
// this lock protects various portions of this implementation during
// select()
@ -69,12 +70,12 @@ impl<T: Send> Packet<T> {
pub fn new() -> Packet<T> {
let p = Packet {
queue: mpsc::Queue::new(),
cnt: atomic::AtomicInt::new(0),
cnt: AtomicInt::new(0),
steals: 0,
to_wake: atomic::AtomicUint::new(0),
channels: atomic::AtomicInt::new(2),
port_dropped: atomic::AtomicBool::new(false),
sender_drain: atomic::AtomicInt::new(0),
to_wake: AtomicUint::new(0),
channels: AtomicInt::new(2),
port_dropped: AtomicBool::new(false),
sender_drain: AtomicInt::new(0),
select_lock: Mutex::new(()),
};
return p;
@ -98,10 +99,10 @@ impl<T: Send> Packet<T> {
token: Option<SignalToken>,
guard: MutexGuard<()>) {
token.map(|token| {
assert_eq!(self.cnt.load(atomic::SeqCst), 0);
assert_eq!(self.to_wake.load(atomic::SeqCst), 0);
self.to_wake.store(unsafe { token.cast_to_uint() }, atomic::SeqCst);
self.cnt.store(-1, atomic::SeqCst);
assert_eq!(self.cnt.load(Ordering::SeqCst), 0);
assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
self.to_wake.store(unsafe { token.cast_to_uint() }, Ordering::SeqCst);
self.cnt.store(-1, Ordering::SeqCst);
// This store is a little sketchy. What's happening here is that
// we're transferring a blocker from a oneshot or stream channel to
@ -134,7 +135,7 @@ impl<T: Send> Packet<T> {
pub fn send(&mut self, t: T) -> Result<(), T> {
// See Port::drop for what's going on
if self.port_dropped.load(atomic::SeqCst) { return Err(t) }
if self.port_dropped.load(Ordering::SeqCst) { return Err(t) }
// Note that the multiple sender case is a little trickier
// semantically than the single sender case. The logic for
@ -161,12 +162,12 @@ impl<T: Send> Packet<T> {
// preflight check serves as the definitive "this will never be
// received". Once we get beyond this check, we have permanently
// entered the realm of "this may be received"
if self.cnt.load(atomic::SeqCst) < DISCONNECTED + FUDGE {
if self.cnt.load(Ordering::SeqCst) < DISCONNECTED + FUDGE {
return Err(t)
}
self.queue.push(t);
match self.cnt.fetch_add(1, atomic::SeqCst) {
match self.cnt.fetch_add(1, Ordering::SeqCst) {
-1 => {
self.take_to_wake().signal();
}
@ -183,9 +184,9 @@ impl<T: Send> Packet<T> {
n if n < DISCONNECTED + FUDGE => {
// see the comment in 'try' for a shared channel for why this
// window of "not disconnected" is ok.
self.cnt.store(DISCONNECTED, atomic::SeqCst);
self.cnt.store(DISCONNECTED, Ordering::SeqCst);
if self.sender_drain.fetch_add(1, atomic::SeqCst) == 0 {
if self.sender_drain.fetch_add(1, Ordering::SeqCst) == 0 {
loop {
// drain the queue, for info on the thread yield see the
// discussion in try_recv
@ -198,7 +199,7 @@ impl<T: Send> Packet<T> {
}
// maybe we're done, if we're not the last ones
// here, then we need to go try again.
if self.sender_drain.fetch_sub(1, atomic::SeqCst) == 1 {
if self.sender_drain.fetch_sub(1, Ordering::SeqCst) == 1 {
break
}
}
@ -239,15 +240,15 @@ impl<T: Send> Packet<T> {
// Essentially the exact same thing as the stream decrement function.
// Returns true if blocking should proceed.
fn decrement(&mut self, token: SignalToken) -> StartResult {
assert_eq!(self.to_wake.load(atomic::SeqCst), 0);
assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
let ptr = unsafe { token.cast_to_uint() };
self.to_wake.store(ptr, atomic::SeqCst);
self.to_wake.store(ptr, Ordering::SeqCst);
let steals = self.steals;
self.steals = 0;
match self.cnt.fetch_sub(1 + steals, atomic::SeqCst) {
DISCONNECTED => { self.cnt.store(DISCONNECTED, atomic::SeqCst); }
match self.cnt.fetch_sub(1 + steals, Ordering::SeqCst) {
DISCONNECTED => { self.cnt.store(DISCONNECTED, Ordering::SeqCst); }
// If we factor in our steals and notice that the channel has no
// data, we successfully sleep
n => {
@ -256,7 +257,7 @@ impl<T: Send> Packet<T> {
}
}
self.to_wake.store(0, atomic::SeqCst);
self.to_wake.store(0, Ordering::SeqCst);
drop(unsafe { SignalToken::cast_from_uint(ptr) });
Abort
}
@ -297,9 +298,9 @@ impl<T: Send> Packet<T> {
// might decrement steals.
Some(data) => {
if self.steals > MAX_STEALS {
match self.cnt.swap(0, atomic::SeqCst) {
match self.cnt.swap(0, Ordering::SeqCst) {
DISCONNECTED => {
self.cnt.store(DISCONNECTED, atomic::SeqCst);
self.cnt.store(DISCONNECTED, Ordering::SeqCst);
}
n => {
let m = cmp::min(n, self.steals);
@ -316,7 +317,7 @@ impl<T: Send> Packet<T> {
// See the discussion in the stream implementation for why we try
// again.
None => {
match self.cnt.load(atomic::SeqCst) {
match self.cnt.load(Ordering::SeqCst) {
n if n != DISCONNECTED => Err(Empty),
_ => {
match self.queue.pop() {
@ -334,20 +335,20 @@ impl<T: Send> Packet<T> {
// Prepares this shared packet for a channel clone, essentially just bumping
// a refcount.
pub fn clone_chan(&mut self) {
self.channels.fetch_add(1, atomic::SeqCst);
self.channels.fetch_add(1, Ordering::SeqCst);
}
// Decrement the reference count on a channel. This is called whenever a
// Chan is dropped and may end up waking up a receiver. It's the receiver's
// responsibility on the other end to figure out that we've disconnected.
pub fn drop_chan(&mut self) {
match self.channels.fetch_sub(1, atomic::SeqCst) {
match self.channels.fetch_sub(1, Ordering::SeqCst) {
1 => {}
n if n > 1 => return,
n => panic!("bad number of channels left {}", n),
}
match self.cnt.swap(DISCONNECTED, atomic::SeqCst) {
match self.cnt.swap(DISCONNECTED, Ordering::SeqCst) {
-1 => { self.take_to_wake().signal(); }
DISCONNECTED => {}
n => { assert!(n >= 0); }
@ -357,10 +358,10 @@ impl<T: Send> Packet<T> {
// See the long discussion inside of stream.rs for why the queue is drained,
// and why it is done in this fashion.
pub fn drop_port(&mut self) {
self.port_dropped.store(true, atomic::SeqCst);
self.port_dropped.store(true, Ordering::SeqCst);
let mut steals = self.steals;
while {
let cnt = self.cnt.compare_and_swap(steals, DISCONNECTED, atomic::SeqCst);
let cnt = self.cnt.compare_and_swap(steals, DISCONNECTED, Ordering::SeqCst);
cnt != DISCONNECTED && cnt != steals
} {
// See the discussion in 'try_recv' for why we yield
@ -376,8 +377,8 @@ impl<T: Send> Packet<T> {
// Consumes ownership of the 'to_wake' field.
fn take_to_wake(&mut self) -> SignalToken {
let ptr = self.to_wake.load(atomic::SeqCst);
self.to_wake.store(0, atomic::SeqCst);
let ptr = self.to_wake.load(Ordering::SeqCst);
self.to_wake.store(0, Ordering::SeqCst);
assert!(ptr != 0);
unsafe { SignalToken::cast_from_uint(ptr) }
}
@ -392,15 +393,15 @@ impl<T: Send> Packet<T> {
// This is different than the stream version because there's no need to peek
// at the queue, we can just look at the local count.
pub fn can_recv(&mut self) -> bool {
let cnt = self.cnt.load(atomic::SeqCst);
let cnt = self.cnt.load(Ordering::SeqCst);
cnt == DISCONNECTED || cnt - self.steals > 0
}
// increment the count on the channel (used for selection)
fn bump(&mut self, amt: int) -> int {
match self.cnt.fetch_add(amt, atomic::SeqCst) {
match self.cnt.fetch_add(amt, Ordering::SeqCst) {
DISCONNECTED => {
self.cnt.store(DISCONNECTED, atomic::SeqCst);
self.cnt.store(DISCONNECTED, Ordering::SeqCst);
DISCONNECTED
}
n => n
@ -444,13 +445,13 @@ impl<T: Send> Packet<T> {
// the channel count and figure out what we should do to make it
// positive.
let steals = {
let cnt = self.cnt.load(atomic::SeqCst);
let cnt = self.cnt.load(Ordering::SeqCst);
if cnt < 0 && cnt != DISCONNECTED {-cnt} else {0}
};
let prev = self.bump(steals + 1);
if prev == DISCONNECTED {
assert_eq!(self.to_wake.load(atomic::SeqCst), 0);
assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
true
} else {
let cur = prev + steals + 1;
@ -458,7 +459,7 @@ impl<T: Send> Packet<T> {
if prev < 0 {
drop(self.take_to_wake());
} else {
while self.to_wake.load(atomic::SeqCst) != 0 {
while self.to_wake.load(Ordering::SeqCst) != 0 {
Thread::yield_now();
}
}
@ -479,8 +480,8 @@ impl<T: Send> Drop for Packet<T> {
// disconnection, but also a proper fence before the read of
// `to_wake`, so this assert cannot be removed with also removing
// the `to_wake` assert.
assert_eq!(self.cnt.load(atomic::SeqCst), DISCONNECTED);
assert_eq!(self.to_wake.load(atomic::SeqCst), 0);
assert_eq!(self.channels.load(atomic::SeqCst), 0);
assert_eq!(self.cnt.load(Ordering::SeqCst), DISCONNECTED);
assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
assert_eq!(self.channels.load(Ordering::SeqCst), 0);
}
}

View File

@ -41,7 +41,7 @@ use alloc::boxed::Box;
use core::mem;
use core::cell::UnsafeCell;
use sync::atomic::{AtomicPtr, Relaxed, AtomicUint, Acquire, Release};
use sync::atomic::{AtomicPtr, AtomicUint, Ordering};
// Node within the linked list queue of messages to send
struct Node<T> {
@ -109,7 +109,7 @@ impl<T: Send> Queue<T> {
pub unsafe fn new(bound: uint) -> Queue<T> {
let n1 = Node::new();
let n2 = Node::new();
(*n1).next.store(n2, Relaxed);
(*n1).next.store(n2, Ordering::Relaxed);
Queue {
tail: UnsafeCell::new(n2),
tail_prev: AtomicPtr::new(n1),
@ -131,8 +131,8 @@ impl<T: Send> Queue<T> {
let n = self.alloc();
assert!((*n).value.is_none());
(*n).value = Some(t);
(*n).next.store(0 as *mut Node<T>, Relaxed);
(**self.head.get()).next.store(n, Release);
(*n).next.store(0 as *mut Node<T>, Ordering::Relaxed);
(**self.head.get()).next.store(n, Ordering::Release);
*self.head.get() = n;
}
}
@ -144,23 +144,23 @@ impl<T: Send> Queue<T> {
// only one subtracting from the cache).
if *self.first.get() != *self.tail_copy.get() {
if self.cache_bound > 0 {
let b = self.cache_subtractions.load(Relaxed);
self.cache_subtractions.store(b + 1, Relaxed);
let b = self.cache_subtractions.load(Ordering::Relaxed);
self.cache_subtractions.store(b + 1, Ordering::Relaxed);
}
let ret = *self.first.get();
*self.first.get() = (*ret).next.load(Relaxed);
*self.first.get() = (*ret).next.load(Ordering::Relaxed);
return ret;
}
// If the above fails, then update our copy of the tail and try
// again.
*self.tail_copy.get() = self.tail_prev.load(Acquire);
*self.tail_copy.get() = self.tail_prev.load(Ordering::Acquire);
if *self.first.get() != *self.tail_copy.get() {
if self.cache_bound > 0 {
let b = self.cache_subtractions.load(Relaxed);
self.cache_subtractions.store(b + 1, Relaxed);
let b = self.cache_subtractions.load(Ordering::Relaxed);
self.cache_subtractions.store(b + 1, Ordering::Relaxed);
}
let ret = *self.first.get();
*self.first.get() = (*ret).next.load(Relaxed);
*self.first.get() = (*ret).next.load(Ordering::Relaxed);
return ret;
}
// If all of that fails, then we have to allocate a new node
@ -177,25 +177,26 @@ impl<T: Send> Queue<T> {
// tail's next field and see if we can use it. If we do a pop, then
// the current tail node is a candidate for going into the cache.
let tail = *self.tail.get();
let next = (*tail).next.load(Acquire);
let next = (*tail).next.load(Ordering::Acquire);
if next.is_null() { return None }
assert!((*next).value.is_some());
let ret = (*next).value.take();
*self.tail.get() = next;
if self.cache_bound == 0 {
self.tail_prev.store(tail, Release);
self.tail_prev.store(tail, Ordering::Release);
} else {
// FIXME: this is dubious with overflow.
let additions = self.cache_additions.load(Relaxed);
let subtractions = self.cache_subtractions.load(Relaxed);
let additions = self.cache_additions.load(Ordering::Relaxed);
let subtractions = self.cache_subtractions.load(Ordering::Relaxed);
let size = additions - subtractions;
if size < self.cache_bound {
self.tail_prev.store(tail, Release);
self.cache_additions.store(additions + 1, Relaxed);
self.tail_prev.store(tail, Ordering::Release);
self.cache_additions.store(additions + 1, Ordering::Relaxed);
} else {
(*self.tail_prev.load(Relaxed)).next.store(next, Relaxed);
(*self.tail_prev.load(Ordering::Relaxed))
.next.store(next, Ordering::Relaxed);
// We have successfully erased all references to 'tail', so
// now we can safely drop it.
let _: Box<Node<T>> = mem::transmute(tail);
@ -217,7 +218,7 @@ impl<T: Send> Queue<T> {
// stripped out.
unsafe {
let tail = *self.tail.get();
let next = (*tail).next.load(Acquire);
let next = (*tail).next.load(Ordering::Acquire);
if next.is_null() { return None }
return (*next).value.as_mut();
}
@ -230,7 +231,7 @@ impl<T: Send> Drop for Queue<T> {
unsafe {
let mut cur = *self.first.get();
while !cur.is_null() {
let next = (*cur).next.load(Relaxed);
let next = (*cur).next.load(Ordering::Relaxed);
let _n: Box<Node<T>> = mem::transmute(cur);
cur = next;
}

View File

@ -28,10 +28,10 @@ use core::cmp;
use core::int;
use thread::Thread;
use sync::atomic::{AtomicInt, AtomicUint, Ordering, AtomicBool};
use sync::mpsc::Receiver;
use sync::mpsc::blocking::{self, SignalToken};
use sync::mpsc::spsc_queue as spsc;
use sync::mpsc::Receiver;
use sync::atomic;
const DISCONNECTED: int = int::MIN;
#[cfg(test)]
@ -42,11 +42,11 @@ const MAX_STEALS: int = 1 << 20;
pub struct Packet<T> {
queue: spsc::Queue<Message<T>>, // internal queue for all message
cnt: atomic::AtomicInt, // How many items are on this channel
cnt: AtomicInt, // How many items are on this channel
steals: int, // How many times has a port received without blocking?
to_wake: atomic::AtomicUint, // SignalToken for the blocked thread to wake up
to_wake: AtomicUint, // SignalToken for the blocked thread to wake up
port_dropped: atomic::AtomicBool, // flag if the channel has been destroyed.
port_dropped: AtomicBool, // flag if the channel has been destroyed.
}
pub enum Failure<T> {
@ -79,11 +79,11 @@ impl<T: Send> Packet<T> {
Packet {
queue: unsafe { spsc::Queue::new(128) },
cnt: atomic::AtomicInt::new(0),
cnt: AtomicInt::new(0),
steals: 0,
to_wake: atomic::AtomicUint::new(0),
to_wake: AtomicUint::new(0),
port_dropped: atomic::AtomicBool::new(false),
port_dropped: AtomicBool::new(false),
}
}
@ -91,7 +91,7 @@ impl<T: Send> Packet<T> {
// If the other port has deterministically gone away, then definitely
// must return the data back up the stack. Otherwise, the data is
// considered as being sent.
if self.port_dropped.load(atomic::SeqCst) { return Err(t) }
if self.port_dropped.load(Ordering::SeqCst) { return Err(t) }
match self.do_send(Data(t)) {
UpSuccess | UpDisconnected => {},
@ -103,14 +103,14 @@ impl<T: Send> Packet<T> {
pub fn upgrade(&mut self, up: Receiver<T>) -> UpgradeResult {
// If the port has gone away, then there's no need to proceed any
// further.
if self.port_dropped.load(atomic::SeqCst) { return UpDisconnected }
if self.port_dropped.load(Ordering::SeqCst) { return UpDisconnected }
self.do_send(GoUp(up))
}
fn do_send(&mut self, t: Message<T>) -> UpgradeResult {
self.queue.push(t);
match self.cnt.fetch_add(1, atomic::SeqCst) {
match self.cnt.fetch_add(1, Ordering::SeqCst) {
// As described in the mod's doc comment, -1 == wakeup
-1 => UpWoke(self.take_to_wake()),
// As as described before, SPSC queues must be >= -2
@ -124,7 +124,7 @@ impl<T: Send> Packet<T> {
// will never remove this data. We can only have at most one item to
// drain (the port drains the rest).
DISCONNECTED => {
self.cnt.store(DISCONNECTED, atomic::SeqCst);
self.cnt.store(DISCONNECTED, Ordering::SeqCst);
let first = self.queue.pop();
let second = self.queue.pop();
assert!(second.is_none());
@ -143,8 +143,8 @@ impl<T: Send> Packet<T> {
// Consumes ownership of the 'to_wake' field.
fn take_to_wake(&mut self) -> SignalToken {
let ptr = self.to_wake.load(atomic::SeqCst);
self.to_wake.store(0, atomic::SeqCst);
let ptr = self.to_wake.load(Ordering::SeqCst);
self.to_wake.store(0, Ordering::SeqCst);
assert!(ptr != 0);
unsafe { SignalToken::cast_from_uint(ptr) }
}
@ -153,15 +153,15 @@ impl<T: Send> Packet<T> {
// back if it shouldn't sleep. Note that this is the location where we take
// steals into account.
fn decrement(&mut self, token: SignalToken) -> Result<(), SignalToken> {
assert_eq!(self.to_wake.load(atomic::SeqCst), 0);
assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
let ptr = unsafe { token.cast_to_uint() };
self.to_wake.store(ptr, atomic::SeqCst);
self.to_wake.store(ptr, Ordering::SeqCst);
let steals = self.steals;
self.steals = 0;
match self.cnt.fetch_sub(1 + steals, atomic::SeqCst) {
DISCONNECTED => { self.cnt.store(DISCONNECTED, atomic::SeqCst); }
match self.cnt.fetch_sub(1 + steals, Ordering::SeqCst) {
DISCONNECTED => { self.cnt.store(DISCONNECTED, Ordering::SeqCst); }
// If we factor in our steals and notice that the channel has no
// data, we successfully sleep
n => {
@ -170,7 +170,7 @@ impl<T: Send> Packet<T> {
}
}
self.to_wake.store(0, atomic::SeqCst);
self.to_wake.store(0, Ordering::SeqCst);
Err(unsafe { SignalToken::cast_from_uint(ptr) })
}
@ -217,9 +217,9 @@ impl<T: Send> Packet<T> {
// adding back in whatever we couldn't factor into steals.
Some(data) => {
if self.steals > MAX_STEALS {
match self.cnt.swap(0, atomic::SeqCst) {
match self.cnt.swap(0, Ordering::SeqCst) {
DISCONNECTED => {
self.cnt.store(DISCONNECTED, atomic::SeqCst);
self.cnt.store(DISCONNECTED, Ordering::SeqCst);
}
n => {
let m = cmp::min(n, self.steals);
@ -237,7 +237,7 @@ impl<T: Send> Packet<T> {
}
None => {
match self.cnt.load(atomic::SeqCst) {
match self.cnt.load(Ordering::SeqCst) {
n if n != DISCONNECTED => Err(Empty),
// This is a little bit of a tricky case. We failed to pop
@ -266,7 +266,7 @@ impl<T: Send> Packet<T> {
pub fn drop_chan(&mut self) {
// Dropping a channel is pretty simple, we just flag it as disconnected
// and then wakeup a blocker if there is one.
match self.cnt.swap(DISCONNECTED, atomic::SeqCst) {
match self.cnt.swap(DISCONNECTED, Ordering::SeqCst) {
-1 => { self.take_to_wake().signal(); }
DISCONNECTED => {}
n => { assert!(n >= 0); }
@ -293,7 +293,7 @@ impl<T: Send> Packet<T> {
// sends are gated on this flag, so we're immediately guaranteed that
// there are a bounded number of active sends that we'll have to deal
// with.
self.port_dropped.store(true, atomic::SeqCst);
self.port_dropped.store(true, Ordering::SeqCst);
// Now that we're guaranteed to deal with a bounded number of senders,
// we need to drain the queue. This draining process happens atomically
@ -306,7 +306,7 @@ impl<T: Send> Packet<T> {
let mut steals = self.steals;
while {
let cnt = self.cnt.compare_and_swap(
steals, DISCONNECTED, atomic::SeqCst);
steals, DISCONNECTED, Ordering::SeqCst);
cnt != DISCONNECTED && cnt != steals
} {
loop {
@ -351,9 +351,9 @@ impl<T: Send> Packet<T> {
// increment the count on the channel (used for selection)
fn bump(&mut self, amt: int) -> int {
match self.cnt.fetch_add(amt, atomic::SeqCst) {
match self.cnt.fetch_add(amt, Ordering::SeqCst) {
DISCONNECTED => {
self.cnt.store(DISCONNECTED, atomic::SeqCst);
self.cnt.store(DISCONNECTED, Ordering::SeqCst);
DISCONNECTED
}
n => n
@ -403,7 +403,7 @@ impl<T: Send> Packet<T> {
// of time until the data is actually sent.
if was_upgrade {
assert_eq!(self.steals, 0);
assert_eq!(self.to_wake.load(atomic::SeqCst), 0);
assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
return Ok(true)
}
@ -416,7 +416,7 @@ impl<T: Send> Packet<T> {
// If we were previously disconnected, then we know for sure that there
// is no task in to_wake, so just keep going
let has_data = if prev == DISCONNECTED {
assert_eq!(self.to_wake.load(atomic::SeqCst), 0);
assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
true // there is data, that data is that we're disconnected
} else {
let cur = prev + steals + 1;
@ -439,7 +439,7 @@ impl<T: Send> Packet<T> {
if prev < 0 {
drop(self.take_to_wake());
} else {
while self.to_wake.load(atomic::SeqCst) != 0 {
while self.to_wake.load(Ordering::SeqCst) != 0 {
Thread::yield_now();
}
}
@ -478,7 +478,7 @@ impl<T: Send> Drop for Packet<T> {
// disconnection, but also a proper fence before the read of
// `to_wake`, so this assert cannot be removed with also removing
// the `to_wake` assert.
assert_eq!(self.cnt.load(atomic::SeqCst), DISCONNECTED);
assert_eq!(self.to_wake.load(atomic::SeqCst), 0);
assert_eq!(self.cnt.load(Ordering::SeqCst), DISCONNECTED);
assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
}
}

View File

@ -41,14 +41,15 @@ use self::Blocker::*;
use vec::Vec;
use core::mem;
use sync::{atomic, Mutex, MutexGuard};
use sync::atomic::{Ordering, AtomicUint};
use sync::mpsc::blocking::{self, WaitToken, SignalToken};
use sync::mpsc::select::StartResult::{self, Installed, Abort};
use sync::{Mutex, MutexGuard};
pub struct Packet<T> {
/// Only field outside of the mutex. Just done for kicks, but mainly because
/// the other shared channel already had the code implemented
channels: atomic::AtomicUint,
channels: AtomicUint,
lock: Mutex<State<T>>,
}
@ -137,7 +138,7 @@ fn wakeup<T>(token: SignalToken, guard: MutexGuard<State<T>>) {
impl<T: Send> Packet<T> {
pub fn new(cap: uint) -> Packet<T> {
Packet {
channels: atomic::AtomicUint::new(1),
channels: AtomicUint::new(1),
lock: Mutex::new(State {
disconnected: false,
blocker: NoneBlocked,
@ -304,12 +305,12 @@ impl<T: Send> Packet<T> {
// Prepares this shared packet for a channel clone, essentially just bumping
// a refcount.
pub fn clone_chan(&self) {
self.channels.fetch_add(1, atomic::SeqCst);
self.channels.fetch_add(1, Ordering::SeqCst);
}
pub fn drop_chan(&self) {
// Only flag the channel as disconnected if we're the last channel
match self.channels.fetch_sub(1, atomic::SeqCst) {
match self.channels.fetch_sub(1, Ordering::SeqCst) {
1 => {}
_ => return
}
@ -412,7 +413,7 @@ impl<T: Send> Packet<T> {
#[unsafe_destructor]
impl<T: Send> Drop for Packet<T> {
fn drop(&mut self) {
assert_eq!(self.channels.load(atomic::SeqCst), 0);
assert_eq!(self.channels.load(Ordering::SeqCst), 0);
let mut guard = self.lock.lock().unwrap();
assert!(guard.queue.dequeue().is_none());
assert!(guard.canceled.is_none());

View File

@ -17,7 +17,7 @@ use int;
use kinds::Sync;
use mem::drop;
use ops::FnOnce;
use sync::atomic;
use sync::atomic::{AtomicInt, Ordering, ATOMIC_INT_INIT};
use sync::{StaticMutex, MUTEX_INIT};
/// A synchronization primitive which can be used to run a one-time global
@ -39,8 +39,8 @@ use sync::{StaticMutex, MUTEX_INIT};
#[stable]
pub struct Once {
mutex: StaticMutex,
cnt: atomic::AtomicInt,
lock_cnt: atomic::AtomicInt,
cnt: AtomicInt,
lock_cnt: AtomicInt,
}
unsafe impl Sync for Once {}
@ -49,8 +49,8 @@ unsafe impl Sync for Once {}
#[stable]
pub const ONCE_INIT: Once = Once {
mutex: MUTEX_INIT,
cnt: atomic::ATOMIC_INT_INIT,
lock_cnt: atomic::ATOMIC_INT_INIT,
cnt: ATOMIC_INT_INIT,
lock_cnt: ATOMIC_INT_INIT,
};
impl Once {
@ -66,7 +66,7 @@ impl Once {
#[stable]
pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
// Optimize common path: load is much cheaper than fetch_add.
if self.cnt.load(atomic::SeqCst) < 0 {
if self.cnt.load(Ordering::SeqCst) < 0 {
return
}
@ -97,11 +97,11 @@ impl Once {
// calling `call_once` will return immediately before the initialization
// has completed.
let prev = self.cnt.fetch_add(1, atomic::SeqCst);
let prev = self.cnt.fetch_add(1, Ordering::SeqCst);
if prev < 0 {
// Make sure we never overflow, we'll never have int::MIN
// simultaneous calls to `call_once` to make this value go back to 0
self.cnt.store(int::MIN, atomic::SeqCst);
self.cnt.store(int::MIN, Ordering::SeqCst);
return
}
@ -109,15 +109,15 @@ impl Once {
// otherwise we run the job and record how many people will try to grab
// this lock
let guard = self.mutex.lock();
if self.cnt.load(atomic::SeqCst) > 0 {
if self.cnt.load(Ordering::SeqCst) > 0 {
f();
let prev = self.cnt.swap(int::MIN, atomic::SeqCst);
self.lock_cnt.store(prev, atomic::SeqCst);
let prev = self.cnt.swap(int::MIN, Ordering::SeqCst);
self.lock_cnt.store(prev, Ordering::SeqCst);
}
drop(guard);
// Last one out cleans up after everyone else, no leaks!
if self.lock_cnt.fetch_add(-1, atomic::SeqCst) == 1 {
if self.lock_cnt.fetch_add(-1, Ordering::SeqCst) == 1 {
unsafe { self.mutex.destroy() }
}
}

View File

@ -58,7 +58,7 @@
use prelude::v1::*;
use sync::atomic::{self, AtomicUint};
use sync::atomic::{self, AtomicUint, Ordering};
use sync::{Mutex, Once, ONCE_INIT};
use sys::thread_local as imp;
@ -166,7 +166,7 @@ impl StaticKey {
/// Note that this does *not* run the user-provided destructor if one was
/// specified at definition time. Doing so must be done manually.
pub unsafe fn destroy(&self) {
match self.inner.key.swap(0, atomic::SeqCst) {
match self.inner.key.swap(0, Ordering::SeqCst) {
0 => {}
n => { imp::destroy(n as imp::Key) }
}
@ -174,7 +174,7 @@ impl StaticKey {
#[inline]
unsafe fn key(&self) -> imp::Key {
match self.inner.key.load(atomic::Relaxed) {
match self.inner.key.load(Ordering::Relaxed) {
0 => self.lazy_init() as imp::Key,
n => n as imp::Key
}
@ -199,7 +199,7 @@ impl StaticKey {
key2
};
assert!(key != 0);
match self.inner.key.compare_and_swap(0, key as uint, atomic::SeqCst) {
match self.inner.key.compare_and_swap(0, key as uint, Ordering::SeqCst) {
// The CAS succeeded, so we've created the actual key
0 => key as uint,
// If someone beat us to the punch, use their key instead

View File

@ -20,7 +20,6 @@ use libc::{self, c_int, c_char, c_void};
use os;
use path::{BytesContainer};
use ptr;
use sync::atomic::{AtomicInt, SeqCst};
use sys::fs::FileDesc;
use os::TMPBUF_SZ;

View File

@ -13,7 +13,8 @@ use prelude::v1::*;
use libc;
use c_str::CString;
use mem;
use sync::{atomic, Arc, Mutex};
use sync::{Arc, Mutex};
use sync::atomic::{AtomicBool, Ordering};
use io::{self, IoResult, IoError};
use sys::{self, timer, retry, c, set_nonblocking, wouldblock};
@ -242,7 +243,7 @@ impl UnixListener {
listener: self,
reader: reader,
writer: writer,
closed: atomic::AtomicBool::new(false),
closed: AtomicBool::new(false),
}),
deadline: 0,
})
@ -260,7 +261,7 @@ struct AcceptorInner {
listener: UnixListener,
reader: FileDesc,
writer: FileDesc,
closed: atomic::AtomicBool,
closed: AtomicBool,
}
impl UnixAcceptor {
@ -269,7 +270,7 @@ impl UnixAcceptor {
pub fn accept(&mut self) -> IoResult<UnixStream> {
let deadline = if self.deadline == 0 {None} else {Some(self.deadline)};
while !self.inner.closed.load(atomic::SeqCst) {
while !self.inner.closed.load(Ordering::SeqCst) {
unsafe {
let mut storage: libc::sockaddr_storage = mem::zeroed();
let storagep = &mut storage as *mut libc::sockaddr_storage;
@ -297,7 +298,7 @@ impl UnixAcceptor {
}
pub fn close_accept(&mut self) -> IoResult<()> {
self.inner.closed.store(true, atomic::SeqCst);
self.inner.closed.store(true, Ordering::SeqCst);
let fd = FileDesc::new(self.inner.writer.fd(), false);
match fd.write(&[0]) {
Ok(..) => Ok(()),

View File

@ -16,7 +16,8 @@ use libc;
use mem;
use ptr;
use super::{last_error, last_net_error, retry, sock_t};
use sync::{Arc, atomic};
use sync::Arc;
use sync::atomic::{AtomicBool, Ordering};
use sys::fs::FileDesc;
use sys::{set_nonblocking, wouldblock};
use sys;
@ -74,7 +75,7 @@ impl TcpListener {
listener: self,
reader: reader,
writer: writer,
closed: atomic::AtomicBool::new(false),
closed: AtomicBool::new(false),
}),
deadline: 0,
})
@ -96,7 +97,7 @@ struct AcceptorInner {
listener: TcpListener,
reader: FileDesc,
writer: FileDesc,
closed: atomic::AtomicBool,
closed: AtomicBool,
}
unsafe impl Sync for AcceptorInner {}
@ -121,7 +122,7 @@ impl TcpAcceptor {
// self-pipe is never written to unless close_accept() is called.
let deadline = if self.deadline == 0 {None} else {Some(self.deadline)};
while !self.inner.closed.load(atomic::SeqCst) {
while !self.inner.closed.load(Ordering::SeqCst) {
match retry(|| unsafe {
libc::accept(self.fd(), ptr::null_mut(), ptr::null_mut())
}) {
@ -145,7 +146,7 @@ impl TcpAcceptor {
}
pub fn close_accept(&mut self) -> IoResult<()> {
self.inner.closed.store(true, atomic::SeqCst);
self.inner.closed.store(true, Ordering::SeqCst);
let fd = FileDesc::new(self.inner.writer.fd(), false);
match fd.write(&[0]) {
Ok(..) => Ok(()),

Some files were not shown because too many files have changed in this diff Show More