auto merge of #18575 : alexcrichton/rust/rollup, r=alexcrichton

This commit is contained in:
bors 2014-11-03 21:07:45 +00:00
commit b11b706545
95 changed files with 2641 additions and 1853 deletions

View File

@ -287,7 +287,7 @@ The benchmarking runner offers two ways to avoid this. Either, the
closure that the `iter` method receives can return an arbitrary value
which forces the optimizer to consider the result used and ensures it
cannot remove the computation entirely. This could be done for the
example above by adjusting the `bh.iter` call to
example above by adjusting the `b.iter` call to
~~~
# struct X; impl X { fn iter<T>(&self, _: || -> T) {} } let b = X;

View File

@ -494,14 +494,14 @@ non-deterministic aspect:
$ cargo run
Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world)
Running `target/hello_world`
numbers[1] is 2
numbers[0] is 1
numbers[2] is 3
numbers[1] is 3
numbers[0] is 2
numbers[2] is 4
$ cargo run
Running `target/hello_world`
numbers[2] is 3
numbers[1] is 2
numbers[0] is 1
numbers[2] is 4
numbers[1] is 3
numbers[0] is 2
```
Each time, we get a slightly different output, because each thread works in a

View File

@ -400,11 +400,11 @@ An _integer literal_ has one of four forms:
* A _decimal literal_ starts with a *decimal digit* and continues with any
mixture of *decimal digits* and _underscores_.
* A _hex literal_ starts with the character sequence `U+0030` `U+0078`
(`0x`) and continues as any mixture hex digits and underscores.
(`0x`) and continues as any mixture of hex digits and underscores.
* An _octal literal_ starts with the character sequence `U+0030` `U+006F`
(`0o`) and continues as any mixture octal digits and underscores.
(`0o`) and continues as any mixture of octal digits and underscores.
* A _binary literal_ starts with the character sequence `U+0030` `U+0062`
(`0b`) and continues as any mixture binary digits and underscores.
(`0b`) and continues as any mixture of binary digits and underscores.
An integer literal may be followed (immediately, without any spaces) by an
_integer suffix_, which changes the type of the literal. There are two kinds of
@ -944,10 +944,10 @@ An example of `use` declarations:
```
use std::iter::range_step;
use std::option::{Some, None};
use std::collections::hashmap::{mod, HashMap};
use std::collections::hash_map::{mod, HashMap};
# fn foo<T>(_: T){}
# fn bar(map: HashMap<String, uint>, set: hashmap::HashSet<String>){}
fn foo<T>(_: T){}
fn bar(map1: HashMap<String, uint>, map2: hash_map::HashMap<String, uint>){}
fn main() {
// Equivalent to 'std::iter::range_step(0u, 10u, 2u);'
@ -957,10 +957,10 @@ fn main() {
// std::option::None]);'
foo(vec![Some(1.0f64), None]);
// Both `hash` and `HashMap` are in scope.
let map = HashMap::new();
let set = hashmap::HashSet::new();
bar(map, set);
// Both `hash_map` and `HashMap` are in scope.
let map1 = HashMap::new();
let map2 = hash_map::HashMap::new();
bar(map1, map2);
}
```
@ -2100,15 +2100,15 @@ plugins](guide-plugin.html#lint-plugins) can provide additional lint checks.
```{.ignore}
mod m1 {
// Missing documentation is ignored here
#[allow(missing_doc)]
#[allow(missing_docs)]
pub fn undocumented_one() -> int { 1 }
// Missing documentation signals a warning here
#[warn(missing_doc)]
#[warn(missing_docs)]
pub fn undocumented_too() -> int { 2 }
// Missing documentation signals an error here
#[deny(missing_doc)]
#[deny(missing_docs)]
pub fn undocumented_end() -> int { 3 }
}
```
@ -2117,16 +2117,16 @@ This example shows how one can use `allow` and `warn` to toggle a particular
check on and off.
```{.ignore}
#[warn(missing_doc)]
#[warn(missing_docs)]
mod m2{
#[allow(missing_doc)]
#[allow(missing_docs)]
mod nested {
// Missing documentation is ignored here
pub fn undocumented_one() -> int { 1 }
// Missing documentation signals a warning here,
// despite the allow above.
#[warn(missing_doc)]
#[warn(missing_docs)]
pub fn undocumented_two() -> int { 2 }
}
@ -2139,10 +2139,10 @@ This example shows how one can use `forbid` to disallow uses of `allow` for
that lint check.
```{.ignore}
#[forbid(missing_doc)]
#[forbid(missing_docs)]
mod m3 {
// Attempting to toggle warning signals an error here
#[allow(missing_doc)]
#[allow(missing_docs)]
/// Returns 2.
pub fn undocumented_too() -> int { 2 }
}
@ -4096,7 +4096,7 @@ cause transitions between the states. The lifecycle states of a task are:
* running
* blocked
* panicked
* panicked
* dead
A task begins its lifecycle &mdash; once it has been spawned &mdash; in the

View File

@ -62,6 +62,10 @@ body {
font-size: 18px;
color: #333;
line-height: 1.428571429;
-webkit-font-feature-settings: "kern", "liga";
-moz-font-feature-settings: "kern", "liga";
font-feature-settings: "kern", "liga";
}
@media (min-width: 768px) {
body {

View File

@ -34,7 +34,7 @@ preamble = '''// Copyright 2012-2014 The Rust Project Developers. See the COPYRI
// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
#![allow(missing_doc, non_uppercase_statics, non_snake_case)]
#![allow(missing_docs, non_uppercase_statics, non_snake_case)]
'''
# Mapping taken from Table 12 from:

View File

@ -19,14 +19,14 @@
//!
//! This is a larger example which implements [Dijkstra's algorithm][dijkstra]
//! to solve the [shortest path problem][sssp] on a [directed graph][dir_graph].
//! It showcases how to use the `PriorityQueue` with custom types.
//! It showcases how to use the `BinaryHeap` with custom types.
//!
//! [dijkstra]: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
//! [sssp]: http://en.wikipedia.org/wiki/Shortest_path_problem
//! [dir_graph]: http://en.wikipedia.org/wiki/Directed_graph
//!
//! ```
//! use std::collections::PriorityQueue;
//! use std::collections::BinaryHeap;
//! use std::uint;
//!
//! #[deriving(Eq, PartialEq)]
@ -68,7 +68,7 @@
//! // dist[node] = current shortest distance from `start` to `node`
//! let mut dist = Vec::from_elem(adj_list.len(), uint::MAX);
//!
//! let mut pq = PriorityQueue::new();
//! let mut pq = BinaryHeap::new();
//!
//! // We're at `start`, with a zero cost
//! dist[start] = 0u;
@ -166,52 +166,52 @@ use vec::Vec;
///
/// This will be a max-heap.
#[deriving(Clone)]
pub struct PriorityQueue<T> {
pub struct BinaryHeap<T> {
data: Vec<T>,
}
impl<T: Ord> Default for PriorityQueue<T> {
impl<T: Ord> Default for BinaryHeap<T> {
#[inline]
fn default() -> PriorityQueue<T> { PriorityQueue::new() }
fn default() -> BinaryHeap<T> { BinaryHeap::new() }
}
impl<T: Ord> PriorityQueue<T> {
/// Creates an empty `PriorityQueue` as a max-heap.
impl<T: Ord> BinaryHeap<T> {
/// Creates an empty `BinaryHeap` as a max-heap.
///
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// let pq: PriorityQueue<uint> = PriorityQueue::new();
/// use std::collections::BinaryHeap;
/// let pq: BinaryHeap<uint> = BinaryHeap::new();
/// ```
pub fn new() -> PriorityQueue<T> { PriorityQueue{data: vec!(),} }
pub fn new() -> BinaryHeap<T> { BinaryHeap{data: vec!(),} }
/// Creates an empty `PriorityQueue` with a specific capacity.
/// Creates an empty `BinaryHeap` with a specific capacity.
/// This preallocates enough memory for `capacity` elements,
/// so that the `PriorityQueue` does not have to be reallocated
/// so that the `BinaryHeap` does not have to be reallocated
/// until it contains at least that many values.
///
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// let pq: PriorityQueue<uint> = PriorityQueue::with_capacity(10u);
/// use std::collections::BinaryHeap;
/// let pq: BinaryHeap<uint> = BinaryHeap::with_capacity(10u);
/// ```
pub fn with_capacity(capacity: uint) -> PriorityQueue<T> {
PriorityQueue { data: Vec::with_capacity(capacity) }
pub fn with_capacity(capacity: uint) -> BinaryHeap<T> {
BinaryHeap { data: Vec::with_capacity(capacity) }
}
/// Creates a `PriorityQueue` from a vector. This is sometimes called
/// Creates a `BinaryHeap` from a vector. This is sometimes called
/// `heapifying` the vector.
///
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// let pq = PriorityQueue::from_vec(vec![9i, 1, 2, 7, 3, 2]);
/// use std::collections::BinaryHeap;
/// let pq = BinaryHeap::from_vec(vec![9i, 1, 2, 7, 3, 2]);
/// ```
pub fn from_vec(xs: Vec<T>) -> PriorityQueue<T> {
let mut q = PriorityQueue{data: xs,};
pub fn from_vec(xs: Vec<T>) -> BinaryHeap<T> {
let mut q = BinaryHeap{data: xs,};
let mut n = q.len() / 2;
while n > 0 {
n -= 1;
@ -226,8 +226,8 @@ impl<T: Ord> PriorityQueue<T> {
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// let pq = PriorityQueue::from_vec(vec![1i, 2, 3, 4]);
/// use std::collections::BinaryHeap;
/// let pq = BinaryHeap::from_vec(vec![1i, 2, 3, 4]);
///
/// // Print 1, 2, 3, 4 in arbitrary order
/// for x in pq.iter() {
@ -243,9 +243,9 @@ impl<T: Ord> PriorityQueue<T> {
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let mut pq = PriorityQueue::new();
/// let mut pq = BinaryHeap::new();
/// assert_eq!(pq.top(), None);
///
/// pq.push(1i);
@ -263,36 +263,36 @@ impl<T: Ord> PriorityQueue<T> {
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let pq: PriorityQueue<uint> = PriorityQueue::with_capacity(100u);
/// let pq: BinaryHeap<uint> = BinaryHeap::with_capacity(100u);
/// assert!(pq.capacity() >= 100u);
/// ```
pub fn capacity(&self) -> uint { self.data.capacity() }
/// Reserves capacity for exactly `n` elements in the `PriorityQueue`.
/// Reserves capacity for exactly `n` elements in the `BinaryHeap`.
/// Do nothing if the capacity is already sufficient.
///
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let mut pq: PriorityQueue<uint> = PriorityQueue::new();
/// let mut pq: BinaryHeap<uint> = BinaryHeap::new();
/// pq.reserve_exact(100u);
/// assert!(pq.capacity() == 100u);
/// ```
pub fn reserve_exact(&mut self, n: uint) { self.data.reserve_exact(n) }
/// Reserves capacity for at least `n` elements in the `PriorityQueue`.
/// Reserves capacity for at least `n` elements in the `BinaryHeap`.
/// Do nothing if the capacity is already sufficient.
///
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let mut pq: PriorityQueue<uint> = PriorityQueue::new();
/// let mut pq: BinaryHeap<uint> = BinaryHeap::new();
/// pq.reserve(100u);
/// assert!(pq.capacity() >= 100u);
/// ```
@ -306,9 +306,9 @@ impl<T: Ord> PriorityQueue<T> {
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let mut pq = PriorityQueue::from_vec(vec![1i, 3]);
/// let mut pq = BinaryHeap::from_vec(vec![1i, 3]);
///
/// assert_eq!(pq.pop(), Some(3i));
/// assert_eq!(pq.pop(), Some(1i));
@ -332,9 +332,9 @@ impl<T: Ord> PriorityQueue<T> {
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let mut pq = PriorityQueue::new();
/// let mut pq = BinaryHeap::new();
/// pq.push(3i);
/// pq.push(5i);
/// pq.push(1i);
@ -354,9 +354,9 @@ impl<T: Ord> PriorityQueue<T> {
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let mut pq = PriorityQueue::new();
/// let mut pq = BinaryHeap::new();
/// pq.push(1i);
/// pq.push(5i);
///
@ -380,9 +380,9 @@ impl<T: Ord> PriorityQueue<T> {
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let mut pq = PriorityQueue::new();
/// let mut pq = BinaryHeap::new();
///
/// assert_eq!(pq.replace(1i), None);
/// assert_eq!(pq.replace(3i), Some(1i));
@ -400,15 +400,15 @@ impl<T: Ord> PriorityQueue<T> {
}
}
/// Consumes the `PriorityQueue` and returns the underlying vector
/// Consumes the `BinaryHeap` and returns the underlying vector
/// in arbitrary order.
///
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let pq = PriorityQueue::from_vec(vec![1i, 2, 3, 4, 5, 6, 7]);
/// let pq = BinaryHeap::from_vec(vec![1i, 2, 3, 4, 5, 6, 7]);
/// let vec = pq.into_vec();
///
/// // Will print in some order
@ -416,17 +416,17 @@ impl<T: Ord> PriorityQueue<T> {
/// println!("{}", x);
/// }
/// ```
pub fn into_vec(self) -> Vec<T> { let PriorityQueue{data: v} = self; v }
pub fn into_vec(self) -> Vec<T> { let BinaryHeap{data: v} = self; v }
/// Consumes the `PriorityQueue` and returns a vector in sorted
/// Consumes the `BinaryHeap` and returns a vector in sorted
/// (ascending) order.
///
/// # Example
///
/// ```
/// use std::collections::PriorityQueue;
/// use std::collections::BinaryHeap;
///
/// let mut pq = PriorityQueue::from_vec(vec![1i, 2, 4, 5, 7]);
/// let mut pq = BinaryHeap::from_vec(vec![1i, 2, 4, 5, 7]);
/// pq.push(6);
/// pq.push(3);
///
@ -504,7 +504,7 @@ impl<T: Ord> PriorityQueue<T> {
pub fn clear(&mut self) { self.data.truncate(0) }
}
/// `PriorityQueue` iterator.
/// `BinaryHeap` iterator.
pub struct Items <'a, T:'a> {
iter: slice::Items<'a, T>,
}
@ -517,14 +517,14 @@ impl<'a, T> Iterator<&'a T> for Items<'a, T> {
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
}
impl<T: Ord> FromIterator<T> for PriorityQueue<T> {
fn from_iter<Iter: Iterator<T>>(mut iter: Iter) -> PriorityQueue<T> {
impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
fn from_iter<Iter: Iterator<T>>(mut iter: Iter) -> BinaryHeap<T> {
let vec: Vec<T> = iter.collect();
PriorityQueue::from_vec(vec)
BinaryHeap::from_vec(vec)
}
}
impl<T: Ord> Extendable<T> for PriorityQueue<T> {
impl<T: Ord> Extendable<T> for BinaryHeap<T> {
fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
let (lower, _) = iter.size_hint();
@ -541,14 +541,14 @@ impl<T: Ord> Extendable<T> for PriorityQueue<T> {
mod tests {
use std::prelude::*;
use priority_queue::PriorityQueue;
use super::BinaryHeap;
use vec::Vec;
#[test]
fn test_iterator() {
let data = vec!(5i, 9, 3);
let iterout = [9i, 5, 3];
let pq = PriorityQueue::from_vec(data);
let pq = BinaryHeap::from_vec(data);
let mut i = 0;
for el in pq.iter() {
assert_eq!(*el, iterout[i]);
@ -561,7 +561,7 @@ mod tests {
let data = vec!(2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1);
let mut sorted = data.clone();
sorted.sort();
let mut heap = PriorityQueue::from_vec(data);
let mut heap = BinaryHeap::from_vec(data);
while !heap.is_empty() {
assert_eq!(heap.top().unwrap(), sorted.last().unwrap());
assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
@ -570,7 +570,7 @@ mod tests {
#[test]
fn test_push() {
let mut heap = PriorityQueue::from_vec(vec!(2i, 4, 9));
let mut heap = BinaryHeap::from_vec(vec!(2i, 4, 9));
assert_eq!(heap.len(), 3);
assert!(*heap.top().unwrap() == 9);
heap.push(11);
@ -592,7 +592,7 @@ mod tests {
#[test]
fn test_push_unique() {
let mut heap = PriorityQueue::from_vec(vec!(box 2i, box 4, box 9));
let mut heap = BinaryHeap::from_vec(vec!(box 2i, box 4, box 9));
assert_eq!(heap.len(), 3);
assert!(*heap.top().unwrap() == box 9);
heap.push(box 11);
@ -614,7 +614,7 @@ mod tests {
#[test]
fn test_push_pop() {
let mut heap = PriorityQueue::from_vec(vec!(5i, 5, 2, 1, 3));
let mut heap = BinaryHeap::from_vec(vec!(5i, 5, 2, 1, 3));
assert_eq!(heap.len(), 5);
assert_eq!(heap.push_pop(6), 6);
assert_eq!(heap.len(), 5);
@ -628,7 +628,7 @@ mod tests {
#[test]
fn test_replace() {
let mut heap = PriorityQueue::from_vec(vec!(5i, 5, 2, 1, 3));
let mut heap = BinaryHeap::from_vec(vec!(5i, 5, 2, 1, 3));
assert_eq!(heap.len(), 5);
assert_eq!(heap.replace(6).unwrap(), 5);
assert_eq!(heap.len(), 5);
@ -641,7 +641,7 @@ mod tests {
}
fn check_to_vec(mut data: Vec<int>) {
let heap = PriorityQueue::from_vec(data.clone());
let heap = BinaryHeap::from_vec(data.clone());
let mut v = heap.clone().into_vec();
v.sort();
data.sort();
@ -669,19 +669,19 @@ mod tests {
#[test]
fn test_empty_pop() {
let mut heap: PriorityQueue<int> = PriorityQueue::new();
let mut heap: BinaryHeap<int> = BinaryHeap::new();
assert!(heap.pop().is_none());
}
#[test]
fn test_empty_top() {
let empty: PriorityQueue<int> = PriorityQueue::new();
let empty: BinaryHeap<int> = BinaryHeap::new();
assert!(empty.top().is_none());
}
#[test]
fn test_empty_replace() {
let mut heap: PriorityQueue<int> = PriorityQueue::new();
let mut heap: BinaryHeap<int> = BinaryHeap::new();
heap.replace(5).is_none();
}
@ -689,7 +689,7 @@ mod tests {
fn test_from_iter() {
let xs = vec!(9u, 8, 7, 6, 5, 4, 3, 2, 1);
let mut q: PriorityQueue<uint> = xs.as_slice().iter().rev().map(|&x| x).collect();
let mut q: BinaryHeap<uint> = xs.as_slice().iter().rev().map(|&x| x).collect();
for &x in xs.iter() {
assert_eq!(q.pop().unwrap(), x);

View File

@ -8,6 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// FIXME(Gankro): Bitv and BitvSet are very tightly coupled. Ideally (for maintenance),
// they should be in separate files/modules, with BitvSet only using Bitv's public API.
//! Collections implemented with bit vectors.
//!
//! # Example
@ -1654,7 +1657,7 @@ mod tests {
use std::rand::Rng;
use test::Bencher;
use bitv::{Bitv, BitvSet, from_fn, from_bytes};
use super::{Bitv, BitvSet, from_fn, from_bytes};
use bitv;
use vec::Vec;

View File

@ -23,7 +23,7 @@ use core::default::Default;
use core::{iter, fmt, mem};
use core::fmt::Show;
use ringbuf::RingBuf;
use ring_buf::RingBuf;
/// A map based on a B-Tree.
///

View File

@ -8,27 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use self::map::BTreeMap;
pub use self::map::Entries;
pub use self::map::MutEntries;
pub use self::map::MoveEntries;
pub use self::map::Keys;
pub use self::map::Values;
pub use self::map::Entry;
pub use self::map::Occupied;
pub use self::map::Vacant;
pub use self::map::OccupiedEntry;
pub use self::map::VacantEntry;
pub use self::set::BTreeSet;
pub use self::set::Items;
pub use self::set::MoveItems;
pub use self::set::DifferenceItems;
pub use self::set::UnionItems;
pub use self::set::SymDifferenceItems;
pub use self::set::IntersectionItems;
mod node;
mod map;
mod set;
pub mod map;
pub mod set;

View File

@ -13,7 +13,7 @@
use core::prelude::*;
use super::{BTreeMap, Keys, MoveEntries};
use btree_map::{BTreeMap, Keys, MoveEntries};
use std::hash::Hash;
use core::default::Default;
use core::{iter, fmt};

View File

@ -155,7 +155,7 @@ mod test {
use std::prelude::*;
use std::mem;
use enum_set::{EnumSet, CLike};
use super::{EnumSet, CLike};
#[deriving(PartialEq, Show)]
#[repr(uint)]

View File

@ -37,34 +37,72 @@ extern crate alloc;
#[cfg(test)] #[phase(plugin, link)] extern crate std;
#[cfg(test)] #[phase(plugin, link)] extern crate log;
pub use bitv::{Bitv, BitvSet};
pub use btree::{BTreeMap, BTreeSet};
pub use binary_heap::BinaryHeap;
pub use bitv::Bitv;
pub use bitv_set::BitvSet;
pub use btree_map::BTreeMap;
pub use btree_set::BTreeSet;
pub use dlist::DList;
pub use enum_set::EnumSet;
pub use priority_queue::PriorityQueue;
pub use ringbuf::RingBuf;
pub use smallintmap::SmallIntMap;
pub use ring_buf::RingBuf;
pub use string::String;
pub use treemap::{TreeMap, TreeSet};
pub use trie::{TrieMap, TrieSet};
pub use tree_map::TreeMap;
pub use tree_set::TreeSet;
pub use trie_map::TrieMap;
pub use trie_set::TrieSet;
pub use vec::Vec;
pub use vec_map::VecMap;
mod macros;
pub mod bitv;
pub mod btree;
pub mod binary_heap;
mod bit;
mod btree;
pub mod dlist;
pub mod enum_set;
pub mod priority_queue;
pub mod ringbuf;
pub mod smallintmap;
pub mod treemap;
pub mod trie;
pub mod ring_buf;
mod tree;
mod trie;
pub mod slice;
pub mod str;
pub mod string;
pub mod vec;
pub mod hash;
pub mod vec_map;
pub mod bitv {
pub use bit::{Bitv, Bits, from_fn, from_bytes};
}
pub mod bitv_set {
pub use bit::{BitvSet, BitPositions, TwoBitPositions};
}
pub mod tree_map {
pub use tree::map::*;
}
pub mod tree_set {
pub use tree::set::*;
}
pub mod trie_map {
pub use trie::map::*;
}
pub mod trie_set {
pub use trie::set::*;
}
pub mod btree_map {
pub use btree::map::*;
}
pub mod btree_set {
pub use btree::set::*;
}
#[cfg(test)] mod bench;

View File

@ -62,7 +62,7 @@ use core::prelude::{PartialEq, PartialOrd, Result, AsSlice, Some, Tuple2};
use core::prelude::{range};
use hash;
use ringbuf::RingBuf;
use ring_buf::RingBuf;
use string::String;
use unicode;
use vec::Vec;

View File

@ -0,0 +1,36 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Maps are collections of unique keys with corresponding values, and sets are
//! just unique keys without a corresponding value. The `Map` and `Set` traits in
//! `std::container` define the basic interface.
//!
//! This crate defines the `TreeMap` and `TreeSet` types. Their keys must implement `Ord`.
//!
//! `TreeMap`s are ordered.
//!
//! ## Example
//!
//! ```{rust}
//! use std::collections::TreeSet;
//!
//! let mut tree_set = TreeSet::new();
//!
//! tree_set.insert(2i);
//! tree_set.insert(1i);
//! tree_set.insert(3i);
//!
//! for i in tree_set.iter() {
//! println!("{}", i) // prints 1, then 2, then 3
//! }
//! ```
pub mod map;
pub mod set;

View File

@ -0,0 +1,950 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::prelude::*;
use core::default::Default;
use core::fmt;
use core::fmt::Show;
use core::iter::Peekable;
use core::iter;
use std::hash::{Writer, Hash};
use tree_map::{TreeMap, Entries, RevEntries, MoveEntries};
/// An implementation of the `Set` trait on top of the `TreeMap` container. The
/// only requirement is that the type of the elements contained ascribes to the
/// `Ord` trait.
///
/// ## Example
///
/// ```{rust}
/// use std::collections::TreeSet;
///
/// let mut set = TreeSet::new();
///
/// set.insert(2i);
/// set.insert(1i);
/// set.insert(3i);
///
/// for i in set.iter() {
/// println!("{}", i) // prints 1, then 2, then 3
/// }
///
/// set.remove(&3);
///
/// if !set.contains(&3) {
/// println!("set does not contain a 3 anymore");
/// }
/// ```
///
/// The easiest way to use `TreeSet` with a custom type is to implement `Ord`.
/// We must also implement `PartialEq`, `Eq` and `PartialOrd`.
///
/// ```
/// use std::collections::TreeSet;
///
/// // We need `Eq` and `PartialEq`, these can be derived.
/// #[deriving(Eq, PartialEq)]
/// struct Troll<'a> {
/// name: &'a str,
/// level: uint,
/// }
///
/// // Implement `Ord` and sort trolls by level.
/// impl<'a> Ord for Troll<'a> {
/// fn cmp(&self, other: &Troll) -> Ordering {
/// // If we swap `self` and `other`, we get descending ordering.
/// self.level.cmp(&other.level)
/// }
/// }
///
/// // `PartialOrd` needs to be implemented as well.
/// impl<'a> PartialOrd for Troll<'a> {
/// fn partial_cmp(&self, other: &Troll) -> Option<Ordering> {
/// Some(self.cmp(other))
/// }
/// }
///
/// let mut trolls = TreeSet::new();
///
/// trolls.insert(Troll { name: "Orgarr", level: 2 });
/// trolls.insert(Troll { name: "Blargarr", level: 3 });
/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 });
/// trolls.insert(Troll { name: "Wartilda", level: 1 });
///
/// println!("You are facing {} trolls!", trolls.len());
///
/// // Print the trolls, ordered by level with smallest level first
/// for x in trolls.iter() {
/// println!("level {}: {}!", x.level, x.name);
/// }
///
/// // Kill all trolls
/// trolls.clear();
/// assert_eq!(trolls.len(), 0);
/// ```
#[deriving(Clone)]
pub struct TreeSet<T> {
map: TreeMap<T, ()>
}
impl<T: PartialEq + Ord> PartialEq for TreeSet<T> {
#[inline]
fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
}
impl<T: Eq + Ord> Eq for TreeSet<T> {}
impl<T: Ord> PartialOrd for TreeSet<T> {
#[inline]
fn partial_cmp(&self, other: &TreeSet<T>) -> Option<Ordering> {
self.map.partial_cmp(&other.map)
}
}
impl<T: Ord> Ord for TreeSet<T> {
#[inline]
fn cmp(&self, other: &TreeSet<T>) -> Ordering {
iter::order::cmp(self.iter(), other.iter())
}
}
impl<T: Ord + Show> Show for TreeSet<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "{{"));
for (i, x) in self.iter().enumerate() {
if i != 0 { try!(write!(f, ", ")); }
try!(write!(f, "{}", *x));
}
write!(f, "}}")
}
}
impl<T: Ord> Default for TreeSet<T> {
#[inline]
fn default() -> TreeSet<T> { TreeSet::new() }
}
impl<T: Ord> TreeSet<T> {
/// Creates an empty `TreeSet`.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
/// let mut set: TreeSet<int> = TreeSet::new();
/// ```
#[inline]
pub fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
/// Gets a lazy iterator over the values in the set, in ascending order.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
/// let set: TreeSet<int> = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect();
///
/// // Will print in ascending order.
/// for x in set.iter() {
/// println!("{}", x);
/// }
/// ```
#[inline]
pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
SetItems{iter: self.map.iter()}
}
/// Gets a lazy iterator over the values in the set, in descending order.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
/// let set: TreeSet<int> = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect();
///
/// // Will print in descending order.
/// for x in set.rev_iter() {
/// println!("{}", x);
/// }
/// ```
#[inline]
pub fn rev_iter<'a>(&'a self) -> RevSetItems<'a, T> {
RevSetItems{iter: self.map.rev_iter()}
}
/// Creates a consuming iterator, that is, one that moves each value out of the
/// set in ascending order. The set cannot be used after calling this.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
/// let set: TreeSet<int> = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect();
///
/// // Not possible with a regular `.iter()`
/// let v: Vec<int> = set.into_iter().collect();
/// assert_eq!(v, vec![1, 2, 3, 4, 5]);
/// ```
#[inline]
pub fn into_iter(self) -> MoveSetItems<T> {
self.map.into_iter().map(|(value, _)| value)
}
/// Gets a lazy iterator pointing to the first value not less than `v` (greater or equal).
/// If all elements in the set are less than `v` empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
/// let set: TreeSet<int> = [2, 4, 6, 8].iter().map(|&x| x).collect();
///
/// assert_eq!(set.lower_bound(&4).next(), Some(&4));
/// assert_eq!(set.lower_bound(&5).next(), Some(&6));
/// assert_eq!(set.lower_bound(&10).next(), None);
/// ```
#[inline]
pub fn lower_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> {
SetItems{iter: self.map.lower_bound(v)}
}
/// Gets a lazy iterator pointing to the first value greater than `v`.
/// If all elements in the set are less than or equal to `v` an
/// empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
/// let set: TreeSet<int> = [2, 4, 6, 8].iter().map(|&x| x).collect();
///
/// assert_eq!(set.upper_bound(&4).next(), Some(&6));
/// assert_eq!(set.upper_bound(&5).next(), Some(&6));
/// assert_eq!(set.upper_bound(&10).next(), None);
/// ```
#[inline]
pub fn upper_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> {
SetItems{iter: self.map.upper_bound(v)}
}
/// Visits the values representing the difference, in ascending order.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
/// let b: TreeSet<int> = [3, 4, 5].iter().map(|&x| x).collect();
///
/// // Can be seen as `a - b`.
/// for x in a.difference(&b) {
/// println!("{}", x); // Print 1 then 2
/// }
///
/// let diff: TreeSet<int> = a.difference(&b).map(|&x| x).collect();
/// assert_eq!(diff, [1, 2].iter().map(|&x| x).collect());
///
/// // Note that difference is not symmetric,
/// // and `b - a` means something else:
/// let diff: TreeSet<int> = b.difference(&a).map(|&x| x).collect();
/// assert_eq!(diff, [4, 5].iter().map(|&x| x).collect());
/// ```
pub fn difference<'a>(&'a self, other: &'a TreeSet<T>) -> DifferenceItems<'a, T> {
DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
}
/// Visits the values representing the symmetric difference, in ascending order.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
/// let b: TreeSet<int> = [3, 4, 5].iter().map(|&x| x).collect();
///
/// // Print 1, 2, 4, 5 in ascending order.
/// for x in a.symmetric_difference(&b) {
/// println!("{}", x);
/// }
///
/// let diff1: TreeSet<int> = a.symmetric_difference(&b).map(|&x| x).collect();
/// let diff2: TreeSet<int> = b.symmetric_difference(&a).map(|&x| x).collect();
///
/// assert_eq!(diff1, diff2);
/// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect());
/// ```
pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet<T>)
-> SymDifferenceItems<'a, T> {
SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
}
/// Visits the values representing the intersection, in ascending order.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
/// let b: TreeSet<int> = [2, 3, 4].iter().map(|&x| x).collect();
///
/// // Print 2, 3 in ascending order.
/// for x in a.intersection(&b) {
/// println!("{}", x);
/// }
///
/// let diff: TreeSet<int> = a.intersection(&b).map(|&x| x).collect();
/// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect());
/// ```
pub fn intersection<'a>(&'a self, other: &'a TreeSet<T>)
-> IntersectionItems<'a, T> {
IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()}
}
/// Visits the values representing the union, in ascending order.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let a: TreeSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
/// let b: TreeSet<int> = [3, 4, 5].iter().map(|&x| x).collect();
///
/// // Print 1, 2, 3, 4, 5 in ascending order.
/// for x in a.union(&b) {
/// println!("{}", x);
/// }
///
/// let diff: TreeSet<int> = a.union(&b).map(|&x| x).collect();
/// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect());
/// ```
pub fn union<'a>(&'a self, other: &'a TreeSet<T>) -> UnionItems<'a, T> {
UnionItems{a: self.iter().peekable(), b: other.iter().peekable()}
}
/// Return the number of elements in the set
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let mut v = TreeSet::new();
/// assert_eq!(v.len(), 0);
/// v.insert(1i);
/// assert_eq!(v.len(), 1);
/// ```
#[inline]
pub fn len(&self) -> uint { self.map.len() }
/// Returns true if the set contains no elements
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let mut v = TreeSet::new();
/// assert!(v.is_empty());
/// v.insert(1i);
/// assert!(!v.is_empty());
/// ```
pub fn is_empty(&self) -> bool { self.len() == 0 }
/// Clears the set, removing all values.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let mut v = TreeSet::new();
/// v.insert(1i);
/// v.clear();
/// assert!(v.is_empty());
/// ```
#[inline]
pub fn clear(&mut self) { self.map.clear() }
/// Returns `true` if the set contains a value.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let set: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
/// assert_eq!(set.contains(&1), true);
/// assert_eq!(set.contains(&4), false);
/// ```
#[inline]
pub fn contains(&self, value: &T) -> bool {
self.map.contains_key(value)
}
/// Returns `true` if the set has no elements in common with `other`.
/// This is equivalent to checking for an empty intersection.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let a: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
/// let mut b: TreeSet<int> = TreeSet::new();
///
/// assert_eq!(a.is_disjoint(&b), true);
/// b.insert(4);
/// assert_eq!(a.is_disjoint(&b), true);
/// b.insert(1);
/// assert_eq!(a.is_disjoint(&b), false);
/// ```
pub fn is_disjoint(&self, other: &TreeSet<T>) -> bool {
self.intersection(other).next().is_none()
}
/// Returns `true` if the set is a subset of another.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let sup: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
/// let mut set: TreeSet<int> = TreeSet::new();
///
/// assert_eq!(set.is_subset(&sup), true);
/// set.insert(2);
/// assert_eq!(set.is_subset(&sup), true);
/// set.insert(4);
/// assert_eq!(set.is_subset(&sup), false);
/// ```
pub fn is_subset(&self, other: &TreeSet<T>) -> bool {
let mut x = self.iter();
let mut y = other.iter();
let mut a = x.next();
let mut b = y.next();
while a.is_some() {
if b.is_none() {
return false;
}
let a1 = a.unwrap();
let b1 = b.unwrap();
match b1.cmp(a1) {
Less => (),
Greater => return false,
Equal => a = x.next(),
}
b = y.next();
}
true
}
/// Returns `true` if the set is a superset of another.
///
/// # Example
///
/// ```
/// use std::collections::TreeSet;
///
/// let sub: TreeSet<int> = [1i, 2].iter().map(|&x| x).collect();
/// let mut set: TreeSet<int> = TreeSet::new();
///
/// assert_eq!(set.is_superset(&sub), false);
///
/// set.insert(0);
/// set.insert(1);
/// assert_eq!(set.is_superset(&sub), false);
///
/// set.insert(2);
/// assert_eq!(set.is_superset(&sub), true);
/// ```
pub fn is_superset(&self, other: &TreeSet<T>) -> bool {
other.is_subset(self)
}
/// Adds a value to the set. Returns `true` if the value was not already
/// present in the set.
///
/// # Example
///
/// ```
/// use std::collections::BTreeSet;
///
/// let mut set = BTreeSet::new();
///
/// assert_eq!(set.insert(2i), true);
/// assert_eq!(set.insert(2i), false);
/// assert_eq!(set.len(), 1);
/// ```
#[inline]
pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
/// Removes a value from the set. Returns `true` if the value was
/// present in the set.
///
/// # Example
///
/// ```
/// use std::collections::BTreeSet;
///
/// let mut set = BTreeSet::new();
///
/// set.insert(2i);
/// assert_eq!(set.remove(&2), true);
/// assert_eq!(set.remove(&2), false);
/// ```
#[inline]
pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
}
/// A lazy forward iterator over a set.
pub struct SetItems<'a, T:'a> {
iter: Entries<'a, T, ()>
}
/// A lazy backward iterator over a set.
pub struct RevSetItems<'a, T:'a> {
iter: RevEntries<'a, T, ()>
}
/// A lazy forward iterator over a set that consumes the set while iterating.
pub type MoveSetItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;
/// A lazy iterator producing elements in the set difference (in-order).
pub struct DifferenceItems<'a, T:'a> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}
/// A lazy iterator producing elements in the set symmetric difference (in-order).
pub struct SymDifferenceItems<'a, T:'a> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}
/// A lazy iterator producing elements in the set intersection (in-order).
pub struct IntersectionItems<'a, T:'a> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}
/// A lazy iterator producing elements in the set union (in-order).
pub struct UnionItems<'a, T:'a> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}
/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
short: Ordering, long: Ordering) -> Ordering {
match (x, y) {
(None , _ ) => short,
(_ , None ) => long,
(Some(x1), Some(y1)) => x1.cmp(y1),
}
}
impl<'a, T> Iterator<&'a T> for SetItems<'a, T> {
#[inline]
fn next(&mut self) -> Option<&'a T> {
self.iter.next().map(|(value, _)| value)
}
}
impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> {
#[inline]
fn next(&mut self) -> Option<&'a T> {
self.iter.next().map(|(value, _)| value)
}
}
impl<'a, T: Ord> Iterator<&'a T> for DifferenceItems<'a, T> {
fn next(&mut self) -> Option<&'a T> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Less, Less) {
Less => return self.a.next(),
Equal => { self.a.next(); self.b.next(); }
Greater => { self.b.next(); }
}
}
}
}
impl<'a, T: Ord> Iterator<&'a T> for SymDifferenceItems<'a, T> {
fn next(&mut self) -> Option<&'a T> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
Less => return self.a.next(),
Equal => { self.a.next(); self.b.next(); }
Greater => return self.b.next(),
}
}
}
}
impl<'a, T: Ord> Iterator<&'a T> for IntersectionItems<'a, T> {
fn next(&mut self) -> Option<&'a T> {
loop {
let o_cmp = match (self.a.peek(), self.b.peek()) {
(None , _ ) => None,
(_ , None ) => None,
(Some(a1), Some(b1)) => Some(a1.cmp(b1)),
};
match o_cmp {
None => return None,
Some(Less) => { self.a.next(); }
Some(Equal) => { self.b.next(); return self.a.next() }
Some(Greater) => { self.b.next(); }
}
}
}
}
impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> {
fn next(&mut self) -> Option<&'a T> {
loop {
match cmp_opt(self.a.peek(), self.b.peek(), Greater, Less) {
Less => return self.a.next(),
Equal => { self.b.next(); return self.a.next() }
Greater => return self.b.next(),
}
}
}
}
impl<T: Ord> FromIterator<T> for TreeSet<T> {
fn from_iter<Iter: Iterator<T>>(iter: Iter) -> TreeSet<T> {
let mut set = TreeSet::new();
set.extend(iter);
set
}
}
impl<T: Ord> Extendable<T> for TreeSet<T> {
#[inline]
fn extend<Iter: Iterator<T>>(&mut self, mut iter: Iter) {
for elem in iter {
self.insert(elem);
}
}
}
impl<S: Writer, T: Ord + Hash<S>> Hash<S> for TreeSet<T> {
fn hash(&self, state: &mut S) {
for elt in self.iter() {
elt.hash(state);
}
}
}
#[cfg(test)]
mod test {
use std::prelude::*;
use std::hash;
use super::TreeSet;
#[test]
fn test_clear() {
let mut s = TreeSet::new();
s.clear();
assert!(s.insert(5i));
assert!(s.insert(12));
assert!(s.insert(19));
s.clear();
assert!(!s.contains(&5));
assert!(!s.contains(&12));
assert!(!s.contains(&19));
assert!(s.is_empty());
}
#[test]
fn test_disjoint() {
let mut xs = TreeSet::new();
let mut ys = TreeSet::new();
assert!(xs.is_disjoint(&ys));
assert!(ys.is_disjoint(&xs));
assert!(xs.insert(5i));
assert!(ys.insert(11i));
assert!(xs.is_disjoint(&ys));
assert!(ys.is_disjoint(&xs));
assert!(xs.insert(7));
assert!(xs.insert(19));
assert!(xs.insert(4));
assert!(ys.insert(2));
assert!(ys.insert(-11));
assert!(xs.is_disjoint(&ys));
assert!(ys.is_disjoint(&xs));
assert!(ys.insert(7));
assert!(!xs.is_disjoint(&ys));
assert!(!ys.is_disjoint(&xs));
}
#[test]
fn test_subset_and_superset() {
let mut a = TreeSet::new();
assert!(a.insert(0i));
assert!(a.insert(5));
assert!(a.insert(11));
assert!(a.insert(7));
let mut b = TreeSet::new();
assert!(b.insert(0i));
assert!(b.insert(7));
assert!(b.insert(19));
assert!(b.insert(250));
assert!(b.insert(11));
assert!(b.insert(200));
assert!(!a.is_subset(&b));
assert!(!a.is_superset(&b));
assert!(!b.is_subset(&a));
assert!(!b.is_superset(&a));
assert!(b.insert(5));
assert!(a.is_subset(&b));
assert!(!a.is_superset(&b));
assert!(!b.is_subset(&a));
assert!(b.is_superset(&a));
}
#[test]
fn test_iterator() {
let mut m = TreeSet::new();
assert!(m.insert(3i));
assert!(m.insert(0));
assert!(m.insert(4));
assert!(m.insert(2));
assert!(m.insert(1));
let mut n = 0;
for x in m.iter() {
assert_eq!(*x, n);
n += 1
}
}
#[test]
fn test_rev_iter() {
let mut m = TreeSet::new();
assert!(m.insert(3i));
assert!(m.insert(0));
assert!(m.insert(4));
assert!(m.insert(2));
assert!(m.insert(1));
let mut n = 4;
for x in m.rev_iter() {
assert_eq!(*x, n);
n -= 1;
}
}
#[test]
fn test_move_iter() {
let s: TreeSet<int> = range(0i, 5).collect();
let mut n = 0;
for x in s.into_iter() {
assert_eq!(x, n);
n += 1;
}
}
#[test]
fn test_move_iter_size_hint() {
let s: TreeSet<int> = vec!(0i, 1).into_iter().collect();
let mut it = s.into_iter();
assert_eq!(it.size_hint(), (2, Some(2)));
assert!(it.next() != None);
assert_eq!(it.size_hint(), (1, Some(1)));
assert!(it.next() != None);
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next(), None);
}
#[test]
fn test_clone_eq() {
let mut m = TreeSet::new();
m.insert(1i);
m.insert(2);
assert!(m.clone() == m);
}
#[test]
fn test_hash() {
let mut x = TreeSet::new();
let mut y = TreeSet::new();
x.insert(1i);
x.insert(2);
x.insert(3);
y.insert(3i);
y.insert(2);
y.insert(1);
assert!(hash::hash(&x) == hash::hash(&y));
}
fn check(a: &[int],
b: &[int],
expected: &[int],
f: |&TreeSet<int>, &TreeSet<int>, f: |&int| -> bool| -> bool) {
let mut set_a = TreeSet::new();
let mut set_b = TreeSet::new();
for x in a.iter() { assert!(set_a.insert(*x)) }
for y in b.iter() { assert!(set_b.insert(*y)) }
let mut i = 0;
f(&set_a, &set_b, |x| {
assert_eq!(*x, expected[i]);
i += 1;
true
});
assert_eq!(i, expected.len());
}
#[test]
fn test_intersection() {
fn check_intersection(a: &[int], b: &[int], expected: &[int]) {
check(a, b, expected, |x, y, f| x.intersection(y).all(f))
}
check_intersection([], [], []);
check_intersection([1, 2, 3], [], []);
check_intersection([], [1, 2, 3], []);
check_intersection([2], [1, 2, 3], [2]);
check_intersection([1, 2, 3], [2], [2]);
check_intersection([11, 1, 3, 77, 103, 5, -5],
[2, 11, 77, -9, -42, 5, 3],
[3, 5, 11, 77]);
}
#[test]
fn test_difference() {
fn check_difference(a: &[int], b: &[int], expected: &[int]) {
check(a, b, expected, |x, y, f| x.difference(y).all(f))
}
check_difference([], [], []);
check_difference([1, 12], [], [1, 12]);
check_difference([], [1, 2, 3, 9], []);
check_difference([1, 3, 5, 9, 11],
[3, 9],
[1, 5, 11]);
check_difference([-5, 11, 22, 33, 40, 42],
[-12, -5, 14, 23, 34, 38, 39, 50],
[11, 22, 33, 40, 42]);
}
#[test]
fn test_symmetric_difference() {
fn check_symmetric_difference(a: &[int], b: &[int],
expected: &[int]) {
check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
}
check_symmetric_difference([], [], []);
check_symmetric_difference([1, 2, 3], [2], [1, 3]);
check_symmetric_difference([2], [1, 2, 3], [1, 3]);
check_symmetric_difference([1, 3, 5, 9, 11],
[-2, 3, 9, 14, 22],
[-2, 1, 5, 11, 14, 22]);
}
#[test]
fn test_union() {
fn check_union(a: &[int], b: &[int],
expected: &[int]) {
check(a, b, expected, |x, y, f| x.union(y).all(f))
}
check_union([], [], []);
check_union([1, 2, 3], [2], [1, 2, 3]);
check_union([2], [1, 2, 3], [1, 2, 3]);
check_union([1, 3, 5, 9, 11, 16, 19, 24],
[-2, 1, 5, 9, 13, 19],
[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
}
#[test]
fn test_zip() {
let mut x = TreeSet::new();
x.insert(5u);
x.insert(12u);
x.insert(11u);
let mut y = TreeSet::new();
y.insert("foo");
y.insert("bar");
let x = x;
let y = y;
let mut z = x.iter().zip(y.iter());
// FIXME: #5801: this needs a type hint to compile...
let result: Option<(&uint, & &'static str)> = z.next();
assert_eq!(result.unwrap(), (&5u, &("bar")));
let result: Option<(&uint, & &'static str)> = z.next();
assert_eq!(result.unwrap(), (&11u, &("foo")));
let result: Option<(&uint, & &'static str)> = z.next();
assert!(result.is_none());
}
#[test]
fn test_from_iter() {
let xs = [1i, 2, 3, 4, 5, 6, 7, 8, 9];
let set: TreeSet<int> = xs.iter().map(|&x| x).collect();
for x in xs.iter() {
assert!(set.contains(x));
}
}
#[test]
fn test_show() {
let mut set: TreeSet<int> = TreeSet::new();
let empty: TreeSet<int> = TreeSet::new();
set.insert(1);
set.insert(2);
let set_str = format!("{}", set);
assert!(set_str == "{1, 2}".to_string());
assert_eq!(format!("{}", empty), "{}".to_string());
}
}

View File

@ -654,335 +654,6 @@ impl<T> IndexMut<uint, T> for TrieMap<T> {
}
}
/// A set implemented as a radix trie.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut set = TrieSet::new();
/// set.insert(6);
/// set.insert(28);
/// set.insert(6);
///
/// assert_eq!(set.len(), 2);
///
/// if !set.contains(&3) {
/// println!("3 is not in the set");
/// }
///
/// // Print contents in order
/// for x in set.iter() {
/// println!("{}", x);
/// }
///
/// set.remove(&6);
/// assert_eq!(set.len(), 1);
///
/// set.clear();
/// assert!(set.is_empty());
/// ```
#[deriving(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct TrieSet {
map: TrieMap<()>
}
impl Show for TrieSet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "{{"));
for (i, x) in self.iter().enumerate() {
if i != 0 { try!(write!(f, ", ")); }
try!(write!(f, "{}", x));
}
write!(f, "}}")
}
}
impl Default for TrieSet {
#[inline]
fn default() -> TrieSet { TrieSet::new() }
}
impl TrieSet {
/// Creates an empty TrieSet.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
/// let mut set = TrieSet::new();
/// ```
#[inline]
pub fn new() -> TrieSet {
TrieSet{map: TrieMap::new()}
}
/// Visits all values in reverse order. Aborts traversal when `f` returns `false`.
/// Returns `true` if `f` returns `true` for all elements.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [1, 2, 3, 4, 5].iter().map(|&x| x).collect();
///
/// let mut vec = Vec::new();
/// assert_eq!(true, set.each_reverse(|&x| { vec.push(x); true }));
/// assert_eq!(vec, vec![5, 4, 3, 2, 1]);
///
/// // Stop when we reach 3
/// let mut vec = Vec::new();
/// assert_eq!(false, set.each_reverse(|&x| { vec.push(x); x != 3 }));
/// assert_eq!(vec, vec![5, 4, 3]);
/// ```
#[inline]
pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
self.map.each_reverse(|k, _| f(k))
}
/// Gets an iterator over the values in the set, in sorted order.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut set = TrieSet::new();
/// set.insert(3);
/// set.insert(2);
/// set.insert(1);
/// set.insert(2);
///
/// // Print 1, 2, 3
/// for x in set.iter() {
/// println!("{}", x);
/// }
/// ```
#[inline]
pub fn iter<'a>(&'a self) -> SetItems<'a> {
SetItems{iter: self.map.iter()}
}
/// Gets an iterator pointing to the first value that is not less than `val`.
/// If all values in the set are less than `val` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
/// assert_eq!(set.lower_bound(4).next(), Some(4));
/// assert_eq!(set.lower_bound(5).next(), Some(6));
/// assert_eq!(set.lower_bound(10).next(), None);
/// ```
pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.lower_bound(val)}
}
/// Gets an iterator pointing to the first value that key is greater than `val`.
/// If all values in the set are less than or equal to `val` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
/// assert_eq!(set.upper_bound(4).next(), Some(6));
/// assert_eq!(set.upper_bound(5).next(), Some(6));
/// assert_eq!(set.upper_bound(10).next(), None);
/// ```
pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.upper_bound(val)}
}
/// Return the number of elements in the set
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut v = TrieSet::new();
/// assert_eq!(v.len(), 0);
/// v.insert(1);
/// assert_eq!(v.len(), 1);
/// ```
#[inline]
pub fn len(&self) -> uint { self.map.len() }
/// Returns true if the set contains no elements
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut v = TrieSet::new();
/// assert!(v.is_empty());
/// v.insert(1);
/// assert!(!v.is_empty());
/// ```
pub fn is_empty(&self) -> bool { self.len() == 0 }
/// Clears the set, removing all values.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut v = TrieSet::new();
/// v.insert(1);
/// v.clear();
/// assert!(v.is_empty());
/// ```
#[inline]
pub fn clear(&mut self) { self.map.clear() }
/// Returns `true` if the set contains a value.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
/// assert_eq!(set.contains(&1), true);
/// assert_eq!(set.contains(&4), false);
/// ```
#[inline]
pub fn contains(&self, value: &uint) -> bool {
self.map.contains_key(value)
}
/// Returns `true` if the set has no elements in common with `other`.
/// This is equivalent to checking for an empty intersection.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
/// let mut b: TrieSet = TrieSet::new();
///
/// assert_eq!(a.is_disjoint(&b), true);
/// b.insert(4);
/// assert_eq!(a.is_disjoint(&b), true);
/// b.insert(1);
/// assert_eq!(a.is_disjoint(&b), false);
/// ```
#[inline]
pub fn is_disjoint(&self, other: &TrieSet) -> bool {
self.iter().all(|v| !other.contains(&v))
}
/// Returns `true` if the set is a subset of another.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let sup: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
/// let mut set: TrieSet = TrieSet::new();
///
/// assert_eq!(set.is_subset(&sup), true);
/// set.insert(2);
/// assert_eq!(set.is_subset(&sup), true);
/// set.insert(4);
/// assert_eq!(set.is_subset(&sup), false);
/// ```
#[inline]
pub fn is_subset(&self, other: &TrieSet) -> bool {
self.iter().all(|v| other.contains(&v))
}
/// Returns `true` if the set is a superset of another.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let sub: TrieSet = [1, 2].iter().map(|&x| x).collect();
/// let mut set: TrieSet = TrieSet::new();
///
/// assert_eq!(set.is_superset(&sub), false);
///
/// set.insert(0);
/// set.insert(1);
/// assert_eq!(set.is_superset(&sub), false);
///
/// set.insert(2);
/// assert_eq!(set.is_superset(&sub), true);
/// ```
#[inline]
pub fn is_superset(&self, other: &TrieSet) -> bool {
other.is_subset(self)
}
/// Adds a value to the set. Returns `true` if the value was not already
/// present in the set.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut set = TrieSet::new();
///
/// assert_eq!(set.insert(2), true);
/// assert_eq!(set.insert(2), false);
/// assert_eq!(set.len(), 1);
/// ```
#[inline]
pub fn insert(&mut self, value: uint) -> bool {
self.map.insert(value, ())
}
/// Removes a value from the set. Returns `true` if the value was
/// present in the set.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut set = TrieSet::new();
///
/// set.insert(2);
/// assert_eq!(set.remove(&2), true);
/// assert_eq!(set.remove(&2), false);
/// ```
#[inline]
pub fn remove(&mut self, value: &uint) -> bool {
self.map.remove(value)
}
}
impl FromIterator<uint> for TrieSet {
fn from_iter<Iter: Iterator<uint>>(iter: Iter) -> TrieSet {
let mut set = TrieSet::new();
set.extend(iter);
set
}
}
impl Extendable<uint> for TrieSet {
fn extend<Iter: Iterator<uint>>(&mut self, mut iter: Iter) {
for elem in iter {
self.insert(elem);
}
}
}
struct TrieNode<T> {
count: uint,
children: [Child<T>, ..SIZE]
@ -1255,23 +926,8 @@ macro_rules! iterator_impl {
iterator_impl! { Entries, iter = iter, mutability = }
iterator_impl! { MutEntries, iter = iter_mut, mutability = mut }
/// A forward iterator over a set.
pub struct SetItems<'a> {
iter: Entries<'a, ()>
}
impl<'a> Iterator<uint> for SetItems<'a> {
fn next(&mut self) -> Option<uint> {
self.iter.next().map(|(key, _)| key)
}
fn size_hint(&self) -> (uint, Option<uint>) {
self.iter.size_hint()
}
}
#[cfg(test)]
mod test_map {
mod test {
use std::prelude::*;
use std::iter::range_step;
use std::uint;
@ -1687,7 +1343,7 @@ mod test_map {
}
#[cfg(test)]
mod bench_map {
mod bench {
use std::prelude::*;
use std::rand::{weak_rng, Rng};
use test::{Bencher, black_box};
@ -1802,98 +1458,3 @@ mod bench_map {
})
}
}
#[cfg(test)]
mod test_set {
use std::prelude::*;
use std::uint;
use super::TrieSet;
#[test]
fn test_sane_chunk() {
let x = 1;
let y = 1 << (uint::BITS - 1);
let mut trie = TrieSet::new();
assert!(trie.insert(x));
assert!(trie.insert(y));
assert_eq!(trie.len(), 2);
let expected = [x, y];
for (i, x) in trie.iter().enumerate() {
assert_eq!(expected[i], x);
}
}
#[test]
fn test_from_iter() {
let xs = vec![9u, 8, 7, 6, 5, 4, 3, 2, 1];
let set: TrieSet = xs.iter().map(|&x| x).collect();
for x in xs.iter() {
assert!(set.contains(x));
}
}
#[test]
fn test_show() {
let mut set = TrieSet::new();
let empty = TrieSet::new();
set.insert(1);
set.insert(2);
let set_str = format!("{}", set);
assert!(set_str == "{1, 2}".to_string());
assert_eq!(format!("{}", empty), "{}".to_string());
}
#[test]
fn test_clone() {
let mut a = TrieSet::new();
a.insert(1);
a.insert(2);
a.insert(3);
assert!(a.clone() == a);
}
#[test]
fn test_lt() {
let mut a = TrieSet::new();
let mut b = TrieSet::new();
assert!(!(a < b) && !(b < a));
assert!(b.insert(2u));
assert!(a < b);
assert!(a.insert(3u));
assert!(!(a < b) && b < a);
assert!(b.insert(1));
assert!(b < a);
assert!(a.insert(0));
assert!(a < b);
assert!(a.insert(6));
assert!(a < b && !(b < a));
}
#[test]
fn test_ord() {
let mut a = TrieSet::new();
let mut b = TrieSet::new();
assert!(a <= b && a >= b);
assert!(a.insert(1u));
assert!(a > b && a >= b);
assert!(b < a && b <= a);
assert!(b.insert(2u));
assert!(b > a && b >= a);
assert!(a < b && a <= b);
}
}

View File

@ -0,0 +1,20 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Maps are collections of unique keys with corresponding values, and sets are
//! just unique keys without a corresponding value. The `Map` and `Set` traits in
//! `std::container` define the basic interface.
//!
//! This crate defines `TrieMap` and `TrieSet`, which require `uint` keys.
//!
//! `TrieMap` is ordered.
pub mod map;
pub mod set;

View File

@ -0,0 +1,457 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::prelude::*;
use core::default::Default;
use core::fmt;
use core::fmt::Show;
use std::hash::Hash;
use trie_map::{TrieMap, Entries};
/// A set implemented as a radix trie.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut set = TrieSet::new();
/// set.insert(6);
/// set.insert(28);
/// set.insert(6);
///
/// assert_eq!(set.len(), 2);
///
/// if !set.contains(&3) {
/// println!("3 is not in the set");
/// }
///
/// // Print contents in order
/// for x in set.iter() {
/// println!("{}", x);
/// }
///
/// set.remove(&6);
/// assert_eq!(set.len(), 1);
///
/// set.clear();
/// assert!(set.is_empty());
/// ```
#[deriving(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct TrieSet {
map: TrieMap<()>
}
impl Show for TrieSet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "{{"));
for (i, x) in self.iter().enumerate() {
if i != 0 { try!(write!(f, ", ")); }
try!(write!(f, "{}", x));
}
write!(f, "}}")
}
}
impl Default for TrieSet {
#[inline]
fn default() -> TrieSet { TrieSet::new() }
}
impl TrieSet {
/// Creates an empty TrieSet.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
/// let mut set = TrieSet::new();
/// ```
#[inline]
pub fn new() -> TrieSet {
TrieSet{map: TrieMap::new()}
}
/// Visits all values in reverse order. Aborts traversal when `f` returns `false`.
/// Returns `true` if `f` returns `true` for all elements.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [1, 2, 3, 4, 5].iter().map(|&x| x).collect();
///
/// let mut vec = Vec::new();
/// assert_eq!(true, set.each_reverse(|&x| { vec.push(x); true }));
/// assert_eq!(vec, vec![5, 4, 3, 2, 1]);
///
/// // Stop when we reach 3
/// let mut vec = Vec::new();
/// assert_eq!(false, set.each_reverse(|&x| { vec.push(x); x != 3 }));
/// assert_eq!(vec, vec![5, 4, 3]);
/// ```
#[inline]
pub fn each_reverse(&self, f: |&uint| -> bool) -> bool {
self.map.each_reverse(|k, _| f(k))
}
/// Gets an iterator over the values in the set, in sorted order.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut set = TrieSet::new();
/// set.insert(3);
/// set.insert(2);
/// set.insert(1);
/// set.insert(2);
///
/// // Print 1, 2, 3
/// for x in set.iter() {
/// println!("{}", x);
/// }
/// ```
#[inline]
pub fn iter<'a>(&'a self) -> SetItems<'a> {
SetItems{iter: self.map.iter()}
}
/// Gets an iterator pointing to the first value that is not less than `val`.
/// If all values in the set are less than `val` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
/// assert_eq!(set.lower_bound(4).next(), Some(4));
/// assert_eq!(set.lower_bound(5).next(), Some(6));
/// assert_eq!(set.lower_bound(10).next(), None);
/// ```
pub fn lower_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.lower_bound(val)}
}
/// Gets an iterator pointing to the first value that key is greater than `val`.
/// If all values in the set are less than or equal to `val` an empty iterator is returned.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [2, 4, 6, 8].iter().map(|&x| x).collect();
/// assert_eq!(set.upper_bound(4).next(), Some(6));
/// assert_eq!(set.upper_bound(5).next(), Some(6));
/// assert_eq!(set.upper_bound(10).next(), None);
/// ```
pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
SetItems{iter: self.map.upper_bound(val)}
}
/// Return the number of elements in the set
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut v = TrieSet::new();
/// assert_eq!(v.len(), 0);
/// v.insert(1);
/// assert_eq!(v.len(), 1);
/// ```
#[inline]
pub fn len(&self) -> uint { self.map.len() }
/// Returns true if the set contains no elements
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut v = TrieSet::new();
/// assert!(v.is_empty());
/// v.insert(1);
/// assert!(!v.is_empty());
/// ```
pub fn is_empty(&self) -> bool { self.len() == 0 }
/// Clears the set, removing all values.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut v = TrieSet::new();
/// v.insert(1);
/// v.clear();
/// assert!(v.is_empty());
/// ```
#[inline]
pub fn clear(&mut self) { self.map.clear() }
/// Returns `true` if the set contains a value.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let set: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
/// assert_eq!(set.contains(&1), true);
/// assert_eq!(set.contains(&4), false);
/// ```
#[inline]
pub fn contains(&self, value: &uint) -> bool {
self.map.contains_key(value)
}
/// Returns `true` if the set has no elements in common with `other`.
/// This is equivalent to checking for an empty intersection.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
/// let mut b: TrieSet = TrieSet::new();
///
/// assert_eq!(a.is_disjoint(&b), true);
/// b.insert(4);
/// assert_eq!(a.is_disjoint(&b), true);
/// b.insert(1);
/// assert_eq!(a.is_disjoint(&b), false);
/// ```
#[inline]
pub fn is_disjoint(&self, other: &TrieSet) -> bool {
self.iter().all(|v| !other.contains(&v))
}
/// Returns `true` if the set is a subset of another.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let sup: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
/// let mut set: TrieSet = TrieSet::new();
///
/// assert_eq!(set.is_subset(&sup), true);
/// set.insert(2);
/// assert_eq!(set.is_subset(&sup), true);
/// set.insert(4);
/// assert_eq!(set.is_subset(&sup), false);
/// ```
#[inline]
pub fn is_subset(&self, other: &TrieSet) -> bool {
self.iter().all(|v| other.contains(&v))
}
/// Returns `true` if the set is a superset of another.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let sub: TrieSet = [1, 2].iter().map(|&x| x).collect();
/// let mut set: TrieSet = TrieSet::new();
///
/// assert_eq!(set.is_superset(&sub), false);
///
/// set.insert(0);
/// set.insert(1);
/// assert_eq!(set.is_superset(&sub), false);
///
/// set.insert(2);
/// assert_eq!(set.is_superset(&sub), true);
/// ```
#[inline]
pub fn is_superset(&self, other: &TrieSet) -> bool {
other.is_subset(self)
}
/// Adds a value to the set. Returns `true` if the value was not already
/// present in the set.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut set = TrieSet::new();
///
/// assert_eq!(set.insert(2), true);
/// assert_eq!(set.insert(2), false);
/// assert_eq!(set.len(), 1);
/// ```
#[inline]
pub fn insert(&mut self, value: uint) -> bool {
self.map.insert(value, ())
}
/// Removes a value from the set. Returns `true` if the value was
/// present in the set.
///
/// # Example
///
/// ```
/// use std::collections::TrieSet;
///
/// let mut set = TrieSet::new();
///
/// set.insert(2);
/// assert_eq!(set.remove(&2), true);
/// assert_eq!(set.remove(&2), false);
/// ```
#[inline]
pub fn remove(&mut self, value: &uint) -> bool {
self.map.remove(value)
}
}
impl FromIterator<uint> for TrieSet {
fn from_iter<Iter: Iterator<uint>>(iter: Iter) -> TrieSet {
let mut set = TrieSet::new();
set.extend(iter);
set
}
}
impl Extendable<uint> for TrieSet {
fn extend<Iter: Iterator<uint>>(&mut self, mut iter: Iter) {
for elem in iter {
self.insert(elem);
}
}
}
/// A forward iterator over a set.
pub struct SetItems<'a> {
iter: Entries<'a, ()>
}
impl<'a> Iterator<uint> for SetItems<'a> {
fn next(&mut self) -> Option<uint> {
self.iter.next().map(|(key, _)| key)
}
fn size_hint(&self) -> (uint, Option<uint>) {
self.iter.size_hint()
}
}
#[cfg(test)]
mod test {
use std::prelude::*;
use std::uint;
use super::TrieSet;
#[test]
fn test_sane_chunk() {
let x = 1;
let y = 1 << (uint::BITS - 1);
let mut trie = TrieSet::new();
assert!(trie.insert(x));
assert!(trie.insert(y));
assert_eq!(trie.len(), 2);
let expected = [x, y];
for (i, x) in trie.iter().enumerate() {
assert_eq!(expected[i], x);
}
}
#[test]
fn test_from_iter() {
let xs = vec![9u, 8, 7, 6, 5, 4, 3, 2, 1];
let set: TrieSet = xs.iter().map(|&x| x).collect();
for x in xs.iter() {
assert!(set.contains(x));
}
}
#[test]
fn test_show() {
let mut set = TrieSet::new();
let empty = TrieSet::new();
set.insert(1);
set.insert(2);
let set_str = format!("{}", set);
assert!(set_str == "{1, 2}".to_string());
assert_eq!(format!("{}", empty), "{}".to_string());
}
#[test]
fn test_clone() {
let mut a = TrieSet::new();
a.insert(1);
a.insert(2);
a.insert(3);
assert!(a.clone() == a);
}
#[test]
fn test_lt() {
let mut a = TrieSet::new();
let mut b = TrieSet::new();
assert!(!(a < b) && !(b < a));
assert!(b.insert(2u));
assert!(a < b);
assert!(a.insert(3u));
assert!(!(a < b) && b < a);
assert!(b.insert(1));
assert!(b < a);
assert!(a.insert(0));
assert!(a < b);
assert!(a.insert(6));
assert!(a < b && !(b < a));
}
#[test]
fn test_ord() {
let mut a = TrieSet::new();
let mut b = TrieSet::new();
assert!(a <= b && a >= b);
assert!(a.insert(1u));
assert!(a > b && a >= b);
assert!(b < a && b <= a);
assert!(b.insert(2u));
assert!(b > a && b >= a);
assert!(a < b && a <= b);
}
}

