auto merge of #19955 : Gankro/rust/kill-all-code, r=aturon
EnumSet lives on in libcollections so that librustc can still use it. This adds a direct dependency on libcollections to librustc and libserialize. Should not be merged until https://github.com/rust-lang/rfcs/pull/509 is accepted. All of these collections have already been moved to collect-rs where they will ideally be maintained and experimented with, or will be replaced by something better: https://github.com/Gankro/collect-rs/ [breaking-change] r? @aturon @alexcrichton
This commit is contained in:
commit
840de07208
src
libcollections
librustc
librustdoc
libserialize
libstd/collections
libtest
test
@ -46,10 +46,6 @@ pub use dlist::DList;
|
||||
pub use enum_set::EnumSet;
|
||||
pub use ring_buf::RingBuf;
|
||||
pub use string::String;
|
||||
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;
|
||||
|
||||
@ -61,8 +57,6 @@ mod btree;
|
||||
pub mod dlist;
|
||||
pub mod enum_set;
|
||||
pub mod ring_buf;
|
||||
mod tree;
|
||||
mod trie;
|
||||
pub mod slice;
|
||||
pub mod str;
|
||||
pub mod string;
|
||||
@ -77,22 +71,6 @@ 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::*;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,35 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Maps are collections of unique keys with corresponding values, and sets are
|
||||
//! just unique keys without a corresponding value.
|
||||
//!
|
||||
//! This crate defines the `TreeMap` and `TreeSet` types. Their keys must implement `Ord`.
|
||||
//!
|
||||
//! `TreeMap`s are ordered.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```{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;
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,19 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Maps are collections of unique keys with corresponding values, and sets are
|
||||
//! just unique keys without a corresponding value.
|
||||
//!
|
||||
//! This crate defines `TrieMap` and `TrieSet`, which require `uint` keys.
|
||||
//!
|
||||
//! `TrieMap` is ordered.
|
||||
|
||||
pub mod map;
|
||||
pub mod set;
|
@ -1,972 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// FIXME(conventions): implement bounded iterators
|
||||
// FIXME(conventions): replace each_reverse by making iter DoubleEnded
|
||||
// FIXME(conventions): implement iter_mut and into_iter
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::default::Default;
|
||||
use core::fmt;
|
||||
use core::fmt::Show;
|
||||
use core::iter::Peekable;
|
||||
use std::hash::Hash;
|
||||
|
||||
use trie_map::{TrieMap, Entries};
|
||||
|
||||
/// A set implemented as a radix trie.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
#[stable]
|
||||
impl Default for TrieSet {
|
||||
#[inline]
|
||||
#[stable]
|
||||
fn default() -> TrieSet { TrieSet::new() }
|
||||
}
|
||||
|
||||
impl TrieSet {
|
||||
/// Creates an empty TrieSet.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
/// let mut set = TrieSet::new();
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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)}
|
||||
}
|
||||
|
||||
/// Visits the values representing the difference, in ascending order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
|
||||
/// let b: TrieSet = [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 diff1: TrieSet = a.difference(&b).collect();
|
||||
/// assert_eq!(diff1, [1, 2].iter().map(|&x| x).collect());
|
||||
///
|
||||
/// // Note that difference is not symmetric,
|
||||
/// // and `b - a` means something else:
|
||||
/// let diff2: TrieSet = b.difference(&a).collect();
|
||||
/// assert_eq!(diff2, [4, 5].iter().map(|&x| x).collect());
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn difference<'a>(&'a self, other: &'a TrieSet) -> DifferenceItems<'a> {
|
||||
DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
|
||||
}
|
||||
|
||||
/// Visits the values representing the symmetric difference, in ascending order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
|
||||
/// let b: TrieSet = [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: TrieSet = a.symmetric_difference(&b).collect();
|
||||
/// let diff2: TrieSet = b.symmetric_difference(&a).collect();
|
||||
///
|
||||
/// assert_eq!(diff1, diff2);
|
||||
/// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect());
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle."]
|
||||
pub fn symmetric_difference<'a>(&'a self, other: &'a TrieSet) -> SymDifferenceItems<'a> {
|
||||
SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()}
|
||||
}
|
||||
|
||||
/// Visits the values representing the intersection, in ascending order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
|
||||
/// let b: TrieSet = [2, 3, 4].iter().map(|&x| x).collect();
|
||||
///
|
||||
/// // Print 2, 3 in ascending order.
|
||||
/// for x in a.intersection(&b) {
|
||||
/// println!("{}", x);
|
||||
/// }
|
||||
///
|
||||
/// let diff: TrieSet = a.intersection(&b).collect();
|
||||
/// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect());
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn intersection<'a>(&'a self, other: &'a TrieSet) -> IntersectionItems<'a> {
|
||||
IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()}
|
||||
}
|
||||
|
||||
/// Visits the values representing the union, in ascending order.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
|
||||
/// let b: TrieSet = [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: TrieSet = a.union(&b).collect();
|
||||
/// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect());
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn union<'a>(&'a self, other: &'a TrieSet) -> UnionItems<'a> {
|
||||
UnionItems{a: self.iter().peekable(), b: other.iter().peekable()}
|
||||
}
|
||||
|
||||
/// Return the number of elements in the set
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let mut v = TrieSet::new();
|
||||
/// assert_eq!(v.len(), 0);
|
||||
/// v.insert(1);
|
||||
/// assert_eq!(v.len(), 1);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn len(&self) -> uint { self.map.len() }
|
||||
|
||||
/// Returns true if the set contains no elements
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let mut v = TrieSet::new();
|
||||
/// assert!(v.is_empty());
|
||||
/// v.insert(1);
|
||||
/// assert!(!v.is_empty());
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
|
||||
/// Clears the set, removing all values.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let mut v = TrieSet::new();
|
||||
/// v.insert(1);
|
||||
/// v.clear();
|
||||
/// assert!(v.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn clear(&mut self) { self.map.clear() }
|
||||
|
||||
/// Returns `true` if the set contains a value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
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.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn insert(&mut self, value: uint) -> bool {
|
||||
self.map.insert(value, ()).is_none()
|
||||
}
|
||||
|
||||
/// Removes a value from the set. Returns `true` if the value was
|
||||
/// present in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// 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]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn remove(&mut self, value: &uint) -> bool {
|
||||
self.map.remove(value).is_some()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<uint> for TrieSet {
|
||||
fn from_iter<Iter: Iterator<uint>>(iter: Iter) -> TrieSet {
|
||||
let mut set = TrieSet::new();
|
||||
set.extend(iter);
|
||||
set
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<uint> for TrieSet {
|
||||
fn extend<Iter: Iterator<uint>>(&mut self, mut iter: Iter) {
|
||||
for elem in iter {
|
||||
self.insert(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
impl BitOr<TrieSet, TrieSet> for TrieSet {
|
||||
/// Returns the union of `self` and `rhs` as a new `TrieSet`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
/// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
|
||||
///
|
||||
/// let set: TrieSet = a | b;
|
||||
/// let v: Vec<uint> = set.iter().collect();
|
||||
/// assert_eq!(v, vec![1u, 2, 3, 4, 5]);
|
||||
/// ```
|
||||
fn bitor(&self, rhs: &TrieSet) -> TrieSet {
|
||||
self.union(rhs).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
impl<'a, 'b> BitOr<&'b TrieSet, TrieSet> for &'a TrieSet {
|
||||
/// Returns the union of `self` and `rhs` as a new `TrieSet`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
/// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
|
||||
///
|
||||
/// let set: TrieSet = &a | &b;
|
||||
/// let v: Vec<uint> = set.iter().collect();
|
||||
/// assert_eq!(v, vec![1u, 2, 3, 4, 5]);
|
||||
/// ```
|
||||
fn bitor(self, rhs: &TrieSet) -> TrieSet {
|
||||
self.union(rhs).collect()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
impl BitAnd<TrieSet, TrieSet> for TrieSet {
|
||||
/// Returns the intersection of `self` and `rhs` as a new `TrieSet`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
/// let b: TrieSet = vec![2, 3, 4].into_iter().collect();
|
||||
///
|
||||
/// let set: TrieSet = a & b;
|
||||
/// let v: Vec<uint> = set.iter().collect();
|
||||
/// assert_eq!(v, vec![2u, 3]);
|
||||
/// ```
|
||||
fn bitand(&self, rhs: &TrieSet) -> TrieSet {
|
||||
self.intersection(rhs).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
impl<'a, 'b> BitAnd<&'b TrieSet, TrieSet> for &'a TrieSet {
|
||||
/// Returns the intersection of `self` and `rhs` as a new `TrieSet`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
/// let b: TrieSet = vec![2, 3, 4].into_iter().collect();
|
||||
///
|
||||
/// let set: TrieSet = &a & &b;
|
||||
/// let v: Vec<uint> = set.iter().collect();
|
||||
/// assert_eq!(v, vec![2u, 3]);
|
||||
/// ```
|
||||
fn bitand(self, rhs: &TrieSet) -> TrieSet {
|
||||
self.intersection(rhs).collect()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
impl BitXor<TrieSet, TrieSet> for TrieSet {
|
||||
/// Returns the symmetric difference of `self` and `rhs` as a new `TrieSet`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
/// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
|
||||
///
|
||||
/// let set: TrieSet = a ^ b;
|
||||
/// let v: Vec<uint> = set.iter().collect();
|
||||
/// assert_eq!(v, vec![1u, 2, 4, 5]);
|
||||
/// ```
|
||||
fn bitxor(&self, rhs: &TrieSet) -> TrieSet {
|
||||
self.symmetric_difference(rhs).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
impl<'a, 'b> BitXor<&'b TrieSet, TrieSet> for &'a TrieSet {
|
||||
/// Returns the symmetric difference of `self` and `rhs` as a new `TrieSet`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
/// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
|
||||
///
|
||||
/// let set: TrieSet = &a ^ &b;
|
||||
/// let v: Vec<uint> = set.iter().collect();
|
||||
/// assert_eq!(v, vec![1u, 2, 4, 5]);
|
||||
/// ```
|
||||
fn bitxor(self, rhs: &TrieSet) -> TrieSet {
|
||||
self.symmetric_difference(rhs).collect()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove impl after a snapshot
|
||||
#[cfg(stage0)]
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
impl Sub<TrieSet, TrieSet> for TrieSet {
|
||||
/// Returns the difference of `self` and `rhs` as a new `TrieSet`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
/// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
|
||||
///
|
||||
/// let set: TrieSet = a - b;
|
||||
/// let v: Vec<uint> = set.iter().collect();
|
||||
/// assert_eq!(v, vec![1u, 2]);
|
||||
/// ```
|
||||
fn sub(&self, rhs: &TrieSet) -> TrieSet {
|
||||
self.difference(rhs).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
impl<'a, 'b> Sub<&'b TrieSet, TrieSet> for &'a TrieSet {
|
||||
/// Returns the difference of `self` and `rhs` as a new `TrieSet`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::TrieSet;
|
||||
///
|
||||
/// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
/// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
|
||||
///
|
||||
/// let set: TrieSet = &a - &b;
|
||||
/// let v: Vec<uint> = set.iter().collect();
|
||||
/// assert_eq!(v, vec![1u, 2]);
|
||||
/// ```
|
||||
fn sub(self, rhs: &TrieSet) -> TrieSet {
|
||||
self.difference(rhs).collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// A forward iterator over a set.
|
||||
pub struct SetItems<'a> {
|
||||
iter: Entries<'a, ()>
|
||||
}
|
||||
|
||||
/// An iterator producing elements in the set difference (in-order).
|
||||
pub struct DifferenceItems<'a> {
|
||||
a: Peekable<uint, SetItems<'a>>,
|
||||
b: Peekable<uint, SetItems<'a>>,
|
||||
}
|
||||
|
||||
/// An iterator producing elements in the set symmetric difference (in-order).
|
||||
pub struct SymDifferenceItems<'a> {
|
||||
a: Peekable<uint, SetItems<'a>>,
|
||||
b: Peekable<uint, SetItems<'a>>,
|
||||
}
|
||||
|
||||
/// An iterator producing elements in the set intersection (in-order).
|
||||
pub struct IntersectionItems<'a> {
|
||||
a: Peekable<uint, SetItems<'a>>,
|
||||
b: Peekable<uint, SetItems<'a>>,
|
||||
}
|
||||
|
||||
/// An iterator producing elements in the set union (in-order).
|
||||
pub struct UnionItems<'a> {
|
||||
a: Peekable<uint, SetItems<'a>>,
|
||||
b: Peekable<uint, SetItems<'a>>,
|
||||
}
|
||||
|
||||
/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
|
||||
fn cmp_opt(x: Option<&uint>, y: Option<&uint>, short: Ordering, long: Ordering) -> Ordering {
|
||||
match (x, y) {
|
||||
(None , _ ) => short,
|
||||
(_ , None ) => long,
|
||||
(Some(x1), Some(y1)) => x1.cmp(y1),
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator<uint> for DifferenceItems<'a> {
|
||||
fn next(&mut self) -> Option<uint> {
|
||||
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> Iterator<uint> for SymDifferenceItems<'a> {
|
||||
fn next(&mut self) -> Option<uint> {
|
||||
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> Iterator<uint> for IntersectionItems<'a> {
|
||||
fn next(&mut self) -> Option<uint> {
|
||||
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> Iterator<uint> for UnionItems<'a> {
|
||||
fn next(&mut self) -> Option<uint> {
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::prelude::*;
|
||||
use std::uint;
|
||||
use vec::Vec;
|
||||
|
||||
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}");
|
||||
assert_eq!(format!("{}", empty), "{}");
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
|
||||
struct Counter<'a, 'b> {
|
||||
i: &'a mut uint,
|
||||
expected: &'b [uint],
|
||||
}
|
||||
|
||||
impl<'a, 'b> FnMut(uint) -> bool for Counter<'a, 'b> {
|
||||
extern "rust-call" fn call_mut(&mut self, (x,): (uint,)) -> bool {
|
||||
assert_eq!(x, self.expected[*self.i]);
|
||||
*self.i += 1;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn check<F>(a: &[uint], b: &[uint], expected: &[uint], f: F) where
|
||||
// FIXME Replace `Counter` with `Box<FnMut(&uint) -> bool>`
|
||||
F: FnOnce(&TrieSet, &TrieSet, Counter) -> bool,
|
||||
{
|
||||
let mut set_a = TrieSet::new();
|
||||
let mut set_b = TrieSet::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, Counter { i: &mut i, expected: expected });
|
||||
assert_eq!(i, expected.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection() {
|
||||
fn check_intersection(a: &[uint], b: &[uint], expected: &[uint]) {
|
||||
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],
|
||||
&[2, 11, 77, 5, 3],
|
||||
&[3, 5, 11, 77]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_difference() {
|
||||
fn check_difference(a: &[uint], b: &[uint], expected: &[uint]) {
|
||||
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(&[11, 22, 33, 40, 42],
|
||||
&[14, 23, 34, 38, 39, 50],
|
||||
&[11, 22, 33, 40, 42]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symmetric_difference() {
|
||||
fn check_symmetric_difference(a: &[uint], b: &[uint], expected: &[uint]) {
|
||||
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],
|
||||
&[3, 9, 14, 22],
|
||||
&[1, 5, 11, 14, 22]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_union() {
|
||||
fn check_union(a: &[uint], b: &[uint], expected: &[uint]) {
|
||||
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],
|
||||
&[1, 5, 9, 13, 19],
|
||||
&[1, 3, 5, 9, 11, 13, 16, 19, 24]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_or() {
|
||||
let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
let b: TrieSet = vec![3, 4, 5].into_iter().collect();
|
||||
|
||||
let set: TrieSet = &a | &b;
|
||||
let v: Vec<uint> = set.iter().collect();
|
||||
assert_eq!(v, vec![1u, 2, 3, 4, 5]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_and() {
|
||||
let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
let b: TrieSet = vec![2, 3, 4].into_iter().collect();
|
||||
|
||||
let set: TrieSet = &a & &b;
|
||||
let v: Vec<uint> = set.iter().collect();
|
||||
assert_eq!(v, vec![2u, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_xor() {
|
||||
let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
let b: TrieSet = vec![3, 4, 5].into_iter().collect();
|
||||
|
||||
let set: TrieSet = &a ^ &b;
|
||||
let v: Vec<uint> = set.iter().collect();
|
||||
assert_eq!(v, vec![1u, 2, 4, 5]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sub() {
|
||||
let a: TrieSet = vec![1, 2, 3].into_iter().collect();
|
||||
let b: TrieSet = vec![3, 4, 5].into_iter().collect();
|
||||
|
||||
let set: TrieSet = &a - &b;
|
||||
let v: Vec<uint> = set.iter().collect();
|
||||
assert_eq!(v, vec![1u, 2]);
|
||||
}
|
||||
}
|
@ -36,6 +36,7 @@ extern crate rustc_llvm;
|
||||
extern crate rustc_back;
|
||||
extern crate serialize;
|
||||
extern crate rbml;
|
||||
extern crate collections;
|
||||
#[phase(plugin, link)] extern crate log;
|
||||
#[phase(plugin, link)] extern crate syntax;
|
||||
|
||||
|
@ -77,7 +77,7 @@ use std::hash::{Hash, sip, Writer};
|
||||
use std::mem;
|
||||
use std::ops;
|
||||
use std::rc::Rc;
|
||||
use std::collections::enum_set::{EnumSet, CLike};
|
||||
use collections::enum_set::{EnumSet, CLike};
|
||||
use std::collections::hash_map::{HashMap, Occupied, Vacant};
|
||||
use syntax::abi;
|
||||
use syntax::ast::{CrateNum, DefId, DUMMY_NODE_ID, Ident, ItemTrait, LOCAL_CRATE};
|
||||
|
@ -472,7 +472,7 @@ fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
|
||||
// "crate": { parsed crate ... },
|
||||
// "plugins": { output of plugins ... }
|
||||
// }
|
||||
let mut json = std::collections::TreeMap::new();
|
||||
let mut json = std::collections::BTreeMap::new();
|
||||
json.insert("schema".to_string(), Json::String(SCHEMA_VERSION.to_string()));
|
||||
let plugins_json = res.into_iter()
|
||||
.filter_map(|opt| {
|
||||
|
@ -15,9 +15,8 @@ use std::default::Default;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use {Decodable, Encodable, Decoder, Encoder};
|
||||
use std::collections::{DList, RingBuf, TreeMap, TreeSet, HashMap, HashSet,
|
||||
TrieMap, TrieSet, VecMap};
|
||||
use std::collections::enum_set::{EnumSet, CLike};
|
||||
use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, VecMap};
|
||||
use collections::enum_set::{EnumSet, CLike};
|
||||
|
||||
impl<
|
||||
E,
|
||||
@ -78,7 +77,7 @@ impl<
|
||||
S: Encoder<E>,
|
||||
K: Encodable<S, E> + PartialEq + Ord,
|
||||
V: Encodable<S, E> + PartialEq
|
||||
> Encodable<S, E> for TreeMap<K, V> {
|
||||
> Encodable<S, E> for BTreeMap<K, V> {
|
||||
fn encode(&self, e: &mut S) -> Result<(), E> {
|
||||
e.emit_map(self.len(), |e| {
|
||||
let mut i = 0;
|
||||
@ -97,10 +96,10 @@ impl<
|
||||
D: Decoder<E>,
|
||||
K: Decodable<D, E> + PartialEq + Ord,
|
||||
V: Decodable<D, E> + PartialEq
|
||||
> Decodable<D, E> for TreeMap<K, V> {
|
||||
fn decode(d: &mut D) -> Result<TreeMap<K, V>, E> {
|
||||
> Decodable<D, E> for BTreeMap<K, V> {
|
||||
fn decode(d: &mut D) -> Result<BTreeMap<K, V>, E> {
|
||||
d.read_map(|d, len| {
|
||||
let mut map = TreeMap::new();
|
||||
let mut map = BTreeMap::new();
|
||||
for i in range(0u, len) {
|
||||
let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
|
||||
let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
|
||||
@ -115,7 +114,7 @@ impl<
|
||||
E,
|
||||
S: Encoder<E>,
|
||||
T: Encodable<S, E> + PartialEq + Ord
|
||||
> Encodable<S, E> for TreeSet<T> {
|
||||
> Encodable<S, E> for BTreeSet<T> {
|
||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
s.emit_seq(self.len(), |s| {
|
||||
let mut i = 0;
|
||||
@ -132,10 +131,10 @@ impl<
|
||||
E,
|
||||
D: Decoder<E>,
|
||||
T: Decodable<D, E> + PartialEq + Ord
|
||||
> Decodable<D, E> for TreeSet<T> {
|
||||
fn decode(d: &mut D) -> Result<TreeSet<T>, E> {
|
||||
> Decodable<D, E> for BTreeSet<T> {
|
||||
fn decode(d: &mut D) -> Result<BTreeSet<T>, E> {
|
||||
d.read_seq(|d, len| {
|
||||
let mut set = TreeSet::new();
|
||||
let mut set = BTreeSet::new();
|
||||
for i in range(0u, len) {
|
||||
set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
|
||||
}
|
||||
@ -255,63 +254,6 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
E,
|
||||
S: Encoder<E>,
|
||||
V: Encodable<S, E>
|
||||
> Encodable<S, E> for TrieMap<V> {
|
||||
fn encode(&self, e: &mut S) -> Result<(), E> {
|
||||
e.emit_map(self.len(), |e| {
|
||||
for (i, (key, val)) in self.iter().enumerate() {
|
||||
try!(e.emit_map_elt_key(i, |e| key.encode(e)));
|
||||
try!(e.emit_map_elt_val(i, |e| val.encode(e)));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
E,
|
||||
D: Decoder<E>,
|
||||
V: Decodable<D, E>
|
||||
> Decodable<D, E> for TrieMap<V> {
|
||||
fn decode(d: &mut D) -> Result<TrieMap<V>, E> {
|
||||
d.read_map(|d, len| {
|
||||
let mut map = TrieMap::new();
|
||||
for i in range(0u, len) {
|
||||
let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
|
||||
let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
|
||||
map.insert(key, val);
|
||||
}
|
||||
Ok(map)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, S: Encoder<E>> Encodable<S, E> for TrieSet {
|
||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
s.emit_seq(self.len(), |s| {
|
||||
for (i, e) in self.iter().enumerate() {
|
||||
try!(s.emit_seq_elt(i, |s| e.encode(s)));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<E, D: Decoder<E>> Decodable<D, E> for TrieSet {
|
||||
fn decode(d: &mut D) -> Result<TrieSet, E> {
|
||||
d.read_seq(|d, len| {
|
||||
let mut set = TrieSet::new();
|
||||
for i in range(0u, len) {
|
||||
set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
|
||||
}
|
||||
Ok(set)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
E,
|
||||
S: Encoder<E>,
|
||||
|
@ -151,7 +151,7 @@
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate serialize;
|
||||
//! use std::collections::TreeMap;
|
||||
//! use std::collections::BTreeMap;
|
||||
//! use serialize::json::{mod, Json, ToJson};
|
||||
//!
|
||||
//! // Only generate `Decodable` trait implementation
|
||||
@ -165,7 +165,7 @@
|
||||
//! // Specify encoding method manually
|
||||
//! impl ToJson for TestStruct {
|
||||
//! fn to_json(&self) -> Json {
|
||||
//! let mut d = TreeMap::new();
|
||||
//! let mut d = BTreeMap::new();
|
||||
//! // All standard types implement `to_json()`, so use it
|
||||
//! d.insert("data_int".to_string(), self.data_int.to_json());
|
||||
//! d.insert("data_str".to_string(), self.data_str.to_json());
|
||||
@ -198,7 +198,7 @@ use self::ParserState::*;
|
||||
use self::InternalStackElement::*;
|
||||
|
||||
use std;
|
||||
use std::collections::{HashMap, TreeMap};
|
||||
use std::collections::{HashMap, BTreeMap};
|
||||
use std::{char, f64, fmt, io, num, str};
|
||||
use std::mem::{swap, transmute};
|
||||
use std::num::{Float, FPNaN, FPInfinite, Int};
|
||||
@ -223,7 +223,7 @@ pub enum Json {
|
||||
}
|
||||
|
||||
pub type Array = Vec<Json>;
|
||||
pub type Object = TreeMap<string::String, Json>;
|
||||
pub type Object = BTreeMap<string::String, Json>;
|
||||
|
||||
/// The errors that can arise while parsing a JSON stream.
|
||||
#[deriving(Clone, PartialEq)]
|
||||
@ -973,7 +973,7 @@ impl Json {
|
||||
self.as_object().is_some()
|
||||
}
|
||||
|
||||
/// If the Json value is an Object, returns the associated TreeMap.
|
||||
/// If the Json value is an Object, returns the associated BTreeMap.
|
||||
/// Returns None otherwise.
|
||||
pub fn as_object<'a>(&'a self) -> Option<&'a Object> {
|
||||
match self {
|
||||
@ -1909,7 +1909,7 @@ impl<T: Iterator<char>> Builder<T> {
|
||||
fn build_object(&mut self) -> Result<Json, BuilderError> {
|
||||
self.bump();
|
||||
|
||||
let mut values = TreeMap::new();
|
||||
let mut values = BTreeMap::new();
|
||||
|
||||
loop {
|
||||
match self.token {
|
||||
@ -2391,9 +2391,9 @@ impl<A: ToJson> ToJson for Vec<A> {
|
||||
fn to_json(&self) -> Json { Json::Array(self.iter().map(|elt| elt.to_json()).collect()) }
|
||||
}
|
||||
|
||||
impl<A: ToJson> ToJson for TreeMap<string::String, A> {
|
||||
impl<A: ToJson> ToJson for BTreeMap<string::String, A> {
|
||||
fn to_json(&self) -> Json {
|
||||
let mut d = TreeMap::new();
|
||||
let mut d = BTreeMap::new();
|
||||
for (key, value) in self.iter() {
|
||||
d.insert((*key).clone(), value.to_json());
|
||||
}
|
||||
@ -2403,7 +2403,7 @@ impl<A: ToJson> ToJson for TreeMap<string::String, A> {
|
||||
|
||||
impl<A: ToJson> ToJson for HashMap<string::String, A> {
|
||||
fn to_json(&self) -> Json {
|
||||
let mut d = TreeMap::new();
|
||||
let mut d = BTreeMap::new();
|
||||
for (key, value) in self.iter() {
|
||||
d.insert((*key).clone(), value.to_json());
|
||||
}
|
||||
@ -2451,7 +2451,7 @@ mod tests {
|
||||
use super::{PrettyEncoder, Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser,
|
||||
StackElement, Stack, Encoder, Decoder};
|
||||
use std::{i64, u64, f32, f64, io};
|
||||
use std::collections::TreeMap;
|
||||
use std::collections::BTreeMap;
|
||||
use std::num::Float;
|
||||
use std::string;
|
||||
|
||||
@ -2501,7 +2501,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn mk_object(items: &[(string::String, Json)]) -> Json {
|
||||
let mut d = TreeMap::new();
|
||||
let mut d = BTreeMap::new();
|
||||
|
||||
for item in items.iter() {
|
||||
match *item {
|
||||
@ -3075,7 +3075,7 @@ mod tests {
|
||||
fn test_decode_map() {
|
||||
let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
|
||||
\"fields\":[\"Henry\", 349]}}";
|
||||
let mut map: TreeMap<string::String, Animal> = super::decode(s).unwrap();
|
||||
let mut map: BTreeMap<string::String, Animal> = super::decode(s).unwrap();
|
||||
|
||||
assert_eq!(map.remove(&"a".into_string()), Some(Dog));
|
||||
assert_eq!(map.remove(&"b".into_string()), Some(Frog("Henry".into_string(), 349)));
|
||||
@ -3350,9 +3350,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_prettyencoder_indent_level_param() {
|
||||
use std::str::from_utf8;
|
||||
use std::collections::TreeMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
let mut tree = TreeMap::new();
|
||||
let mut tree = BTreeMap::new();
|
||||
|
||||
tree.insert("hello".into_string(), String("guten tag".into_string()));
|
||||
tree.insert("goodbye".into_string(), String("sayonara".into_string()));
|
||||
@ -3719,13 +3719,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_to_json() {
|
||||
use std::collections::{HashMap,TreeMap};
|
||||
use std::collections::{HashMap,BTreeMap};
|
||||
use super::ToJson;
|
||||
|
||||
let array2 = Array(vec!(U64(1), U64(2)));
|
||||
let array3 = Array(vec!(U64(1), U64(2), U64(3)));
|
||||
let object = {
|
||||
let mut tree_map = TreeMap::new();
|
||||
let mut tree_map = BTreeMap::new();
|
||||
tree_map.insert("a".into_string(), U64(1));
|
||||
tree_map.insert("b".into_string(), U64(2));
|
||||
Object(tree_map)
|
||||
@ -3758,7 +3758,7 @@ mod tests {
|
||||
assert_eq!((&[1u, 2, 3]).to_json(), array3);
|
||||
assert_eq!((vec![1u, 2]).to_json(), array2);
|
||||
assert_eq!(vec!(1u, 2, 3).to_json(), array3);
|
||||
let mut tree_map = TreeMap::new();
|
||||
let mut tree_map = BTreeMap::new();
|
||||
tree_map.insert("a".into_string(), 1u);
|
||||
tree_map.insert("b".into_string(), 2);
|
||||
assert_eq!(tree_map.to_json(), object);
|
||||
|
@ -33,6 +33,8 @@ extern crate test;
|
||||
#[phase(plugin, link)]
|
||||
extern crate log;
|
||||
|
||||
extern crate collections;
|
||||
|
||||
pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
|
||||
DecoderHelpers, EncoderHelpers};
|
||||
|
||||
|
@ -1,471 +0,0 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
|
||||
//! A cache that holds a limited number of key-value pairs. When the
|
||||
//! capacity of the cache is exceeded, the least-recently-used
|
||||
//! (where "used" means a look-up or putting the pair into the cache)
|
||||
//! pair is automatically removed.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! ```rust
|
||||
//! use std::collections::LruCache;
|
||||
//!
|
||||
//! let mut cache: LruCache<int, int> = LruCache::new(2);
|
||||
//! cache.insert(1, 10);
|
||||
//! cache.insert(2, 20);
|
||||
//! cache.insert(3, 30);
|
||||
//! assert!(cache.get(&1).is_none());
|
||||
//! assert_eq!(*cache.get(&2).unwrap(), 20);
|
||||
//! assert_eq!(*cache.get(&3).unwrap(), 30);
|
||||
//!
|
||||
//! cache.insert(2, 22);
|
||||
//! assert_eq!(*cache.get(&2).unwrap(), 22);
|
||||
//!
|
||||
//! cache.insert(6, 60);
|
||||
//! assert!(cache.get(&3).is_none());
|
||||
//!
|
||||
//! cache.set_capacity(1);
|
||||
//! assert!(cache.get(&2).is_none());
|
||||
//! ```
|
||||
|
||||
use cmp::{PartialEq, Eq};
|
||||
use collections::HashMap;
|
||||
use fmt;
|
||||
use hash::Hash;
|
||||
use iter::{range, Iterator, Extend};
|
||||
use mem;
|
||||
use ops::Drop;
|
||||
use option::Option;
|
||||
use option::Option::{Some, None};
|
||||
use boxed::Box;
|
||||
use ptr;
|
||||
use result::Result::{Ok, Err};
|
||||
|
||||
// FIXME(conventions): implement iterators?
|
||||
// FIXME(conventions): implement indexing?
|
||||
|
||||
struct KeyRef<K> { k: *const K }
|
||||
|
||||
struct LruEntry<K, V> {
|
||||
next: *mut LruEntry<K, V>,
|
||||
prev: *mut LruEntry<K, V>,
|
||||
key: K,
|
||||
value: V,
|
||||
}
|
||||
|
||||
/// An LRU Cache.
|
||||
pub struct LruCache<K, V> {
|
||||
map: HashMap<KeyRef<K>, Box<LruEntry<K, V>>>,
|
||||
max_size: uint,
|
||||
head: *mut LruEntry<K, V>,
|
||||
}
|
||||
|
||||
impl<S, K: Hash<S>> Hash<S> for KeyRef<K> {
|
||||
fn hash(&self, state: &mut S) {
|
||||
unsafe { (*self.k).hash(state) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: PartialEq> PartialEq for KeyRef<K> {
|
||||
fn eq(&self, other: &KeyRef<K>) -> bool {
|
||||
unsafe{ (*self.k).eq(&*other.k) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq> Eq for KeyRef<K> {}
|
||||
|
||||
impl<K, V> LruEntry<K, V> {
|
||||
fn new(k: K, v: V) -> LruEntry<K, V> {
|
||||
LruEntry {
|
||||
key: k,
|
||||
value: v,
|
||||
next: ptr::null_mut(),
|
||||
prev: ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq, V> LruCache<K, V> {
|
||||
/// Create an LRU Cache that holds at most `capacity` items.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::LruCache;
|
||||
/// let mut cache: LruCache<int, &str> = LruCache::new(10);
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn new(capacity: uint) -> LruCache<K, V> {
|
||||
let cache = LruCache {
|
||||
map: HashMap::new(),
|
||||
max_size: capacity,
|
||||
head: unsafe{ mem::transmute(box mem::uninitialized::<LruEntry<K, V>>()) },
|
||||
};
|
||||
unsafe {
|
||||
(*cache.head).next = cache.head;
|
||||
(*cache.head).prev = cache.head;
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
/// Deprecated: Replaced with `insert`.
|
||||
#[deprecated = "Replaced with `insert`"]
|
||||
pub fn put(&mut self, k: K, v: V) {
|
||||
self.insert(k, v);
|
||||
}
|
||||
|
||||
/// Inserts a key-value pair into the cache. If the key already existed, the old value is
|
||||
/// returned.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::LruCache;
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(1i, "a");
|
||||
/// cache.insert(2, "b");
|
||||
/// assert_eq!(cache.get(&1), Some(&"a"));
|
||||
/// assert_eq!(cache.get(&2), Some(&"b"));
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
|
||||
let (node_ptr, node_opt, old_val) = match self.map.get_mut(&KeyRef{k: &k}) {
|
||||
Some(node) => {
|
||||
let old_val = mem::replace(&mut node.value, v);
|
||||
let node_ptr: *mut LruEntry<K, V> = &mut **node;
|
||||
(node_ptr, None, Some(old_val))
|
||||
}
|
||||
None => {
|
||||
let mut node = box LruEntry::new(k, v);
|
||||
let node_ptr: *mut LruEntry<K, V> = &mut *node;
|
||||
(node_ptr, Some(node), None)
|
||||
}
|
||||
};
|
||||
match node_opt {
|
||||
None => {
|
||||
// Existing node, just update LRU position
|
||||
self.detach(node_ptr);
|
||||
self.attach(node_ptr);
|
||||
}
|
||||
Some(node) => {
|
||||
let keyref = unsafe { &(*node_ptr).key };
|
||||
self.map.insert(KeyRef{k: keyref}, node);
|
||||
self.attach(node_ptr);
|
||||
if self.len() > self.capacity() {
|
||||
self.remove_lru();
|
||||
}
|
||||
}
|
||||
}
|
||||
old_val
|
||||
}
|
||||
|
||||
/// Return a value corresponding to the key in the cache.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::LruCache;
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(1i, "a");
|
||||
/// cache.insert(2, "b");
|
||||
/// cache.insert(2, "c");
|
||||
/// cache.insert(3, "d");
|
||||
///
|
||||
/// assert_eq!(cache.get(&1), None);
|
||||
/// assert_eq!(cache.get(&2), Some(&"c"));
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn get(&mut self, k: &K) -> Option<&V> {
|
||||
let (value, node_ptr_opt) = match self.map.get_mut(&KeyRef{k: k}) {
|
||||
None => (None, None),
|
||||
Some(node) => {
|
||||
let node_ptr: *mut LruEntry<K, V> = &mut **node;
|
||||
(Some(unsafe { &(*node_ptr).value }), Some(node_ptr))
|
||||
}
|
||||
};
|
||||
match node_ptr_opt {
|
||||
None => (),
|
||||
Some(node_ptr) => {
|
||||
self.detach(node_ptr);
|
||||
self.attach(node_ptr);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/// Deprecated: Renamed to `remove`.
|
||||
#[deprecated = "Renamed to `remove`"]
|
||||
pub fn pop(&mut self, k: &K) -> Option<V> {
|
||||
self.remove(k)
|
||||
}
|
||||
|
||||
/// Remove and return a value corresponding to the key from the cache.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::LruCache;
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(2i, "a");
|
||||
///
|
||||
/// assert_eq!(cache.remove(&1), None);
|
||||
/// assert_eq!(cache.remove(&2), Some("a"));
|
||||
/// assert_eq!(cache.remove(&2), None);
|
||||
/// assert_eq!(cache.len(), 0);
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn remove(&mut self, k: &K) -> Option<V> {
|
||||
match self.map.remove(&KeyRef{k: k}) {
|
||||
None => None,
|
||||
Some(lru_entry) => Some(lru_entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the maximum number of key-value pairs the cache can hold.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::LruCache;
|
||||
/// let mut cache: LruCache<int, &str> = LruCache::new(2);
|
||||
/// assert_eq!(cache.capacity(), 2);
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn capacity(&self) -> uint {
|
||||
self.max_size
|
||||
}
|
||||
|
||||
/// Deprecated: Renamed to `set_capacity`.
|
||||
#[deprecated = "Renamed to `set_capacity`"]
|
||||
pub fn change_capacity(&mut self, capacity: uint) {
|
||||
self.set_capacity(capacity)
|
||||
}
|
||||
|
||||
/// Change the number of key-value pairs the cache can hold. Remove
|
||||
/// least-recently-used key-value pairs if necessary.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::LruCache;
|
||||
/// let mut cache = LruCache::new(2);
|
||||
///
|
||||
/// cache.insert(1i, "a");
|
||||
/// cache.insert(2, "b");
|
||||
/// cache.insert(3, "c");
|
||||
///
|
||||
/// assert_eq!(cache.get(&1), None);
|
||||
/// assert_eq!(cache.get(&2), Some(&"b"));
|
||||
/// assert_eq!(cache.get(&3), Some(&"c"));
|
||||
///
|
||||
/// cache.set_capacity(3);
|
||||
/// cache.insert(1i, "a");
|
||||
/// cache.insert(2, "b");
|
||||
///
|
||||
/// assert_eq!(cache.get(&1), Some(&"a"));
|
||||
/// assert_eq!(cache.get(&2), Some(&"b"));
|
||||
/// assert_eq!(cache.get(&3), Some(&"c"));
|
||||
///
|
||||
/// cache.set_capacity(1);
|
||||
///
|
||||
/// assert_eq!(cache.get(&1), None);
|
||||
/// assert_eq!(cache.get(&2), None);
|
||||
/// assert_eq!(cache.get(&3), Some(&"c"));
|
||||
/// ```
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn set_capacity(&mut self, capacity: uint) {
|
||||
for _ in range(capacity, self.len()) {
|
||||
self.remove_lru();
|
||||
}
|
||||
self.max_size = capacity;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn remove_lru(&mut self) {
|
||||
if self.len() > 0 {
|
||||
let lru = unsafe { (*self.head).prev };
|
||||
self.detach(lru);
|
||||
self.map.remove(&KeyRef{k: unsafe { &(*lru).key }});
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn detach(&mut self, node: *mut LruEntry<K, V>) {
|
||||
unsafe {
|
||||
(*(*node).prev).next = (*node).next;
|
||||
(*(*node).next).prev = (*node).prev;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn attach(&mut self, node: *mut LruEntry<K, V>) {
|
||||
unsafe {
|
||||
(*node).next = (*self.head).next;
|
||||
(*node).prev = self.head;
|
||||
(*self.head).next = node;
|
||||
(*(*node).next).prev = node;
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the number of key-value pairs in the cache.
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn len(&self) -> uint { self.map.len() }
|
||||
|
||||
/// Returns whether the cache is currently empty.
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
|
||||
/// Clear the cache of all key-value pairs.
|
||||
#[unstable = "matches collection reform specification, waiting for dust to settle"]
|
||||
pub fn clear(&mut self) { self.map.clear(); }
|
||||
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq, V> Extend<(K, V)> for LruCache<K, V> {
|
||||
fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
|
||||
for (k, v) in iter{
|
||||
self.insert(k, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
|
||||
/// Return a string that lists the key-value pairs from most-recently
|
||||
/// used to least-recently used.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "{{"));
|
||||
let mut cur = self.head;
|
||||
for i in range(0, self.len()) {
|
||||
if i > 0 { try!(write!(f, ", ")) }
|
||||
unsafe {
|
||||
cur = (*cur).next;
|
||||
try!(write!(f, "{}", (*cur).key));
|
||||
}
|
||||
try!(write!(f, ": "));
|
||||
unsafe {
|
||||
try!(write!(f, "{}", (*cur).value));
|
||||
}
|
||||
}
|
||||
write!(f, r"}}")
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<K, V> Drop for LruCache<K, V> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
let node: Box<LruEntry<K, V>> = mem::transmute(self.head);
|
||||
// Prevent compiler from trying to drop the un-initialized field in the sigil node.
|
||||
let box internal_node = node;
|
||||
let LruEntry { next: _, prev: _, key: k, value: v } = internal_node;
|
||||
mem::forget(k);
|
||||
mem::forget(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use prelude::*;
|
||||
use super::LruCache;
|
||||
|
||||
fn assert_opt_eq<V: PartialEq>(opt: Option<&V>, v: V) {
|
||||
assert!(opt.is_some());
|
||||
assert!(opt.unwrap() == &v);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_put_and_get() {
|
||||
let mut cache: LruCache<int, int> = LruCache::new(2);
|
||||
cache.insert(1, 10);
|
||||
cache.insert(2, 20);
|
||||
assert_opt_eq(cache.get(&1), 10);
|
||||
assert_opt_eq(cache.get(&2), 20);
|
||||
assert_eq!(cache.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_put_update() {
|
||||
let mut cache: LruCache<String, Vec<u8>> = LruCache::new(1);
|
||||
cache.insert("1".to_string(), vec![10, 10]);
|
||||
cache.insert("1".to_string(), vec![10, 19]);
|
||||
assert_opt_eq(cache.get(&"1".to_string()), vec![10, 19]);
|
||||
assert_eq!(cache.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expire_lru() {
|
||||
let mut cache: LruCache<String, String> = LruCache::new(2);
|
||||
cache.insert("foo1".to_string(), "bar1".to_string());
|
||||
cache.insert("foo2".to_string(), "bar2".to_string());
|
||||
cache.insert("foo3".to_string(), "bar3".to_string());
|
||||
assert!(cache.get(&"foo1".to_string()).is_none());
|
||||
cache.insert("foo2".to_string(), "bar2update".to_string());
|
||||
cache.insert("foo4".to_string(), "bar4".to_string());
|
||||
assert!(cache.get(&"foo3".to_string()).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pop() {
|
||||
let mut cache: LruCache<int, int> = LruCache::new(2);
|
||||
cache.insert(1, 10);
|
||||
cache.insert(2, 20);
|
||||
assert_eq!(cache.len(), 2);
|
||||
let opt1 = cache.remove(&1);
|
||||
assert!(opt1.is_some());
|
||||
assert_eq!(opt1.unwrap(), 10);
|
||||
assert!(cache.get(&1).is_none());
|
||||
assert_eq!(cache.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_change_capacity() {
|
||||
let mut cache: LruCache<int, int> = LruCache::new(2);
|
||||
assert_eq!(cache.capacity(), 2);
|
||||
cache.insert(1, 10);
|
||||
cache.insert(2, 20);
|
||||
cache.set_capacity(1);
|
||||
assert!(cache.get(&1).is_none());
|
||||
assert_eq!(cache.capacity(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_string() {
|
||||
let mut cache: LruCache<int, int> = LruCache::new(3);
|
||||
cache.insert(1, 10);
|
||||
cache.insert(2, 20);
|
||||
cache.insert(3, 30);
|
||||
assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}");
|
||||
cache.insert(2, 22);
|
||||
assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}");
|
||||
cache.insert(6, 60);
|
||||
assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}");
|
||||
cache.get(&3);
|
||||
assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}");
|
||||
cache.set_capacity(2);
|
||||
assert_eq!(cache.to_string(), "{3: 30, 6: 60}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clear() {
|
||||
let mut cache: LruCache<int, int> = LruCache::new(2);
|
||||
cache.insert(1, 10);
|
||||
cache.insert(2, 20);
|
||||
cache.clear();
|
||||
assert!(cache.get(&1).is_none());
|
||||
assert!(cache.get(&2).is_none());
|
||||
assert_eq!(cache.to_string(), "{}");
|
||||
}
|
||||
}
|
@ -24,8 +24,8 @@
|
||||
//! Rust's collections can be grouped into four major categories:
|
||||
//!
|
||||
//! * Sequences: `Vec`, `RingBuf`, `DList`, `BitV`
|
||||
//! * Maps: `HashMap`, `BTreeMap`, `TreeMap`, `TrieMap`, `VecMap`, `LruCache`
|
||||
//! * Sets: `HashSet`, `BTreeSet`, `TreeSet`, `TrieSet`, `BitVSet`, `EnumSet`
|
||||
//! * Maps: `HashMap`, `BTreeMap`, `VecMap`
|
||||
//! * Sets: `HashSet`, `BTreeSet`, `BitVSet`
|
||||
//! * Misc: `BinaryHeap`
|
||||
//!
|
||||
//! # When Should You Use Which Collection?
|
||||
@ -64,16 +64,6 @@
|
||||
//! * You want to be able to get all of the entries in order on-demand.
|
||||
//! * You want a sorted map.
|
||||
//!
|
||||
//! ### Use a `TreeMap` when:
|
||||
//! * You want a `BTreeMap`, but can't tolerate inconsistent performance.
|
||||
//! * You want a `BTreeMap`, but have *very large* keys or values.
|
||||
//! * You want a `BTreeMap`, but have keys that are expensive to compare.
|
||||
//! * You want a `BTreeMap`, but you accept arbitrary untrusted inputs.
|
||||
//!
|
||||
//! ### Use a `TrieMap` when:
|
||||
//! * You want a `HashMap`, but with many potentially large `uint` keys.
|
||||
//! * You want a `BTreeMap`, but with potentially large `uint` keys.
|
||||
//!
|
||||
//! ### 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.
|
||||
@ -90,18 +80,11 @@
|
||||
//! ### Use a `BitVSet` when:
|
||||
//! * You want a `VecSet`.
|
||||
//!
|
||||
//! ### Use an `EnumSet` when:
|
||||
//! * You want a C-like enum, stored in a single `uint`.
|
||||
//!
|
||||
//! ### 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.
|
||||
//!
|
||||
//! ### Use an `LruCache` when:
|
||||
//! * You want a cache that discards infrequently used items when it becomes full.
|
||||
//! * You want a least-recently-used cache.
|
||||
//!
|
||||
//! # Correct and Efficient Usage of Collections
|
||||
//!
|
||||
//! Of course, knowing which collection is the right one for the job doesn't instantly
|
||||
@ -329,15 +312,21 @@
|
||||
#![experimental]
|
||||
|
||||
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 core_collections::{DList, RingBuf, VecMap};
|
||||
|
||||
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};
|
||||
/// Deprecated: Moved to collect-rs: https://github.com/Gankro/collect-rs/
|
||||
#[deprecated = "Moved to collect-rs: https://github.com/Gankro/collect-rs/"]
|
||||
pub use core_collections::EnumSet;
|
||||
|
||||
pub use core_collections::{binary_heap, bitv, bitv_set, btree_map, btree_set};
|
||||
pub use core_collections::{dlist, ring_buf, vec_map};
|
||||
|
||||
/// Deprecated: Moved to collect-rs: https://github.com/Gankro/collect-rs/
|
||||
#[deprecated = "Moved to collect-rs: https://github.com/Gankro/collect-rs/"]
|
||||
pub use core_collections::enum_set;
|
||||
|
||||
pub use self::hash_map::HashMap;
|
||||
pub use self::hash_set::HashSet;
|
||||
pub use self::lru_cache::LruCache;
|
||||
|
||||
mod hash;
|
||||
|
||||
@ -350,5 +339,3 @@ pub mod hash_set {
|
||||
//! A hashset
|
||||
pub use super::hash::set::*;
|
||||
}
|
||||
|
||||
pub mod lru_cache;
|
||||
|
@ -49,7 +49,7 @@ use self::NamePadding::*;
|
||||
use self::OutputLocation::*;
|
||||
|
||||
use std::any::{Any, AnyRefExt};
|
||||
use std::collections::TreeMap;
|
||||
use std::collections::BTreeMap;
|
||||
use stats::Stats;
|
||||
use getopts::{OptGroup, optflag, optopt};
|
||||
use regex::Regex;
|
||||
@ -230,7 +230,7 @@ impl Metric {
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
pub struct MetricMap(TreeMap<String,Metric>);
|
||||
pub struct MetricMap(BTreeMap<String,Metric>);
|
||||
|
||||
impl Clone for MetricMap {
|
||||
fn clone(&self) -> MetricMap {
|
||||
@ -251,7 +251,7 @@ pub enum MetricChange {
|
||||
|
||||
impl Copy for MetricChange {}
|
||||
|
||||
pub type MetricDiff = TreeMap<String,MetricChange>;
|
||||
pub type MetricDiff = BTreeMap<String,MetricChange>;
|
||||
|
||||
// The default console test runner. It accepts the command line
|
||||
// arguments and a vector of test_descs.
|
||||
@ -1191,7 +1191,7 @@ fn calc_result(desc: &TestDesc, task_result: Result<(), Box<Any+Send>>) -> TestR
|
||||
impl MetricMap {
|
||||
|
||||
pub fn new() -> MetricMap {
|
||||
MetricMap(TreeMap::new())
|
||||
MetricMap(BTreeMap::new())
|
||||
}
|
||||
|
||||
/// Load MetricDiff from a file.
|
||||
@ -1227,7 +1227,7 @@ impl MetricMap {
|
||||
/// map.
|
||||
pub fn compare_to_old(&self, old: &MetricMap,
|
||||
noise_pct: Option<f64>) -> MetricDiff {
|
||||
let mut diff : MetricDiff = TreeMap::new();
|
||||
let mut diff : MetricDiff = BTreeMap::new();
|
||||
let MetricMap(ref selfmap) = *self;
|
||||
let MetricMap(ref old) = *old;
|
||||
for (k, vold) in old.iter() {
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
use std::collections::{TrieMap, TreeMap, HashMap, HashSet};
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::os;
|
||||
use std::rand::{Rng, IsaacRng, SeedableRng};
|
||||
use std::time::Duration;
|
||||
@ -26,7 +26,7 @@ trait MutableMap {
|
||||
fn find(&self, k: &uint) -> Option<&uint>;
|
||||
}
|
||||
|
||||
impl MutableMap for TreeMap<uint, uint> {
|
||||
impl MutableMap for BTreeMap<uint, uint> {
|
||||
fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); }
|
||||
fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() }
|
||||
fn find(&self, k: &uint) -> Option<&uint> { self.get(k) }
|
||||
@ -36,11 +36,6 @@ impl MutableMap for HashMap<uint, uint> {
|
||||
fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() }
|
||||
fn find(&self, k: &uint) -> Option<&uint> { self.get(k) }
|
||||
}
|
||||
impl MutableMap for TrieMap<uint> {
|
||||
fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); }
|
||||
fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() }
|
||||
fn find(&self, k: &uint) -> Option<&uint> { self.get(k) }
|
||||
}
|
||||
|
||||
fn ascending<M: MutableMap>(map: &mut M, n_keys: uint) {
|
||||
println!(" Ascending integers:");
|
||||
@ -134,21 +129,21 @@ fn main() {
|
||||
println!("{} keys", n_keys);
|
||||
|
||||
// FIXME: #9970
|
||||
println!("{}", "\nTreeMap:");
|
||||
println!("{}", "\nBTreeMap:");
|
||||
|
||||
{
|
||||
let mut map: TreeMap<uint,uint> = TreeMap::new();
|
||||
let mut map: BTreeMap<uint,uint> = BTreeMap::new();
|
||||
ascending(&mut map, n_keys);
|
||||
}
|
||||
|
||||
{
|
||||
let mut map: TreeMap<uint,uint> = TreeMap::new();
|
||||
let mut map: BTreeMap<uint,uint> = BTreeMap::new();
|
||||
descending(&mut map, n_keys);
|
||||
}
|
||||
|
||||
{
|
||||
println!(" Random integers:");
|
||||
let mut map: TreeMap<uint,uint> = TreeMap::new();
|
||||
let mut map: BTreeMap<uint,uint> = BTreeMap::new();
|
||||
vector(&mut map, n_keys, rand.as_slice());
|
||||
}
|
||||
|
||||
@ -170,23 +165,4 @@ fn main() {
|
||||
let mut map: HashMap<uint,uint> = HashMap::new();
|
||||
vector(&mut map, n_keys, rand.as_slice());
|
||||
}
|
||||
|
||||
// FIXME: #9970
|
||||
println!("{}", "\nTrieMap:");
|
||||
|
||||
{
|
||||
let mut map: TrieMap<uint> = TrieMap::new();
|
||||
ascending(&mut map, n_keys);
|
||||
}
|
||||
|
||||
{
|
||||
let mut map: TrieMap<uint> = TrieMap::new();
|
||||
descending(&mut map, n_keys);
|
||||
}
|
||||
|
||||
{
|
||||
println!(" Random integers:");
|
||||
let mut map: TrieMap<uint> = TrieMap::new();
|
||||
vector(&mut map, n_keys, rand.as_slice());
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ extern crate rand;
|
||||
|
||||
use std::collections::BitvSet;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::TreeSet;
|
||||
use std::collections::BTreeSet;
|
||||
use std::hash::Hash;
|
||||
use std::os;
|
||||
use std::time::Duration;
|
||||
@ -48,7 +48,7 @@ impl<T: Hash + Eq> MutableSet<T> for HashSet<T> {
|
||||
fn remove(&mut self, k: &T) -> bool { self.remove(k) }
|
||||
fn contains(&self, k: &T) -> bool { self.contains(k) }
|
||||
}
|
||||
impl<T: Ord> MutableSet<T> for TreeSet<T> {
|
||||
impl<T: Ord> MutableSet<T> for BTreeSet<T> {
|
||||
fn insert(&mut self, k: T) { self.insert(k); }
|
||||
fn remove(&mut self, k: &T) -> bool { self.remove(k) }
|
||||
fn contains(&self, k: &T) -> bool { self.contains(k) }
|
||||
@ -207,14 +207,14 @@ fn main() {
|
||||
let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
|
||||
let mut results = empty_results();
|
||||
results.bench_int(&mut rng, num_keys, max, || {
|
||||
let s: TreeSet<uint> = TreeSet::new();
|
||||
let s: BTreeSet<uint> = BTreeSet::new();
|
||||
s
|
||||
});
|
||||
results.bench_str(&mut rng, num_keys, || {
|
||||
let s: TreeSet<String> = TreeSet::new();
|
||||
let s: BTreeSet<String> = BTreeSet::new();
|
||||
s
|
||||
});
|
||||
write_results("collections::TreeSet", &results);
|
||||
write_results("collections::BTreeSet", &results);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -12,9 +12,9 @@
|
||||
|
||||
// this file has some special \r\n endings (use xxd to see them)
|
||||
|
||||
fn main() {assert_eq!(b"", b"\
|
||||
fn main() {assert_eq!(b"", b"\
|
||||
");
|
||||
assert_eq!(b"\n", b"
|
||||
assert_eq!(b"\n", b"
|
||||
");
|
||||
}
|
||||
|
||||
|
@ -10,13 +10,13 @@
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use self::collections::TreeMap;
|
||||
use self::collections::BTreeMap;
|
||||
use std::option::Option::Some;
|
||||
use std::str::SendStr;
|
||||
use std::string::ToString;
|
||||
|
||||
pub fn main() {
|
||||
let mut map: TreeMap<SendStr, uint> = TreeMap::new();
|
||||
let mut map: BTreeMap<SendStr, uint> = BTreeMap::new();
|
||||
assert!(map.insert("foo".into_cow(), 42).is_none());
|
||||
assert!(map.insert("foo".to_string().into_cow(), 42).is_some());
|
||||
assert!(map.insert("foo".into_cow(), 42).is_some());
|
||||
|
Loading…
x
Reference in New Issue
Block a user