//! use std::sync::Arc;
//! use std::thread::Thread;
//!
-//! let five = Arc::new(5);
+//! let five = Arc::new(5i);
//!
//! for i in range(0u, 10) {
//! let five = five.clone();
//! use std::sync::{Arc, Mutex};
//! use std::thread::Thread;
//!
-//! let five = Arc::new(Mutex::new(5));
+//! let five = Arc::new(Mutex::new(5i));
//!
//! for _ in range(0u, 10) {
//! let five = five.clone();
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
/// ```
#[inline]
#[stable]
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
/// let weak_five = five.downgrade();
/// ```
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
/// five.clone();
/// ```
/// ```
/// use std::sync::Arc;
///
- /// let mut five = Arc::new(5);
+ /// let mut five = Arc::new(5i);
///
/// let mut_five = five.make_unique();
/// ```
/// use std::sync::Arc;
///
/// {
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
/// // stuff
///
/// drop(five); // explict drop
/// }
/// {
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
/// // stuff
///
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
/// let weak_five = five.downgrade();
///
/// ```
/// use std::sync::Arc;
///
- /// let weak_five = Arc::new(5).downgrade();
+ /// let weak_five = Arc::new(5i).downgrade();
///
/// weak_five.clone();
/// ```
/// use std::sync::Arc;
///
/// {
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
/// let weak_five = five.downgrade();
///
/// // stuff
/// drop(weak_five); // explict drop
/// }
/// {
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
/// let weak_five = five.downgrade();
///
/// // stuff
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
- /// five == Arc::new(5);
+ /// five == Arc::new(5i);
/// ```
fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
- /// five != Arc::new(5);
+ /// five != Arc::new(5i);
/// ```
fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) }
}
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
- /// five.partial_cmp(&Arc::new(5));
+ /// five.partial_cmp(&Arc::new(5i));
/// ```
fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
(**self).partial_cmp(&**other)
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
- /// five < Arc::new(5);
+ /// five < Arc::new(5i);
/// ```
fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) }
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
- /// five <= Arc::new(5);
+ /// five <= Arc::new(5i);
/// ```
fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) }
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
- /// five > Arc::new(5);
+ /// five > Arc::new(5i);
/// ```
fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
/// ```
/// use std::sync::Arc;
///
- /// let five = Arc::new(5);
+ /// let five = Arc::new(5i);
///
- /// five >= Arc::new(5);
+ /// five >= Arc::new(5i);
/// ```
fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
}
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
/// ```
#[stable]
pub fn new(value: T) -> Rc<T> {
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
/// let weak_five = five.downgrade();
/// ```
/// use std::rc;
/// use std::rc::Rc;
///
-/// let five = Rc::new(5);
+/// let five = Rc::new(5i);
///
/// rc::is_unique(&five);
/// ```
/// ```
/// use std::rc::Rc;
///
- /// let mut five = Rc::new(5);
+ /// let mut five = Rc::new(5i);
///
/// let mut_five = five.make_unique();
/// ```
/// use std::rc::Rc;
///
/// {
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
/// // stuff
///
/// drop(five); // explict drop
/// }
/// {
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
/// // stuff
///
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
/// five.clone();
/// ```
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
- /// five == Rc::new(5);
+ /// five == Rc::new(5i);
/// ```
#[inline(always)]
fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
- /// five != Rc::new(5);
+ /// five != Rc::new(5i);
/// ```
#[inline(always)]
fn ne(&self, other: &Rc<T>) -> bool { **self != **other }
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
- /// five.partial_cmp(&Rc::new(5));
+ /// five.partial_cmp(&Rc::new(5i));
/// ```
#[inline(always)]
fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> {
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
- /// five < Rc::new(5);
+ /// five < Rc::new(5i);
/// ```
#[inline(always)]
fn lt(&self, other: &Rc<T>) -> bool { **self < **other }
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
- /// five <= Rc::new(5);
+ /// five <= Rc::new(5i);
/// ```
#[inline(always)]
fn le(&self, other: &Rc<T>) -> bool { **self <= **other }
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
- /// five > Rc::new(5);
+ /// five > Rc::new(5i);
/// ```
#[inline(always)]
fn gt(&self, other: &Rc<T>) -> bool { **self > **other }
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
- /// five >= Rc::new(5);
+ /// five >= Rc::new(5i);
/// ```
#[inline(always)]
fn ge(&self, other: &Rc<T>) -> bool { **self >= **other }
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
- /// five.partial_cmp(&Rc::new(5));
+ /// five.partial_cmp(&Rc::new(5i));
/// ```
#[inline]
fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
/// ```
/// use std::rc::Rc;
///
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
///
/// let weak_five = five.downgrade();
///
/// use std::rc::Rc;
///
/// {
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
/// let weak_five = five.downgrade();
///
/// // stuff
/// drop(weak_five); // explict drop
/// }
/// {
- /// let five = Rc::new(5);
+ /// let five = Rc::new(5i);
/// let weak_five = five.downgrade();
///
/// // stuff
/// ```
/// use std::rc::Rc;
///
- /// let weak_five = Rc::new(5).downgrade();
+ /// let weak_five = Rc::new(5i).downgrade();
///
/// weak_five.clone();
/// ```
///
/// ```
/// use std::collections::BinaryHeap;
- /// let heap = BinaryHeap::from_vec(vec![9, 1, 2, 7, 3, 2]);
+ /// let heap = BinaryHeap::from_vec(vec![9i, 1, 2, 7, 3, 2]);
/// ```
pub fn from_vec(vec: Vec<T>) -> BinaryHeap<T> {
let mut heap = BinaryHeap { data: vec };
///
/// ```
/// use std::collections::BinaryHeap;
- /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
+ /// let heap = BinaryHeap::from_vec(vec![1i, 2, 3, 4]);
///
/// // Print 1, 2, 3, 4 in arbitrary order
/// for x in heap.iter() {
///
/// ```
/// use std::collections::BinaryHeap;
- /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
+ /// let heap = BinaryHeap::from_vec(vec![1i, 2, 3, 4]);
///
/// // Print 1, 2, 3, 4 in arbitrary order
/// for x in heap.into_iter() {
/// let mut heap = BinaryHeap::new();
/// assert_eq!(heap.peek(), None);
///
- /// heap.push(1);
+ /// heap.push(1i);
/// heap.push(5);
/// heap.push(2);
/// assert_eq!(heap.peek(), Some(&5));
///
/// ```
/// use std::collections::BinaryHeap;
- /// let mut heap = BinaryHeap::from_vec(vec![1, 3]);
+ /// let mut heap = BinaryHeap::from_vec(vec![1i, 3]);
///
/// assert_eq!(heap.pop(), Some(3));
/// assert_eq!(heap.pop(), Some(1));
/// ```
/// use std::collections::BinaryHeap;
/// let mut heap = BinaryHeap::new();
- /// heap.push(3);
+ /// heap.push(3i);
/// heap.push(5);
/// heap.push(1);
///
/// ```
/// use std::collections::BinaryHeap;
/// let mut heap = BinaryHeap::new();
- /// heap.push(1);
+ /// heap.push(1i);
/// heap.push(5);
///
/// assert_eq!(heap.push_pop(3), 5);
/// use std::collections::BinaryHeap;
/// let mut heap = BinaryHeap::new();
///
- /// assert_eq!(heap.replace(1), None);
+ /// assert_eq!(heap.replace(1i), None);
/// assert_eq!(heap.replace(3), Some(1));
/// assert_eq!(heap.len(), 1);
/// assert_eq!(heap.peek(), Some(&3));
///
/// ```
/// use std::collections::BinaryHeap;
- /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4, 5, 6, 7]);
+ /// let heap = BinaryHeap::from_vec(vec![1i, 2, 3, 4, 5, 6, 7]);
/// let vec = heap.into_vec();
///
/// // Will print in some order
/// ```
/// use std::collections::BinaryHeap;
///
- /// let mut heap = BinaryHeap::from_vec(vec![1, 2, 4, 5, 7]);
+ /// let mut heap = BinaryHeap::from_vec(vec![1i, 2, 4, 5, 7]);
/// heap.push(6);
/// heap.push(3);
///
/// let vec = heap.into_sorted_vec();
- /// assert_eq!(vec, vec![1, 2, 3, 4, 5, 6, 7]);
+ /// assert_eq!(vec, vec![1i, 2, 3, 4, 5, 6, 7]);
/// ```
pub fn into_sorted_vec(mut self) -> Vec<T> {
let mut end = self.len();
///
/// let mut v = BTreeSet::new();
/// assert_eq!(v.len(), 0);
- /// v.insert(1);
+ /// v.insert(1i);
/// assert_eq!(v.len(), 1);
/// ```
#[stable]
///
/// let mut v = BTreeSet::new();
/// assert!(v.is_empty());
- /// v.insert(1);
+ /// v.insert(1i);
/// assert!(!v.is_empty());
/// ```
#[stable]
/// use std::collections::BTreeSet;
///
/// let mut v = BTreeSet::new();
- /// v.insert(1);
+ /// v.insert(1i);
/// v.clear();
/// assert!(v.is_empty());
/// ```
/// ```
/// use std::collections::BTreeSet;
///
- /// let set: BTreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let set: BTreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
/// assert_eq!(set.contains(&1), true);
/// assert_eq!(set.contains(&4), false);
/// ```
/// ```
/// use std::collections::BTreeSet;
///
- /// let a: BTreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let a: BTreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
/// let mut b: BTreeSet<int> = BTreeSet::new();
///
/// assert_eq!(a.is_disjoint(&b), true);
/// ```
/// use std::collections::BTreeSet;
///
- /// let sup: BTreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
+ /// let sup: BTreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
/// let mut set: BTreeSet<int> = BTreeSet::new();
///
/// assert_eq!(set.is_subset(&sup), true);
/// ```
/// use std::collections::BTreeSet;
///
- /// let sub: BTreeSet<int> = [1, 2].iter().map(|&x| x).collect();
+ /// let sub: BTreeSet<int> = [1i, 2].iter().map(|&x| x).collect();
/// let mut set: BTreeSet<int> = BTreeSet::new();
///
/// assert_eq!(set.is_superset(&sub), false);
///
/// let mut set = BTreeSet::new();
///
- /// assert_eq!(set.insert(2), true);
- /// assert_eq!(set.insert(2), false);
+ /// assert_eq!(set.insert(2i), true);
+ /// assert_eq!(set.insert(2i), false);
/// assert_eq!(set.len(), 1);
/// ```
#[stable]
///
/// let mut set = BTreeSet::new();
///
- /// set.insert(2);
+ /// set.insert(2i);
/// assert_eq!(set.remove(&2), true);
/// assert_eq!(set.remove(&2), false);
/// ```
///
/// let mut a = DList::new();
/// let mut b = DList::new();
- /// a.push_back(1);
+ /// a.push_back(1i);
/// a.push_back(2);
- /// b.push_back(3);
+ /// b.push_back(3i);
/// b.push_back(4);
///
/// a.append(b);
/// use std::collections::DList;
///
/// let mut d = DList::new();
- /// d.push_back(1);
+ /// d.push_back(1i);
/// d.push_back(3);
/// assert_eq!(3, *d.back().unwrap());
/// ```
///
/// let mut d = DList::new();
/// assert_eq!(d.pop_back(), None);
- /// d.push_back(1);
+ /// d.push_back(1i);
/// d.push_back(3);
/// assert_eq!(d.pop_back(), Some(3));
/// ```
/// }
/// {
/// let vec: Vec<int> = list.into_iter().collect();
- /// assert_eq!(vec, vec![1, 2, 3, 4]);
+ /// assert_eq!(vec, vec![1i, 2, 3, 4]);
/// }
/// ```
#[inline]
/// use std::collections::RingBuf;
///
/// let mut buf = RingBuf::new();
- /// buf.push_back(3);
+ /// buf.push_back(3i);
/// buf.push_back(4);
/// buf.push_back(5);
/// assert_eq!(buf.get(1).unwrap(), &4);
/// use std::collections::RingBuf;
///
/// let mut buf = RingBuf::new();
- /// buf.push_back(3);
+ /// buf.push_back(3i);
/// buf.push_back(4);
/// buf.push_back(5);
/// match buf.get_mut(1) {
/// use std::collections::RingBuf;
///
/// let mut buf = RingBuf::new();
- /// buf.push_back(3);
+ /// buf.push_back(3i);
/// buf.push_back(4);
/// buf.push_back(5);
/// buf.swap(0, 2);
/// use std::collections::RingBuf;
///
/// let mut buf = RingBuf::new();
- /// buf.push_back(5);
+ /// buf.push_back(5i);
/// buf.push_back(3);
/// buf.push_back(4);
/// let b: &[_] = &[&5, &3, &4];
/// use std::collections::RingBuf;
///
/// let mut buf = RingBuf::new();
- /// buf.push_back(5);
+ /// buf.push_back(5i);
/// buf.push_back(3);
/// buf.push_back(4);
/// for num in buf.iter_mut() {
///
/// let mut v = RingBuf::new();
/// assert_eq!(v.len(), 0);
- /// v.push_back(1);
+ /// v.push_back(1i);
/// assert_eq!(v.len(), 1);
/// ```
#[stable]
///
/// let mut v = RingBuf::new();
/// assert!(v.is_empty());
- /// v.push_front(1);
+ /// v.push_front(1i);
/// assert!(!v.is_empty());
/// ```
#[stable]
/// use std::collections::RingBuf;
///
/// let mut v = RingBuf::new();
- /// v.push_back(1);
+ /// v.push_back(1i);
/// assert_eq!(v.drain().next(), Some(1));
/// assert!(v.is_empty());
/// ```
/// use std::collections::RingBuf;
///
/// let mut v = RingBuf::new();
- /// v.push_back(1);
+ /// v.push_back(1i);
/// v.clear();
/// assert!(v.is_empty());
/// ```
/// let mut d = RingBuf::new();
/// assert_eq!(d.front(), None);
///
- /// d.push_back(1);
- /// d.push_back(2);
- /// assert_eq!(d.front(), Some(&1));
+ /// d.push_back(1i);
+ /// d.push_back(2i);
+ /// assert_eq!(d.front(), Some(&1i));
/// ```
#[stable]
pub fn front(&self) -> Option<&T> {
/// let mut d = RingBuf::new();
/// assert_eq!(d.front_mut(), None);
///
- /// d.push_back(1);
- /// d.push_back(2);
+ /// d.push_back(1i);
+ /// d.push_back(2i);
/// match d.front_mut() {
- /// Some(x) => *x = 9,
+ /// Some(x) => *x = 9i,
/// None => (),
/// }
- /// assert_eq!(d.front(), Some(&9));
+ /// assert_eq!(d.front(), Some(&9i));
/// ```
#[stable]
pub fn front_mut(&mut self) -> Option<&mut T> {
/// let mut d = RingBuf::new();
/// assert_eq!(d.back(), None);
///
- /// d.push_back(1);
- /// d.push_back(2);
- /// assert_eq!(d.back(), Some(&2));
+ /// d.push_back(1i);
+ /// d.push_back(2i);
+ /// assert_eq!(d.back(), Some(&2i));
/// ```
#[stable]
pub fn back(&self) -> Option<&T> {
/// let mut d = RingBuf::new();
/// assert_eq!(d.back(), None);
///
- /// d.push_back(1);
- /// d.push_back(2);
+ /// d.push_back(1i);
+ /// d.push_back(2i);
/// match d.back_mut() {
- /// Some(x) => *x = 9,
+ /// Some(x) => *x = 9i,
/// None => (),
/// }
- /// assert_eq!(d.back(), Some(&9));
+ /// assert_eq!(d.back(), Some(&9i));
/// ```
#[stable]
pub fn back_mut(&mut self) -> Option<&mut T> {
/// use std::collections::RingBuf;
///
/// let mut d = RingBuf::new();
- /// d.push_back(1);
- /// d.push_back(2);
+ /// d.push_back(1i);
+ /// d.push_back(2i);
///
- /// assert_eq!(d.pop_front(), Some(1));
- /// assert_eq!(d.pop_front(), Some(2));
+ /// assert_eq!(d.pop_front(), Some(1i));
+ /// assert_eq!(d.pop_front(), Some(2i));
/// assert_eq!(d.pop_front(), None);
/// ```
#[stable]
/// use std::collections::RingBuf;
///
/// let mut d = RingBuf::new();
- /// d.push_front(1);
- /// d.push_front(2);
- /// assert_eq!(d.front(), Some(&2));
+ /// d.push_front(1i);
+ /// d.push_front(2i);
+ /// assert_eq!(d.front(), Some(&2i));
/// ```
#[stable]
pub fn push_front(&mut self, t: T) {
/// use std::collections::RingBuf;
///
/// let mut buf = RingBuf::new();
- /// buf.push_back(1);
+ /// buf.push_back(1i);
/// buf.push_back(3);
/// assert_eq!(3, *buf.back().unwrap());
/// ```
///
/// let mut buf = RingBuf::new();
/// assert_eq!(buf.pop_back(), None);
- /// buf.push_back(1);
+ /// buf.push_back(1i);
/// buf.push_back(3);
/// assert_eq!(buf.pop_back(), Some(3));
/// ```
/// use std::collections::RingBuf;
///
/// let mut buf = RingBuf::new();
- /// buf.push_back(10);
+ /// buf.push_back(10i);
/// buf.push_back(12);
/// buf.insert(1,11);
/// assert_eq!(Some(&11), buf.get(1));
/// use std::collections::RingBuf;
///
/// let mut buf = RingBuf::new();
- /// buf.push_back(5);
- /// buf.push_back(10);
- /// buf.push_back(12);
+ /// buf.push_back(5i);
+ /// buf.push_back(10i);
+ /// buf.push_back(12i);
/// buf.push_back(15);
/// buf.remove(2);
/// assert_eq!(Some(&15), buf.get(2));
//!
//! ```rust
//! // slicing a Vec
-//! let vec = vec!(1, 2, 3);
+//! let vec = vec!(1i, 2, 3);
//! let int_slice = vec.as_slice();
//! // coercing an array to a slice
//! let str_slice: &[&str] = &["one", "two", "three"];
//! block of memory that a mutable slice points to:
//!
//! ```rust
-//! let x: &mut[int] = &mut [1, 2, 3];
+//! let x: &mut[int] = &mut [1i, 2, 3];
//! x[1] = 7;
//! assert_eq!(x[0], 1);
//! assert_eq!(x[1], 7);
//! ```rust
//! #![feature(slicing_syntax)]
//! fn main() {
-//! let numbers = [0, 1, 2];
+//! let numbers = [0i, 1i, 2i];
//! let last_numbers = numbers[1..3];
-//! // last_numbers is now &[1, 2]
+//! // last_numbers is now &[1i, 2i]
//! }
//! ```
//!
//! type of the slice is `int`, the element type of the iterator is `&int`.
//!
//! ```rust
-//! let numbers = [0, 1, 2];
+//! let numbers = [0i, 1i, 2i];
//! for &x in numbers.iter() {
//! println!("{} is a number!", x);
//! }
use alloc::boxed::Box;
use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
-use core::cmp;
-use core::iter::{range_step, MultiplicativeIterator};
+use core::clone::Clone;
+use core::cmp::Ordering::{self, Greater, Less};
+use core::cmp::{self, Ord, PartialEq};
+use core::iter::{Iterator, IteratorExt};
+use core::iter::{range, range_step, MultiplicativeIterator};
use core::kinds::Sized;
use core::mem::size_of;
use core::mem;
-use core::ops::{FnMut,SliceMut};
-use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
-use core::prelude::{Ord, Ordering, PtrExt, Some, range, IteratorCloneExt, Result};
+use core::ops::{FnMut, SliceMut};
+use core::option::Option::{self, Some, None};
+use core::ptr::PtrExt;
use core::ptr;
+use core::result::Result;
use core::slice as core_slice;
use self::Direction::*;
use vec::Vec;
pub use core::slice::{Chunks, AsSlice, Windows};
-pub use core::slice::{Iter, IterMut, PartialEqSliceExt};
+pub use core::slice::{Iter, IterMut};
pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split};
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
////////////////////////////////////////////////////////////////////////////////
/// Allocating extension methods for slices.
#[stable]
-pub trait SliceExt for Sized? {
+pub trait SliceExt {
#[stable]
type Item;
/// # Examples
///
/// ```rust
- /// let mut v = [5, 4, 1, 3, 2];
+ /// let mut v = [5i, 4, 1, 3, 2];
/// v.sort_by(|a, b| a.cmp(b));
/// assert!(v == [1, 2, 3, 4, 5]);
///
/// assert!(v == [5, 4, 3, 2, 1]);
/// ```
#[stable]
- fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering;
+ fn sort_by<F>(&mut self, compare: F) where F: FnMut(&Self::Item, &Self::Item) -> Ordering;
/// Consumes `src` and moves as many elements as it can into `self`
/// from the range [start,end).
/// # Examples
///
/// ```rust
- /// let mut a = [1, 2, 3, 4, 5];
- /// let b = vec![6, 7, 8];
+ /// let mut a = [1i, 2, 3, 4, 5];
+ /// let b = vec![6i, 7, 8];
/// let num_moved = a.move_from(b, 0, 3);
/// assert_eq!(num_moved, 3);
- /// assert!(a == [6, 7, 8, 4, 5]);
+ /// assert!(a == [6i, 7, 8, 4, 5]);
/// ```
#[experimental = "uncertain about this API approach"]
- fn move_from(&mut self, src: Vec<T>, start: uint, end: uint) -> uint;
+ fn move_from(&mut self, src: Vec<Self::Item>, start: uint, end: uint) -> uint;
/// Returns a subslice spanning the interval [`start`, `end`).
///
///
/// Slicing with `start` equal to `end` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
- fn slice(&self, start: uint, end: uint) -> &[T];
+ fn slice(&self, start: uint, end: uint) -> &[Self::Item];
/// Returns a subslice from `start` to the end of the slice.
///
///
/// Slicing from `self.len()` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
- fn slice_from(&self, start: uint) -> &[T];
+ fn slice_from(&self, start: uint) -> &[Self::Item];
/// Returns a subslice from the start of the slice to `end`.
///
///
/// Slicing to `0` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
- fn slice_to(&self, end: uint) -> &[T];
+ fn slice_to(&self, end: uint) -> &[Self::Item];
/// Divides one slice into two at an index.
///
///
/// Panics if `mid > len`.
#[stable]
- fn split_at(&self, mid: uint) -> (&[T], &[T]);
+ fn split_at(&self, mid: uint) -> (&[Self::Item], &[Self::Item]);
/// Returns an iterator over the slice
#[stable]
- fn iter(&self) -> Iter<T>;
+ fn iter(&self) -> Iter<Self::Item>;
/// Returns an iterator over subslices separated by elements that match
/// `pred`. The matched element is not contained in the subslices.
#[stable]
- fn split<F>(&self, pred: F) -> Split<T, F>
- where F: FnMut(&T) -> bool;
+ fn split<F>(&self, pred: F) -> Split<Self::Item, F>
+ where F: FnMut(&Self::Item) -> bool;
/// Returns an iterator over subslices separated by elements that match
/// `pred`, limited to splitting at most `n` times. The matched element is
/// not contained in the subslices.
#[stable]
- fn splitn<F>(&self, n: uint, pred: F) -> SplitN<T, F>
- where F: FnMut(&T) -> bool;
+ fn splitn<F>(&self, n: uint, pred: F) -> SplitN<Self::Item, F>
+ where F: FnMut(&Self::Item) -> bool;
/// Returns an iterator over subslices separated by elements that match
/// `pred` limited to splitting at most `n` times. This starts at the end of
/// the slice and works backwards. The matched element is not contained in
/// the subslices.
#[stable]
- fn rsplitn<F>(&self, n: uint, pred: F) -> RSplitN<T, F>
- where F: FnMut(&T) -> bool;
+ fn rsplitn<F>(&self, n: uint, pred: F) -> RSplitN<Self::Item, F>
+ where F: FnMut(&Self::Item) -> bool;
/// Returns an iterator over all contiguous windows of length
/// `size`. The windows overlap. If the slice is shorter than
/// `[3,4]`):
///
/// ```rust
- /// let v = &[1, 2, 3, 4];
+ /// let v = &[1i, 2, 3, 4];
/// for win in v.windows(2) {
/// println!("{}", win);
/// }
/// ```
#[stable]
- fn windows(&self, size: uint) -> Windows<T>;
+ fn windows(&self, size: uint) -> Windows<Self::Item>;
/// Returns an iterator over `size` elements of the slice at a
/// time. The chunks do not overlap. If `size` does not divide the
/// `[3,4]`, `[5]`):
///
/// ```rust
- /// let v = &[1, 2, 3, 4, 5];
+ /// let v = &[1i, 2, 3, 4, 5];
/// for win in v.chunks(2) {
/// println!("{}", win);
/// }
/// ```
#[stable]
- fn chunks(&self, size: uint) -> Chunks<T>;
+ fn chunks(&self, size: uint) -> Chunks<Self::Item>;
/// Returns the element of a slice at the given index, or `None` if the
/// index is out of bounds.
#[stable]
- fn get(&self, index: uint) -> Option<&T>;
+ fn get(&self, index: uint) -> Option<&Self::Item>;
/// Returns the first element of a slice, or `None` if it is empty.
#[stable]
- fn first(&self) -> Option<&T>;
-
- /// Deprecated: renamed to `first`.
- #[deprecated = "renamed to `first`"]
- fn head(&self) -> Option<&T> { self.first() }
+ fn first(&self) -> Option<&Self::Item>;
/// Returns all but the first element of a slice.
#[experimental = "likely to be renamed"]
- fn tail(&self) -> &[T];
+ fn tail(&self) -> &[Self::Item];
/// Returns all but the last element of a slice.
#[experimental = "likely to be renamed"]
- fn init(&self) -> &[T];
+ fn init(&self) -> &[Self::Item];
/// Returns the last element of a slice, or `None` if it is empty.
#[stable]
- fn last(&self) -> Option<&T>;
+ fn last(&self) -> Option<&Self::Item>;
/// Returns a pointer to the element at the given index, without doing
/// bounds checking.
#[stable]
- unsafe fn get_unchecked(&self, index: uint) -> &T;
-
- /// Deprecated: renamed to `get_unchecked`.
- #[deprecated = "renamed to get_unchecked"]
- unsafe fn unsafe_get(&self, index: uint) -> &T {
- self.get_unchecked(index)
- }
+ unsafe fn get_unchecked(&self, index: uint) -> &Self::Item;
/// Returns an unsafe pointer to the slice's buffer
///
/// Modifying the slice may cause its buffer to be reallocated, which
/// would also make any pointers to it invalid.
#[stable]
- fn as_ptr(&self) -> *const T;
+ fn as_ptr(&self) -> *const Self::Item;
/// Binary search a sorted slice with a comparator function.
///
/// found; the fourth could match any position in `[1,4]`.
///
/// ```rust
- /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+ /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
/// let s = s.as_slice();
///
/// let seek = 13;
/// ```
#[stable]
fn binary_search_by<F>(&self, f: F) -> Result<uint, uint> where
- F: FnMut(&T) -> Ordering;
+ F: FnMut(&Self::Item) -> Ordering;
/// Return the number of elements in the slice
///
/// # Example
///
/// ```
- /// let a = [1, 2, 3];
+ /// let a = [1i, 2, 3];
/// assert_eq!(a.len(), 3);
/// ```
#[stable]
/// # Example
///
/// ```
- /// let a = [1, 2, 3];
+ /// let a = [1i, 2, 3];
/// assert!(!a.is_empty());
/// ```
#[inline]
/// Returns a mutable reference to the element at the given index,
/// or `None` if the index is out of bounds
#[stable]
- fn get_mut(&mut self, index: uint) -> Option<&mut T>;
+ fn get_mut(&mut self, index: uint) -> Option<&mut Self::Item>;
/// Work with `self` as a mut slice.
/// Primarily intended for getting a &mut [T] from a [T; N].
#[stable]
- fn as_mut_slice(&mut self) -> &mut [T];
+ fn as_mut_slice(&mut self) -> &mut [Self::Item];
/// Returns a mutable subslice spanning the interval [`start`, `end`).
///
///
/// Slicing with `start` equal to `end` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
- fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T];
+ fn slice_mut(&mut self, start: uint, end: uint) -> &mut [Self::Item];
/// Returns a mutable subslice from `start` to the end of the slice.
///
///
/// Slicing from `self.len()` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
- fn slice_from_mut(&mut self, start: uint) -> &mut [T];
+ fn slice_from_mut(&mut self, start: uint) -> &mut [Self::Item];
/// Returns a mutable subslice from the start of the slice to `end`.
///
///
/// Slicing to `0` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
- fn slice_to_mut(&mut self, end: uint) -> &mut [T];
+ fn slice_to_mut(&mut self, end: uint) -> &mut [Self::Item];
/// Returns an iterator that allows modifying each value
#[stable]
- fn iter_mut(&mut self) -> IterMut<T>;
+ fn iter_mut(&mut self) -> IterMut<Self::Item>;
/// Returns a mutable pointer to the first element of a slice, or `None` if it is empty
#[stable]
- fn first_mut(&mut self) -> Option<&mut T>;
-
- /// Depreated: renamed to `first_mut`.
- #[deprecated = "renamed to first_mut"]
- fn head_mut(&mut self) -> Option<&mut T> {
- self.first_mut()
- }
+ fn first_mut(&mut self) -> Option<&mut Self::Item>;
/// Returns all but the first element of a mutable slice
#[experimental = "likely to be renamed or removed"]
- fn tail_mut(&mut self) -> &mut [T];
+ fn tail_mut(&mut self) -> &mut [Self::Item];
/// Returns all but the last element of a mutable slice
#[experimental = "likely to be renamed or removed"]
- fn init_mut(&mut self) -> &mut [T];
+ fn init_mut(&mut self) -> &mut [Self::Item];
/// Returns a mutable pointer to the last item in the slice.
#[stable]
- fn last_mut(&mut self) -> Option<&mut T>;
+ fn last_mut(&mut self) -> Option<&mut Self::Item>;
/// Returns an iterator over mutable subslices separated by elements that
/// match `pred`. The matched element is not contained in the subslices.
#[stable]
- fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
- where F: FnMut(&T) -> bool;
+ fn split_mut<F>(&mut self, pred: F) -> SplitMut<Self::Item, F>
+ where F: FnMut(&Self::Item) -> bool;
/// Returns an iterator over subslices separated by elements that match
/// `pred`, limited to splitting at most `n` times. The matched element is
/// not contained in the subslices.
#[stable]
- fn splitn_mut<F>(&mut self, n: uint, pred: F) -> SplitNMut<T, F>
- where F: FnMut(&T) -> bool;
+ fn splitn_mut<F>(&mut self, n: uint, pred: F) -> SplitNMut<Self::Item, F>
+ where F: FnMut(&Self::Item) -> bool;
/// Returns an iterator over subslices separated by elements that match
/// `pred` limited to splitting at most `n` times. This starts at the end of
/// the slice and works backwards. The matched element is not contained in
/// the subslices.
#[stable]
- fn rsplitn_mut<F>(&mut self, n: uint, pred: F) -> RSplitNMut<T, F>
- where F: FnMut(&T) -> bool;
+ fn rsplitn_mut<F>(&mut self, n: uint, pred: F) -> RSplitNMut<Self::Item, F>
+ where F: FnMut(&Self::Item) -> bool;
/// Returns an iterator over `chunk_size` elements of the slice at a time.
/// The chunks are mutable and do not overlap. If `chunk_size` does
///
/// Panics if `chunk_size` is 0.
#[stable]
- fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut<T>;
+ fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut<Self::Item>;
/// Swaps two elements in a slice.
///
/// # Example
///
/// ```rust
- /// let mut v = [1, 2, 3, 4, 5, 6];
+ /// let mut v = [1i, 2, 3, 4, 5, 6];
///
/// // scoped to restrict the lifetime of the borrows
/// {
/// let (left, right) = v.split_at_mut(0);
/// assert!(left == []);
- /// assert!(right == [1, 2, 3, 4, 5, 6]);
+ /// assert!(right == [1i, 2, 3, 4, 5, 6]);
/// }
///
/// {
/// let (left, right) = v.split_at_mut(2);
- /// assert!(left == [1, 2]);
- /// assert!(right == [3, 4, 5, 6]);
+ /// assert!(left == [1i, 2]);
+ /// assert!(right == [3i, 4, 5, 6]);
/// }
///
/// {
/// let (left, right) = v.split_at_mut(6);
- /// assert!(left == [1, 2, 3, 4, 5, 6]);
+ /// assert!(left == [1i, 2, 3, 4, 5, 6]);
/// assert!(right == []);
/// }
/// ```
#[stable]
- fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]);
+ fn split_at_mut(&mut self, mid: uint) -> (&mut [Self::Item], &mut [Self::Item]);
/// Reverse the order of elements in a slice, in place.
///
/// # Example
///
/// ```rust
- /// let mut v = [1, 2, 3];
+ /// let mut v = [1i, 2, 3];
/// v.reverse();
- /// assert!(v == [3, 2, 1]);
+ /// assert!(v == [3i, 2, 1]);
/// ```
#[stable]
fn reverse(&mut self);
/// Returns an unsafe mutable pointer to the element in index
#[stable]
- unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T;
-
- /// Deprecated: renamed to `get_unchecked_mut`.
- #[deprecated = "renamed to get_unchecked_mut"]
- unsafe fn unchecked_mut(&mut self, index: uint) -> &mut T {
- self.get_unchecked_mut(index)
- }
+ unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut Self::Item;
/// Return an unsafe mutable pointer to the slice's buffer.
///
/// would also make any pointers to it invalid.
#[inline]
#[stable]
- fn as_mut_ptr(&mut self) -> *mut T;
+ fn as_mut_ptr(&mut self) -> *mut Self::Item;
+
+ /// Copies `self` into a new `Vec`.
+ #[stable]
+ fn to_vec(&self) -> Vec<Self::Item> where Self::Item: Clone;
+
+ /// Creates an iterator that yields every possible permutation of the
+ /// vector in succession.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// let v = [1i, 2, 3];
+ /// let mut perms = v.permutations();
+ ///
+ /// for p in perms {
+ /// println!("{}", p);
+ /// }
+ /// ```
+ ///
+ /// Iterating through permutations one by one.
+ ///
+ /// ```rust
+ /// let v = [1i, 2, 3];
+ /// let mut perms = v.permutations();
+ ///
+ /// assert_eq!(Some(vec![1i, 2, 3]), perms.next());
+ /// assert_eq!(Some(vec![1i, 3, 2]), perms.next());
+ /// assert_eq!(Some(vec![3i, 1, 2]), perms.next());
+ /// ```
+ #[unstable]
+ fn permutations(&self) -> Permutations<Self::Item> where Self::Item: Clone;
+
+ /// Copies as many elements from `src` as it can into `self` (the
+ /// shorter of `self.len()` and `src.len()`). Returns the number
+ /// of elements copied.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let mut dst = [0i, 0, 0];
+ /// let src = [1i, 2];
+ ///
+ /// assert!(dst.clone_from_slice(&src) == 2);
+ /// assert!(dst == [1, 2, 0]);
+ ///
+ /// let src2 = [3i, 4, 5, 6];
+ /// assert!(dst.clone_from_slice(&src2) == 3);
+ /// assert!(dst == [3i, 4, 5]);
+ /// ```
+ #[experimental]
+ fn clone_from_slice(&mut self, &[Self::Item]) -> uint where Self::Item: Clone;
+
+ /// Sorts the slice, in place.
+ ///
+ /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// let mut v = [-5i, 4, 1, -3, 2];
+ ///
+ /// v.sort();
+ /// assert!(v == [-5i, -3, 1, 2, 4]);
+ /// ```
+ #[stable]
+ fn sort(&mut self) where Self::Item: Ord;
+
+ /// Binary search a sorted slice for a given element.
+ ///
+ /// If the value is found then `Ok` is returned, containing the
+ /// index of the matching element; if the value is not found then
+ /// `Err` is returned, containing the index where a matching
+ /// element could be inserted while maintaining sorted order.
+ ///
+ /// # Example
+ ///
+ /// Looks up a series of four elements. The first is found, with a
+ /// uniquely determined position; the second and third are not
+ /// found; the fourth could match any position in `[1,4]`.
+ ///
+ /// ```rust
+ /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+ /// let s = s.as_slice();
+ ///
+ /// assert_eq!(s.binary_search(&13), Ok(9));
+ /// assert_eq!(s.binary_search(&4), Err(7));
+ /// assert_eq!(s.binary_search(&100), Err(13));
+ /// let r = s.binary_search(&1);
+ /// assert!(match r { Ok(1...4) => true, _ => false, });
+ /// ```
+ #[stable]
+ fn binary_search(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord;
+
+ /// Deprecated: use `binary_search` instead.
+ #[deprecated = "use binary_search instead"]
+ fn binary_search_elem(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord {
+ self.binary_search(x)
+ }
+
+ /// Mutates the slice to the next lexicographic permutation.
+ ///
+ /// Returns `true` if successful and `false` if the slice is at the
+ /// last-ordered permutation.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let v: &mut [_] = &mut [0i, 1, 2];
+ /// v.next_permutation();
+ /// let b: &mut [_] = &mut [0i, 2, 1];
+ /// assert!(v == b);
+ /// v.next_permutation();
+ /// let b: &mut [_] = &mut [1i, 0, 2];
+ /// assert!(v == b);
+ /// ```
+ #[unstable = "uncertain if this merits inclusion in std"]
+ fn next_permutation(&mut self) -> bool where Self::Item: Ord;
+
+ /// Mutates the slice to the previous lexicographic permutation.
+ ///
+ /// Returns `true` if successful and `false` if the slice is at the
+ /// first-ordered permutation.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let v: &mut [_] = &mut [1i, 0, 2];
+ /// v.prev_permutation();
+ /// let b: &mut [_] = &mut [0i, 2, 1];
+ /// assert!(v == b);
+ /// v.prev_permutation();
+ /// let b: &mut [_] = &mut [0i, 1, 2];
+ /// assert!(v == b);
+ /// ```
+ #[unstable = "uncertain if this merits inclusion in std"]
+ fn prev_permutation(&mut self) -> bool where Self::Item: Ord;
+
+ /// Find the first index containing a matching value.
+ #[experimental]
+ fn position_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
+
+ /// Find the last index containing a matching value.
+ #[experimental]
+ fn rposition_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
+
+ /// Return true if the slice contains an element with the given value.
+ #[stable]
+ fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
+
+ /// Returns true if `needle` is a prefix of the slice.
+ #[stable]
+ fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
+
+ /// Returns true if `needle` is a suffix of the slice.
+ #[stable]
+ fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
+
+ /// Convert `self` into a vector without clones or allocation.
+ #[experimental]
+ fn into_vec(self: Box<Self>) -> Vec<Self::Item>;
}
#[stable]
fn as_mut_ptr(&mut self) -> *mut T {
core_slice::SliceExt::as_mut_ptr(self)
}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Extension traits for slices over specifc kinds of data
-////////////////////////////////////////////////////////////////////////////////
-
-/// Extension methods for boxed slices.
-#[experimental = "likely to merge into SliceExt if it survives"]
-pub trait BoxedSliceExt<T> {
- /// Convert `self` into a vector without clones or allocation.
- #[experimental]
- fn into_vec(self) -> Vec<T>;
-}
-
-#[experimental = "trait is experimental"]
-impl<T> BoxedSliceExt<T> for Box<[T]> {
- fn into_vec(mut self) -> Vec<T> {
- unsafe {
- let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len());
- mem::forget(self);
- xs
- }
- }
-}
-
-/// Allocating extension methods for slices containing `Clone` elements.
-#[unstable = "likely to be merged into SliceExt"]
-pub trait CloneSliceExt<T> for Sized? {
- /// Copies `self` into a new `Vec`.
- #[stable]
- fn to_vec(&self) -> Vec<T>;
-
- /// Deprecated: use `iter().cloned().partition(f)` instead.
- #[deprecated = "use iter().cloned().partition(f) instead"]
- fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool;
-
- /// Creates an iterator that yields every possible permutation of the
- /// vector in succession.
- ///
- /// # Examples
- ///
- /// ```rust
- /// let v = [1, 2, 3];
- /// let mut perms = v.permutations();
- ///
- /// for p in perms {
- /// println!("{}", p);
- /// }
- /// ```
- ///
- /// Iterating through permutations one by one.
- ///
- /// ```rust
- /// let v = [1, 2, 3];
- /// let mut perms = v.permutations();
- ///
- /// assert_eq!(Some(vec![1, 2, 3]), perms.next());
- /// assert_eq!(Some(vec![1, 3, 2]), perms.next());
- /// assert_eq!(Some(vec![3, 1, 2]), perms.next());
- /// ```
- #[unstable]
- fn permutations(&self) -> Permutations<T>;
-
- /// Copies as many elements from `src` as it can into `self` (the
- /// shorter of `self.len()` and `src.len()`). Returns the number
- /// of elements copied.
- ///
- /// # Example
- ///
- /// ```rust
- /// let mut dst = [0, 0, 0];
- /// let src = [1, 2];
- ///
- /// assert!(dst.clone_from_slice(&src) == 2);
- /// assert!(dst == [1, 2, 0]);
- ///
- /// let src2 = [3, 4, 5, 6];
- /// assert!(dst.clone_from_slice(&src2) == 3);
- /// assert!(dst == [3, 4, 5]);
- /// ```
- #[experimental]
- fn clone_from_slice(&mut self, &[T]) -> uint;
-}
-
-#[unstable = "trait is unstable"]
-impl<T: Clone> CloneSliceExt<T> for [T] {
/// Returns a copy of `v`.
#[inline]
- fn to_vec(&self) -> Vec<T> {
+ fn to_vec(&self) -> Vec<T> where T: Clone {
let mut vector = Vec::with_capacity(self.len());
vector.push_all(self);
vector
}
-
- #[inline]
- fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
- self.iter().cloned().partition(f)
- }
-
/// Returns an iterator over all permutations of a vector.
- fn permutations(&self) -> Permutations<T> {
+ fn permutations(&self) -> Permutations<T> where T: Clone {
Permutations{
swaps: ElementSwaps::new(self.len()),
v: self.to_vec(),
}
}
- fn clone_from_slice(&mut self, src: &[T]) -> uint {
- core_slice::CloneSliceExt::clone_from_slice(self, src)
+ fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone {
+ core_slice::SliceExt::clone_from_slice(self, src)
}
-}
-/// Allocating extension methods for slices on Ord values.
-#[unstable = "likely to merge with SliceExt"]
-pub trait OrdSliceExt<T> for Sized? {
- /// Sorts the slice, in place.
- ///
- /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
- ///
- /// # Examples
- ///
- /// ```rust
- /// let mut v = [-5, 4, 1, -3, 2];
- ///
- /// v.sort();
- /// assert!(v == [-5, -3, 1, 2, 4]);
- /// ```
- #[stable]
- fn sort(&mut self);
+ #[inline]
+ fn sort(&mut self) where T: Ord {
+ self.sort_by(|a, b| a.cmp(b))
+ }
- /// Binary search a sorted slice for a given element.
- ///
- /// If the value is found then `Ok` is returned, containing the
- /// index of the matching element; if the value is not found then
- /// `Err` is returned, containing the index where a matching
- /// element could be inserted while maintaining sorted order.
- ///
- /// # Example
- ///
- /// Looks up a series of four elements. The first is found, with a
- /// uniquely determined position; the second and third are not
- /// found; the fourth could match any position in `[1,4]`.
- ///
- /// ```rust
- /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
- /// let s = s.as_slice();
- ///
- /// assert_eq!(s.binary_search(&13), Ok(9));
- /// assert_eq!(s.binary_search(&4), Err(7));
- /// assert_eq!(s.binary_search(&100), Err(13));
- /// let r = s.binary_search(&1);
- /// assert!(match r { Ok(1...4) => true, _ => false, });
- /// ```
- #[stable]
- fn binary_search(&self, x: &T) -> Result<uint, uint>;
+ fn binary_search(&self, x: &T) -> Result<uint, uint> where T: Ord {
+ core_slice::SliceExt::binary_search(self, x)
+ }
- /// Deprecated: use `binary_search` instead.
- #[deprecated = "use binary_search instead"]
- fn binary_search_elem(&self, x: &T) -> Result<uint, uint> {
- self.binary_search(x)
+ fn next_permutation(&mut self) -> bool where T: Ord {
+ core_slice::SliceExt::next_permutation(self)
}
- /// Mutates the slice to the next lexicographic permutation.
- ///
- /// Returns `true` if successful and `false` if the slice is at the
- /// last-ordered permutation.
- ///
- /// # Example
- ///
- /// ```rust
- /// let v: &mut [_] = &mut [0, 1, 2];
- /// v.next_permutation();
- /// let b: &mut [_] = &mut [0, 2, 1];
- /// assert!(v == b);
- /// v.next_permutation();
- /// let b: &mut [_] = &mut [1, 0, 2];
- /// assert!(v == b);
- /// ```
- #[unstable = "uncertain if this merits inclusion in std"]
- fn next_permutation(&mut self) -> bool;
+ fn prev_permutation(&mut self) -> bool where T: Ord {
+ core_slice::SliceExt::prev_permutation(self)
+ }
- /// Mutates the slice to the previous lexicographic permutation.
- ///
- /// Returns `true` if successful and `false` if the slice is at the
- /// first-ordered permutation.
- ///
- /// # Example
- ///
- /// ```rust
- /// let v: &mut [_] = &mut [1, 0, 2];
- /// v.prev_permutation();
- /// let b: &mut [_] = &mut [0, 2, 1];
- /// assert!(v == b);
- /// v.prev_permutation();
- /// let b: &mut [_] = &mut [0, 1, 2];
- /// assert!(v == b);
- /// ```
- #[unstable = "uncertain if this merits inclusion in std"]
- fn prev_permutation(&mut self) -> bool;
-}
+ fn position_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
+ core_slice::SliceExt::position_elem(self, t)
+ }
-#[unstable = "trait is unstable"]
-impl<T: Ord> OrdSliceExt<T> for [T] {
- #[inline]
- fn sort(&mut self) {
- self.sort_by(|a, b| a.cmp(b))
+ fn rposition_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
+ core_slice::SliceExt::rposition_elem(self, t)
}
- fn binary_search(&self, x: &T) -> Result<uint, uint> {
- core_slice::OrdSliceExt::binary_search(self, x)
+ fn contains(&self, x: &T) -> bool where T: PartialEq {
+ core_slice::SliceExt::contains(self, x)
}
- fn next_permutation(&mut self) -> bool {
- core_slice::OrdSliceExt::next_permutation(self)
+ fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
+ core_slice::SliceExt::starts_with(self, needle)
}
- fn prev_permutation(&mut self) -> bool {
- core_slice::OrdSliceExt::prev_permutation(self)
+ fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
+ core_slice::SliceExt::ends_with(self, needle)
+ }
+
+ fn into_vec(mut self: Box<Self>) -> Vec<T> {
+ unsafe {
+ let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len());
+ mem::forget(self);
+ xs
+ }
}
}
+////////////////////////////////////////////////////////////////////////////////
+// Extension traits for slices over specifc kinds of data
+////////////////////////////////////////////////////////////////////////////////
#[unstable = "U should be an associated type"]
/// An extension trait for concatenating slices
pub trait SliceConcatExt<T: ?Sized, U> {
#[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] {
/// The last generated swap is always (0, 1), and it returns the
/// sequence to its initial order.
#[experimental]
-#[deriving(Clone)]
+#[derive(Clone)]
pub struct ElementSwaps {
sdir: Vec<SizeDirection>,
/// If `true`, emit the last swap that returns the sequence to initial
// Iterators
////////////////////////////////////////////////////////////////////////////////
-#[deriving(Copy, Clone)]
+#[derive(Copy, Clone)]
enum Direction { Pos, Neg }
/// An `Index` and `Direction` together.
-#[deriving(Copy, Clone)]
+#[derive(Copy, Clone)]
struct SizeDirection {
size: uint,
dir: Direction,
}
#[unstable = "trait is unstable"]
-impl<T: Clone> Iterator<Vec<T>> for Permutations<T> {
+impl<T: Clone> Iterator for Permutations<T> {
+ type Item = Vec<T>;
+
#[inline]
fn next(&mut self) -> Option<Vec<T>> {
match self.swaps.next() {
}
}
-/// 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, DoubleEndedIteratorExt};
- use prelude::{OrdSliceExt, CloneSliceExt, PartialEqSliceExt, AsSlice};
+ 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};
#[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);
}
// 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);
#[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);
}
// 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);
}
#[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]
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];
}
}
- #[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] = [];
#[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]
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() {
assert!(values == [2, 3, 5, 6, 7]);
}
- #[deriving(Clone, PartialEq)]
+ #[derive(Clone, PartialEq)]
struct Foo;
#[test]
use prelude::*;
use core::mem;
use core::ptr;
+ use core::iter::repeat;
use std::rand::{weak_rng, Rng};
use test::{Bencher, black_box};
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;
#[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;
#[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();
});
#[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)
});
}
#[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())
})
#[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())
#[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())
})
#[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())
#[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)
})
#[bench]
fn zero_1kb_from_elem(b: &mut Bencher) {
b.iter(|| {
- Vec::from_elem(1024, 0u8)
+ repeat(0u8).take(1024).collect::<Vec<_>>()
});
}
fn random_inserts(b: &mut Bencher) {
let mut rng = weak_rng();
b.iter(|| {
- let mut v = Vec::from_elem(30, (0u, 0u));
- for _ in range(0u, 100) {
- let l = v.len();
- v.insert(rng.gen::<uint>() % (l + 1),
- (1, 1));
- }
- })
+ 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),
+ (1, 1));
+ }
+ })
}
#[bench]
fn random_removes(b: &mut Bencher) {
let mut rng = weak_rng();
b.iter(|| {
- let mut v = Vec::from_elem(130, (0u, 0u));
- for _ in range(0u, 100) {
- let l = v.len();
- v.remove(rng.gen::<uint>() % l);
- }
- })
+ 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);
+ }
+ })
}
#[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();
});
#[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();
});
//! ```
//! let ys: Vec<i32> = vec![];
//!
-//! let zs = vec![1, 2, 3, 4, 5];
+//! let zs = vec![1i32, 2, 3, 4, 5];
//! ```
//!
//! Push:
//!
//! ```
-//! let mut xs = vec![1, 2];
+//! let mut xs = vec![1i32, 2];
//!
//! xs.push(3);
//! ```
//! And pop:
//!
//! ```
-//! let mut xs = vec![1, 2];
+//! let mut xs = vec![1i32, 2];
//!
//! let two = xs.pop();
//! ```
///
/// ```
/// let mut vec = Vec::new();
-/// vec.push(1);
-/// vec.push(2);
+/// vec.push(1i);
+/// vec.push(2i);
///
/// assert_eq!(vec.len(), 2);
/// assert_eq!(vec[0], 1);
/// assert_eq!(vec.pop(), Some(2));
/// assert_eq!(vec.len(), 1);
///
-/// vec[0] = 7;
+/// vec[0] = 7i;
/// assert_eq!(vec[0], 7);
///
/// vec.push_all(&[1, 2, 3]);
/// for x in vec.iter() {
/// println!("{}", x);
/// }
-/// assert_eq!(vec, vec![7, 1, 2, 3]);
+/// assert_eq!(vec, vec![7i, 1, 2, 3]);
/// ```
///
/// The `vec!` macro is provided to make initialization more convenient:
///
/// ```
-/// let mut vec = vec![1, 2, 3];
+/// let mut vec = vec![1i, 2i, 3i];
/// vec.push(4);
/// assert_eq!(vec, vec![1, 2, 3, 4]);
/// ```
/// ```
/// let mut stack = Vec::new();
///
-/// stack.push(1);
-/// stack.push(2);
-/// stack.push(3);
+/// stack.push(1i);
+/// stack.push(2i);
+/// stack.push(3i);
///
/// loop {
/// let top = match stack.pop() {
/// use std::mem;
///
/// fn main() {
- /// let mut v = vec![1, 2, 3];
+ /// let mut v = vec![1i, 2, 3];
///
/// // Pull out the various important pieces of information about `v`
/// let p = v.as_mut_ptr();
///
/// // Put everything back together into a Vec
/// let rebuilt = Vec::from_raw_parts(p, len, cap);
- /// assert_eq!(rebuilt, vec![4, 5, 6]);
+ /// assert_eq!(rebuilt, vec![4i, 5i, 6i]);
/// }
/// }
/// ```
/// # Examples
///
/// ```
- /// let mut vec = vec![1, 2, 3, 4];
+ /// let mut vec = vec![1i, 2, 3, 4];
/// vec.truncate(2);
/// assert_eq!(vec, vec![1, 2]);
/// ```
/// ```
/// fn foo(slice: &mut [int]) {}
///
- /// let mut vec = vec![1, 2];
+ /// let mut vec = vec![1i, 2];
/// foo(vec.as_mut_slice());
/// ```
#[inline]
/// # Examples
///
/// ```
- /// let mut vec = vec![1, 2, 3];
+ /// let mut vec = vec![1i, 2, 3];
/// vec.insert(1, 4);
/// assert_eq!(vec, vec![1, 4, 2, 3]);
/// vec.insert(4, 5);
/// # Examples
///
/// ```
- /// let mut v = vec![1, 2, 3];
+ /// let mut v = vec![1i, 2, 3];
/// assert_eq!(v.remove(1), 2);
/// assert_eq!(v, vec![1, 3]);
/// ```
/// # Examples
///
/// ```
- /// let mut vec = vec![1, 2, 3, 4];
+ /// let mut vec = vec![1i, 2, 3, 4];
/// vec.retain(|&x| x%2 == 0);
/// assert_eq!(vec, vec![2, 4]);
/// ```
/// # Examples
///
/// ```rust
- /// let mut vec = vec!(1, 2);
+ /// let mut vec = vec!(1i, 2);
/// vec.push(3);
/// assert_eq!(vec, vec!(1, 2, 3));
/// ```
/// # Examples
///
/// ```rust
- /// let mut vec = vec![1, 2, 3];
+ /// let mut vec = vec![1i, 2, 3];
/// assert_eq!(vec.pop(), Some(3));
/// assert_eq!(vec, vec![1, 2]);
/// ```
/// # Examples
///
/// ```
- /// let mut v = vec![1, 2, 3];
+ /// let mut v = vec![1i, 2, 3];
///
/// v.clear();
///
/// # Examples
///
/// ```
- /// let a = vec![1, 2, 3];
+ /// let a = vec![1i, 2, 3];
/// assert_eq!(a.len(), 3);
/// ```
#[inline]
/// let mut v = Vec::new();
/// assert!(v.is_empty());
///
- /// v.push(1);
+ /// v.push(1i);
/// assert!(!v.is_empty());
/// ```
#[stable]
/// vec.resize(3, "world");
/// assert_eq!(vec, vec!["hello", "world", "world"]);
///
- /// let mut vec = vec![1, 2, 3, 4];
+ /// let mut vec = vec![1i, 2, 3, 4];
/// vec.resize(2, 0);
/// assert_eq!(vec, vec![1, 2]);
/// ```
/// # Examples
///
/// ```
- /// let mut vec = vec![1];
- /// vec.push_all(&[2, 3, 4]);
+ /// let mut vec = vec![1i];
+ /// vec.push_all(&[2i, 3, 4]);
/// assert_eq!(vec, vec![1, 2, 3, 4]);
/// ```
#[inline]
/// # Examples
///
/// ```
- /// let mut vec = vec![1, 2, 2, 3, 2];
+ /// let mut vec = vec![1i, 2, 2, 3, 2];
///
/// vec.dedup();
///
- /// assert_eq!(vec, vec![1, 2, 3, 2]);
+ /// assert_eq!(vec, vec![1i, 2, 3, 2]);
/// ```
#[stable]
pub fn dedup(&mut self) {
/// ```
/// fn foo(slice: &[int]) {}
///
- /// let vec = vec![1, 2];
+ /// let vec = vec![1i, 2];
/// foo(vec.as_slice());
/// ```
#[inline]
/// ```
/// use std::sync::atomic::AtomicPtr;
///
- /// let ptr = &mut 5;
+ /// let ptr = &mut 5i;
/// let atomic_ptr = AtomicPtr::new(ptr);
/// ```
#[inline]
/// ```
/// use std::sync::atomic::{AtomicPtr, Ordering};
///
- /// let ptr = &mut 5;
+ /// let ptr = &mut 5i;
/// let some_ptr = AtomicPtr::new(ptr);
///
/// let value = some_ptr.load(Ordering::Relaxed);
/// ```
/// use std::sync::atomic::{AtomicPtr, Ordering};
///
- /// let ptr = &mut 5;
+ /// let ptr = &mut 5i;
/// let some_ptr = AtomicPtr::new(ptr);
///
- /// let other_ptr = &mut 10;
+ /// let other_ptr = &mut 10i;
///
/// some_ptr.store(other_ptr, Ordering::Relaxed);
/// ```
/// ```
/// use std::sync::atomic::{AtomicPtr, Ordering};
///
- /// let ptr = &mut 5;
+ /// let ptr = &mut 5i;
/// let some_ptr = AtomicPtr::new(ptr);
///
- /// let other_ptr = &mut 10;
+ /// let other_ptr = &mut 10i;
///
/// let value = some_ptr.swap(other_ptr, Ordering::Relaxed);
/// ```
/// ```
/// use std::sync::atomic::{AtomicPtr, Ordering};
///
- /// let ptr = &mut 5;
+ /// let ptr = &mut 5i;
/// let some_ptr = AtomicPtr::new(ptr);
///
- /// let other_ptr = &mut 10;
- /// let another_ptr = &mut 10;
+ /// let other_ptr = &mut 10i;
+ /// let another_ptr = &mut 10i;
///
/// let value = some_ptr.compare_and_swap(other_ptr, another_ptr, Ordering::Relaxed);
/// ```
///
/// ```
/// use std::fmt::radix;
-/// assert_eq!(format!("{}", radix(55, 36)), "1j".to_string());
+/// assert_eq!(format!("{}", radix(55i, 36)), "1j".to_string());
/// ```
#[unstable = "may be renamed or move to a different module"]
pub fn radix<T>(x: T, base: u8) -> RadixFmt<T, Radix> {
//! translated to the `loop` below.
//!
//! ```rust
-//! let values = vec![1, 2, 3];
+//! let values = vec![1i, 2, 3];
//!
//! // "Syntactical sugar" taking advantage of an iterator
//! for &x in values.iter() {
/// # Example
///
/// ```rust
- /// let a = [0];
- /// let b = [1];
+ /// let a = [0i];
+ /// let b = [1i];
/// let mut it = a.iter().chain(b.iter());
/// assert_eq!(it.next().unwrap(), &0);
/// assert_eq!(it.next().unwrap(), &1);
/// # Example
///
/// ```rust
- /// let a = [0];
- /// let b = [1];
+ /// let a = [0i];
+ /// let b = [1i];
/// let mut it = a.iter().zip(b.iter());
- /// let (x0, x1) = (0, 1);
+ /// let (x0, x1) = (0i, 1i);
/// assert_eq!(it.next().unwrap(), (&x0, &x1));
/// assert!(it.next().is_none());
/// ```
/// # Example
///
/// ```rust
- /// let a = [1, 2];
+ /// let a = [1i, 2];
/// let mut it = a.iter().map(|&x| 2 * x);
/// assert_eq!(it.next().unwrap(), 2);
/// assert_eq!(it.next().unwrap(), 4);
/// # Example
///
/// ```rust
- /// let a = [1, 2];
+ /// let a = [1i, 2];
/// let mut it = a.iter().filter(|&x| *x > 1);
/// assert_eq!(it.next().unwrap(), &2);
/// assert!(it.next().is_none());
/// # Example
///
/// ```rust
- /// let a = [1, 2];
+ /// let a = [1i, 2];
/// let mut it = a.iter().filter_map(|&x| if x > 1 {Some(2 * x)} else {None});
/// assert_eq!(it.next().unwrap(), 4);
/// assert!(it.next().is_none());
/// # Example
///
/// ```rust
- /// let a = [100, 200];
+ /// let a = [100i, 200];
/// let mut it = a.iter().enumerate();
- /// let (x100, x200) = (100, 200);
+ /// let (x100, x200) = (100i, 200i);
/// assert_eq!(it.next().unwrap(), (0, &x100));
/// assert_eq!(it.next().unwrap(), (1, &x200));
/// assert!(it.next().is_none());
/// # Example
///
/// ```rust
- /// let xs = [100, 200, 300];
+ /// let xs = [100i, 200, 300];
/// let mut it = xs.iter().map(|x| *x).peekable();
/// assert_eq!(*it.peek().unwrap(), 100);
/// assert_eq!(it.next().unwrap(), 100);
/// # Example
///
/// ```rust
- /// let a = [1, 2, 3, 2, 1];
+ /// let a = [1i, 2, 3, 2, 1];
/// let mut it = a.iter().skip_while(|&a| *a < 3);
/// assert_eq!(it.next().unwrap(), &3);
/// assert_eq!(it.next().unwrap(), &2);
/// # Example
///
/// ```rust
- /// let a = [1, 2, 3, 2, 1];
+ /// let a = [1i, 2, 3, 2, 1];
/// let mut it = a.iter().take_while(|&a| *a < 3);
/// assert_eq!(it.next().unwrap(), &1);
/// assert_eq!(it.next().unwrap(), &2);
/// # Example
///
/// ```rust
- /// let a = [1, 2, 3, 4, 5];
+ /// let a = [1i, 2, 3, 4, 5];
/// let mut it = a.iter().skip(3);
/// assert_eq!(it.next().unwrap(), &4);
/// assert_eq!(it.next().unwrap(), &5);
/// # Example
///
/// ```rust
- /// let a = [1, 2, 3, 4, 5];
+ /// let a = [1i, 2, 3, 4, 5];
/// let mut it = a.iter().take(3);
/// assert_eq!(it.next().unwrap(), &1);
/// assert_eq!(it.next().unwrap(), &2);
/// # Example
///
/// ```rust
- /// let a = [1, 2, 3, 4, 5];
+ /// let a = [1i, 2, 3, 4, 5];
/// let mut it = a.iter().scan(1, |fac, &x| {
/// *fac = *fac * x;
/// Some(*fac)
/// }
/// sum
/// }
- /// let x = vec![1,2,3,7,8,9];
+ /// let x = vec![1i,2,3,7,8,9];
/// assert_eq!(process(x.into_iter()), 6);
- /// let x = vec![1,2,3];
+ /// let x = vec![1i,2,3];
/// assert_eq!(process(x.into_iter()), 1006);
/// ```
#[inline]
/// # Example
///
/// ```rust
- /// let a = [1, 2, 3, 4, 5];
+ /// let a = [1i, 2, 3, 4, 5];
/// let b: Vec<int> = a.iter().map(|&x| x).collect();
/// assert!(a.as_slice() == b.as_slice());
/// ```
/// do not.
///
/// ```
- /// let vec = vec![1, 2, 3, 4];
+ /// let vec = vec![1i, 2i, 3i, 4i];
/// let (even, odd): (Vec<int>, Vec<int>) = vec.into_iter().partition(|&n| n % 2 == 0);
/// assert_eq!(even, vec![2, 4]);
/// assert_eq!(odd, vec![1, 3]);
/// # Example
///
/// ```rust
- /// let a = [1, 2, 3, 4, 5];
+ /// let a = [1i, 2, 3, 4, 5];
/// assert!(a.iter().fold(0, |a, &b| a + b) == 15);
/// ```
#[inline]
/// # Example
///
/// ```rust
- /// let a = [1, 2, 3, 4, 5];
+ /// let a = [1i, 2, 3, 4, 5];
/// assert!(a.iter().all(|x| *x > 0));
/// assert!(!a.iter().all(|x| *x > 2));
/// ```
/// # Example
///
/// ```rust
- /// let a = [1, 2, 3, 4, 5];
+ /// let a = [1i, 2, 3, 4, 5];
/// let mut it = a.iter();
/// assert!(it.any(|x| *x == 3));
/// assert!(!it.any(|x| *x == 3));
/// ```rust
/// use core::num::SignedInt;
///
- /// let xs = [-3, 0, 1, 5, -10];
+ /// let xs = [-3i, 0, 1, 5, -10];
/// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
/// ```
#[inline]
/// ```rust
/// use core::num::SignedInt;
///
- /// let xs = [-3, 0, 1, 5, -10];
+ /// let xs = [-3i, 0, 1, 5, -10];
/// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
/// ```
#[inline]
/// ```rust
/// use std::iter::AdditiveIterator;
///
- /// let a: [i32] = [1, 2, 3, 4, 5];
+ /// let a = [1i, 2, 3, 4, 5];
/// let mut it = a.iter().map(|&x| x);
/// assert!(it.sum() == 15);
/// ```
impl_multiplicative! { f32, 1.0 }
impl_multiplicative! { f64, 1.0 }
+<<<<<<< HEAD
+=======
+/// A trait for iterators over elements which can be compared to one another.
+#[unstable = "recently renamed for new extension trait conventions"]
+pub trait IteratorOrdExt<A> {
+ /// Consumes the entire iterator to return the maximum element.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let a = [1i, 2, 3, 4, 5];
+ /// assert!(a.iter().max().unwrap() == &5);
+ /// ```
+ fn max(self) -> Option<A>;
+
+ /// Consumes the entire iterator to return the minimum element.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let a = [1i, 2, 3, 4, 5];
+ /// assert!(a.iter().min().unwrap() == &1);
+ /// ```
+ fn min(self) -> Option<A>;
+
+ /// `min_max` finds the minimum and maximum elements in the iterator.
+ ///
+ /// The return type `MinMaxResult` is an enum of three variants:
+ ///
+ /// - `NoElements` if the iterator is empty.
+ /// - `OneElement(x)` if the iterator has exactly one element.
+ /// - `MinMax(x, y)` is returned otherwise, where `x <= y`. Two
+ /// values are equal if and only if there is more than one
+ /// element in the iterator and all elements are equal.
+ ///
+ /// On an iterator of length `n`, `min_max` does `1.5 * n` comparisons,
+ /// and so is faster than calling `min` and `max` separately which does `2 * n` comparisons.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax};
+ ///
+ /// let v: [int; 0] = [];
+ /// assert_eq!(v.iter().min_max(), NoElements);
+ ///
+ /// let v = [1i];
+ /// assert!(v.iter().min_max() == OneElement(&1));
+ ///
+ /// let v = [1i, 2, 3, 4, 5];
+ /// assert!(v.iter().min_max() == MinMax(&1, &5));
+ ///
+ /// let v = [1i, 2, 3, 4, 5, 6];
+ /// assert!(v.iter().min_max() == MinMax(&1, &6));
+ ///
+ /// let v = [1i, 1, 1, 1];
+ /// assert!(v.iter().min_max() == MinMax(&1, &1));
+ /// ```
+ fn min_max(self) -> MinMaxResult<A>;
+}
+
+#[unstable = "trait is unstable"]
+impl<T, I> IteratorOrdExt<T> for I where I: Iterator<Item=T>, T: Ord {
+ #[inline]
+ fn max(self) -> Option<T> {
+ self.fold(None, |max, x| {
+ match max {
+ None => Some(x),
+ Some(y) => Some(cmp::max(x, y))
+ }
+ })
+ }
+
+ #[inline]
+ fn min(self) -> Option<T> {
+ self.fold(None, |min, x| {
+ match min {
+ None => Some(x),
+ Some(y) => Some(cmp::min(x, y))
+ }
+ })
+ }
+
+ fn min_max(mut self) -> MinMaxResult<T> {
+ let (mut min, mut max) = match self.next() {
+ None => return NoElements,
+ Some(x) => {
+ match self.next() {
+ None => return OneElement(x),
+ Some(y) => if x < y {(x, y)} else {(y,x)}
+ }
+ }
+ };
+
+ loop {
+ // `first` and `second` are the two next elements we want to look at.
+ // We first compare `first` and `second` (#1). The smaller one is then compared to
+ // current minimum (#2). The larger one is compared to current maximum (#3). This
+ // way we do 3 comparisons for 2 elements.
+ let first = match self.next() {
+ None => break,
+ Some(x) => x
+ };
+ let second = match self.next() {
+ None => {
+ if first < min {
+ min = first;
+ } else if first > max {
+ max = first;
+ }
+ break;
+ }
+ Some(x) => x
+ };
+ if first < second {
+ if first < min {min = first;}
+ if max < second {max = second;}
+ } else {
+ if second < min {min = second;}
+ if max < first {max = first;}
+ }
+ }
+
+ MinMax(min, max)
+ }
+}
+
+>>>>>>> parent of f031671... Remove i suffix in docs
/// `MinMaxResult` is an enum returned by `min_max`. See `IteratorOrdExt::min_max` for more detail.
#[derive(Clone, PartialEq, Show)]
#[unstable = "unclear whether such a fine-grained result is widely useful"]
/// let r: MinMaxResult<int> = NoElements;
/// assert_eq!(r.into_option(), None);
///
- /// let r = OneElement(1);
+ /// let r = OneElement(1i);
/// assert_eq!(r.into_option(), Some((1,1)));
///
- /// let r = MinMax(1, 2);
+ /// let r = MinMax(1i,2i);
/// assert_eq!(r.into_option(), Some((1,2)));
/// ```
#[unstable = "type is unstable"]
I: ExactSizeIterator + Iterator<Item=D>,
{}
+<<<<<<< HEAD
+=======
+#[unstable = "recently renamed for extension trait conventions"]
+/// An extension trait for cloneable iterators.
+pub trait CloneIteratorExt {
+ /// Repeats an iterator endlessly
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use std::iter::{CloneIteratorExt, count};
+ ///
+ /// let a = count(1i,1i).take(1);
+ /// let mut cy = a.cycle();
+ /// assert_eq!(cy.next(), Some(1));
+ /// assert_eq!(cy.next(), Some(1));
+ /// ```
+ #[stable]
+ fn cycle(self) -> Cycle<Self>;
+}
+
+impl<I> CloneIteratorExt for I where I: Iterator + Clone {
+ #[inline]
+ fn cycle(self) -> Cycle<I> {
+ Cycle{orig: self.clone(), iter: self}
+ }
+}
+
+>>>>>>> parent of f031671... Remove i suffix in docs
/// An iterator that repeats endlessly
#[derive(Clone, Copy)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
/// ```
/// use std::mem;
///
-/// let x = &mut 5;
-/// let y = &mut 42;
+/// let x = &mut 5i;
+/// let y = &mut 42i;
///
/// mem::swap(x, y);
///
-/// assert_eq!(42, *x);
-/// assert_eq!(5, *y);
+/// assert_eq!(42i, *x);
+/// assert_eq!(5i, *y);
/// ```
#[inline]
#[stable]
/// ```rust
/// use std::num::Int;
///
- /// assert_eq!(2.pow(4), 16);
+ /// assert_eq!(2i.pow(4), 16);
/// ```
#[inline]
fn pow(self, mut exp: uint) -> Self {
///
/// ```
/// let x = Some("foo");
- /// assert_eq!(x.ok_or(0), Ok("foo"));
+ /// assert_eq!(x.ok_or(0i), Ok("foo"));
///
/// let x: Option<&str> = None;
- /// assert_eq!(x.ok_or(0), Err(0));
+ /// assert_eq!(x.ok_or(0i), Err(0i));
/// ```
#[inline]
#[experimental]
///
/// ```
/// let x = Some("foo");
- /// assert_eq!(x.ok_or_else(|| 0), Ok("foo"));
+ /// assert_eq!(x.ok_or_else(|| 0i), Ok("foo"));
///
/// let x: Option<&str> = None;
- /// assert_eq!(x.ok_or_else(|| 0), Err(0));
+ /// assert_eq!(x.ok_or_else(|| 0i), Err(0i));
/// ```
#[inline]
#[experimental]
/// let good_year = good_year_from_input.parse().unwrap_or_default();
/// let bad_year = bad_year_from_input.parse().unwrap_or_default();
///
- /// assert_eq!(1909, good_year);
- /// assert_eq!(0, bad_year);
+ /// assert_eq!(1909i, good_year);
+ /// assert_eq!(0i, bad_year);
/// ```
#[inline]
#[stable]
/// #[macro_use] extern crate log;
///
/// fn main() {
-/// let ret = 3;
+/// let ret = 3i;
/// info!("this function is about to return: {}", ret);
/// }
/// ```
/// #[macro_use] extern crate log;
///
/// fn main() {
-/// debug!("x = {x}, y = {y}", x=10, y=20);
+/// debug!("x = {x}, y = {y}", x=10i, y=20i);
/// }
/// ```
///
/// ```
/// use std::rand::{thread_rng, Rng};
///
- /// let choices = [1, 2, 4, 8, 16, 32];
+ /// let choices = [1i, 2, 4, 8, 16, 32];
/// let mut rng = thread_rng();
/// println!("{}", rng.choose(&choices));
/// # // replace with slicing syntax when it's stable!
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
- /// let mut y = [1, 2, 3];
+ /// let mut y = [1i, 2, 3];
/// rng.shuffle(&mut y);
/// println!("{}", y.as_slice());
/// rng.shuffle(&mut y);
///
/// let h = SipHasher::new();
/// let mut set = HashSet::with_capacity_and_hasher(10u, h);
- /// set.insert(1);
+ /// set.insert(1i);
/// ```
#[inline]
#[unstable = "hasher stuff is unclear"]
///
/// ```
/// use std::collections::HashSet;
- /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
///
/// // Can be seen as `a - b`.
/// for x in a.difference(&b) {
/// }
///
/// let diff: HashSet<int> = a.difference(&b).map(|&x| x).collect();
- /// assert_eq!(diff, [1].iter().map(|&x| x).collect());
+ /// assert_eq!(diff, [1i].iter().map(|&x| x).collect());
///
/// // Note that difference is not symmetric,
/// // and `b - a` means something else:
/// let diff: HashSet<int> = b.difference(&a).map(|&x| x).collect();
- /// assert_eq!(diff, [4].iter().map(|&x| x).collect());
+ /// assert_eq!(diff, [4i].iter().map(|&x| x).collect());
/// ```
#[stable]
pub fn difference<'a>(&'a self, other: &'a HashSet<T, H>) -> Difference<'a, T, H> {
///
/// ```
/// use std::collections::HashSet;
- /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
///
/// // Print 1, 4 in arbitrary order.
/// for x in a.symmetric_difference(&b) {
/// let diff2: HashSet<int> = b.symmetric_difference(&a).map(|&x| x).collect();
///
/// assert_eq!(diff1, diff2);
- /// assert_eq!(diff1, [1, 4].iter().map(|&x| x).collect());
+ /// assert_eq!(diff1, [1i, 4].iter().map(|&x| x).collect());
/// ```
#[stable]
pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, H>)
///
/// ```
/// use std::collections::HashSet;
- /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
///
/// // Print 2, 3 in arbitrary order.
/// for x in a.intersection(&b) {
/// }
///
/// let diff: HashSet<int> = a.intersection(&b).map(|&x| x).collect();
- /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect());
+ /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect());
/// ```
#[stable]
pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>) -> Intersection<'a, T, H> {
///
/// ```
/// use std::collections::HashSet;
- /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
- /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+ /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
///
/// // Print 1, 2, 3, 4 in arbitrary order.
/// for x in a.union(&b) {
/// }
///
/// let diff: HashSet<int> = a.union(&b).map(|&x| x).collect();
- /// assert_eq!(diff, [1, 2, 3, 4].iter().map(|&x| x).collect());
+ /// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect());
/// ```
#[stable]
pub fn union<'a>(&'a self, other: &'a HashSet<T, H>) -> Union<'a, T, H> {
/// # #![allow(unreachable_code)]
/// panic!();
/// panic!("this is a terrible mistake!");
-/// panic!(4); // panic with the value of 4 to be collected elsewhere
+/// panic!(4i); // panic with the value of 4 to be collected elsewhere
/// panic!("this is a {} {message}", "fancy", message = "message");
/// ```
#[macro_export]
/// // assert with a custom message
/// # let x = true;
/// assert!(x, "x wasn't true!");
-/// # let a = 3; let b = 27;
+/// # let a = 3i; let b = 27i;
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]
/// # Example
///
/// ```
-/// let a = 3;
-/// let b = 1 + 2;
+/// let a = 3i;
+/// let b = 1i + 2i;
/// assert_eq!(a, b);
/// ```
#[macro_export]
/// // assert with a custom message
/// # let x = true;
/// debug_assert!(x, "x wasn't true!");
-/// # let a = 3; let b = 27;
+/// # let a = 3i; let b = 27i;
/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]
/// # Example
///
/// ```
-/// let a = 3;
-/// let b = 1 + 2;
+/// let a = 3i;
+/// let b = 1i + 2i;
/// debug_assert_eq!(a, b);
/// ```
#[macro_export]
/// ```
/// format!("test");
/// format!("hello {}", "world!");
-/// format!("x = {}, y = {y}", 10, y = 30);
+/// format!("x = {}, y = {y}", 10i, y = 30i);
/// ```
#[macro_export]
#[stable]
/// let (tx1, rx1) = channel();
/// let (tx2, rx2) = channel();
/// # fn long_running_task() {}
-/// # fn calculate_the_answer() -> int { 42 }
+/// # fn calculate_the_answer() -> int { 42i }
///
/// Thread::spawn(move|| { long_running_task(); tx1.send(()) }).detach();
/// Thread::spawn(move|| { tx2.send(calculate_the_answer()) }).detach();
/// # Example
///
/// ```
- /// let s = concat!("test", 10, 'b', true);
+ /// let s = concat!("test", 10i, 'b', true);
/// assert_eq!(s, "test10btrue");
/// ```
#[macro_export]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Communication primitives for concurrent tasks
-//!
-//! Rust makes it very difficult to share data among tasks to prevent race
-//! conditions and to improve parallelism, but there is often a need for
-//! communication between concurrent tasks. The primitives defined in this
-//! module are the building blocks for synchronization in rust.
+//! Multi-producer, single-consumer communication primitives threads
//!
//! This module provides message-based communication over channels, concretely
//! defined among three types:
//! * `Receiver`
//!
//! A `Sender` or `SyncSender` is used to send data to a `Receiver`. Both
-//! senders are clone-able such that many tasks can send simultaneously to one
-//! receiver. These channels are *task blocking*, not *thread blocking*. This
-//! means that if one task is blocked on a channel, other tasks can continue to
-//! make progress.
+//! senders are clone-able (multi-producer) such that many threads can send
+//! simultaneously to one receiver (single-consumer).
//!
-//! Rust channels come in one of two flavors:
+//! These channels come in two flavors:
//!
//! 1. An asynchronous, infinitely buffered channel. The `channel()` function
//! will return a `(Sender, Receiver)` tuple where all sends will be
//! "rendezvous" channel where each sender atomically hands off a message to
//! a receiver.
//!
-//! ## Panic Propagation
+//! ## Disconnection
//!
-//! In addition to being a core primitive for communicating in rust, channels
-//! are the points at which panics are propagated among tasks. Whenever the one
-//! half of channel is closed, the other half will have its next operation
-//! `panic!`. The purpose of this is to allow propagation of panics among tasks
-//! that are linked to one another via channels.
+//! The send and receive operations on channels will all return a `Result`
+//! indicating whether the operation succeeded or not. An unsuccessful operation
+//! is normally indicative of the other half of a channel having "hung up" by
+//! being dropped in its corresponding thread.
//!
-//! There are methods on both of senders and receivers to perform their
-//! respective operations without panicking, however.
+//! Once half of a channel has been deallocated, most operations can no longer
+//! continue to make progress, so `Err` will be returned. Many applications will
+//! continue to `unwrap()` the results returned from this module, instigating a
+//! propagation of failure among threads if one unexpectedly dies.
//!
-//! # Example
+//! # Examples
//!
//! Simple usage:
//!
//! ```
//! use std::thread::Thread;
+//! use std::sync::mpsc::channel;
//!
//! // Create a simple streaming channel
//! let (tx, rx) = channel();
//! Thread::spawn(move|| {
-//! tx.send(10);
+//! tx.send(10i).unwrap();
//! }).detach();
-//! assert_eq!(rx.recv(), 10);
+//! assert_eq!(rx.recv().unwrap(), 10i);
//! ```
//!
//! Shared usage:
//!
//! ```
//! use std::thread::Thread;
+//! use std::sync::mpsc::channel;
//!
//! // Create a shared channel that can be sent along from many threads
//! // where tx is the sending half (tx for transmission), and rx is the receiving
//! for i in range(0i, 10i) {
//! let tx = tx.clone();
//! Thread::spawn(move|| {
-//! tx.send(i);
+//! tx.send(i).unwrap();
//! }).detach()
//! }
//!
//! for _ in range(0i, 10i) {
-//! let j = rx.recv();
+//! let j = rx.recv().unwrap();
//! assert!(0 <= j && j < 10);
//! }
//! ```
//!
//! Propagating panics:
//!
-//! ```should_fail
-//! // The call to recv() will panic!() because the channel has already hung
-//! // up (or been deallocated)
+//! ```
+//! use std::sync::mpsc::channel;
+//!
+//! // The call to recv() will return an error because the channel has already
+//! // hung up (or been deallocated)
//! let (tx, rx) = channel::<int>();
//! drop(tx);
-//! rx.recv();
+//! assert!(rx.recv().is_err());
//! ```
//!
//! Synchronous channels:
//!
//! ```
//! use std::thread::Thread;
+//! use std::sync::mpsc::sync_channel;
//!
//! let (tx, rx) = sync_channel::<int>(0);
//! Thread::spawn(move|| {
//! // This will wait for the parent task to start receiving
-//! tx.send(53);
+//! tx.send(53).unwrap();
//! }).detach();
-//! rx.recv();
+//! rx.recv().unwrap();
//! ```
//!
//! Reading from a channel with a timeout requires to use a Timer together
//! after 10 seconds no matter what:
//!
//! ```no_run
+//! use std::sync::mpsc::channel;
//! use std::io::timer::Timer;
//! use std::time::Duration;
//!
//!
//! loop {
//! select! {
-//! val = rx.recv() => println!("Received {}", val),
-//! () = timeout.recv() => {
+//! val = rx.recv() => println!("Received {}", val.unwrap()),
+//! _ = timeout.recv() => {
//! println!("timed out, total time was more than 10 seconds");
//! break;
//! }
//! has been inactive for 5 seconds:
//!
//! ```no_run
+//! use std::sync::mpsc::channel;
//! use std::io::timer::Timer;
//! use std::time::Duration;
//!
//! let timeout = timer.oneshot(Duration::seconds(5));
//!
//! select! {
-//! val = rx.recv() => println!("Received {}", val),
-//! () = timeout.recv() => {
+//! val = rx.recv() => println!("Received {}", val.unwrap()),
+//! _ = timeout.recv() => {
//! println!("timed out, no message received in 5 seconds");
//! break;
//! }
// And now that you've seen all the races that I found and attempted to fix,
// here's the code for you to find some more!
-use core::prelude::*;
+use prelude::v1::*;
-pub use self::TryRecvError::*;
-pub use self::TrySendError::*;
-
-use alloc::arc::Arc;
-use core::kinds;
-use core::kinds::marker;
-use core::mem;
-use core::cell::UnsafeCell;
+use sync::Arc;
+use fmt;
+use kinds::marker;
+use mem;
+use cell::UnsafeCell;
pub use self::select::{Select, Handle};
use self::select::StartResult;
use self::select::StartResult::*;
use self::blocking::SignalToken;
-macro_rules! test {
- { fn $name:ident() $b:block $(#[$a:meta])*} => (
- mod $name {
- #![allow(unused_imports)]
-
- use super::*;
- use comm::*;
- use thread::Thread;
- use prelude::{Ok, Err, spawn, range, drop, Box, Some, None, Option};
- use prelude::{Vec, Buffer, from_str, Clone};
-
- $(#[$a])* #[test] fn f() { $b }
- }
- )
-}
-
mod blocking;
mod oneshot;
mod select;
/// The receiving-half of Rust's channel type. This half can only be owned by
/// one task
-#[unstable]
+#[stable]
pub struct Receiver<T> {
inner: UnsafeCell<Flavor<T>>,
}
/// An iterator over messages on a receiver, this iterator will block
/// whenever `next` is called, waiting for a new message, and `None` will be
/// returned when the corresponding channel has hung up.
-#[unstable]
-pub struct Messages<'a, T:'a> {
+#[stable]
+pub struct Iter<'a, T:'a> {
rx: &'a Receiver<T>
}
/// The sending-half of Rust's asynchronous channel type. This half can only be
/// owned by one task, but it can be cloned to send to other tasks.
-#[unstable]
+#[stable]
pub struct Sender<T> {
inner: UnsafeCell<Flavor<T>>,
}
/// The sending-half of Rust's synchronous channel type. This half can only be
/// owned by one task, but it can be cloned to send to other tasks.
-#[unstable = "this type may be renamed, but it will always exist"]
+#[stable]
pub struct SyncSender<T> {
inner: Arc<RacyCell<sync::Packet<T>>>,
// can't share in an arc
_marker: marker::NoSync,
}
+/// An error returned from the `send` function on channels.
+///
+/// A `send` operation can only fail if the receiving end of a channel is
+/// disconnected, implying that the data could never be received. The error
+/// contains the data being sent as a payload so it can be recovered.
+#[derive(PartialEq, Eq)]
+#[stable]
+pub struct SendError<T>(pub T);
+
+/// An error returned from the `recv` function on a `Receiver`.
+///
+/// The `recv` operation can only fail if the sending half of a channel is
+/// disconnected, implying that no further messages will ever be received.
+#[derive(PartialEq, Eq, Clone, Copy)]
+#[stable]
+pub struct RecvError;
+
/// This enumeration is the list of the possible reasons that try_recv could not
/// return data when called.
-#[deriving(PartialEq, Clone, Copy, Show)]
-#[experimental = "this is likely to be removed in changing try_recv()"]
+#[derive(PartialEq, Clone, Copy)]
+#[stable]
pub enum TryRecvError {
/// This channel is currently empty, but the sender(s) have not yet
/// disconnected, so data may yet become available.
+ #[stable]
Empty,
+
/// This channel's sending half has become disconnected, and there will
/// never be any more data received on this channel
+ #[stable]
Disconnected,
}
/// This enumeration is the list of the possible error outcomes for the
/// `SyncSender::try_send` method.
-#[deriving(PartialEq, Clone, Show)]
-#[experimental = "this is likely to be removed in changing try_send()"]
+#[derive(PartialEq, Clone)]
+#[stable]
pub enum TrySendError<T> {
/// The data could not be sent on the channel because it would require that
/// the callee block to send the data.
/// If this is a buffered channel, then the buffer is full at this time. If
/// this is not a buffered channel, then there is no receiver available to
/// acquire the data.
+ #[stable]
Full(T),
+
/// This channel's receiving half has disconnected, so the data could not be
/// sent. The data is returned back to the callee in this case.
- RecvDisconnected(T),
+ #[stable]
+ Disconnected(T),
}
enum Flavor<T> {
/// # Example
///
/// ```
+/// use std::sync::mpsc::channel;
/// use std::thread::Thread;
///
/// // tx is is the sending half (tx for transmission), and rx is the receiving
/// // Spawn off an expensive computation
/// Thread::spawn(move|| {
/// # fn expensive_computation() {}
-/// tx.send(expensive_computation());
+/// tx.send(expensive_computation()).unwrap();
/// }).detach();
///
/// // Do some useful work for awhile
///
/// // Let's see what that answer was
-/// println!("{}", rx.recv());
+/// println!("{}", rx.recv().unwrap());
/// ```
-#[unstable]
+#[stable]
pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
let a = Arc::new(RacyCell::new(oneshot::Packet::new()));
(Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a)))
/// # Example
///
/// ```
+/// use std::sync::mpsc::sync_channel;
/// use std::thread::Thread;
///
/// let (tx, rx) = sync_channel(1);
///
/// // this returns immediately
-/// tx.send(1);
+/// tx.send(1i).unwrap();
///
/// Thread::spawn(move|| {
/// // this will block until the previous message has been received
-/// tx.send(2);
+/// tx.send(2i).unwrap();
/// }).detach();
///
-/// assert_eq!(rx.recv(), 1);
-/// assert_eq!(rx.recv(), 2);
+/// assert_eq!(rx.recv().unwrap(), 1i);
+/// assert_eq!(rx.recv().unwrap(), 2i);
/// ```
-#[unstable = "this function may be renamed to more accurately reflect the type \
- of channel that is is creating"]
+#[stable]
pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
let a = Arc::new(RacyCell::new(sync::Packet::new(bound)));
(SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a)))
}
}
- /// Sends a value along this channel to be received by the corresponding
- /// receiver.
- ///
- /// Rust channels are infinitely buffered so this method will never block.
- ///
- /// # Panics
- ///
- /// This function will panic if the other end of the channel has hung up.
- /// This means that if the corresponding receiver has fallen out of scope,
- /// this function will trigger a panic message saying that a message is
- /// being sent on a closed channel.
- ///
- /// Note that if this function does *not* panic, it does not mean that the
- /// data will be successfully received. All sends are placed into a queue,
- /// so it is possible for a send to succeed (the other end is alive), but
- /// then the other end could immediately disconnect.
- ///
- /// The purpose of this functionality is to propagate panics among tasks.
- /// If a panic is not desired, then consider using the `send_opt` method
- #[experimental = "this function is being considered candidate for removal \
- to adhere to the general guidelines of rust"]
- pub fn send(&self, t: T) {
- if self.send_opt(t).is_err() {
- panic!("sending on a closed channel");
- }
- }
-
/// Attempts to send a value on this channel, returning it back if it could
/// not be sent.
///
/// will be received. It is possible for the corresponding receiver to
/// hang up immediately after this function returns `Ok`.
///
- /// Like `send`, this method will never block.
- ///
- /// # Panics
- ///
- /// This method will never panic, it will return the message back to the
- /// caller if the other end is disconnected
+ /// This method will never block the current thread.
///
/// # Example
///
/// ```
+ /// use std::sync::mpsc::channel;
+ ///
/// let (tx, rx) = channel();
///
/// // This send is always successful
- /// assert_eq!(tx.send_opt(1), Ok(()));
+ /// tx.send(1i).unwrap();
///
/// // This send will fail because the receiver is gone
/// drop(rx);
- /// assert_eq!(tx.send_opt(1), Err(1));
+ /// assert_eq!(tx.send(1i).err().unwrap().0, 1);
/// ```
#[stable]
pub fn send(&self, t: T) -> Result<(), SendError<T>> {
unsafe {
let p = p.get();
if !(*p).sent() {
- return (*p).send(t);
+ return (*p).send(t).map_err(SendError);
} else {
let a =
Arc::new(RacyCell::new(stream::Packet::new()));
- match (*p).upgrade(Receiver::new(Flavor::Stream(a.clone()))) {
+ let rx = Receiver::new(Flavor::Stream(a.clone()));
+ match (*p).upgrade(rx) {
oneshot::UpSuccess => {
let ret = (*a.get()).send(t);
(a, ret)
// asleep (we're looking at it), so the receiver
// can't go away.
(*a.get()).send(t).ok().unwrap();
- token.signal();
+ token.signal();
(a, Ok(()))
}
}
}
}
}
- Flavor::Stream(ref p) => return unsafe { (*p.get()).send(t) },
- Flavor::Shared(ref p) => return unsafe { (*p.get()).send(t) },
+ Flavor::Stream(ref p) => return unsafe {
+ (*p.get()).send(t).map_err(SendError)
+ },
+ Flavor::Shared(ref p) => return unsafe {
+ (*p.get()).send(t).map_err(SendError)
+ },
Flavor::Sync(..) => unreachable!(),
};
let tmp = Sender::new(Flavor::Stream(new_inner));
mem::swap(self.inner_mut(), tmp.inner_mut());
}
- return ret;
+ ret.map_err(SendError)
}
}
let a = Arc::new(RacyCell::new(shared::Packet::new()));
unsafe {
let guard = (*a.get()).postinit_lock();
- match (*p.get()).upgrade(Receiver::new(Flavor::Shared(a.clone()))) {
+ let rx = Receiver::new(Flavor::Shared(a.clone()));
+ match (*p.get()).upgrade(rx) {
oneshot::UpSuccess |
oneshot::UpDisconnected => (a, None, guard),
oneshot::UpWoke(task) => (a, Some(task), guard)
let a = Arc::new(RacyCell::new(shared::Packet::new()));
unsafe {
let guard = (*a.get()).postinit_lock();
- match (*p.get()).upgrade(Receiver::new(Flavor::Shared(a.clone()))) {
+ let rx = Receiver::new(Flavor::Shared(a.clone()));
+ match (*p.get()).upgrade(rx) {
stream::UpSuccess |
stream::UpDisconnected => (a, None, guard),
stream::UpWoke(task) => (a, Some(task), guard),
/// available or a receiver is available to hand off the message to.
///
/// Note that a successful send does *not* guarantee that the receiver will
- /// ever see the data if there is a buffer on this channel. Messages may be
+ /// ever see the data if there is a buffer on this channel. Items may be
/// enqueued in the internal buffer for the receiver to receive at a later
/// time. If the buffer size is 0, however, it can be guaranteed that the
/// receiver has indeed received the data if this function returns success.
///
- /// # Panics
- ///
- /// Similarly to `Sender::send`, this function will panic if the
- /// corresponding `Receiver` for this channel has disconnected. This
- /// behavior is used to propagate panics among tasks.
- ///
- /// If a panic is not desired, you can achieve the same semantics with the
- /// `SyncSender::send_opt` method which will not panic if the receiver
- /// disconnects.
- #[experimental = "this function is being considered candidate for removal \
- to adhere to the general guidelines of rust"]
- pub fn send(&self, t: T) {
- if self.send_opt(t).is_err() {
- panic!("sending on a closed channel");
- }
- }
-
- /// Send a value on a channel, returning it back if the receiver
- /// disconnected
- ///
- /// This method will *block* to send the value `t` on the channel, but if
- /// the value could not be sent due to the receiver disconnecting, the value
- /// is returned back to the callee. This function is similar to `try_send`,
- /// except that it will block if the channel is currently full.
- ///
- /// # Panics
- ///
- /// This function cannot panic.
- #[unstable = "this function may be renamed to send() in the future"]
- pub fn send_opt(&self, t: T) -> Result<(), T> {
- unsafe { (*self.inner.get()).send(t) }
+ /// This function will never panic, but it may return `Err` if the
+ /// `Receiver` has disconnected and is no longer able to receive
+ /// information.
+ #[stable]
+ pub fn send(&self, t: T) -> Result<(), SendError<T>> {
+ unsafe { (*self.inner.get()).send(t).map_err(SendError) }
}
/// Attempts to send a value on this channel without blocking.
///
- /// This method differs from `send_opt` by returning immediately if the
+ /// This method differs from `send` by returning immediately if the
/// channel's buffer is full or no receiver is waiting to acquire some
- /// data. Compared with `send_opt`, this function has two failure cases
+ /// data. Compared with `send`, this function has two failure cases
/// instead of one (one for disconnection, one for a full buffer).
///
/// See `SyncSender::send` for notes about guarantees of whether the
/// receiver has received the data or not if this function is successful.
- ///
- /// # Panics
- ///
- /// This function cannot panic
- #[unstable = "the return type of this function is candidate for \
- modification"]
+ #[stable]
pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
unsafe { (*self.inner.get()).try_send(t) }
}
Receiver { inner: UnsafeCell::new(inner) }
}
- /// Blocks waiting for a value on this receiver
- ///
- /// This function will block if necessary to wait for a corresponding send
- /// on the channel from its paired `Sender` structure. This receiver will
- /// be woken up when data is ready, and the data will be returned.
- ///
- /// # Panics
- ///
- /// Similar to channels, this method will trigger a task panic if the
- /// other end of the channel has hung up (been deallocated). The purpose of
- /// this is to propagate panics among tasks.
- ///
- /// If a panic is not desired, then there are two options:
- ///
- /// * If blocking is still desired, the `recv_opt` method will return `None`
- /// when the other end hangs up
- ///
- /// * If blocking is not desired, then the `try_recv` method will attempt to
- /// peek at a value on this receiver.
- #[experimental = "this function is being considered candidate for removal \
- to adhere to the general guidelines of rust"]
- pub fn recv(&self) -> T {
- match self.recv_opt() {
- Ok(t) => t,
- Err(()) => panic!("receiving on a closed channel"),
- }
- }
-
/// Attempts to return a pending value on this receiver without blocking
///
/// This method will never block the caller in order to wait for data to
///
/// This is useful for a flavor of "optimistic check" before deciding to
/// block on a receiver.
- ///
- /// # Panics
- ///
- /// This function cannot panic.
- #[unstable = "the return type of this function may be altered"]
+ #[stable]
pub fn try_recv(&self) -> Result<T, TryRecvError> {
loop {
let new_port = match *unsafe { self.inner() } {
Flavor::Oneshot(ref p) => {
match unsafe { (*p.get()).try_recv() } {
Ok(t) => return Ok(t),
- Err(oneshot::Empty) => return Err(Empty),
- Err(oneshot::Disconnected) => return Err(Disconnected),
+ Err(oneshot::Empty) => return Err(TryRecvError::Empty),
+ Err(oneshot::Disconnected) => {
+ return Err(TryRecvError::Disconnected)
+ }
Err(oneshot::Upgraded(rx)) => rx,
}
}
Flavor::Stream(ref p) => {
match unsafe { (*p.get()).try_recv() } {
Ok(t) => return Ok(t),
- Err(stream::Empty) => return Err(Empty),
- Err(stream::Disconnected) => return Err(Disconnected),
+ Err(stream::Empty) => return Err(TryRecvError::Empty),
+ Err(stream::Disconnected) => {
+ return Err(TryRecvError::Disconnected)
+ }
Err(stream::Upgraded(rx)) => rx,
}
}
Flavor::Shared(ref p) => {
match unsafe { (*p.get()).try_recv() } {
Ok(t) => return Ok(t),
- Err(shared::Empty) => return Err(Empty),
- Err(shared::Disconnected) => return Err(Disconnected),
+ Err(shared::Empty) => return Err(TryRecvError::Empty),
+ Err(shared::Disconnected) => {
+ return Err(TryRecvError::Disconnected)
+ }
}
}
Flavor::Sync(ref p) => {
match unsafe { (*p.get()).try_recv() } {
Ok(t) => return Ok(t),
- Err(sync::Empty) => return Err(Empty),
- Err(sync::Disconnected) => return Err(Disconnected),
+ Err(sync::Empty) => return Err(TryRecvError::Empty),
+ Err(sync::Disconnected) => {
+ return Err(TryRecvError::Disconnected)
+ }
}
}
};
}
}
- /// Attempt to wait for a value on this receiver, but does not panic if the
+ /// Attempt to wait for a value on this receiver, returning an error if the
/// corresponding channel has hung up.
///
- /// This implementation of iterators for ports will always block if there is
- /// not data available on the receiver, but it will not panic in the case
- /// that the channel has been deallocated.
+ /// This function will always block the current thread if there is no data
+ /// available and it's possible for more data to be sent. Once a message is
+ /// sent to the corresponding `Sender`, then this receiver will wake up and
+ /// return that message.
///
- /// In other words, this function has the same semantics as the `recv`
- /// method except for the panic aspect.
- ///
- /// If the channel has hung up, then `Err` is returned. Otherwise `Ok` of
- /// the value found on the receiver is returned.
- #[unstable = "this function may be renamed to recv()"]
- pub fn recv_opt(&self) -> Result<T, ()> {
+ /// If the corresponding `Sender` has disconnected, or it disconnects while
+ /// this call is blocking, this call will wake up and return `Err` to
+ /// indicate that no more messages can ever be received on this channel.
+ #[stable]
+ pub fn recv(&self) -> Result<T, RecvError> {
loop {
let new_port = match *unsafe { self.inner() } {
Flavor::Oneshot(ref p) => {
match unsafe { (*p.get()).recv() } {
Ok(t) => return Ok(t),
Err(oneshot::Empty) => return unreachable!(),
- Err(oneshot::Disconnected) => return Err(()),
+ Err(oneshot::Disconnected) => return Err(RecvError),
Err(oneshot::Upgraded(rx)) => rx,
}
}
match unsafe { (*p.get()).recv() } {
Ok(t) => return Ok(t),
Err(stream::Empty) => return unreachable!(),
- Err(stream::Disconnected) => return Err(()),
+ Err(stream::Disconnected) => return Err(RecvError),
Err(stream::Upgraded(rx)) => rx,
}
}
match unsafe { (*p.get()).recv() } {
Ok(t) => return Ok(t),
Err(shared::Empty) => return unreachable!(),
- Err(shared::Disconnected) => return Err(()),
+ Err(shared::Disconnected) => return Err(RecvError),
}
}
- Flavor::Sync(ref p) => return unsafe { (*p.get()).recv() }
+ Flavor::Sync(ref p) => return unsafe {
+ (*p.get()).recv().map_err(|()| RecvError)
+ }
};
unsafe {
mem::swap(self.inner_mut(), new_port.inner_mut());
/// Returns an iterator that will block waiting for messages, but never
/// `panic!`. It will return `None` when the channel has hung up.
- #[unstable]
- pub fn iter<'a>(&'a self) -> Messages<'a, T> {
- Messages { rx: self }
+ #[stable]
+ pub fn iter(&self) -> Iter<T> {
+ Iter { rx: self }
}
}
unsafe impl<T:Send> Send for RacyCell<T> { }
-unsafe impl<T> kinds::Sync for RacyCell<T> { } // Oh dear
+unsafe impl<T> Sync for RacyCell<T> { } // Oh dear
+
+impl<T> fmt::Show for SendError<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ "sending on a closed channel".fmt(f)
+ }
+}
+
+impl<T> fmt::Show for TrySendError<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ TrySendError::Full(..) => {
+ "sending on a full channel".fmt(f)
+ }
+ TrySendError::Disconnected(..) => {
+ "sending on a closed channel".fmt(f)
+ }
+ }
+ }
+}
+
+impl fmt::Show for RecvError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ "receiving on a closed channel".fmt(f)
+ }
+}
+impl fmt::Show for TryRecvError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ TryRecvError::Empty => {
+ "receiving on an empty channel".fmt(f)
+ }
+ TryRecvError::Disconnected => {
+ "receiving on a closed channel".fmt(f)
+ }
+ }
+ }
+}
#[cfg(test)]
mod test {
- use super::*;
- use prelude::{spawn, range, Some, None, from_str, Clone, Str};
+ use prelude::v1::*;
+
use os;
+ use super::*;
+ use thread::Thread;
pub fn stress_factor() -> uint {
match os::getenv("RUST_TEST_STRESS") {
- Some(val) => from_str::<uint>(val.as_slice()).unwrap(),
+ Some(val) => val.parse().unwrap(),
None => 1,
}
}
- test! { fn smoke() {
+ #[test]
+ fn smoke() {
let (tx, rx) = channel::<int>();
- tx.send(1);
- assert_eq!(rx.recv(), 1);
- } }
+ tx.send(1).unwrap();
+ assert_eq!(rx.recv().unwrap(), 1);
+ }
- test! { fn drop_full() {
+ #[test]
+ fn drop_full() {
let (tx, _rx) = channel();
- tx.send(box 1i);
- } }
+ tx.send(box 1i).unwrap();
+ }
- test! { fn drop_full_shared() {
+ #[test]
+ fn drop_full_shared() {
let (tx, _rx) = channel();
drop(tx.clone());
drop(tx.clone());
- tx.send(box 1i);
- } }
+ tx.send(box 1i).unwrap();
+ }
- test! { fn smoke_shared() {
+ #[test]
+ fn smoke_shared() {
let (tx, rx) = channel::<int>();
- tx.send(1);
- assert_eq!(rx.recv(), 1);
+ tx.send(1).unwrap();
+ assert_eq!(rx.recv().unwrap(), 1);
let tx = tx.clone();
- tx.send(1);
- assert_eq!(rx.recv(), 1);
- } }
+ tx.send(1).unwrap();
+ assert_eq!(rx.recv().unwrap(), 1);
+ }
- test! { fn smoke_threads() {
+ #[test]
+ fn smoke_threads() {
let (tx, rx) = channel::<int>();
- spawn(move|| {
- tx.send(1);
+ let _t = Thread::spawn(move|| {
+ tx.send(1).unwrap();
});
- assert_eq!(rx.recv(), 1);
- } }
+ assert_eq!(rx.recv().unwrap(), 1);
+ }
- test! { fn smoke_port_gone() {
+ #[test]
+ fn smoke_port_gone() {
let (tx, rx) = channel::<int>();
drop(rx);
- tx.send(1);
- } #[should_fail] }
+ assert!(tx.send(1).is_err());
+ }
- test! { fn smoke_shared_port_gone() {
+ #[test]
+ fn smoke_shared_port_gone() {
let (tx, rx) = channel::<int>();
drop(rx);
- tx.send(1);
- } #[should_fail] }
+ assert!(tx.send(1).is_err())
+ }
- test! { fn smoke_shared_port_gone2() {
+ #[test]
+ fn smoke_shared_port_gone2() {
let (tx, rx) = channel::<int>();
drop(rx);
let tx2 = tx.clone();
drop(tx);
- tx2.send(1);
- } #[should_fail] }
+ assert!(tx2.send(1).is_err());
+ }
- test! { fn port_gone_concurrent() {
+ #[test]
+ fn port_gone_concurrent() {
let (tx, rx) = channel::<int>();
- spawn(move|| {
- rx.recv();
+ let _t = Thread::spawn(move|| {
+ rx.recv().unwrap();
});
- loop { tx.send(1) }
- } #[should_fail] }
+ while tx.send(1).is_ok() {}
+ }
- test! { fn port_gone_concurrent_shared() {
+ #[test]
+ fn port_gone_concurrent_shared() {
let (tx, rx) = channel::<int>();
let tx2 = tx.clone();
- spawn(move|| {
- rx.recv();
+ let _t = Thread::spawn(move|| {
+ rx.recv().unwrap();
});
- loop {
- tx.send(1);
- tx2.send(1);
- }
- } #[should_fail] }
+ while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
+ }
- test! { fn smoke_chan_gone() {
+ #[test]
+ fn smoke_chan_gone() {
let (tx, rx) = channel::<int>();
drop(tx);
- rx.recv();
- } #[should_fail] }
+ assert!(rx.recv().is_err());
+ }
- test! { fn smoke_chan_gone_shared() {
+ #[test]
+ fn smoke_chan_gone_shared() {
let (tx, rx) = channel::<()>();
let tx2 = tx.clone();
drop(tx);
drop(tx2);
- rx.recv();
- } #[should_fail] }
+ assert!(rx.recv().is_err());
+ }
- test! { fn chan_gone_concurrent() {
+ #[test]
+ fn chan_gone_concurrent() {
let (tx, rx) = channel::<int>();
- spawn(move|| {
- tx.send(1);
- tx.send(1);
+ let _t = Thread::spawn(move|| {
+ tx.send(1).unwrap();
+ tx.send(1).unwrap();
});
- loop { rx.recv(); }
- } #[should_fail] }
+ while rx.recv().is_ok() {}
+ }
- test! { fn stress() {
+ #[test]
+ fn stress() {
let (tx, rx) = channel::<int>();
- spawn(move|| {
- for _ in range(0u, 10000) { tx.send(1i); }
+ let t = Thread::spawn(move|| {
+ for _ in range(0u, 10000) { tx.send(1i).unwrap(); }
});
for _ in range(0u, 10000) {
- assert_eq!(rx.recv(), 1);
+ assert_eq!(rx.recv().unwrap(), 1);
}
- } }
+ t.join().ok().unwrap();
+ }
- test! { fn stress_shared() {
+ #[test]
+ fn stress_shared() {
static AMT: uint = 10000;
static NTHREADS: uint = 8;
let (tx, rx) = channel::<int>();
- let (dtx, drx) = channel::<()>();
- spawn(move|| {
+ let t = Thread::spawn(move|| {
for _ in range(0, AMT * NTHREADS) {
- assert_eq!(rx.recv(), 1);
+ assert_eq!(rx.recv().unwrap(), 1);
}
match rx.try_recv() {
Ok(..) => panic!(),
_ => {}
}
- dtx.send(());
});
for _ in range(0, NTHREADS) {
let tx = tx.clone();
- spawn(move|| {
- for _ in range(0, AMT) { tx.send(1); }
- });
+ Thread::spawn(move|| {
+ for _ in range(0, AMT) { tx.send(1).unwrap(); }
+ }).detach();
}
drop(tx);
- drx.recv();
- } }
+ t.join().ok().unwrap();
+ }
#[test]
fn send_from_outside_runtime() {
let (tx1, rx1) = channel::<()>();
let (tx2, rx2) = channel::<int>();
- let (tx3, rx3) = channel::<()>();
- let tx4 = tx3.clone();
- spawn(move|| {
- tx1.send(());
+ let t1 = Thread::spawn(move|| {
+ tx1.send(()).unwrap();
for _ in range(0i, 40) {
- assert_eq!(rx2.recv(), 1);
+ assert_eq!(rx2.recv().unwrap(), 1);
}
- tx3.send(());
});
- rx1.recv();
- spawn(move|| {
+ rx1.recv().unwrap();
+ let t2 = Thread::spawn(move|| {
for _ in range(0i, 40) {
- tx2.send(1);
+ tx2.send(1).unwrap();
}
- tx4.send(());
});
- rx3.recv();
- rx3.recv();
+ t1.join().ok().unwrap();
+ t2.join().ok().unwrap();
}
#[test]
fn recv_from_outside_runtime() {
let (tx, rx) = channel::<int>();
- let (dtx, drx) = channel();
- spawn(move|| {
+ let t = Thread::spawn(move|| {
for _ in range(0i, 40) {
- assert_eq!(rx.recv(), 1);
+ assert_eq!(rx.recv().unwrap(), 1);
}
- dtx.send(());
});
for _ in range(0u, 40) {
- tx.send(1);
+ tx.send(1).unwrap();
}
- drx.recv();
+ t.join().ok().unwrap();
}
#[test]
fn no_runtime() {
let (tx1, rx1) = channel::<int>();
let (tx2, rx2) = channel::<int>();
- let (tx3, rx3) = channel::<()>();
- let tx4 = tx3.clone();
- spawn(move|| {
- assert_eq!(rx1.recv(), 1);
- tx2.send(2);
- tx4.send(());
+ let t1 = Thread::spawn(move|| {
+ assert_eq!(rx1.recv().unwrap(), 1);
+ tx2.send(2).unwrap();
});
- spawn(move|| {
- tx1.send(1);
- assert_eq!(rx2.recv(), 2);
- tx3.send(());
+ let t2 = Thread::spawn(move|| {
+ tx1.send(1).unwrap();
+ assert_eq!(rx2.recv().unwrap(), 2);
});
- rx3.recv();
- rx3.recv();
+ t1.join().ok().unwrap();
+ t2.join().ok().unwrap();
}
- test! { fn oneshot_single_thread_close_port_first() {
+ #[test]
+ fn oneshot_single_thread_close_port_first() {
// Simple test of closing without sending
let (_tx, rx) = channel::<int>();
drop(rx);
- } }
+ }
- test! { fn oneshot_single_thread_close_chan_first() {
+ #[test]
+ fn oneshot_single_thread_close_chan_first() {
// Simple test of closing without sending
let (tx, _rx) = channel::<int>();
drop(tx);
- } }
+ }
- test! { fn oneshot_single_thread_send_port_close() {
+ #[test]
+ fn oneshot_single_thread_send_port_close() {
// Testing that the sender cleans up the payload if receiver is closed
let (tx, rx) = channel::<Box<int>>();
drop(rx);
- tx.send(box 0);
- } #[should_fail] }
+ assert!(tx.send(box 0).is_err());
+ }
- test! { fn oneshot_single_thread_recv_chan_close() {
+ #[test]
+ fn oneshot_single_thread_recv_chan_close() {
// Receiving on a closed chan will panic
let res = Thread::spawn(move|| {
let (tx, rx) = channel::<int>();
drop(tx);
- rx.recv();
+ rx.recv().unwrap();
}).join();
// What is our res?
assert!(res.is_err());
- } }
+ }
- test! { fn oneshot_single_thread_send_then_recv() {
+ #[test]
+ fn oneshot_single_thread_send_then_recv() {
let (tx, rx) = channel::<Box<int>>();
- tx.send(box 10);
- assert!(rx.recv() == box 10);
- } }
+ tx.send(box 10).unwrap();
+ assert!(rx.recv().unwrap() == box 10);
+ }
- test! { fn oneshot_single_thread_try_send_open() {
+ #[test]
+ fn oneshot_single_thread_try_send_open() {
let (tx, rx) = channel::<int>();
- assert!(tx.send_opt(10).is_ok());
- assert!(rx.recv() == 10);
- } }
+ assert!(tx.send(10).is_ok());
+ assert!(rx.recv().unwrap() == 10);
+ }
- test! { fn oneshot_single_thread_try_send_closed() {
+ #[test]
+ fn oneshot_single_thread_try_send_closed() {
let (tx, rx) = channel::<int>();
drop(rx);
- assert!(tx.send_opt(10).is_err());
- } }
+ assert!(tx.send(10).is_err());
+ }
- test! { fn oneshot_single_thread_try_recv_open() {
+ #[test]
+ fn oneshot_single_thread_try_recv_open() {
let (tx, rx) = channel::<int>();
- tx.send(10);
- assert!(rx.recv_opt() == Ok(10));
- } }
+ tx.send(10).unwrap();
+ assert!(rx.recv() == Ok(10));
+ }
- test! { fn oneshot_single_thread_try_recv_closed() {
+ #[test]
+ fn oneshot_single_thread_try_recv_closed() {
let (tx, rx) = channel::<int>();
drop(tx);
- assert!(rx.recv_opt() == Err(()));
- } }
+ assert!(rx.recv().is_err());
+ }
- test! { fn oneshot_single_thread_peek_data() {
+ #[test]
+ fn oneshot_single_thread_peek_data() {
let (tx, rx) = channel::<int>();
- assert_eq!(rx.try_recv(), Err(Empty));
- tx.send(10);
+ assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+ tx.send(10).unwrap();
assert_eq!(rx.try_recv(), Ok(10));
- } }
+ }
- test! { fn oneshot_single_thread_peek_close() {
+ #[test]
+ fn oneshot_single_thread_peek_close() {
let (tx, rx) = channel::<int>();
drop(tx);
- assert_eq!(rx.try_recv(), Err(Disconnected));
- assert_eq!(rx.try_recv(), Err(Disconnected));
- } }
+ assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+ assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+ }
- test! { fn oneshot_single_thread_peek_open() {
+ #[test]
+ fn oneshot_single_thread_peek_open() {
let (_tx, rx) = channel::<int>();
- assert_eq!(rx.try_recv(), Err(Empty));
- } }
+ assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+ }
- test! { fn oneshot_multi_task_recv_then_send() {
+ #[test]
+ fn oneshot_multi_task_recv_then_send() {
let (tx, rx) = channel::<Box<int>>();
- spawn(move|| {
- assert!(rx.recv() == box 10);
+ let _t = Thread::spawn(move|| {
+ assert!(rx.recv().unwrap() == box 10);
});
- tx.send(box 10);
- } }
+ tx.send(box 10).unwrap();
+ }
- test! { fn oneshot_multi_task_recv_then_close() {
+ #[test]
+ fn oneshot_multi_task_recv_then_close() {
let (tx, rx) = channel::<Box<int>>();
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
drop(tx);
});
let res = Thread::spawn(move|| {
- assert!(rx.recv() == box 10);
+ assert!(rx.recv().unwrap() == box 10);
}).join();
assert!(res.is_err());
- } }
+ }
- test! { fn oneshot_multi_thread_close_stress() {
+ #[test]
+ fn oneshot_multi_thread_close_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = channel::<int>();
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
drop(rx);
});
drop(tx);
}
- } }
+ }
- test! { fn oneshot_multi_thread_send_close_stress() {
+ #[test]
+ fn oneshot_multi_thread_send_close_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = channel::<int>();
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
drop(rx);
});
let _ = Thread::spawn(move|| {
- tx.send(1);
+ tx.send(1).unwrap();
}).join();
}
- } }
+ }
- test! { fn oneshot_multi_thread_recv_close_stress() {
+ #[test]
+ fn oneshot_multi_thread_recv_close_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = channel::<int>();
- spawn(move|| {
+ Thread::spawn(move|| {
let res = Thread::spawn(move|| {
- rx.recv();
+ rx.recv().unwrap();
}).join();
assert!(res.is_err());
- });
- spawn(move|| {
- spawn(move|| {
+ }).detach();
+ let _t = Thread::spawn(move|| {
+ Thread::spawn(move|| {
drop(tx);
- });
+ }).detach();
});
}
- } }
+ }
- test! { fn oneshot_multi_thread_send_recv_stress() {
+ #[test]
+ fn oneshot_multi_thread_send_recv_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = channel();
- spawn(move|| {
- tx.send(box 10i);
- });
- spawn(move|| {
- assert!(rx.recv() == box 10i);
+ let _t = Thread::spawn(move|| {
+ tx.send(box 10i).unwrap();
});
+ assert!(rx.recv().unwrap() == box 10i);
}
- } }
+ }
- test! { fn stream_send_recv_stress() {
+ #[test]
+ fn stream_send_recv_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = channel();
fn send(tx: Sender<Box<int>>, i: int) {
if i == 10 { return }
- spawn(move|| {
- tx.send(box i);
+ Thread::spawn(move|| {
+ tx.send(box i).unwrap();
send(tx, i + 1);
- });
+ }).detach();
}
fn recv(rx: Receiver<Box<int>>, i: int) {
if i == 10 { return }
- spawn(move|| {
- assert!(rx.recv() == box i);
+ Thread::spawn(move|| {
+ assert!(rx.recv().unwrap() == box i);
recv(rx, i + 1);
- });
+ }).detach();
}
}
- } }
+ }
- test! { fn recv_a_lot() {
+ #[test]
+ fn recv_a_lot() {
// Regression test that we don't run out of stack in scheduler context
let (tx, rx) = channel();
- for _ in range(0i, 10000) { tx.send(()); }
- for _ in range(0i, 10000) { rx.recv(); }
- } }
+ for _ in range(0i, 10000) { tx.send(()).unwrap(); }
+ for _ in range(0i, 10000) { rx.recv().unwrap(); }
+ }
- test! { fn shared_chan_stress() {
+ #[test]
+ fn shared_chan_stress() {
let (tx, rx) = channel();
let total = stress_factor() + 100;
for _ in range(0, total) {
let tx = tx.clone();
- spawn(move|| {
- tx.send(());
- });
+ Thread::spawn(move|| {
+ tx.send(()).unwrap();
+ }).detach();
}
for _ in range(0, total) {
- rx.recv();
+ rx.recv().unwrap();
}
- } }
+ }
- test! { fn test_nested_recv_iter() {
+ #[test]
+ fn test_nested_recv_iter() {
let (tx, rx) = channel::<int>();
let (total_tx, total_rx) = channel::<int>();
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
let mut acc = 0;
for x in rx.iter() {
acc += x;
}
- total_tx.send(acc);
+ total_tx.send(acc).unwrap();
});
- tx.send(3);
- tx.send(1);
- tx.send(2);
+ tx.send(3).unwrap();
+ tx.send(1).unwrap();
+ tx.send(2).unwrap();
drop(tx);
- assert_eq!(total_rx.recv(), 6);
- } }
+ assert_eq!(total_rx.recv().unwrap(), 6);
+ }
- test! { fn test_recv_iter_break() {
+ #[test]
+ fn test_recv_iter_break() {
let (tx, rx) = channel::<int>();
let (count_tx, count_rx) = channel();
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
let mut count = 0;
for x in rx.iter() {
if count >= 3 {
count += x;
}
}
- count_tx.send(count);
+ count_tx.send(count).unwrap();
});
- tx.send(2);
- tx.send(2);
- tx.send(2);
- let _ = tx.send_opt(2);
+ tx.send(2).unwrap();
+ tx.send(2).unwrap();
+ tx.send(2).unwrap();
+ let _ = tx.send(2);
drop(tx);
- assert_eq!(count_rx.recv(), 4);
- } }
+ assert_eq!(count_rx.recv().unwrap(), 4);
+ }
- test! { fn try_recv_states() {
+ #[test]
+ fn try_recv_states() {
let (tx1, rx1) = channel::<int>();
let (tx2, rx2) = channel::<()>();
let (tx3, rx3) = channel::<()>();
- spawn(move|| {
- rx2.recv();
- tx1.send(1);
- tx3.send(());
- rx2.recv();
+ let _t = Thread::spawn(move|| {
+ rx2.recv().unwrap();
+ tx1.send(1).unwrap();
+ tx3.send(()).unwrap();
+ rx2.recv().unwrap();
drop(tx1);
- tx3.send(());
+ tx3.send(()).unwrap();
});
- assert_eq!(rx1.try_recv(), Err(Empty));
- tx2.send(());
- rx3.recv();
+ assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+ tx2.send(()).unwrap();
+ rx3.recv().unwrap();
assert_eq!(rx1.try_recv(), Ok(1));
- assert_eq!(rx1.try_recv(), Err(Empty));
- tx2.send(());
- rx3.recv();
- assert_eq!(rx1.try_recv(), Err(Disconnected));
- } }
+ assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+ tx2.send(()).unwrap();
+ rx3.recv().unwrap();
+ assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected));
+ }
// This bug used to end up in a livelock inside of the Receiver destructor
// because the internal state of the Shared packet was corrupted
- test! { fn destroy_upgraded_shared_port_when_sender_still_active() {
+ #[test]
+ fn destroy_upgraded_shared_port_when_sender_still_active() {
let (tx, rx) = channel();
let (tx2, rx2) = channel();
- spawn(move|| {
- rx.recv(); // wait on a oneshot
+ let _t = Thread::spawn(move|| {
+ rx.recv().unwrap(); // wait on a oneshot
drop(rx); // destroy a shared
- tx2.send(());
+ tx2.send(()).unwrap();
});
// make sure the other task has gone to sleep
for _ in range(0u, 5000) { Thread::yield_now(); }
// upgrade to a shared chan and send a message
let t = tx.clone();
drop(tx);
- t.send(());
+ t.send(()).unwrap();
// wait for the child task to exit before we exit
- rx2.recv();
- }}
+ rx2.recv().unwrap();
+ }
}
#[cfg(test)]
mod sync_tests {
- use prelude::*;
+ use prelude::v1::*;
+
use os;
+ use thread::Thread;
+ use super::*;
pub fn stress_factor() -> uint {
match os::getenv("RUST_TEST_STRESS") {
- Some(val) => from_str::<uint>(val.as_slice()).unwrap(),
+ Some(val) => val.parse().unwrap(),
None => 1,
}
}
- test! { fn smoke() {
+ #[test]
+ fn smoke() {
let (tx, rx) = sync_channel::<int>(1);
- tx.send(1);
- assert_eq!(rx.recv(), 1);
- } }
+ tx.send(1).unwrap();
+ assert_eq!(rx.recv().unwrap(), 1);
+ }
- test! { fn drop_full() {
+ #[test]
+ fn drop_full() {
let (tx, _rx) = sync_channel(1);
- tx.send(box 1i);
- } }
+ tx.send(box 1i).unwrap();
+ }
- test! { fn smoke_shared() {
+ #[test]
+ fn smoke_shared() {
let (tx, rx) = sync_channel::<int>(1);
- tx.send(1);
- assert_eq!(rx.recv(), 1);
+ tx.send(1).unwrap();
+ assert_eq!(rx.recv().unwrap(), 1);
let tx = tx.clone();
- tx.send(1);
- assert_eq!(rx.recv(), 1);
- } }
+ tx.send(1).unwrap();
+ assert_eq!(rx.recv().unwrap(), 1);
+ }
- test! { fn smoke_threads() {
+ #[test]
+ fn smoke_threads() {
let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| {
- tx.send(1);
+ let _t = Thread::spawn(move|| {
+ tx.send(1).unwrap();
});
- assert_eq!(rx.recv(), 1);
- } }
+ assert_eq!(rx.recv().unwrap(), 1);
+ }
- test! { fn smoke_port_gone() {
+ #[test]
+ fn smoke_port_gone() {
let (tx, rx) = sync_channel::<int>(0);
drop(rx);
- tx.send(1);
- } #[should_fail] }
+ assert!(tx.send(1).is_err());
+ }
- test! { fn smoke_shared_port_gone2() {
+ #[test]
+ fn smoke_shared_port_gone2() {
let (tx, rx) = sync_channel::<int>(0);
drop(rx);
let tx2 = tx.clone();
drop(tx);
- tx2.send(1);
- } #[should_fail] }
+ assert!(tx2.send(1).is_err());
+ }
- test! { fn port_gone_concurrent() {
+ #[test]
+ fn port_gone_concurrent() {
let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| {
- rx.recv();
+ let _t = Thread::spawn(move|| {
+ rx.recv().unwrap();
});
- loop { tx.send(1) }
- } #[should_fail] }
+ while tx.send(1).is_ok() {}
+ }
- test! { fn port_gone_concurrent_shared() {
+ #[test]
+ fn port_gone_concurrent_shared() {
let (tx, rx) = sync_channel::<int>(0);
let tx2 = tx.clone();
- spawn(move|| {
- rx.recv();
+ let _t = Thread::spawn(move|| {
+ rx.recv().unwrap();
});
- loop {
- tx.send(1);
- tx2.send(1);
- }
- } #[should_fail] }
+ while tx.send(1).is_ok() && tx2.send(1).is_ok() {}
+ }
- test! { fn smoke_chan_gone() {
+ #[test]
+ fn smoke_chan_gone() {
let (tx, rx) = sync_channel::<int>(0);
drop(tx);
- rx.recv();
- } #[should_fail] }
+ assert!(rx.recv().is_err());
+ }
- test! { fn smoke_chan_gone_shared() {
+ #[test]
+ fn smoke_chan_gone_shared() {
let (tx, rx) = sync_channel::<()>(0);
let tx2 = tx.clone();
drop(tx);
drop(tx2);
- rx.recv();
- } #[should_fail] }
+ assert!(rx.recv().is_err());
+ }
- test! { fn chan_gone_concurrent() {
+ #[test]
+ fn chan_gone_concurrent() {
let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| {
- tx.send(1);
- tx.send(1);
- });
- loop { rx.recv(); }
- } #[should_fail] }
+ Thread::spawn(move|| {
+ tx.send(1).unwrap();
+ tx.send(1).unwrap();
+ }).detach();
+ while rx.recv().is_ok() {}
+ }
- test! { fn stress() {
+ #[test]
+ fn stress() {
let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| {
- for _ in range(0u, 10000) { tx.send(1); }
- });
+ Thread::spawn(move|| {
+ for _ in range(0u, 10000) { tx.send(1).unwrap(); }
+ }).detach();
for _ in range(0u, 10000) {
- assert_eq!(rx.recv(), 1);
+ assert_eq!(rx.recv().unwrap(), 1);
}
- } }
+ }
- test! { fn stress_shared() {
+ #[test]
+ fn stress_shared() {
static AMT: uint = 1000;
static NTHREADS: uint = 8;
let (tx, rx) = sync_channel::<int>(0);
let (dtx, drx) = sync_channel::<()>(0);
- spawn(move|| {
+ Thread::spawn(move|| {
for _ in range(0, AMT * NTHREADS) {
- assert_eq!(rx.recv(), 1);
+ assert_eq!(rx.recv().unwrap(), 1);
}
match rx.try_recv() {
Ok(..) => panic!(),
_ => {}
}
- dtx.send(());
- });
+ dtx.send(()).unwrap();
+ }).detach();
for _ in range(0, NTHREADS) {
let tx = tx.clone();
- spawn(move|| {
- for _ in range(0, AMT) { tx.send(1); }
- });
+ Thread::spawn(move|| {
+ for _ in range(0, AMT) { tx.send(1).unwrap(); }
+ }).detach();
}
drop(tx);
- drx.recv();
- } }
+ drx.recv().unwrap();
+ }
- test! { fn oneshot_single_thread_close_port_first() {
+ #[test]
+ fn oneshot_single_thread_close_port_first() {
// Simple test of closing without sending
let (_tx, rx) = sync_channel::<int>(0);
drop(rx);
- } }
+ }
- test! { fn oneshot_single_thread_close_chan_first() {
+ #[test]
+ fn oneshot_single_thread_close_chan_first() {
// Simple test of closing without sending
let (tx, _rx) = sync_channel::<int>(0);
drop(tx);
- } }
+ }
- test! { fn oneshot_single_thread_send_port_close() {
+ #[test]
+ fn oneshot_single_thread_send_port_close() {
// Testing that the sender cleans up the payload if receiver is closed
let (tx, rx) = sync_channel::<Box<int>>(0);
drop(rx);
- tx.send(box 0);
- } #[should_fail] }
+ assert!(tx.send(box 0).is_err());
+ }
- test! { fn oneshot_single_thread_recv_chan_close() {
+ #[test]
+ fn oneshot_single_thread_recv_chan_close() {
// Receiving on a closed chan will panic
let res = Thread::spawn(move|| {
let (tx, rx) = sync_channel::<int>(0);
drop(tx);
- rx.recv();
+ rx.recv().unwrap();
}).join();
// What is our res?
assert!(res.is_err());
- } }
+ }
- test! { fn oneshot_single_thread_send_then_recv() {
+ #[test]
+ fn oneshot_single_thread_send_then_recv() {
let (tx, rx) = sync_channel::<Box<int>>(1);
- tx.send(box 10);
- assert!(rx.recv() == box 10);
- } }
+ tx.send(box 10).unwrap();
+ assert!(rx.recv().unwrap() == box 10);
+ }
- test! { fn oneshot_single_thread_try_send_open() {
+ #[test]
+ fn oneshot_single_thread_try_send_open() {
let (tx, rx) = sync_channel::<int>(1);
assert_eq!(tx.try_send(10), Ok(()));
- assert!(rx.recv() == 10);
- } }
+ assert!(rx.recv().unwrap() == 10);
+ }
- test! { fn oneshot_single_thread_try_send_closed() {
+ #[test]
+ fn oneshot_single_thread_try_send_closed() {
let (tx, rx) = sync_channel::<int>(0);
drop(rx);
- assert_eq!(tx.try_send(10), Err(RecvDisconnected(10)));
- } }
+ assert_eq!(tx.try_send(10), Err(TrySendError::Disconnected(10)));
+ }
- test! { fn oneshot_single_thread_try_send_closed2() {
+ #[test]
+ fn oneshot_single_thread_try_send_closed2() {
let (tx, _rx) = sync_channel::<int>(0);
- assert_eq!(tx.try_send(10), Err(Full(10)));
- } }
+ assert_eq!(tx.try_send(10), Err(TrySendError::Full(10)));
+ }
- test! { fn oneshot_single_thread_try_recv_open() {
+ #[test]
+ fn oneshot_single_thread_try_recv_open() {
let (tx, rx) = sync_channel::<int>(1);
- tx.send(10);
- assert!(rx.recv_opt() == Ok(10));
- } }
+ tx.send(10).unwrap();
+ assert!(rx.recv() == Ok(10));
+ }
- test! { fn oneshot_single_thread_try_recv_closed() {
+ #[test]
+ fn oneshot_single_thread_try_recv_closed() {
let (tx, rx) = sync_channel::<int>(0);
drop(tx);
- assert!(rx.recv_opt() == Err(()));
- } }
+ assert!(rx.recv().is_err());
+ }
- test! { fn oneshot_single_thread_peek_data() {
+ #[test]
+ fn oneshot_single_thread_peek_data() {
let (tx, rx) = sync_channel::<int>(1);
- assert_eq!(rx.try_recv(), Err(Empty));
- tx.send(10);
+ assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+ tx.send(10).unwrap();
assert_eq!(rx.try_recv(), Ok(10));
- } }
+ }
- test! { fn oneshot_single_thread_peek_close() {
+ #[test]
+ fn oneshot_single_thread_peek_close() {
let (tx, rx) = sync_channel::<int>(0);
drop(tx);
- assert_eq!(rx.try_recv(), Err(Disconnected));
- assert_eq!(rx.try_recv(), Err(Disconnected));
- } }
+ assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+ assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+ }
- test! { fn oneshot_single_thread_peek_open() {
+ #[test]
+ fn oneshot_single_thread_peek_open() {
let (_tx, rx) = sync_channel::<int>(0);
- assert_eq!(rx.try_recv(), Err(Empty));
- } }
+ assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
+ }
- test! { fn oneshot_multi_task_recv_then_send() {
+ #[test]
+ fn oneshot_multi_task_recv_then_send() {
let (tx, rx) = sync_channel::<Box<int>>(0);
- spawn(move|| {
- assert!(rx.recv() == box 10);
+ let _t = Thread::spawn(move|| {
+ assert!(rx.recv().unwrap() == box 10);
});
- tx.send(box 10);
- } }
+ tx.send(box 10).unwrap();
+ }
- test! { fn oneshot_multi_task_recv_then_close() {
+ #[test]
+ fn oneshot_multi_task_recv_then_close() {
let (tx, rx) = sync_channel::<Box<int>>(0);
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
drop(tx);
});
let res = Thread::spawn(move|| {
- assert!(rx.recv() == box 10);
+ assert!(rx.recv().unwrap() == box 10);
}).join();
assert!(res.is_err());
- } }
+ }
- test! { fn oneshot_multi_thread_close_stress() {
+ #[test]
+ fn oneshot_multi_thread_close_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
drop(rx);
});
drop(tx);
}
- } }
+ }
- test! { fn oneshot_multi_thread_send_close_stress() {
+ #[test]
+ fn oneshot_multi_thread_send_close_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
drop(rx);
});
let _ = Thread::spawn(move || {
- tx.send(1);
+ tx.send(1).unwrap();
}).join();
}
- } }
+ }
- test! { fn oneshot_multi_thread_recv_close_stress() {
+ #[test]
+ fn oneshot_multi_thread_recv_close_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
let res = Thread::spawn(move|| {
- rx.recv();
+ rx.recv().unwrap();
}).join();
assert!(res.is_err());
});
- spawn(move|| {
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
+ Thread::spawn(move|| {
drop(tx);
- });
+ }).detach();
});
}
- } }
+ }
- test! { fn oneshot_multi_thread_send_recv_stress() {
+ #[test]
+ fn oneshot_multi_thread_send_recv_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = sync_channel::<Box<int>>(0);
- spawn(move|| {
- tx.send(box 10i);
- });
- spawn(move|| {
- assert!(rx.recv() == box 10i);
+ let _t = Thread::spawn(move|| {
+ tx.send(box 10i).unwrap();
});
+ assert!(rx.recv().unwrap() == box 10i);
}
- } }
+ }
- test! { fn stream_send_recv_stress() {
+ #[test]
+ fn stream_send_recv_stress() {
for _ in range(0, stress_factor()) {
let (tx, rx) = sync_channel::<Box<int>>(0);
fn send(tx: SyncSender<Box<int>>, i: int) {
if i == 10 { return }
- spawn(move|| {
- tx.send(box i);
+ Thread::spawn(move|| {
+ tx.send(box i).unwrap();
send(tx, i + 1);
- });
+ }).detach();
}
fn recv(rx: Receiver<Box<int>>, i: int) {
if i == 10 { return }
- spawn(move|| {
- assert!(rx.recv() == box i);
+ Thread::spawn(move|| {
+ assert!(rx.recv().unwrap() == box i);
recv(rx, i + 1);
- });
+ }).detach();
}
}
- } }
+ }
- test! { fn recv_a_lot() {
+ #[test]
+ fn recv_a_lot() {
// Regression test that we don't run out of stack in scheduler context
let (tx, rx) = sync_channel(10000);
- for _ in range(0u, 10000) { tx.send(()); }
- for _ in range(0u, 10000) { rx.recv(); }
- } }
+ for _ in range(0u, 10000) { tx.send(()).unwrap(); }
+ for _ in range(0u, 10000) { rx.recv().unwrap(); }
+ }
- test! { fn shared_chan_stress() {
+ #[test]
+ fn shared_chan_stress() {
let (tx, rx) = sync_channel(0);
let total = stress_factor() + 100;
for _ in range(0, total) {
let tx = tx.clone();
- spawn(move|| {
- tx.send(());
- });
+ Thread::spawn(move|| {
+ tx.send(()).unwrap();
+ }).detach();
}
for _ in range(0, total) {
- rx.recv();
+ rx.recv().unwrap();
}
- } }
+ }
- test! { fn test_nested_recv_iter() {
+ #[test]
+ fn test_nested_recv_iter() {
let (tx, rx) = sync_channel::<int>(0);
let (total_tx, total_rx) = sync_channel::<int>(0);
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
let mut acc = 0;
for x in rx.iter() {
acc += x;
}
- total_tx.send(acc);
+ total_tx.send(acc).unwrap();
});
- tx.send(3);
- tx.send(1);
- tx.send(2);
+ tx.send(3).unwrap();
+ tx.send(1).unwrap();
+ tx.send(2).unwrap();
drop(tx);
- assert_eq!(total_rx.recv(), 6);
- } }
+ assert_eq!(total_rx.recv().unwrap(), 6);
+ }
- test! { fn test_recv_iter_break() {
+ #[test]
+ fn test_recv_iter_break() {
let (tx, rx) = sync_channel::<int>(0);
let (count_tx, count_rx) = sync_channel(0);
- spawn(move|| {
+ let _t = Thread::spawn(move|| {
let mut count = 0;
for x in rx.iter() {
if count >= 3 {
count += x;
}
}
- count_tx.send(count);
+ count_tx.send(count).unwrap();
});
- tx.send(2);
- tx.send(2);
- tx.send(2);
+ tx.send(2).unwrap();
+ tx.send(2).unwrap();
+ tx.send(2).unwrap();
let _ = tx.try_send(2);
drop(tx);
- assert_eq!(count_rx.recv(), 4);
- } }
+ assert_eq!(count_rx.recv().unwrap(), 4);
+ }
- test! { fn try_recv_states() {
+ #[test]
+ fn try_recv_states() {
let (tx1, rx1) = sync_channel::<int>(1);
let (tx2, rx2) = sync_channel::<()>(1);
let (tx3, rx3) = sync_channel::<()>(1);
- spawn(move|| {
- rx2.recv();
- tx1.send(1);
- tx3.send(());
- rx2.recv();
+ let _t = Thread::spawn(move|| {
+ rx2.recv().unwrap();
+ tx1.send(1).unwrap();
+ tx3.send(()).unwrap();
+ rx2.recv().unwrap();
drop(tx1);
- tx3.send(());
+ tx3.send(()).unwrap();
});
- assert_eq!(rx1.try_recv(), Err(Empty));
- tx2.send(());
- rx3.recv();
+ assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+ tx2.send(()).unwrap();
+ rx3.recv().unwrap();
assert_eq!(rx1.try_recv(), Ok(1));
- assert_eq!(rx1.try_recv(), Err(Empty));
- tx2.send(());
- rx3.recv();
- assert_eq!(rx1.try_recv(), Err(Disconnected));
- } }
+ assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
+ tx2.send(()).unwrap();
+ rx3.recv().unwrap();
+ assert_eq!(rx1.try_recv(), Err(TryRecvError::Disconnected));
+ }
// This bug used to end up in a livelock inside of the Receiver destructor
// because the internal state of the Shared packet was corrupted
- test! { fn destroy_upgraded_shared_port_when_sender_still_active() {
+ #[test]
+ fn destroy_upgraded_shared_port_when_sender_still_active() {
let (tx, rx) = sync_channel::<()>(0);
let (tx2, rx2) = sync_channel::<()>(0);
- spawn(move|| {
- rx.recv(); // wait on a oneshot
+ let _t = Thread::spawn(move|| {
+ rx.recv().unwrap(); // wait on a oneshot
drop(rx); // destroy a shared
- tx2.send(());
+ tx2.send(()).unwrap();
});
// make sure the other task has gone to sleep
for _ in range(0u, 5000) { Thread::yield_now(); }
// upgrade to a shared chan and send a message
let t = tx.clone();
drop(tx);
- t.send(());
+ t.send(()).unwrap();
// wait for the child task to exit before we exit
- rx2.recv();
- } }
+ rx2.recv().unwrap();
+ }
- test! { fn send_opt1() {
+ #[test]
+ fn send1() {
let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| { rx.recv(); });
- assert_eq!(tx.send_opt(1), Ok(()));
- } }
+ let _t = Thread::spawn(move|| { rx.recv().unwrap(); });
+ assert_eq!(tx.send(1), Ok(()));
+ }
- test! { fn send_opt2() {
+ #[test]
+ fn send2() {
let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| { drop(rx); });
- assert_eq!(tx.send_opt(1), Err(1));
- } }
+ let _t = Thread::spawn(move|| { drop(rx); });
+ assert!(tx.send(1).is_err());
+ }
- test! { fn send_opt3() {
+ #[test]
+ fn send3() {
let (tx, rx) = sync_channel::<int>(1);
- assert_eq!(tx.send_opt(1), Ok(()));
- spawn(move|| { drop(rx); });
- assert_eq!(tx.send_opt(1), Err(1));
- } }
+ assert_eq!(tx.send(1), Ok(()));
+ let _t =Thread::spawn(move|| { drop(rx); });
+ assert!(tx.send(1).is_err());
+ }
- test! { fn send_opt4() {
+ #[test]
+ fn send4() {
let (tx, rx) = sync_channel::<int>(0);
let tx2 = tx.clone();
let (done, donerx) = channel();
let done2 = done.clone();
- spawn(move|| {
- assert_eq!(tx.send_opt(1), Err(1));
- done.send(());
+ let _t = Thread::spawn(move|| {
+ assert!(tx.send(1).is_err());
+ done.send(()).unwrap();
});
- spawn(move|| {
- assert_eq!(tx2.send_opt(2), Err(2));
- done2.send(());
+ let _t = Thread::spawn(move|| {
+ assert!(tx2.send(2).is_err());
+ done2.send(()).unwrap();
});
drop(rx);
- donerx.recv();
- donerx.recv();
- } }
+ donerx.recv().unwrap();
+ donerx.recv().unwrap();
+ }
- test! { fn try_send1() {
+ #[test]
+ fn try_send1() {
let (tx, _rx) = sync_channel::<int>(0);
- assert_eq!(tx.try_send(1), Err(Full(1)));
- } }
+ assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
+ }
- test! { fn try_send2() {
+ #[test]
+ fn try_send2() {
let (tx, _rx) = sync_channel::<int>(1);
assert_eq!(tx.try_send(1), Ok(()));
- assert_eq!(tx.try_send(1), Err(Full(1)));
- } }
+ assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
+ }
- test! { fn try_send3() {
+ #[test]
+ fn try_send3() {
let (tx, rx) = sync_channel::<int>(1);
assert_eq!(tx.try_send(1), Ok(()));
drop(rx);
- assert_eq!(tx.try_send(1), Err(RecvDisconnected(1)));
- } }
-
- test! { fn try_send4() {
- let (tx, rx) = sync_channel::<int>(0);
- spawn(move|| {
- for _ in range(0u, 1000) { Thread::yield_now(); }
- assert_eq!(tx.try_send(1), Ok(()));
- });
- assert_eq!(rx.recv(), 1);
- } #[ignore(reason = "flaky on libnative")] }
+ assert_eq!(tx.try_send(1), Err(TrySendError::Disconnected(1)));
+ }
- test! { fn issue_15761() {
+ #[test]
+ fn issue_15761() {
fn repro() {
let (tx1, rx1) = sync_channel::<()>(3);
let (tx2, rx2) = sync_channel::<()>(3);
- spawn(move|| {
- rx1.recv();
+ let _t = Thread::spawn(move|| {
+ rx1.recv().unwrap();
tx2.try_send(()).unwrap();
});
tx1.try_send(()).unwrap();
- rx2.recv();
+ rx2.recv().unwrap();
}
for _ in range(0u, 100) {
repro()
}
- } }
+ }
}
/// ```
/// use std::sync::RwLock;
///
-/// let lock = RwLock::new(5);
+/// let lock = RwLock::new(5i);
///
/// // many reader locks can be held at once
/// {