View File

@ -31,9 +31,9 @@ use hash::Hash;
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut months = SmallIntMap::new();
/// let mut months = VecMap::new();
/// months.insert(1, "Jan");
/// months.insert(2, "Feb");
/// months.insert(3, "Mar");
@ -60,23 +60,23 @@ use hash::Hash;
/// assert!(months.is_empty());
/// ```
#[deriving(PartialEq, Eq)]
pub struct SmallIntMap<T> {
pub struct VecMap<T> {
v: Vec<Option<T>>,
}
impl<V> Default for SmallIntMap<V> {
impl<V> Default for VecMap<V> {
#[inline]
fn default() -> SmallIntMap<V> { SmallIntMap::new() }
fn default() -> VecMap<V> { VecMap::new() }
}
impl<V:Clone> Clone for SmallIntMap<V> {
impl<V:Clone> Clone for VecMap<V> {
#[inline]
fn clone(&self) -> SmallIntMap<V> {
SmallIntMap { v: self.v.clone() }
fn clone(&self) -> VecMap<V> {
VecMap { v: self.v.clone() }
}
#[inline]
fn clone_from(&mut self, source: &SmallIntMap<V>) {
fn clone_from(&mut self, source: &VecMap<V>) {
self.v.reserve(source.v.len());
for (i, w) in self.v.iter_mut().enumerate() {
*w = source.v[i].clone();
@ -84,34 +84,34 @@ impl<V:Clone> Clone for SmallIntMap<V> {
}
}
impl <S: hash::Writer, T: Hash<S>> Hash<S> for SmallIntMap<T> {
impl <S: hash::Writer, T: Hash<S>> Hash<S> for VecMap<T> {
fn hash(&self, state: &mut S) {
self.v.hash(state)
}
}
impl<V> SmallIntMap<V> {
/// Creates an empty `SmallIntMap`.
impl<V> VecMap<V> {
/// Creates an empty `VecMap`.
///
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// let mut map: SmallIntMap<&str> = SmallIntMap::new();
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::new();
/// ```
pub fn new() -> SmallIntMap<V> { SmallIntMap{v: vec!()} }
pub fn new() -> VecMap<V> { VecMap{v: vec!()} }
/// Creates an empty `SmallIntMap` with space for at least `capacity`
/// Creates an empty `VecMap` with space for at least `capacity`
/// elements before resizing.
///
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// let mut map: SmallIntMap<&str> = SmallIntMap::with_capacity(10);
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::with_capacity(10);
/// ```
pub fn with_capacity(capacity: uint) -> SmallIntMap<V> {
SmallIntMap { v: Vec::with_capacity(capacity) }
pub fn with_capacity(capacity: uint) -> VecMap<V> {
VecMap { v: Vec::with_capacity(capacity) }
}
/// Returns an iterator visiting all keys in ascending order by the keys.
@ -132,9 +132,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// map.insert(3, "c");
/// map.insert(2, "b");
@ -159,9 +159,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// map.insert(2, "b");
/// map.insert(3, "c");
@ -183,15 +183,15 @@ impl<V> SmallIntMap<V> {
}
/// Returns an iterator visiting all key-value pairs in ascending order by
/// the keys, emptying (but not consuming) the original `SmallIntMap`.
/// the keys, emptying (but not consuming) the original `VecMap`.
/// The iterator's element type is `(uint, &'r V)`.
///
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// map.insert(3, "c");
/// map.insert(2, "b");
@ -216,9 +216,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut a = SmallIntMap::new();
/// let mut a = VecMap::new();
/// assert_eq!(a.len(), 0);
/// a.insert(1, "a");
/// assert_eq!(a.len(), 1);
@ -232,9 +232,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut a = SmallIntMap::new();
/// let mut a = VecMap::new();
/// assert!(a.is_empty());
/// a.insert(1, "a");
/// assert!(!a.is_empty());
@ -248,9 +248,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut a = SmallIntMap::new();
/// let mut a = VecMap::new();
/// a.insert(1, "a");
/// a.clear();
/// assert!(a.is_empty());
@ -262,9 +262,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// assert_eq!(map.find(&1), Some(&"a"));
/// assert_eq!(map.find(&2), None);
@ -285,9 +285,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// assert_eq!(map.contains_key(&1), true);
/// assert_eq!(map.contains_key(&2), false);
@ -302,9 +302,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// match map.find_mut(&1) {
/// Some(x) => *x = "b",
@ -330,9 +330,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// assert_eq!(map.insert(2, "value"), true);
/// assert_eq!(map.insert(2, "value2"), false);
/// assert_eq!(map[2], "value2");
@ -353,9 +353,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// assert_eq!(map.remove(&1), false);
/// map.insert(1, "a");
/// assert_eq!(map.remove(&1), true);
@ -370,9 +370,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// assert_eq!(map.swap(37, "a"), None);
/// assert_eq!(map.is_empty(), false);
///
@ -395,9 +395,9 @@ impl<V> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
/// map.insert(1, "a");
/// assert_eq!(map.pop(&1), Some("a"));
/// assert_eq!(map.pop(&1), None);
@ -410,7 +410,7 @@ impl<V> SmallIntMap<V> {
}
}
impl<V:Clone> SmallIntMap<V> {
impl<V:Clone> VecMap<V> {
/// Updates a value in the map. If the key already exists in the map,
/// modifies the value with `ff` taking `oldval, newval`.
/// Otherwise, sets the value to `newval`.
@ -419,9 +419,9 @@ impl<V:Clone> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
///
/// // Key does not exist, will do a simple insert
/// assert!(map.update(1, vec![1i, 2], |mut old, new| { old.extend(new.into_iter()); old }));
@ -443,9 +443,9 @@ impl<V:Clone> SmallIntMap<V> {
/// # Example
///
/// ```
/// use std::collections::SmallIntMap;
/// use std::collections::VecMap;
///
/// let mut map = SmallIntMap::new();
/// let mut map = VecMap::new();
///
/// // Key does not exist, will do a simple insert
/// assert!(map.update_with_key(7, 10, |key, old, new| (old + new) % key));
@ -468,21 +468,21 @@ impl<V:Clone> SmallIntMap<V> {
}
}
impl<V: PartialOrd> PartialOrd for SmallIntMap<V> {
impl<V: PartialOrd> PartialOrd for VecMap<V> {
#[inline]
fn partial_cmp(&self, other: &SmallIntMap<V>) -> Option<Ordering> {
fn partial_cmp(&self, other: &VecMap<V>) -> Option<Ordering> {
iter::order::partial_cmp(self.iter(), other.iter())
}
}
impl<V: Ord> Ord for SmallIntMap<V> {
impl<V: Ord> Ord for VecMap<V> {
#[inline]
fn cmp(&self, other: &SmallIntMap<V>) -> Ordering {
fn cmp(&self, other: &VecMap<V>) -> Ordering {
iter::order::cmp(self.iter(), other.iter())
}
}
impl<V: fmt::Show> fmt::Show for SmallIntMap<V> {
impl<V: fmt::Show> fmt::Show for VecMap<V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "{{"));
@ -495,15 +495,15 @@ impl<V: fmt::Show> fmt::Show for SmallIntMap<V> {
}
}
impl<V> FromIterator<(uint, V)> for SmallIntMap<V> {
fn from_iter<Iter: Iterator<(uint, V)>>(iter: Iter) -> SmallIntMap<V> {
let mut map = SmallIntMap::new();
impl<V> FromIterator<(uint, V)> for VecMap<V> {
fn from_iter<Iter: Iterator<(uint, V)>>(iter: Iter) -> VecMap<V> {
let mut map = VecMap::new();
map.extend(iter);
map
}
}
impl<V> Extendable<(uint, V)> for SmallIntMap<V> {
impl<V> Extendable<(uint, V)> for VecMap<V> {
fn extend<Iter: Iterator<(uint, V)>>(&mut self, mut iter: Iter) {
for (k, v) in iter {
self.insert(k, v);
@ -511,14 +511,14 @@ impl<V> Extendable<(uint, V)> for SmallIntMap<V> {
}
}
impl<V> Index<uint, V> for SmallIntMap<V> {
impl<V> Index<uint, V> for VecMap<V> {
#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a V {
self.find(i).expect("key not present")
}
}
impl<V> IndexMut<uint, V> for SmallIntMap<V> {
impl<V> IndexMut<uint, V> for VecMap<V> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut V {
self.find_mut(i).expect("key not present")
@ -612,11 +612,11 @@ mod test_map {
use vec::Vec;
use hash;
use super::SmallIntMap;
use super::VecMap;
#[test]
fn test_find_mut() {
let mut m = SmallIntMap::new();
let mut m = VecMap::new();
assert!(m.insert(1, 12i));
assert!(m.insert(2, 8));
assert!(m.insert(5, 14));
@ -629,7 +629,7 @@ mod test_map {
#[test]
fn test_len() {
let mut map = SmallIntMap::new();
let mut map = VecMap::new();
assert_eq!(map.len(), 0);
assert!(map.is_empty());
assert!(map.insert(5, 20i));
@ -645,7 +645,7 @@ mod test_map {
#[test]
fn test_clear() {
let mut map = SmallIntMap::new();
let mut map = VecMap::new();
assert!(map.insert(5, 20i));
assert!(map.insert(11, 12));
assert!(map.insert(14, 22));
@ -658,7 +658,7 @@ mod test_map {
#[test]
fn test_insert_with_key() {
let mut map = SmallIntMap::new();
let mut map = VecMap::new();
// given a new key, initialize it with this new count,
// given an existing key, add more to its count
@ -688,7 +688,7 @@ mod test_map {
#[test]
fn test_swap() {
let mut m = SmallIntMap::new();
let mut m = VecMap::new();
assert_eq!(m.swap(1, 2i), None);
assert_eq!(m.swap(1, 3i), Some(2));
assert_eq!(m.swap(1, 4i), Some(3));
@ -696,7 +696,7 @@ mod test_map {
#[test]
fn test_pop() {
let mut m = SmallIntMap::new();
let mut m = VecMap::new();
m.insert(1, 2i);
assert_eq!(m.pop(&1), Some(2));
assert_eq!(m.pop(&1), None);
@ -704,7 +704,7 @@ mod test_map {
#[test]
fn test_keys() {
let mut map = SmallIntMap::new();
let mut map = VecMap::new();
map.insert(1, 'a');
map.insert(2, 'b');
map.insert(3, 'c');
@ -717,7 +717,7 @@ mod test_map {
#[test]
fn test_values() {
let mut map = SmallIntMap::new();
let mut map = VecMap::new();
map.insert(1, 'a');
map.insert(2, 'b');
map.insert(3, 'c');
@ -730,7 +730,7 @@ mod test_map {
#[test]
fn test_iterator() {
let mut m = SmallIntMap::new();
let mut m = VecMap::new();
assert!(m.insert(0, 1i));
assert!(m.insert(1, 2));
@ -755,7 +755,7 @@ mod test_map {
#[test]
fn test_iterator_size_hints() {
let mut m = SmallIntMap::new();
let mut m = VecMap::new();
assert!(m.insert(0, 1i));
assert!(m.insert(1, 2));
@ -771,7 +771,7 @@ mod test_map {
#[test]
fn test_mut_iterator() {
let mut m = SmallIntMap::new();
let mut m = VecMap::new();
assert!(m.insert(0, 1i));
assert!(m.insert(1, 2));
@ -794,7 +794,7 @@ mod test_map {
#[test]
fn test_rev_iterator() {
let mut m = SmallIntMap::new();
let mut m = VecMap::new();
assert!(m.insert(0, 1i));
assert!(m.insert(1, 2));
@ -813,7 +813,7 @@ mod test_map {
#[test]
fn test_mut_rev_iterator() {
let mut m = SmallIntMap::new();
let mut m = VecMap::new();
assert!(m.insert(0, 1i));
assert!(m.insert(1, 2));
@ -836,7 +836,7 @@ mod test_map {
#[test]
fn test_move_iter() {
let mut m = SmallIntMap::new();
let mut m = VecMap::new();
m.insert(1, box 2i);
let mut called = false;
for (k, v) in m.into_iter() {
@ -851,8 +851,8 @@ mod test_map {
#[test]
fn test_show() {
let mut map = SmallIntMap::new();
let empty = SmallIntMap::<int>::new();
let mut map = VecMap::new();
let empty = VecMap::<int>::new();
map.insert(1, 2i);
map.insert(3, 4i);
@ -865,7 +865,7 @@ mod test_map {
#[test]
fn test_clone() {
let mut a = SmallIntMap::new();
let mut a = VecMap::new();
a.insert(1, 'x');
a.insert(4, 'y');
@ -876,8 +876,8 @@ mod test_map {
#[test]
fn test_eq() {
let mut a = SmallIntMap::new();
let mut b = SmallIntMap::new();
let mut a = VecMap::new();
let mut b = VecMap::new();
assert!(a == b);
assert!(a.insert(0, 5i));
@ -894,8 +894,8 @@ mod test_map {
#[test]
fn test_lt() {
let mut a = SmallIntMap::new();
let mut b = SmallIntMap::new();
let mut a = VecMap::new();
let mut b = VecMap::new();
assert!(!(a < b) && !(b < a));
assert!(b.insert(2u, 5i));
@ -912,8 +912,8 @@ mod test_map {
#[test]
fn test_ord() {
let mut a = SmallIntMap::new();
let mut b = SmallIntMap::new();
let mut a = VecMap::new();
let mut b = VecMap::new();
assert!(a <= b && a >= b);
assert!(a.insert(1u, 1i));
@ -926,8 +926,8 @@ mod test_map {
#[test]
fn test_hash() {
let mut x = SmallIntMap::new();
let mut y = SmallIntMap::new();
let mut x = VecMap::new();
let mut y = VecMap::new();
assert!(hash::hash(&x) == hash::hash(&y));
x.insert(1, 'a');
@ -945,7 +945,7 @@ mod test_map {
fn test_from_iter() {
let xs: Vec<(uint, char)> = vec![(1u, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
let map: SmallIntMap<char> = xs.iter().map(|&x| x).collect();
let map: VecMap<char> = xs.iter().map(|&x| x).collect();
for &(k, v) in xs.iter() {
assert_eq!(map.find(&k), Some(&v));
@ -954,7 +954,7 @@ mod test_map {
#[test]
fn test_index() {
let mut map: SmallIntMap<int> = SmallIntMap::new();
let mut map: VecMap<int> = VecMap::new();
map.insert(1, 2);
map.insert(2, 1);
@ -966,7 +966,7 @@ mod test_map {
#[test]
#[should_fail]
fn test_index_nonexistent() {
let mut map: SmallIntMap<int> = SmallIntMap::new();
let mut map: VecMap<int> = VecMap::new();
map.insert(1, 2);
map.insert(2, 1);
@ -980,12 +980,12 @@ mod test_map {
mod bench {
extern crate test;
use self::test::Bencher;
use super::SmallIntMap;
use super::VecMap;
use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
#[bench]
pub fn insert_rand_100(b: &mut Bencher) {
let mut m : SmallIntMap<uint> = SmallIntMap::new();
let mut m : VecMap<uint> = VecMap::new();
insert_rand_n(100, &mut m, b,
|m, i| { m.insert(i, 1); },
|m, i| { m.remove(&i); });
@ -993,7 +993,7 @@ mod bench {
#[bench]
pub fn insert_rand_10_000(b: &mut Bencher) {
let mut m : SmallIntMap<uint> = SmallIntMap::new();
let mut m : VecMap<uint> = VecMap::new();
insert_rand_n(10_000, &mut m, b,
|m, i| { m.insert(i, 1); },
|m, i| { m.remove(&i); });
@ -1002,7 +1002,7 @@ mod bench {
// Insert seq
#[bench]
pub fn insert_seq_100(b: &mut Bencher) {
let mut m : SmallIntMap<uint> = SmallIntMap::new();
let mut m : VecMap<uint> = VecMap::new();
insert_seq_n(100, &mut m, b,
|m, i| { m.insert(i, 1); },
|m, i| { m.remove(&i); });
@ -1010,7 +1010,7 @@ mod bench {
#[bench]
pub fn insert_seq_10_000(b: &mut Bencher) {
let mut m : SmallIntMap<uint> = SmallIntMap::new();
let mut m : VecMap<uint> = VecMap::new();
insert_seq_n(10_000, &mut m, b,
|m, i| { m.insert(i, 1); },
|m, i| { m.remove(&i); });
@ -1019,7 +1019,7 @@ mod bench {
// Find rand
#[bench]
pub fn find_rand_100(b: &mut Bencher) {
let mut m : SmallIntMap<uint> = SmallIntMap::new();
let mut m : VecMap<uint> = VecMap::new();
find_rand_n(100, &mut m, b,
|m, i| { m.insert(i, 1); },
|m, i| { m.find(&i); });
@ -1027,7 +1027,7 @@ mod bench {
#[bench]
pub fn find_rand_10_000(b: &mut Bencher) {
let mut m : SmallIntMap<uint> = SmallIntMap::new();
let mut m : VecMap<uint> = VecMap::new();
find_rand_n(10_000, &mut m, b,
|m, i| { m.insert(i, 1); },
|m, i| { m.find(&i); });
@ -1036,7 +1036,7 @@ mod bench {
// Find seq
#[bench]
pub fn find_seq_100(b: &mut Bencher) {
let mut m : SmallIntMap<uint> = SmallIntMap::new();
let mut m : VecMap<uint> = VecMap::new();
find_seq_n(100, &mut m, b,
|m, i| { m.insert(i, 1); },
|m, i| { m.find(&i); });
@ -1044,7 +1044,7 @@ mod bench {
#[bench]
pub fn find_seq_10_000(b: &mut Bencher) {
let mut m : SmallIntMap<uint> = SmallIntMap::new();
let mut m : VecMap<uint> = VecMap::new();
find_seq_n(10_000, &mut m, b,
|m, i| { m.insert(i, 1); },
|m, i| { m.find(&i); });

View File

@ -250,8 +250,8 @@ pub trait UpperExp for Sized? {
fn fmt(&self, &mut Formatter) -> Result;
}
// FIXME #11938 - UFCS would make us able call the above methods
// directly Show::show(x, fmt).
// NOTE(stage0): Remove macro after next snapshot
#[cfg(stage0)]
macro_rules! uniform_fn_call_workaround {
($( $name: ident, $trait_: ident; )*) => {
$(
@ -262,6 +262,8 @@ macro_rules! uniform_fn_call_workaround {
)*
}
}
// NOTE(stage0): Remove macro after next snapshot
#[cfg(stage0)]
uniform_fn_call_workaround! {
secret_show, Show;
secret_bool, Bool;
@ -568,36 +570,65 @@ pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result,
/// When the compiler determines that the type of an argument *must* be a string
/// (such as for select), then it invokes this method.
// NOTE(stage0): remove function after a snapshot
#[cfg(stage0)]
#[doc(hidden)] #[inline]
pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> {
argument(secret_string, s)
}
/// When the compiler determines that the type of an argument *must* be a string
/// (such as for select), then it invokes this method.
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[doc(hidden)] #[inline]
pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> {
argument(String::fmt, s)
}
/// When the compiler determines that the type of an argument *must* be a uint
/// (such as for plural), then it invokes this method.
// NOTE(stage0): remove function after a snapshot
#[cfg(stage0)]
#[doc(hidden)] #[inline]
pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
argument(secret_unsigned, s)
}
/// When the compiler determines that the type of an argument *must* be a uint
/// (such as for plural), then it invokes this method.
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[doc(hidden)] #[inline]
pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
argument(Unsigned::fmt, s)
}
// Implementations of the core formatting traits
impl<'a, Sized? T: Show> Show for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(*self, f) }
fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
}
impl<'a, Sized? T: Show> Show for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
}
impl<'a> Show for &'a Show+'a {
fn fmt(&self, f: &mut Formatter) -> Result { (*self).fmt(f) }
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl Bool for bool {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_string(&(if *self {"true"} else {"false"}), f)
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl Bool for bool {
fn fmt(&self, f: &mut Formatter) -> Result {
String::fmt(if *self { "true" } else { "false" }, f)
}
}
impl<T: str::Str> String for T {
fn fmt(&self, f: &mut Formatter) -> Result {
f.pad(self.as_slice())
@ -610,6 +641,8 @@ impl String for str {
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl Char for char {
fn fmt(&self, f: &mut Formatter) -> Result {
use char::Char;
@ -621,28 +654,80 @@ impl Char for char {
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl Char for char {
fn fmt(&self, f: &mut Formatter) -> Result {
use char::Char;
let mut utf8 = [0u8, ..4];
let amt = self.encode_utf8(utf8).unwrap_or(0);
let s: &str = unsafe { mem::transmute(utf8[..amt]) };
String::fmt(s, f)
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> Pointer for *const T {
fn fmt(&self, f: &mut Formatter) -> Result {
f.flags |= 1 << (rt::FlagAlternate as uint);
secret_lower_hex::<uint>(&(*self as uint), f)
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> Pointer for *const T {
fn fmt(&self, f: &mut Formatter) -> Result {
f.flags |= 1 << (rt::FlagAlternate as uint);
LowerHex::fmt(&(*self as uint), f)
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> Pointer for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_pointer::<*const T>(&(*self as *const T), f)
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> Pointer for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
Pointer::fmt(&(*self as *const T), f)
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<'a, T> Pointer for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_pointer::<*const T>(&(&**self as *const T), f)
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<'a, T> Pointer for &'a T {
fn fmt(&self, f: &mut Formatter) -> Result {
Pointer::fmt(&(*self as *const T), f)
}
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<'a, T> Pointer for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
secret_pointer::<*const T>(&(&**self as *const T), f)
}
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<'a, T> Pointer for &'a mut T {
fn fmt(&self, f: &mut Formatter) -> Result {
Pointer::fmt(&(&**self as *const T), f)
}
}
macro_rules! floating(($ty:ident) => {
impl Float for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
@ -712,6 +797,8 @@ floating!(f64)
// Implementation of Show for various core types
// NOTE(stage0): remove macro after a snapshot
#[cfg(stage0)]
macro_rules! delegate(($ty:ty to $other:ident) => {
impl Show for $ty {
fn fmt(&self, f: &mut Formatter) -> Result {
@ -719,19 +806,60 @@ macro_rules! delegate(($ty:ty to $other:ident) => {
}
}
})
// NOTE(stage0): remove these macros after a snapshot
#[cfg(stage0)]
delegate!(str to string)
#[cfg(stage0)]
delegate!(bool to bool)
#[cfg(stage0)]
delegate!(char to char)
#[cfg(stage0)]
delegate!(f32 to float)
#[cfg(stage0)]
delegate!(f64 to float)
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
macro_rules! delegate(($ty:ty to $other:ident) => {
impl Show for $ty {
fn fmt(&self, f: &mut Formatter) -> Result {
$other::fmt(self, f)
}
}
})
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(str to String)
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(bool to Bool)
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(char to Char)
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(f32 to Float)
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
delegate!(f64 to Float)
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> Show for *const T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> Show for *const T {
fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
}
// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> Show for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) }
}
#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> Show for *mut T {
fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
}
macro_rules! peel(($name:ident, $($other:ident,)*) => (tuple!($($other,)*)))
macro_rules! tuple (

View File

@ -145,19 +145,19 @@ pub struct Opt {
pub aliases: Vec<Opt>,
}
/// One group of options, e.g., both -h and --help, along with
/// One group of options, e.g., both `-h` and `--help`, along with
/// their shared description and properties.
#[deriving(Clone, PartialEq, Eq)]
pub struct OptGroup {
/// Short Name of the `OptGroup`
/// Short name of the option, e.g. `h` for a `-h` option
pub short_name: String,
/// Long Name of the `OptGroup`
/// Long name of the option, e.g. `help` for a `--help` option
pub long_name: String,
/// Hint
/// Hint for argument, e.g. `FILE` for a `-o FILE` option
pub hint: String,
/// Description
/// Description for usage help text
pub desc: String,
/// Whether it has an argument
/// Whether option has an argument
pub hasarg: HasArg,
/// How often it can occur
pub occur: Occur
@ -393,6 +393,12 @@ fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
}
/// Create a long option that is required and takes an argument.
///
/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
/// * `desc` - Description for usage help
/// * `hint` - Hint that is used in place of the argument in the usage help,
/// e.g. `"FILE"` for a `-o FILE` option
pub fn reqopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptGroup {
let len = short_name.len();
assert!(len == 1 || len == 0);
@ -407,6 +413,12 @@ pub fn reqopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptG
}
/// Create a long option that is optional and takes an argument.
///
/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
/// * `desc` - Description for usage help
/// * `hint` - Hint that is used in place of the argument in the usage help,
/// e.g. `"FILE"` for a `-o FILE` option
pub fn optopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptGroup {
let len = short_name.len();
assert!(len == 1 || len == 0);
@ -421,6 +433,10 @@ pub fn optopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptG
}
/// Create a long option that is optional and does not take an argument.
///
/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
/// * `desc` - Description for usage help
pub fn optflag(short_name: &str, long_name: &str, desc: &str) -> OptGroup {
let len = short_name.len();
assert!(len == 1 || len == 0);
@ -436,6 +452,10 @@ pub fn optflag(short_name: &str, long_name: &str, desc: &str) -> OptGroup {
/// Create a long option that can occur more than once and does not
/// take an argument.
///
/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
/// * `desc` - Description for usage help
pub fn optflagmulti(short_name: &str, long_name: &str, desc: &str) -> OptGroup {
let len = short_name.len();
assert!(len == 1 || len == 0);
@ -450,6 +470,12 @@ pub fn optflagmulti(short_name: &str, long_name: &str, desc: &str) -> OptGroup {
}
/// Create a long option that is optional and takes an optional argument.
///
/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
/// * `desc` - Description for usage help
/// * `hint` - Hint that is used in place of the argument in the usage help,
/// e.g. `"FILE"` for a `-o FILE` option
pub fn optflagopt(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptGroup {
let len = short_name.len();
assert!(len == 1 || len == 0);
@ -465,6 +491,12 @@ pub fn optflagopt(short_name: &str, long_name: &str, desc: &str, hint: &str) ->
/// Create a long option that is optional, takes an argument, and may occur
/// multiple times.
///
/// * `short_name` - e.g. `"h"` for a `-h` option, or `""` for none
/// * `long_name` - e.g. `"help"` for a `--help` option, or `""` for none
/// * `desc` - Description for usage help
/// * `hint` - Hint that is used in place of the argument in the usage help,
/// e.g. `"FILE"` for a `-o FILE` option
pub fn optmulti(short_name: &str, long_name: &str, desc: &str, hint: &str) -> OptGroup {
let len = short_name.len();
assert!(len == 1 || len == 0);

View File

@ -20,6 +20,7 @@ use back::write;
use back::target_strs;
use back::{arm, x86, x86_64, mips, mipsel};
use lint;
use metadata::cstore;
use syntax::abi;
use syntax::ast;
@ -31,7 +32,7 @@ use syntax::parse;
use syntax::parse::token::InternedString;
use std::collections::HashMap;
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use getopts::{optopt, optmulti, optflag, optflagopt};
use getopts;
use std::cell::{RefCell};
@ -78,6 +79,7 @@ pub struct Options {
// parsed code. It remains mutable in case its replacements wants to use
// this.
pub addl_lib_search_paths: RefCell<Vec<Path>>,
pub libs: Vec<(String, cstore::NativeLibaryKind)>,
pub maybe_sysroot: Option<Path>,
pub target_triple: String,
// User-specified cfg meta items. The compiler itself will add additional
@ -130,6 +132,7 @@ pub fn basic_options() -> Options {
externs: HashMap::new(),
crate_name: None,
alt_std_name: None,
libs: Vec::new(),
}
}
@ -575,6 +578,10 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
optflag("h", "help", "Display this message"),
optmulti("", "cfg", "Configure the compilation environment", "SPEC"),
optmulti("L", "", "Add a directory to the library search path", "PATH"),
optmulti("l", "", "Link the generated crate(s) to the specified native
library NAME. The optional KIND can be one of,
static, dylib, or framework. If omitted, dylib is
assumed.", "NAME[:KIND]"),
optmulti("", "crate-type", "Comma separated list of types of crates
for the compiler to emit",
"[bin|lib|rlib|dylib|staticlib]"),
@ -767,6 +774,23 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
Path::new(s.as_slice())
}).collect();
let libs = matches.opt_strs("l").into_iter().map(|s| {
let mut parts = s.as_slice().rsplitn(1, ':');
let kind = parts.next().unwrap();
let (name, kind) = match (parts.next(), kind) {
(None, name) |
(Some(name), "dylib") => (name, cstore::NativeUnknown),
(Some(name), "framework") => (name, cstore::NativeFramework),
(Some(name), "static") => (name, cstore::NativeStatic),
(_, s) => {
early_error(format!("unknown library kind `{}`, expected \
one of dylib, framework, or static",
s).as_slice());
}
};
(name.to_string(), kind)
}).collect();
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
let test = matches.opt_present("test");
let write_dependency_info = (matches.opt_present("dep-info"),
@ -843,7 +867,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
color: color,
externs: externs,
crate_name: crate_name,
alt_std_name: None
alt_std_name: None,
libs: libs,
}
}

View File

@ -37,7 +37,7 @@ use lint::{Context, LintPass, LintArray};
use std::cmp;
use std::collections::HashMap;
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use std::slice;
use std::{int, i8, i16, i32, i64, uint, u8, u16, u32, u64, f32, f64};
use syntax::abi;

View File

@ -24,7 +24,7 @@ use plugin::load::PluginMetadata;
use std::rc::Rc;
use std::collections::HashMap;
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use syntax::ast;
use syntax::abi;
use syntax::attr;
@ -52,7 +52,11 @@ pub fn read_crates(sess: &Session,
visit_crate(&e, krate);
visit::walk_crate(&mut e, krate);
dump_crates(&sess.cstore);
warn_if_multiple_versions(sess.diagnostic(), &sess.cstore)
warn_if_multiple_versions(sess.diagnostic(), &sess.cstore);
for &(ref name, kind) in sess.opts.libs.iter() {
register_native_lib(sess, None, name.clone(), kind);
}
}
impl<'a, 'v> visit::Visitor<'v> for Env<'a> {
@ -233,15 +237,8 @@ fn visit_item(e: &Env, i: &ast::Item) {
Some(k) => {
if k.equiv(&("static")) {
cstore::NativeStatic
} else if (e.sess.targ_cfg.os == abi::OsMacos ||
e.sess.targ_cfg.os == abi::OsiOS) &&
k.equiv(&("framework")) {
cstore::NativeFramework
} else if k.equiv(&("framework")) {
e.sess.span_err(m.span,
"native frameworks are only available \
on OSX targets");
cstore::NativeUnknown
cstore::NativeFramework
} else {
e.sess.span_err(m.span,
format!("unknown kind: `{}`",
@ -263,15 +260,8 @@ fn visit_item(e: &Env, i: &ast::Item) {
InternedString::new("foo")
}
};
if n.get().is_empty() {
e.sess.span_err(m.span,
"#[link(name = \"\")] given with \
empty name");
} else {
e.sess
.cstore
.add_used_library(n.get().to_string(), kind);
}
register_native_lib(e.sess, Some(m.span),
n.get().to_string(), kind);
}
None => {}
}
@ -281,6 +271,32 @@ fn visit_item(e: &Env, i: &ast::Item) {
}
}
fn register_native_lib(sess: &Session, span: Option<Span>, name: String,
kind: cstore::NativeLibaryKind) {
if name.as_slice().is_empty() {
match span {
Some(span) => {
sess.span_err(span, "#[link(name = \"\")] given with \
empty name");
}
None => {
sess.err("empty library name given via `-l`");
}
}
return
}
let is_osx = sess.targ_cfg.os == abi::OsMacos ||
sess.targ_cfg.os == abi::OsiOS;
if kind == cstore::NativeFramework && !is_osx {
let msg = "native frameworks are only available on OSX targets";
match span {
Some(span) => sess.span_err(span, msg),
None => sess.err(msg),
}
}
sess.cstore.add_used_library(name, kind);
}
fn existing_match(e: &Env, name: &str,
hash: Option<&Svh>) -> Option<ast::CrateNum> {
let mut ret = None;

View File

@ -31,7 +31,7 @@ use syntax::attr;
use syntax::diagnostic::expect;
use syntax::parse::token;
use std::collections::hashmap::HashMap;
use std::collections::hash_map::HashMap;
pub struct MethodInfo {
pub name: ast::Name,

View File

@ -50,7 +50,7 @@ pub enum LinkagePreference {
RequireStatic,
}
#[deriving(PartialEq, FromPrimitive)]
#[deriving(PartialEq, FromPrimitive, Clone)]
pub enum NativeLibaryKind {
NativeStatic, // native static library (.a archive)
NativeFramework, // OSX-specific

View File

@ -34,7 +34,7 @@ use std::hash::Hash;
use std::hash;
use std::io::extensions::u64_from_be_bytes;
use std::io;
use std::collections::hashmap::HashMap;
use std::collections::hash_map::HashMap;
use std::rc::Rc;
use std::u64;
use rbml::reader;

View File

@ -237,7 +237,7 @@ use std::slice;
use std::string;
use std::collections::{HashMap, HashSet};
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use flate;
use time;

View File

@ -441,19 +441,13 @@ impl tr for def::Def {
fn tr(&self, dcx: &DecodeContext) -> def::Def {
match *self {
def::DefFn(did, is_ctor) => def::DefFn(did.tr(dcx), is_ctor),
def::DefStaticMethod(did, wrapped_did2) => {
def::DefStaticMethod(did.tr(dcx),
match wrapped_did2 {
def::FromTrait(did2) => {
def::FromTrait(did2.tr(dcx))
}
def::FromImpl(did2) => {
def::FromImpl(did2.tr(dcx))
}
})
def::DefStaticMethod(did, p) => {
def::DefStaticMethod(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
}
def::DefMethod(did0, did1, p) => {
def::DefMethod(did0.tr(dcx), did1.map(|did1| did1.tr(dcx)), p)
def::DefMethod(did0.tr(dcx),
did1.map(|did1| did1.tr(dcx)),
p.map(|did2| did2.tr(dcx)))
}
def::DefSelfTy(nid) => { def::DefSelfTy(dcx.tr_id(nid)) }
def::DefMod(did) => { def::DefMod(did.tr(dcx)) }

View File

@ -28,7 +28,7 @@ use syntax::visit;
use syntax::{ast, ast_map, ast_util, codemap};
use std::rc::Rc;
use std::collections::hashmap::Vacant;
use std::collections::hash_map::Vacant;
//
// This pass classifies expressions by their constant-ness.

View File

@ -51,7 +51,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
live_symbols: Box<HashSet<ast::NodeId>>,
struct_has_extern_repr: bool,
ignore_paths: bool
ignore_non_const_paths: bool
}
impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
@ -62,7 +62,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
tcx: tcx,
live_symbols: box HashSet::new(),
struct_has_extern_repr: false,
ignore_paths: false
ignore_non_const_paths: false
}
}
@ -76,6 +76,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
self.tcx.def_map.borrow().find(id).map(|def| {
match def {
&def::DefConst(_) => {
self.check_def_id(def.def_id())
}
_ if self.ignore_non_const_paths => (),
&def::DefPrimTy(_) => (),
&def::DefVariant(enum_id, variant_id, _) => {
self.check_def_id(enum_id);
@ -283,21 +287,19 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
self.handle_field_pattern_match(pat, fields.as_slice());
}
_ if pat_util::pat_is_const(def_map, pat) => {
// it might be the only use of a static:
// it might be the only use of a const
self.lookup_and_handle_definition(&pat.id)
}
_ => ()
}
self.ignore_paths = true;
self.ignore_non_const_paths = true;
visit::walk_pat(self, pat);
self.ignore_paths = false;
self.ignore_non_const_paths = false;
}
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
if !self.ignore_paths {
self.lookup_and_handle_definition(&id);
}
self.lookup_and_handle_definition(&id);
visit::walk_path(self, path);
}

View File

@ -55,6 +55,15 @@ pub enum MethodProvenance {
FromImpl(ast::DefId),
}
impl MethodProvenance {
pub fn map(self, f: |ast::DefId| -> ast::DefId) -> MethodProvenance {
match self {
FromTrait(did) => FromTrait(f(did)),
FromImpl(did) => FromImpl(f(did))
}
}
}
impl Def {
pub fn def_id(&self) -> ast::DefId {
match *self {

View File

@ -58,7 +58,7 @@ use syntax::visit;
use syntax::visit::Visitor;
use std::collections::{HashMap, HashSet};
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use std::cell::{Cell, RefCell};
use std::mem::replace;
use std::rc::{Rc, Weak};

View File

@ -29,7 +29,7 @@ use middle::typeck::infer;
use middle::typeck::infer::{InferCtxt, TypeSkolemizer};
use middle::ty_fold::TypeFoldable;
use std::cell::RefCell;
use std::collections::hashmap::HashMap;
use std::collections::hash_map::HashMap;
use std::rc::Rc;
use syntax::ast;
use util::ppaux::Repr;
@ -1104,18 +1104,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
* Returns true if `candidate_i` should be dropped in favor of `candidate_j`.
* This is generally true if either:
* - candidate i and candidate j are equivalent; or,
* - candidate i is a where clause bound and candidate j is a concrete impl,
* - candidate i is a conrete impl and candidate j is a where clause bound,
* and the concrete impl is applicable to the types in the where clause bound.
*
* The last case basically occurs with blanket impls like
* `impl<T> Foo for T`. In that case, a bound like `T:Foo` is
* kind of an "false" ambiguity -- both are applicable to any
* type, but in fact coherence requires that the bound will
* always be resolved to the impl anyway.
* The last case refers to cases where there are blanket impls (often conditional
* blanket impls) as well as a where clause. This can come down to one of two cases:
*
* - The impl is truly unconditional (it has no where clauses
* of its own), in which case the where clause is
* unnecessary, because coherence requires that we would
* pick that particular impl anyhow (at least so long as we
* don't have specialization).
*
* - The impl is conditional, in which case we may not have winnowed it out
* because we don't know if the conditions apply, but the where clause is basically
* telling us taht there is some impl, though not necessarily the one we see.
*
* In both cases we prefer to take the where clause, which is
* essentially harmless. See issue #18453 for more details of
* a case where doing the opposite caused us harm.
*/
match (candidate_i, candidate_j) {
(&ParamCandidate(ref vt), &ImplCandidate(impl_def_id)) => {
(&ImplCandidate(impl_def_id), &ParamCandidate(ref vt)) => {
debug!("Considering whether to drop param {} in favor of impl {}",
candidate_i.repr(self.tcx()),
candidate_j.repr(self.tcx()));

View File

@ -623,7 +623,7 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
let retval = Call(bcx, fn_ptr, llargs.as_slice(), None);
match f.sig.output {
ty::FnConverging(output_type) => {
if type_is_zero_size(ccx, output_type) || fcx.llretslotptr.get().is_some() {
if return_type_is_void(ccx, output_type) || fcx.llretslotptr.get().is_some() {
RetVoid(bcx);
} else {
Ret(bcx, retval);

View File

@ -502,7 +502,11 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
}
fn node_method_ty(&self, method_call: typeck::MethodCall) -> Option<ty::t> {
self.tcx().method_map.borrow().find(&method_call).map(|method| method.ty)
self.tcx()
.method_map
.borrow()
.find(&method_call)
.map(|method| monomorphize_type(self, method.ty))
}
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment>> {

View File

@ -745,18 +745,6 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Translate index expression.
let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
// Overloaded. Evaluate `trans_overloaded_op`, which will
// invoke the user's index() method, which basically yields
// a `&T` pointer. We can then proceed down the normal
// path (below) to dereference that `&T`.
let val =
unpack_result!(bcx,
trans_overloaded_op(bcx,
index_expr,
method_call,
base_datum,
vec![(ix_datum, idx.id)],
None));
let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty)).unwrap();
let elt_ty = match ty::deref(ref_ty, true) {
None => {
@ -766,7 +754,25 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
Some(elt_tm) => elt_tm.ty,
};
Datum::new(val, elt_ty, LvalueExpr)
// Overloaded. Evaluate `trans_overloaded_op`, which will
// invoke the user's index() method, which basically yields
// a `&T` pointer. We can then proceed down the normal
// path (below) to dereference that `&T`.
let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_index_elt");
unpack_result!(bcx,
trans_overloaded_op(bcx,
index_expr,
method_call,
base_datum,
vec![(ix_datum, idx.id)],
Some(SaveIn(scratch.val))));
let datum = scratch.to_expr_datum();
if ty::type_is_sized(bcx.tcx(), elt_ty) {
Datum::new(datum.to_llscalarish(bcx), elt_ty, LvalueExpr)
} else {
Datum::new(datum.val, ty::mk_open(bcx.tcx(), elt_ty), LvalueExpr)
}
}
None => {
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx,

View File

@ -43,7 +43,7 @@ use std::mem;
use std::ops;
use std::rc::Rc;
use std::collections::{HashMap, HashSet};
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use arena::TypedArena;
use syntax::abi;
use syntax::ast::{CrateNum, DefId, FnStyle, Ident, ItemTrait, LOCAL_CRATE};

View File

@ -998,14 +998,14 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
Some(i as uint)),
_ => {
tcx.sess.span_fatal(
ast_ty.span, "expected constant expr for vector length");
ast_ty.span, "expected constant expr for array length");
}
}
}
Err(ref r) => {
tcx.sess.span_fatal(
ast_ty.span,
format!("expected constant expr for vector \
format!("expected constant expr for array \
length: {}",
*r).as_slice());
}

View File

@ -19,7 +19,7 @@ use middle::typeck::require_same_types;
use std::cmp;
use std::collections::HashMap;
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use syntax::ast;
use syntax::ast_util;
use syntax::codemap::{Span, Spanned};

View File

@ -118,7 +118,7 @@ use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
use std::cell::{Cell, Ref, RefCell};
use std::collections::HashMap;
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use std::mem::replace;
use std::rc::Rc;
use syntax::abi;

View File

@ -142,7 +142,7 @@ use syntax::visit::Visitor;
use std::cell::{RefCell};
use std::collections::HashMap;
use std::collections::hashmap::{Vacant, Occupied};
use std::collections::hash_map::{Vacant, Occupied};
///////////////////////////////////////////////////////////////////////////
// PUBLIC ENTRY POINTS

View File

@ -18,7 +18,7 @@ use middle::ty_fold::{TypeFolder, TypeFoldable};
use syntax::ast;
use std::collections::HashMap;
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use util::ppaux::Repr;
// Helper functions related to manipulating region types.

View File

@ -187,7 +187,11 @@ pub fn check_object_safety(tcx: &ty::ctxt, object_trait: &ty::TyTrait, span: Spa
receiver through a trait object", method_name))
}
ty::StaticExplicitSelfCategory |
ty::StaticExplicitSelfCategory => {
// Static methods are always object-safe since they
// can't be called through a trait object
return msgs
}
ty::ByReferenceExplicitSelfCategory(..) |
ty::ByBoxExplicitSelfCategory => {}
}

View File

@ -44,7 +44,7 @@ use middle::ty;
use middle::ty_fold;
use middle::ty_fold::TypeFoldable;
use middle::ty_fold::TypeFolder;
use std::collections::hashmap;
use std::collections::hash_map;
use super::InferCtxt;
use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
@ -52,7 +52,7 @@ use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
pub struct TypeSkolemizer<'a, 'tcx:'a> {
infcx: &'a InferCtxt<'a, 'tcx>,
skolemization_count: uint,
skolemization_map: hashmap::HashMap<ty::InferTy, ty::t>,
skolemization_map: hash_map::HashMap<ty::InferTy, ty::t>,
}
impl<'a, 'tcx> TypeSkolemizer<'a, 'tcx> {
@ -60,7 +60,7 @@ impl<'a, 'tcx> TypeSkolemizer<'a, 'tcx> {
TypeSkolemizer {
infcx: infcx,
skolemization_count: 0,
skolemization_map: hashmap::HashMap::new(),
skolemization_map: hash_map::HashMap::new(),
}
}
@ -76,8 +76,8 @@ impl<'a, 'tcx> TypeSkolemizer<'a, 'tcx> {
}
match self.skolemization_map.entry(key) {
hashmap::Occupied(entry) => *entry.get(),
hashmap::Vacant(entry) => {
hash_map::Occupied(entry) => *entry.get(),
hash_map::Vacant(entry) => {
let index = self.skolemization_count;
self.skolemization_count += 1;
let t = ty::mk_infer(self.infcx.tcx, skolemizer(index));

View File

@ -34,7 +34,7 @@
//! both occur before the crate is rendered.
use std::collections::{HashMap, HashSet};
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use std::fmt;
use std::io::fs::PathExtensions;
use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader};

View File

@ -69,6 +69,10 @@ body {
margin: 0;
position: relative;
padding: 10px 15px 20px 15px;
-webkit-font-feature-settings: "kern", "liga";
-moz-font-feature-settings: "kern", "liga";
font-feature-settings: "kern", "liga";
}
h1 {
@ -101,7 +105,7 @@ h3.impl, h3.method, h4.method {
h3.impl, h3.method {
margin-top: 15px;
}
h1, h2, h3, h4, section.sidebar, a.source, .search-input, .content table a, .collapse-toggle {
h1, h2, h3, h4, section.sidebar, a.source, .search-input, .content table :not(code)>a, .collapse-toggle {
font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
@ -177,7 +181,7 @@ nav.sub {
color: #333;
}
.location a:first-child { font-weight: bold; }
.location a:first-child { font-weight: 500; }
.block {
padding: 0 10px;
@ -494,7 +498,7 @@ pre.rust { position: relative; }
}
.collapse-toggle {
font-weight: 100;
font-weight: 300;
position: absolute;
left: 13px;
color: #999;
@ -523,7 +527,6 @@ pre.rust { position: relative; }
.toggle-label {
color: #999;
font-style: italic;
}

View File

@ -31,7 +31,7 @@ extern crate time;
use std::io;
use std::io::{File, MemWriter};
use std::collections::HashMap;
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
use serialize::{json, Decodable, Encodable};
use externalfiles::ExternalHtml;

View File

@ -41,7 +41,7 @@ assert_eq!(*key_vector.get().unwrap(), vec![4]);
use core::prelude::*;
use alloc::heap;
use collections::treemap::TreeMap;
use collections::TreeMap;
use core::cmp;
use core::kinds::marker;
use core::mem;

View File

@ -18,7 +18,7 @@ use iter::{range_inclusive};
#[bench]
fn new_drop(b : &mut Bencher) {
use super::HashMap;
use super::map::HashMap;
b.iter(|| {
let m : HashMap<int, int> = HashMap::new();
@ -28,7 +28,7 @@ fn new_drop(b : &mut Bencher) {
#[bench]
fn new_insert_drop(b : &mut Bencher) {
use super::HashMap;
use super::map::HashMap;
b.iter(|| {
let mut m = HashMap::new();
@ -39,7 +39,7 @@ fn new_insert_drop(b : &mut Bencher) {
#[bench]
fn grow_by_insertion(b: &mut Bencher) {
use super::HashMap;
use super::map::HashMap;
let mut m = HashMap::new();
@ -57,7 +57,7 @@ fn grow_by_insertion(b: &mut Bencher) {
#[bench]
fn find_existing(b: &mut Bencher) {
use super::HashMap;
use super::map::HashMap;
let mut m = HashMap::new();
@ -74,7 +74,7 @@ fn find_existing(b: &mut Bencher) {
#[bench]
fn find_nonexisting(b: &mut Bencher) {
use super::HashMap;
use super::map::HashMap;
let mut m = HashMap::new();
@ -91,7 +91,7 @@ fn find_nonexisting(b: &mut Bencher) {
#[bench]
fn hashmap_as_queue(b: &mut Bencher) {
use super::HashMap;
use super::map::HashMap;
let mut m = HashMap::new();
@ -110,7 +110,7 @@ fn hashmap_as_queue(b: &mut Bencher) {
#[bench]
fn find_pop_insert(b: &mut Bencher) {
use super::HashMap;
use super::map::HashMap;
let mut m = HashMap::new();

View File

@ -10,24 +10,7 @@
//! Unordered containers, implemented as hash-tables
pub use self::map::HashMap;
pub use self::map::Entries;
pub use self::map::MutEntries;
pub use self::map::MoveEntries;
pub use self::map::Entry;
pub use self::map::Occupied;
pub use self::map::Vacant;
pub use self::map::OccupiedEntry;
pub use self::map::VacantEntry;
pub use self::map::Keys;
pub use self::map::Values;
pub use self::map::INITIAL_CAPACITY;
pub use self::set::HashSet;
pub use self::set::SetItems;
pub use self::set::SetMoveItems;
pub use self::set::SetAlgebraItems;
mod bench;
mod map;
mod set;
pub mod map;
pub mod set;
mod table;

View File

@ -22,7 +22,7 @@ use iter;
use option::{Some, None};
use result::{Ok, Err};
use super::{HashMap, Entries, MoveEntries, INITIAL_CAPACITY};
use super::map::{HashMap, Entries, MoveEntries, INITIAL_CAPACITY};
// Future Optimization (FIXME!)

View File

@ -24,9 +24,9 @@
//! Rust's collections can be grouped into four major categories:
//!
//! * Sequences: `Vec`, `RingBuf`, `DList`, `BitV`
//! * Maps: `HashMap`, `BTreeMap`, `TreeMap`, `TrieMap`, `SmallIntMap`, `LruCache`
//! * Maps: `HashMap`, `BTreeMap`, `TreeMap`, `TrieMap`, `VecMap`, `LruCache`
//! * Sets: `HashSet`, `BTreeSet`, `TreeSet`, `TrieSet`, `BitVSet`, `EnumSet`
//! * Misc: `PriorityQueue`
//! * Misc: `BinaryHeap`
//!
//! # When Should You Use Which Collection?
//!
@ -74,7 +74,7 @@
//! * You want a `HashMap`, but with many potentially large `uint` keys.
//! * You want a `BTreeMap`, but with potentially large `uint` keys.
//!
//! ### Use a `SmallIntMap` when:
//! ### Use a `VecMap` when:
//! * You want a `HashMap` but with known to be small `uint` keys.
//! * You want a `BTreeMap`, but with known to be small `uint` keys.
//!
@ -88,12 +88,12 @@
//! * You want a bitvector.
//!
//! ### Use a `BitVSet` when:
//! * You want a `SmallIntSet`.
//! * You want a `VecSet`.
//!
//! ### Use an `EnumSet` when:
//! * You want a C-like enum, stored in a single `uint`.
//!
//! ### Use a `PriorityQueue` when:
//! ### Use a `BinaryHeap` when:
//! * You want to store a bunch of elements, but only ever want to process the "biggest"
//! or "most important" one at any given time.
//! * You want a priority queue.
@ -266,7 +266,7 @@
//! #### Counting the number of times each character in a string occurs
//!
//! ```
//! use std::collections::btree::{BTreeMap, Occupied, Vacant};
//! use std::collections::btree_map::{BTreeMap, Occupied, Vacant};
//!
//! let mut count = BTreeMap::new();
//! let message = "she sells sea shells by the sea shore";
@ -293,7 +293,7 @@
//! #### Tracking the inebriation of customers at a bar
//!
//! ```
//! use std::collections::btree::{BTreeMap, Occupied, Vacant};
//! use std::collections::btree_map::{BTreeMap, Occupied, Vacant};
//!
//! // A client of the bar. They have an id and a blood alcohol level.
//! struct Person { id: u32, blood_alcohol: f32 };
@ -328,14 +328,27 @@
#![experimental]
pub use core_collections::{Bitv, BitvSet, BTreeMap, BTreeSet, DList, EnumSet};
pub use core_collections::{PriorityQueue, RingBuf, SmallIntMap};
pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet};
pub use core_collections::{bitv, btree, dlist, enum_set};
pub use core_collections::{priority_queue, ringbuf, smallintmap, treemap, trie};
pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet};
pub use core_collections::{DList, EnumSet, RingBuf};
pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet, VecMap};
pub use self::hashmap::{HashMap, HashSet};
pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set, dlist, enum_set};
pub use core_collections::{ring_buf, tree_map, tree_set, trie_map, trie_set, vec_map};
pub use self::hash_map::HashMap;
pub use self::hash_set::HashSet;
pub use self::lru_cache::LruCache;
pub mod hashmap;
mod hash;
pub mod hash_map {
//! A hashmap
pub use super::hash::map::*;
}
pub mod hash_set {
//! A hashset
pub use super::hash::set::*;
}
pub mod lru_cache;

View File

@ -424,14 +424,20 @@ pub use core::fmt::{Argument, Arguments, write, radix, Radix, RadixFmt};
#[doc(hidden)]
pub use core::fmt::{argument, argumentstr, argumentuint};
// NOTE(stage0): remove these imports after a snapshot
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_show, secret_string, secret_unsigned};
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_signed, secret_lower_hex, secret_upper_hex};
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_bool, secret_char, secret_octal, secret_binary};
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_float, secret_upper_exp, secret_lower_exp};
#[cfg(stage0)]
#[doc(hidden)]
pub use core::fmt::{secret_pointer};

View File

@ -675,26 +675,23 @@ pub fn check_zero_tts(cx: &ExtCtxt,
/// Extract the string literal from the first token of `tts`. If this
/// is not a string literal, emit an error and return None.
pub fn get_single_str_from_tts(cx: &ExtCtxt,
pub fn get_single_str_from_tts(cx: &mut ExtCtxt,
sp: Span,
tts: &[ast::TokenTree],
name: &str)
-> Option<String> {
if tts.len() != 1 {
cx.span_err(sp, format!("{} takes 1 argument.", name).as_slice());
} else {
match tts[0] {
ast::TtToken(_, token::LitStr(ident)) => return Some(parse::str_lit(ident.as_str())),
ast::TtToken(_, token::LitStrRaw(ident, _)) => {
return Some(parse::raw_str_lit(ident.as_str()))
}
_ => {
cx.span_err(sp,
format!("{} requires a string.", name).as_slice())
}
}
let mut p = cx.new_parser_from_tts(tts);
if p.token == token::Eof {
cx.span_err(sp, format!("{} takes 1 argument", name).as_slice());
return None
}
None
let ret = cx.expander().fold_expr(p.parse_expr());
if p.token != token::Eof {
cx.span_err(sp, format!("{} takes 1 argument", name).as_slice());
}
expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| {
s.get().to_string()
})
}
/// Extract comma-separated expressions from `tts`. If there is a

View File

@ -663,28 +663,28 @@ impl<'a, 'b> Context<'a, 'b> {
fn format_arg(ecx: &ExtCtxt, sp: Span,
ty: &ArgumentType, arg: P<ast::Expr>)
-> P<ast::Expr> {
let (krate, fmt_fn) = match *ty {
let trait_ = match *ty {
Known(ref tyname) => {
match tyname.as_slice() {
"" => ("std", "secret_show"),
"b" => ("std", "secret_bool"),
"c" => ("std", "secret_char"),
"d" | "i" => ("std", "secret_signed"),
"e" => ("std", "secret_lower_exp"),
"E" => ("std", "secret_upper_exp"),
"f" => ("std", "secret_float"),
"o" => ("std", "secret_octal"),
"p" => ("std", "secret_pointer"),
"s" => ("std", "secret_string"),
"t" => ("std", "secret_binary"),
"u" => ("std", "secret_unsigned"),
"x" => ("std", "secret_lower_hex"),
"X" => ("std", "secret_upper_hex"),
"" => "Show",
"b" => "Bool",
"c" => "Char",
"d" | "i" => "Signed",
"e" => "LowerExp",
"E" => "UpperExp",
"f" => "Float",
"o" => "Octal",
"p" => "Pointer",
"s" => "String",
"t" => "Binary",
"u" => "Unsigned",
"x" => "LowerHex",
"X" => "UpperHex",
_ => {
ecx.span_err(sp,
format!("unknown format trait `{}`",
*tyname).as_slice());
("std", "dummy")
"Dummy"
}
}
}
@ -697,9 +697,10 @@ impl<'a, 'b> Context<'a, 'b> {
};
let format_fn = ecx.path_global(sp, vec![
ecx.ident_of(krate),
ecx.ident_of("std"),
ecx.ident_of("fmt"),
ecx.ident_of(fmt_fn)]);
ecx.ident_of(trait_),
ecx.ident_of("fmt")]);
ecx.expr_call_global(sp, vec![
ecx.ident_of("std"),
ecx.ident_of("fmt"),

View File

@ -20,7 +20,7 @@ use ast::{Ident, Mrk, Name, SyntaxContext};
use std::cell::RefCell;
use std::rc::Rc;
use std::collections::HashMap;
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map::{Occupied, Vacant};
/// The SCTable contains a table of SyntaxContext_'s. It
/// represents a flattened tree structure, to avoid having

View File

@ -9,14 +9,16 @@
// except according to those terms.
use ast;
use codemap;
use codemap::{Pos, Span};
use codemap;
use ext::base::*;
use ext::base;
use ext::build::AstBuilder;
use parse;
use parse::token;
use parse;
use print::pprust;
use ptr::P;
use util::small_vector::SmallVector;
use std::io::File;
use std::rc::Rc;
@ -82,14 +84,14 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
/// include! : parse the given file as an expr
/// This is generally a bad idea because it's going to behave
/// unhygienically.
pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'static> {
pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'cx> {
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
Some(f) => f,
None => return DummyResult::expr(sp),
};
// The file will be added to the code map by the parser
let mut p =
let p =
parse::new_sub_parser_from_file(cx.parse_sess(),
cx.cfg(),
&res_rel_file(cx,
@ -98,7 +100,28 @@ pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
true,
None,
sp);
base::MacExpr::new(p.parse_expr())
struct ExpandResult<'a> {
p: parse::parser::Parser<'a>,
}
impl<'a> base::MacResult for ExpandResult<'a> {
fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
Some(self.p.parse_expr())
}
fn make_items(mut self: Box<ExpandResult<'a>>)
-> Option<SmallVector<P<ast::Item>>> {
let mut ret = SmallVector::zero();
loop {
match self.p.parse_item_with_outer_attributes() {
Some(item) => ret.push(item),
None => break
}
}
Some(ret)
}
}
box ExpandResult { p: p }
}
// include_str! : read the given file, insert it as a literal string expr

View File

@ -57,7 +57,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
("default_type_params", Active),
("quote", Active),
("linkage", Active),
("struct_inherit", Active),
("struct_inherit", Removed),
("overloaded_calls", Active),
("unboxed_closure_sugar", Active),

View File

@ -71,8 +71,7 @@ fn color_to_bits(color: color::Color) -> u16 {
}
fn bits_to_color(bits: u16) -> color::Color {
let bits = bits & 0x7;
let color = match bits {
let color = match bits & 0x7 {
0 => color::BLACK,
0x1 => color::BLUE,
0x2 => color::GREEN,
@ -84,11 +83,7 @@ fn bits_to_color(bits: u16) -> color::Color {
_ => unreachable!()
};
if bits >= 8 {
color | 0x8
} else {
color
}
color | (bits & 0x8) // copy the hi-intensity bit
}
impl<T: Writer+Send> WinConsole<T> {

View File

@ -10,8 +10,8 @@
#![allow(missing_docs)]
use std::collections::hashmap;
use std::collections::hashmap::{Occupied, Vacant};
use std::collections::hash_map;
use std::collections::hash_map::{Occupied, Vacant};
use std::fmt::Show;
use std::hash::Hash;
use std::io;
@ -440,8 +440,8 @@ pub fn write_boxplot<T: Float + Show + FromPrimitive>(
/// Returns a HashMap with the number of occurrences of every element in the
/// sequence that the iterator exposes.
pub fn freq_count<T: Iterator<U>, U: Eq+Hash>(mut iter: T) -> hashmap::HashMap<U, uint> {
let mut map: hashmap::HashMap<U,uint> = hashmap::HashMap::new();
pub fn freq_count<T: Iterator<U>, U: Eq+Hash>(mut iter: T) -> hash_map::HashMap<U, uint> {
let mut map: hash_map::HashMap<U,uint> = hash_map::HashMap::new();
for elem in iter {
match map.entry(elem) {
Occupied(mut entry) => { *entry.get_mut() += 1; },

View File

@ -0,0 +1,27 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_type = "rlib"]
struct Foo;
trait Tr {
fn tr(&self);
}
impl Tr for Foo {
fn tr(&self) {}
}
fn take_method<T>(f: fn(&T), t: &T) {}
#[inline]
pub fn pass_method() {
take_method(Tr::tr, &Foo);
}

View File

@ -0,0 +1,27 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_type = "rlib"]
pub trait Tr {
fn tr(&self);
}
pub struct St<V>(pub Vec<V>);
impl<V> Tr for St<V> {
fn tr(&self) {
match self {
&St(ref v) => {
v.iter();
}
}
}
}

View File

@ -0,0 +1,13 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-test: this is not a test
1

View File

@ -0,0 +1,13 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-test: this is not a test
fn foo() { bar() }

View File

@ -14,7 +14,7 @@ extern crate collections;
extern crate rand;
extern crate time;
use std::collections::bitv::BitvSet;
use std::collections::BitvSet;
use std::collections::TreeSet;
use std::hash::Hash;
use std::collections::HashSet;

View File

@ -13,17 +13,17 @@
extern crate collections;
extern crate time;
use std::collections::SmallIntMap;
use std::collections::VecMap;
use std::os;
use std::uint;
fn append_sequential(min: uint, max: uint, map: &mut SmallIntMap<uint>) {
fn append_sequential(min: uint, max: uint, map: &mut VecMap<uint>) {
for i in range(min, max) {
map.insert(i, i + 22u);
}
}
fn check_sequential(min: uint, max: uint, map: &SmallIntMap<uint>) {
fn check_sequential(min: uint, max: uint, map: &VecMap<uint>) {
for i in range(min, max) {
assert_eq!(map[i], i + 22u);
}
@ -45,7 +45,7 @@ fn main() {
let mut appendf = 0.0;
for _ in range(0u, rep) {
let mut map = SmallIntMap::new();
let mut map = VecMap::new();
let start = time::precise_time_s();
append_sequential(0u, max, &mut map);
let mid = time::precise_time_s();

View File

@ -0,0 +1,40 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that overloaded index expressions with DST result types
// can't be used as rvalues
use std::ops::Index;
use std::fmt::Show;
struct S;
impl Index<uint, str> for S {
fn index<'a>(&'a self, _: &uint) -> &'a str {
"hello"
}
}
struct T;
impl Index<uint, Show + 'static> for T {
fn index<'a>(&'a self, idx: &uint) -> &'a Show + 'static {
static x: uint = 42;
&x
}
}
fn main() {
S[0];
//~^ ERROR E0161
T[0];
//~^ ERROR cannot move out of dereference
//~^^ ERROR E0161
}

View File

@ -8,4 +8,4 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() { option_env!(10); } //~ ERROR: requires a string
fn main() { option_env!(10); } //~ ERROR: argument must be a string literal

View File

@ -0,0 +1,17 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags:-l :static
// error-pattern: empty library name given via `-l`
fn main() {
}

View File

@ -0,0 +1,16 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags:-l foo:bar
// error-pattern: unknown library kind `bar`, expected one of dylib, framework, or static
fn main() {
}

View File

@ -0,0 +1,17 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-macos
// ignore-ios
// compile-flags:-l foo:framework
// error-pattern: native frameworks are only available on OSX targets
fn main() {
}

View File

@ -13,6 +13,6 @@
fn main() {
fn bar(n: int) {
let _x: [int, ..n];
//~^ ERROR expected constant expr for vector length: non-constant path in constant expr
//~^ ERROR expected constant expr for array length: non-constant path in constant expr
}
}

View File

@ -10,7 +10,7 @@
// error-pattern:capacity overflow
use std::collections::hashmap::HashMap;
use std::collections::hash_map::HashMap;
use std::uint;
use std::mem::size_of;

View File

@ -0,0 +1,7 @@
-include ../tools.mk
all: $(TMPDIR)/libbar.a
$(RUSTC) foo.rs -lbar:static
$(RUSTC) main.rs
$(call RUN,main)

View File

@ -0,0 +1 @@
void bar() {}

View File

@ -0,0 +1 @@
void bar() {}

View File

@ -0,0 +1,19 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_type = "rlib"]
extern {
fn bar();
}
pub fn foo() {
unsafe { bar(); }
}

View File

@ -0,0 +1,15 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern crate foo;
fn main() {
foo::foo();
}

View File

@ -17,7 +17,7 @@ extern crate time;
// These tests used to be separate files, but I wanted to refactor all
// the common code.
use std::hashmap::{HashMap, HashSet};
use std::collections::{HashMap, HashSet};
use rbml::reader as EBReader;
use rbml::writer as EBWriter;

View File

@ -0,0 +1,37 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that overloaded index expressions with DST result types
// work and don't ICE.
use std::ops::Index;
use std::fmt::Show;
struct S;
impl Index<uint, str> for S {
fn index<'a>(&'a self, _: &uint) -> &'a str {
"hello"
}
}
struct T;
impl Index<uint, Show + 'static> for T {
fn index<'a>(&'a self, idx: &uint) -> &'a Show + 'static {
static x: uint = 42;
&x
}
}
fn main() {
assert_eq!(&S[0], "hello");
assert_eq!(format!("{}", &T[0]).as_slice(), "42");
}

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![deny(missing_doc)]
#![deny(missing_docs)]
#![doc="module"]
#[doc="struct"]

View File

@ -0,0 +1,23 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-pretty
#![deny(dead_code)]
const LOW_RANGE: char = '0';
const HIGH_RANGE: char = '9';
fn main() {
match '5' {
LOW_RANGE...HIGH_RANGE => (),
_ => ()
};
}

View File

@ -0,0 +1,20 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that we don't ICE when inlining a function from another
// crate that uses a trait method as a value due to incorrectly
// translating the def ID of the trait during AST decoding.
// aux-build:issue-18501.rs
extern crate "issue-18501" as issue;
fn main() {
issue::pass_method();
}

View File

@ -0,0 +1,24 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that we don't ICE when translating a generic impl method from
// an extern crate that contains a match expression on a local
// variable lvalue where one of the match case bodies contains an
// expression that autoderefs through an overloaded generic deref
// impl.
// aux-build:issue-18514.rs
extern crate "issue-18514" as ice;
use ice::{Tr, St};
fn main() {
let st: St<()> = St(vec![]);
st.tr();
}

View File

@ -0,0 +1,23 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that coercing bare fn's that return a zero sized type to
// a closure doesn't cause an LLVM ERROR
struct Foo;
fn uint_to_foo(_: uint) -> Foo {
Foo
}
#[allow(unused_must_use)]
fn main() {
range(0u, 10).map(uint_to_foo);
}

View File

@ -0,0 +1,20 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-pretty
fn bar() {}
include!(concat!("", "", "../auxiliary/", "macro-include-items-item.rs"))
fn main() {
foo();
assert_eq!(include!(concat!("", "../auxiliary/", "macro-include-items-expr.rs")), 1u);
}

View File

@ -0,0 +1,27 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Check that object-safe methods are identified as such. Also
// acts as a regression test for #18490
trait Tr {
// Static methods are always safe regardless of other rules
fn new() -> Self;
}
struct St;
impl Tr for St {
fn new() -> St { St }
}
fn main() {
&St as &Tr;
}

View File

@ -0,0 +1,50 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that when there is a conditional (but blanket) impl and a
// where clause, we don't get confused in trait resolution.
//
// Issue #18453.
use std::rc::Rc;
pub trait Foo<M> {
fn foo(&mut self, msg: M);
}
pub trait Bar<M> {
fn dummy(&self) -> M;
}
impl<M, F: Bar<M>> Foo<M> for F {
fn foo(&mut self, msg: M) {
}
}
pub struct Both<M, F> {
inner: Rc<(M, F)>,
}
impl<M, F: Foo<M>> Clone for Both<M, F> {
fn clone(&self) -> Both<M, F> {
Both { inner: self.inner.clone() }
}
}
fn repro1<M, F: Foo<M>>(_both: Both<M, F>) {
}
fn repro2<M, F: Foo<M>>(msg: M, foo: F) {
let both = Both { inner: Rc::new((msg, foo)) };
repro1(both.clone()); // <--- This clone causes problem
}
pub fn main() {
}

View File

@ -10,10 +10,10 @@
#![feature(while_let)]
use std::collections::PriorityQueue;
use std::collections::BinaryHeap;
fn make_pq() -> PriorityQueue<int> {
PriorityQueue::from_vec(vec![1i,2,3])
fn make_pq() -> BinaryHeap<int> {
BinaryHeap::from_vec(vec![1i,2,3])
}
pub fn main() {