diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index a40913a5db2a2..c669fd844fb3e 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -616,7 +616,7 @@ fn find_rust_src_root(config: &Config) -> Option { let path_postfix = Path::new("src/etc/lldb_batchmode.py"); while path.pop() { - if path.join(path_postfix.clone()).is_file() { + if path.join(&path_postfix).is_file() { return Some(path); } } diff --git a/src/libcollections/bench.rs b/src/libcollections/bench.rs new file mode 100644 index 0000000000000..a212f22f89929 --- /dev/null +++ b/src/libcollections/bench.rs @@ -0,0 +1,88 @@ +// Copyright 2013-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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::prelude::*; +use std::rand; +use std::rand::Rng; +use test::Bencher; + +pub fn insert_rand_n(n: uint, map: &mut M, b: &mut Bencher, + insert: |&mut M, uint|, + remove: |&mut M, uint|) { + // setup + let mut rng = rand::weak_rng(); + + for _ in range(0, n) { + insert(map, rng.gen::() % n); + } + + // measure + b.iter(|| { + let k = rng.gen::() % n; + insert(map, k); + remove(map, k); + }) +} + +pub fn insert_seq_n(n: uint, map: &mut M, b: &mut Bencher, + insert: |&mut M, uint|, + remove: |&mut M, uint|) { + // setup + for i in range(0u, n) { + insert(map, i * 2); + } + + // measure + let mut i = 1; + b.iter(|| { + insert(map, i); + remove(map, i); + i = (i + 2) % n; + }) +} + +pub fn find_rand_n(n: uint, map: &mut M, b: &mut Bencher, + insert: |&mut M, uint|, + find: |&M, uint| -> T) { + // setup + let mut rng = rand::weak_rng(); + let mut keys = Vec::from_fn(n, |_| rng.gen::() % n); + + for k in keys.iter() { + insert(map, *k); + } + + rng.shuffle(keys.as_mut_slice()); + + // measure + let mut i = 0; + b.iter(|| { + let t = find(map, keys[i]); + i = (i + 1) % n; + t + }) +} + +pub fn find_seq_n(n: uint, map: &mut M, b: &mut Bencher, + insert: |&mut M, uint|, + find: |&M, uint| -> T) { + // setup + for i in range(0u, n) { + insert(map, i); + } + + // measure + let mut i = 0; + b.iter(|| { + let x = find(map, i); + i = (i + 1) % n; + x + }) +} diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs index 1b12fdcb8dc04..26e0c73724c6a 100644 --- a/src/libcollections/bitv.rs +++ b/src/libcollections/bitv.rs @@ -70,7 +70,6 @@ use core::slice; use core::u32; use std::hash; -use {Mutable, Set, MutableSet, MutableSeq}; use vec::Vec; type MatchWords<'a> = Chain, Skip>>>>; @@ -755,6 +754,20 @@ impl Bitv { } self.set(insert_pos, elem); } + + /// Return the total number of bits in this vector + #[inline] + pub fn len(&self) -> uint { self.nbits } + + /// Returns true if there are no bits in this vector + #[inline] + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Clears all bits in this vector. + #[inline] + pub fn clear(&mut self) { + for w in self.storage.iter_mut() { *w = 0u32; } + } } /// Transforms a byte-vector into a `Bitv`. Each byte becomes eight bits, @@ -804,18 +817,6 @@ impl Default for Bitv { fn default() -> Bitv { Bitv::new() } } -impl Collection for Bitv { - #[inline] - fn len(&self) -> uint { self.nbits } -} - -impl Mutable for Bitv { - #[inline] - fn clear(&mut self) { - for w in self.storage.iter_mut() { *w = 0u32; } - } -} - impl FromIterator for Bitv { fn from_iter>(iterator: I) -> Bitv { let mut ret = Bitv::new(); @@ -1466,61 +1467,45 @@ impl BitvSet { pub fn symmetric_difference_with(&mut self, other: &BitvSet) { self.other_op(other, |w1, w2| w1 ^ w2); } -} - -impl fmt::Show for BitvSet { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!(write!(fmt, "{{")); - let mut first = true; - for n in self.iter() { - if !first { - try!(write!(fmt, ", ")); - } - try!(write!(fmt, "{}", n)); - first = false; - } - write!(fmt, "}}") - } -} -impl hash::Hash for BitvSet { - fn hash(&self, state: &mut S) { - for pos in self.iter() { - pos.hash(state); - } + /// Return the number of set bits in this set. + #[inline] + pub fn len(&self) -> uint { + let &BitvSet(ref bitv) = self; + bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones()) } -} -impl Collection for BitvSet { + /// Returns whether there are no bits set in this set #[inline] - fn len(&self) -> uint { + pub fn is_empty(&self) -> bool { let &BitvSet(ref bitv) = self; - bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones()) + bitv.storage.iter().all(|&n| n == 0) } -} -impl Mutable for BitvSet { + /// Clears all bits in this set #[inline] - fn clear(&mut self) { + pub fn clear(&mut self) { let &BitvSet(ref mut bitv) = self; bitv.clear(); } -} -impl Set for BitvSet { + /// Returns `true` if this set contains the specified integer. #[inline] - fn contains(&self, value: &uint) -> bool { + pub fn contains(&self, value: &uint) -> bool { let &BitvSet(ref bitv) = self; *value < bitv.nbits && bitv.get(*value) } + /// Returns `true` if the set has no elements in common with `other`. + /// This is equivalent to checking for an empty intersection. #[inline] - fn is_disjoint(&self, other: &BitvSet) -> bool { + pub fn is_disjoint(&self, other: &BitvSet) -> bool { self.intersection(other).next().is_none() } + /// Returns `true` if the set is a subset of another. #[inline] - fn is_subset(&self, other: &BitvSet) -> bool { + pub fn is_subset(&self, other: &BitvSet) -> bool { let &BitvSet(ref self_bitv) = self; let &BitvSet(ref other_bitv) = other; @@ -1531,14 +1516,15 @@ impl Set for BitvSet { self_bitv.mask_words(other_bitv.storage.len()).all(|(_, w)| w == 0) } + /// Returns `true` if the set is a superset of another. #[inline] - fn is_superset(&self, other: &BitvSet) -> bool { + pub fn is_superset(&self, other: &BitvSet) -> bool { other.is_subset(self) } -} -impl MutableSet for BitvSet { - fn insert(&mut self, value: uint) -> bool { + /// Adds a value to the set. Returns `true` if the value was not already + /// present in the set. + pub fn insert(&mut self, value: uint) -> bool { if self.contains(&value) { return false; } @@ -1554,7 +1540,9 @@ impl MutableSet for BitvSet { return true; } - fn remove(&mut self, value: &uint) -> bool { + /// Removes a value from the set. Returns `true` if the value was + /// present in the set. + pub fn remove(&mut self, value: &uint) -> bool { if !self.contains(value) { return false; } @@ -1564,6 +1552,29 @@ impl MutableSet for BitvSet { } } +impl fmt::Show for BitvSet { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + try!(write!(fmt, "{{")); + let mut first = true; + for n in self.iter() { + if !first { + try!(write!(fmt, ", ")); + } + try!(write!(fmt, "{}", n)); + first = false; + } + write!(fmt, "}}") + } +} + +impl hash::Hash for BitvSet { + fn hash(&self, state: &mut S) { + for pos in self.iter() { + pos.hash(state); + } + } +} + /// An iterator for `BitvSet`. pub struct BitPositions<'a> { set: &'a BitvSet, @@ -1643,7 +1654,6 @@ mod tests { use std::rand::Rng; use test::Bencher; - use {Set, Mutable, MutableSet, MutableSeq}; use bitv::{Bitv, BitvSet, from_fn, from_bytes}; use bitv; use vec::Vec; diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index dc7d935619f9e..4570d49ba0ace 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -23,11 +23,8 @@ use core::default::Default; use core::{iter, fmt, mem}; use core::fmt::Show; -use {Deque, Map, MutableMap, Mutable, MutableSeq}; use ringbuf::RingBuf; - - /// A map based on a B-Tree. /// /// B-Trees represent a fundamental compromise between cache-efficiency and actually minimizing @@ -145,9 +142,25 @@ impl BTreeMap { b: b, } } -} -impl Map for BTreeMap { + /// Clears the map, removing all values. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut a = BTreeMap::new(); + /// a.insert(1u, "a"); + /// a.clear(); + /// assert!(a.is_empty()); + /// ``` + pub fn clear(&mut self) { + let b = self.b; + // avoid recursive destructors by manually traversing the tree + for _ in mem::replace(self, BTreeMap::with_b(b)).into_iter() {}; + } + // Searching in a B-Tree is pretty straightforward. // // Start at the root. Try to find the key in the current node. If we find it, return it. @@ -155,7 +168,20 @@ impl Map for BTreeMap { // the search key. If no such key exists (they're *all* smaller), then just take the last // edge in the node. If we're in a leaf and we don't find our key, then it's not // in the tree. - fn find(&self, key: &K) -> Option<&V> { + + /// Returns a reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// map.insert(1u, "a"); + /// assert_eq!(map.find(&1), Some(&"a")); + /// assert_eq!(map.find(&2), None); + /// ``` + pub fn find(&self, key: &K) -> Option<&V> { let mut cur_node = &self.root; loop { match cur_node.search(key) { @@ -170,11 +196,41 @@ impl Map for BTreeMap { } } } -} -impl MutableMap for BTreeMap { + /// Returns true if the map contains a value for the specified key. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// map.insert(1u, "a"); + /// assert_eq!(map.contains_key(&1), true); + /// assert_eq!(map.contains_key(&2), false); + /// ``` + #[inline] + pub fn contains_key(&self, key: &K) -> bool { + self.find(key).is_some() + } + + /// Returns a mutable reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// map.insert(1u, "a"); + /// match map.find_mut(&1) { + /// Some(x) => *x = "b", + /// None => (), + /// } + /// assert_eq!(map[1], "b"); + /// ``` // See `find` for implementation notes, this is basically a copy-paste with mut's added - fn find_mut(&mut self, key: &K) -> Option<&mut V> { + pub fn find_mut(&mut self, key: &K) -> Option<&mut V> { // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration let mut temp_node = &mut self.root; loop { @@ -218,7 +274,23 @@ impl MutableMap for BTreeMap { // 2) While ODS may potentially return the pair we *just* inserted after // the split, we will never do this. Again, this shouldn't effect the analysis. - fn swap(&mut self, key: K, mut value: V) -> Option { + /// Inserts a key-value pair from the map. If the key already had a value + /// present in the map, that value is returned. Otherwise, `None` is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// assert_eq!(map.swap(37u, "a"), None); + /// assert_eq!(map.is_empty(), false); + /// + /// map.insert(37, "b"); + /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map[37], "c"); + /// ``` + pub fn swap(&mut self, key: K, mut value: V) -> Option { // This is a stack of rawptrs to nodes paired with indices, respectively // representing the nodes and edges of our search path. We have to store rawptrs // because as far as Rust is concerned, we can mutate aliased data with such a @@ -266,6 +338,25 @@ impl MutableMap for BTreeMap { } } + /// Inserts a key-value pair into the map. An existing value for a + /// key is replaced by the new value. Returns `true` if the key did + /// not already exist in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// assert_eq!(map.insert(2u, "value"), true); + /// assert_eq!(map.insert(2, "value2"), false); + /// assert_eq!(map[2], "value2"); + /// ``` + #[inline] + pub fn insert(&mut self, key: K, value: V) -> bool { + self.swap(key, value).is_none() + } + // Deletion is the most complicated operation for a B-Tree. // // First we do the same kind of search described in @@ -301,7 +392,20 @@ impl MutableMap for BTreeMap { // the underflow handling process on the parent. If merging merges the last two children // of the root, then we replace the root with the merged node. - fn pop(&mut self, key: &K) -> Option { + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// map.insert(1u, "a"); + /// assert_eq!(map.pop(&1), Some("a")); + /// assert_eq!(map.pop(&1), None); + /// ``` + pub fn pop(&mut self, key: &K) -> Option { // See `swap` for a more thorough description of the stuff going on in here let mut stack = stack::PartialSearchStack::new(self); loop { @@ -322,6 +426,24 @@ impl MutableMap for BTreeMap { } } } + + /// Removes a key-value pair from the map. Returns `true` if the key + /// was present in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// assert_eq!(map.remove(&1u), false); + /// map.insert(1, "a"); + /// assert_eq!(map.remove(&1), true); + /// ``` + #[inline] + pub fn remove(&mut self, key: &K) -> bool { + self.pop(key).is_some() + } } /// The stack module provides a safe interface for constructing and manipulating a stack of ptrs @@ -331,7 +453,6 @@ mod stack { use core::prelude::*; use super::BTreeMap; use super::super::node::*; - use {MutableMap, MutableSeq}; use vec::Vec; type StackItem = (*mut Node, uint); @@ -603,20 +724,6 @@ mod stack { } } -impl Collection for BTreeMap { - fn len(&self) -> uint { - self.length - } -} - -impl Mutable for BTreeMap { - fn clear(&mut self) { - let b = self.b; - // avoid recursive destructors by manually traversing the tree - for _ in mem::replace(self, BTreeMap::with_b(b)).into_iter() {}; - } -} - impl FromIterator<(K, V)> for BTreeMap { fn from_iter>(iter: T) -> BTreeMap { let mut map = BTreeMap::new(); @@ -950,6 +1057,34 @@ impl BTreeMap { pub fn values<'a>(&'a self) -> Values<'a, K, V> { self.iter().map(|(_, v)| v) } + + /// Return the number of elements in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut a = BTreeMap::new(); + /// assert_eq!(a.len(), 0); + /// a.insert(1u, "a"); + /// assert_eq!(a.len(), 1); + /// ``` + pub fn len(&self) -> uint { self.length } + + /// Return true if the map contains no elements. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeMap; + /// + /// let mut a = BTreeMap::new(); + /// assert!(a.is_empty()); + /// a.insert(1u, "a"); + /// assert!(!a.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { self.len() == 0 } } impl BTreeMap { @@ -993,7 +1128,6 @@ impl BTreeMap { mod test { use std::prelude::*; - use {Map, MutableMap}; use super::{BTreeMap, Occupied, Vacant}; #[test] @@ -1199,58 +1333,73 @@ mod bench { use test::{Bencher, black_box}; use super::BTreeMap; - use MutableMap; - use deque::bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; + 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 : BTreeMap = BTreeMap::new(); - insert_rand_n(100, &mut m, b); + insert_rand_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } #[bench] pub fn insert_rand_10_000(b: &mut Bencher) { let mut m : BTreeMap = BTreeMap::new(); - insert_rand_n(10_000, &mut m, b); + insert_rand_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } // Insert seq #[bench] pub fn insert_seq_100(b: &mut Bencher) { let mut m : BTreeMap = BTreeMap::new(); - insert_seq_n(100, &mut m, b); + insert_seq_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } #[bench] pub fn insert_seq_10_000(b: &mut Bencher) { let mut m : BTreeMap = BTreeMap::new(); - insert_seq_n(10_000, &mut m, b); + insert_seq_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } // Find rand #[bench] pub fn find_rand_100(b: &mut Bencher) { let mut m : BTreeMap = BTreeMap::new(); - find_rand_n(100, &mut m, b); + find_rand_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } #[bench] pub fn find_rand_10_000(b: &mut Bencher) { let mut m : BTreeMap = BTreeMap::new(); - find_rand_n(10_000, &mut m, b); + find_rand_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } // Find seq #[bench] pub fn find_seq_100(b: &mut Bencher) { let mut m : BTreeMap = BTreeMap::new(); - find_seq_n(100, &mut m, b); + find_seq_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } #[bench] pub fn find_seq_10_000(b: &mut Bencher) { let mut m : BTreeMap = BTreeMap::new(); - find_seq_n(10_000, &mut m, b); + find_seq_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } fn bench_iter(b: &mut Bencher, size: uint) { diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 6b491096e7da4..a15d31ba2842a 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -15,7 +15,6 @@ use core::prelude::*; use core::{slice, mem, ptr}; use core::iter::Zip; -use MutableSeq; use vec; use vec::Vec; diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 8958f0ef5bee7..eac74098758ae 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -20,8 +20,6 @@ use core::{iter, fmt}; use core::iter::Peekable; use core::fmt::Show; -use {Mutable, Set, MutableSet, MutableMap, Map}; - /// A set based on a B-Tree. /// /// See BTreeMap's documentation for a detailed discussion of this collection's performance @@ -109,30 +107,104 @@ impl BTreeSet { pub fn union<'a>(&'a self, other: &'a BTreeSet) -> UnionItems<'a, T> { UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} } -} - -impl Collection for BTreeSet { - fn len(&self) -> uint { - self.map.len() - } -} -impl Mutable for BTreeSet { - fn clear(&mut self) { + /// Return the number of elements in the set + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeSet; + /// + /// let mut v = BTreeSet::new(); + /// assert_eq!(v.len(), 0); + /// v.insert(1i); + /// assert_eq!(v.len(), 1); + /// ``` + pub fn len(&self) -> uint { self.map.len() } + + /// Returns true if the set contains no elements + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeSet; + /// + /// let mut v = BTreeSet::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::BTreeSet; + /// + /// let mut v = BTreeSet::new(); + /// v.insert(1i); + /// v.clear(); + /// assert!(v.is_empty()); + /// ``` + pub fn clear(&mut self) { self.map.clear() } -} -impl Set for BTreeSet { - fn contains(&self, value: &T) -> bool { + /// Returns `true` if the set contains a value. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeSet; + /// + /// let set: BTreeSet = [1i, 2, 3].iter().map(|&x| x).collect(); + /// assert_eq!(set.contains(&1), true); + /// assert_eq!(set.contains(&4), false); + /// ``` + pub fn contains(&self, value: &T) -> bool { self.map.find(value).is_some() } - fn is_disjoint(&self, other: &BTreeSet) -> bool { + /// 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::BTreeSet; + /// + /// let a: BTreeSet = [1i, 2, 3].iter().map(|&x| x).collect(); + /// let mut b: BTreeSet = BTreeSet::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: &BTreeSet) -> bool { self.intersection(other).next().is_none() } - fn is_subset(&self, other: &BTreeSet) -> bool { + /// Returns `true` if the set is a subset of another. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeSet; + /// + /// let sup: BTreeSet = [1i, 2, 3].iter().map(|&x| x).collect(); + /// let mut set: BTreeSet = BTreeSet::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: &BTreeSet) -> bool { // Stolen from TreeMap let mut x = self.iter(); let mut y = other.iter(); @@ -156,14 +228,63 @@ impl Set for BTreeSet { } true } -} -impl MutableSet for BTreeSet{ - fn insert(&mut self, value: T) -> bool { + /// Returns `true` if the set is a superset of another. + /// + /// # Example + /// + /// ``` + /// use std::collections::BTreeSet; + /// + /// let sub: BTreeSet = [1i, 2].iter().map(|&x| x).collect(); + /// let mut set: BTreeSet = BTreeSet::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: &BTreeSet) -> 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); + /// ``` + pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } - fn remove(&mut self, value: &T) -> bool { + /// 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); + /// ``` + pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } } @@ -273,7 +394,6 @@ impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> { mod test { use std::prelude::*; - use {Set, MutableSet}; use super::BTreeSet; use std::hash; diff --git a/src/libcollections/deque.rs b/src/libcollections/deque.rs deleted file mode 100644 index d7970ed8d60c3..0000000000000 --- a/src/libcollections/deque.rs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2013-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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Container traits for collections. - -#[cfg(test)] -pub mod bench { - use std::prelude::*; - use std::rand; - use std::rand::Rng; - use test::Bencher; - use MutableMap; - - pub fn insert_rand_n>(n: uint, - map: &mut M, - b: &mut Bencher) { - // setup - let mut rng = rand::weak_rng(); - - map.clear(); - for _ in range(0, n) { - map.insert(rng.gen::() % n, 1); - } - - // measure - b.iter(|| { - let k = rng.gen::() % n; - map.insert(k, 1); - map.remove(&k); - }) - } - - pub fn insert_seq_n>(n: uint, - map: &mut M, - b: &mut Bencher) { - // setup - map.clear(); - for i in range(0u, n) { - map.insert(i*2, 1); - } - - // measure - let mut i = 1; - b.iter(|| { - map.insert(i, 1); - map.remove(&i); - i = (i + 2) % n; - }) - } - - pub fn find_rand_n>(n: uint, - map: &mut M, - b: &mut Bencher) { - // setup - let mut rng = rand::weak_rng(); - let mut keys = Vec::from_fn(n, |_| rng.gen::() % n); - - for k in keys.iter() { - map.insert(*k, 1); - } - - rng.shuffle(keys.as_mut_slice()); - - // measure - let mut i = 0; - b.iter(|| { - map.find(&keys[i]); - i = (i + 1) % n; - }) - } - - pub fn find_seq_n>(n: uint, - map: &mut M, - b: &mut Bencher) { - // setup - for i in range(0u, n) { - map.insert(i, 1); - } - - // measure - let mut i = 0; - b.iter(|| { - let x = map.find(&i); - i = (i + 1) % n; - x - }) - } -} - diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 22d487bd3a0db..a1e286d124574 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -31,8 +31,6 @@ use core::mem; use core::ptr; use std::hash::{Writer, Hash}; -use {Mutable, Deque, MutableSeq}; - /// A doubly-linked list. pub struct DList { length: uint, @@ -129,34 +127,6 @@ fn link_with_prev(mut next: Box>, prev: Rawlink>) Some(next) } -impl Collection for DList { - /// Returns `true` if the `DList` is empty. - /// - /// This operation should compute in O(1) time. - #[inline] - fn is_empty(&self) -> bool { - self.list_head.is_none() - } - - /// Returns the length of the `DList`. - /// - /// This operation should compute in O(1) time. - #[inline] - fn len(&self) -> uint { - self.length - } -} - -impl Mutable for DList { - /// Removes all elements from the `DList`. - /// - /// This operation should compute in O(n) time. - #[inline] - fn clear(&mut self) { - *self = DList::new() - } -} - // private methods impl DList { /// Add a Node first in the list @@ -217,60 +187,6 @@ impl DList { } } -impl Deque for DList { - /// Provides a reference to the front element, or `None` if the list is - /// empty. - #[inline] - fn front<'a>(&'a self) -> Option<&'a T> { - self.list_head.as_ref().map(|head| &head.value) - } - - /// Provides a mutable reference to the front element, or `None` if the list - /// is empty. - #[inline] - fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> { - self.list_head.as_mut().map(|head| &mut head.value) - } - - /// Provides a reference to the back element, or `None` if the list is - /// empty. - #[inline] - fn back<'a>(&'a self) -> Option<&'a T> { - self.list_tail.resolve_immut().as_ref().map(|tail| &tail.value) - } - - /// Provides a mutable reference to the back element, or `None` if the list - /// is empty. - #[inline] - fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> { - self.list_tail.resolve().map(|tail| &mut tail.value) - } - - /// Adds an element first in the list. - /// - /// This operation should compute in O(1) time. - fn push_front(&mut self, elt: T) { - self.push_front_node(box Node::new(elt)) - } - - /// Removes the first element and returns it, or `None` if the list is - /// empty. - /// - /// This operation should compute in O(1) time. - fn pop_front(&mut self) -> Option { - self.pop_front_node().map(|box Node{value, ..}| value) - } -} - -impl MutableSeq for DList { - fn push(&mut self, elt: T) { - self.push_back_node(box Node::new(elt)) - } - fn pop(&mut self) -> Option { - self.pop_back_node().map(|box Node{value, ..}| value) - } -} - impl Default for DList { #[inline] fn default() -> DList { DList::new() } @@ -495,6 +411,107 @@ impl DList { pub fn into_iter(self) -> MoveItems { MoveItems{list: self} } + + /// Returns `true` if the `DList` is empty. + /// + /// This operation should compute in O(1) time. + #[inline] + pub fn is_empty(&self) -> bool { + self.list_head.is_none() + } + + /// Returns the length of the `DList`. + /// + /// This operation should compute in O(1) time. + #[inline] + pub fn len(&self) -> uint { + self.length + } + + /// Removes all elements from the `DList`. + /// + /// This operation should compute in O(n) time. + #[inline] + pub fn clear(&mut self) { + *self = DList::new() + } + + /// Provides a reference to the front element, or `None` if the list is + /// empty. + #[inline] + pub fn front<'a>(&'a self) -> Option<&'a T> { + self.list_head.as_ref().map(|head| &head.value) + } + + /// Provides a mutable reference to the front element, or `None` if the list + /// is empty. + #[inline] + pub fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> { + self.list_head.as_mut().map(|head| &mut head.value) + } + + /// Provides a reference to the back element, or `None` if the list is + /// empty. + #[inline] + pub fn back<'a>(&'a self) -> Option<&'a T> { + self.list_tail.resolve_immut().as_ref().map(|tail| &tail.value) + } + + /// Provides a mutable reference to the back element, or `None` if the list + /// is empty. + #[inline] + pub fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> { + self.list_tail.resolve().map(|tail| &mut tail.value) + } + + /// Adds an element first in the list. + /// + /// This operation should compute in O(1) time. + pub fn push_front(&mut self, elt: T) { + self.push_front_node(box Node::new(elt)) + } + + /// Removes the first element and returns it, or `None` if the list is + /// empty. + /// + /// This operation should compute in O(1) time. + pub fn pop_front(&mut self) -> Option { + self.pop_front_node().map(|box Node{value, ..}| value) + } + + /// Appends an element to the back of a list + /// + /// # Example + /// + /// ```rust + /// use std::collections::DList; + /// + /// let mut d = DList::new(); + /// d.push(1i); + /// d.push(3); + /// assert_eq!(3, *d.back().unwrap()); + /// ``` + pub fn push(&mut self, elt: T) { + self.push_back_node(box Node::new(elt)) + } + + /// Removes the last element from a list and returns it, or `None` if + /// it is empty. + /// + /// # Example + /// + /// ```rust + /// use std::collections::DList; + /// + /// let mut d = DList::new(); + /// assert_eq!(d.pop(), None); + /// d.push(1i); + /// d.push(3); + /// assert_eq!(d.pop(), Some(3)); + /// ``` + pub fn pop(&mut self) -> Option { + self.pop_back_node().map(|box Node{value, ..}| value) + } } impl DList { @@ -745,7 +762,6 @@ mod tests { use test::Bencher; use test; - use {Deque, MutableSeq}; use super::{DList, Node, ListInsertion}; use vec::Vec; diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index f282549f6f9a4..b78c1897b0659 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -157,8 +157,6 @@ mod test { use enum_set::{EnumSet, CLike}; - use MutableSeq; - #[deriving(PartialEq, Show)] #[repr(uint)] enum Foo { diff --git a/src/libcollections/hash/sip.rs b/src/libcollections/hash/sip.rs index 1f12065750ba3..dd105c44ad336 100644 --- a/src/libcollections/hash/sip.rs +++ b/src/libcollections/hash/sip.rs @@ -279,8 +279,6 @@ mod tests { use super::super::{Hash, Writer}; use super::{SipState, hash, hash_with_keys}; - use MutableSeq; - // Hash just the bytes of the slice, without length prefix struct Bytes<'a>(&'a [u8]); diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 20ad5b6334f32..e28bc76648015 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -37,11 +37,8 @@ extern crate alloc; #[cfg(test)] #[phase(plugin, link)] extern crate std; #[cfg(test)] #[phase(plugin, link)] extern crate log; -use core::prelude::Option; - pub use bitv::{Bitv, BitvSet}; pub use btree::{BTreeMap, BTreeSet}; -pub use core::prelude::Collection; pub use dlist::DList; pub use enum_set::EnumSet; pub use priority_queue::PriorityQueue; @@ -69,457 +66,7 @@ pub mod string; pub mod vec; pub mod hash; -mod deque; - -/// A mutable container type. -pub trait Mutable: Collection { - /// Clears the container, removing all values. - /// - /// # Example - /// - /// ``` - /// let mut v = vec![1i, 2, 3]; - /// v.clear(); - /// assert!(v.is_empty()); - /// ``` - fn clear(&mut self); -} - -/// A key-value store where values may be looked up by their keys. This trait -/// provides basic operations to operate on these stores. -pub trait Map: Collection { - /// Returns a reference to the value corresponding to the key. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1i); - /// assert_eq!(map.find(&"a"), Some(&1i)); - /// assert_eq!(map.find(&"b"), None); - /// ``` - fn find<'a>(&'a self, key: &K) -> Option<&'a V>; - - /// Returns true if the map contains a value for the specified key. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1i); - /// assert_eq!(map.contains_key(&"a"), true); - /// assert_eq!(map.contains_key(&"b"), false); - /// ``` - #[inline] - fn contains_key(&self, key: &K) -> bool { - self.find(key).is_some() - } -} - -/// A key-value store (map) where the values can be modified. -pub trait MutableMap: Map + Mutable { - /// Inserts a key-value pair into the map. An existing value for a - /// key is replaced by the new value. Returns `true` if the key did - /// not already exist in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map = HashMap::new(); - /// assert_eq!(map.insert("key", 2i), true); - /// assert_eq!(map.insert("key", 9i), false); - /// assert_eq!(map["key"], 9i); - /// ``` - #[inline] - fn insert(&mut self, key: K, value: V) -> bool { - self.swap(key, value).is_none() - } - - /// Removes a key-value pair from the map. Returns `true` if the key - /// was present in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map = HashMap::new(); - /// assert_eq!(map.remove(&"key"), false); - /// map.insert("key", 2i); - /// assert_eq!(map.remove(&"key"), true); - /// ``` - #[inline] - fn remove(&mut self, key: &K) -> bool { - self.pop(key).is_some() - } - - /// Inserts a key-value pair into the map. If the key already had a value - /// present in the map, that value is returned. Otherwise, `None` is - /// returned. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map = HashMap::new(); - /// assert_eq!(map.swap("a", 37i), None); - /// assert_eq!(map.is_empty(), false); - /// - /// map.insert("a", 1i); - /// assert_eq!(map.swap("a", 37i), Some(1i)); - /// assert_eq!(map["a"], 37i); - /// ``` - fn swap(&mut self, k: K, v: V) -> Option; - - /// Removes a key from the map, returning the value at the key if the key - /// was previously in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map: HashMap<&str, int> = HashMap::new(); - /// map.insert("a", 1i); - /// assert_eq!(map.pop(&"a"), Some(1i)); - /// assert_eq!(map.pop(&"a"), None); - /// ``` - fn pop(&mut self, k: &K) -> Option; - - /// Returns a mutable reference to the value corresponding to the key. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1i); - /// match map.find_mut(&"a") { - /// Some(x) => *x = 7i, - /// None => (), - /// } - /// assert_eq!(map["a"], 7i); - /// ``` - fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>; -} - -/// A group of objects which are each distinct from one another. This -/// trait represents actions which can be performed on sets to iterate over -/// them. -pub trait Set: Collection { - /// Returns `true` if the set contains a value. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashSet; - /// - /// let set: HashSet = [1i, 2, 3].iter().map(|&x| x).collect(); - /// assert_eq!(set.contains(&1), true); - /// assert_eq!(set.contains(&4), false); - /// ``` - fn contains(&self, value: &T) -> bool; - - /// 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::HashSet; - /// - /// let a: HashSet = [1i, 2, 3].iter().map(|&x| x).collect(); - /// let mut b: HashSet = HashSet::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); - /// ``` - fn is_disjoint(&self, other: &Self) -> bool; - - /// Returns `true` if the set is a subset of another. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashSet; - /// - /// let sup: HashSet = [1i, 2, 3].iter().map(|&x| x).collect(); - /// let mut set: HashSet = HashSet::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); - /// ``` - fn is_subset(&self, other: &Self) -> bool; - - /// Returns `true` if the set is a superset of another. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashSet; - /// - /// let sub: HashSet = [1i, 2].iter().map(|&x| x).collect(); - /// let mut set: HashSet = HashSet::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); - /// ``` - fn is_superset(&self, other: &Self) -> bool { - other.is_subset(self) - } - - // FIXME #8154: Add difference, sym. difference, intersection and union iterators -} - -/// A mutable collection of values which are distinct from one another that -/// can be mutated. -pub trait MutableSet: Set + Mutable { - /// Adds a value to the set. Returns `true` if the value was not already - /// present in the set. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashSet; - /// - /// let mut set = HashSet::new(); - /// - /// assert_eq!(set.insert(2i), true); - /// assert_eq!(set.insert(2i), false); - /// assert_eq!(set.len(), 1); - /// ``` - fn insert(&mut self, value: T) -> bool; - - /// Removes a value from the set. Returns `true` if the value was - /// present in the set. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashSet; - /// - /// let mut set = HashSet::new(); - /// - /// set.insert(2i); - /// assert_eq!(set.remove(&2), true); - /// assert_eq!(set.remove(&2), false); - /// ``` - fn remove(&mut self, value: &T) -> bool; -} - -pub trait MutableSeq: Mutable { - /// Appends an element to the back of a collection. - /// - /// # Example - /// - /// ```rust - /// let mut vec = vec!(1i, 2); - /// vec.push(3); - /// assert_eq!(vec, vec!(1, 2, 3)); - /// ``` - fn push(&mut self, t: T); - - /// Removes the last element from a collection and returns it, or `None` if - /// it is empty. - /// - /// # Example - /// - /// ```rust - /// let mut vec = vec!(1i, 2, 3); - /// assert_eq!(vec.pop(), Some(3)); - /// assert_eq!(vec, vec!(1, 2)); - /// ``` - fn pop(&mut self) -> Option; -} - -/// A double-ended sequence that allows querying, insertion and deletion at both -/// ends. -/// -/// # Example -/// -/// With a `Deque` we can simulate a queue efficiently: -/// -/// ``` -/// use std::collections::{RingBuf, Deque}; -/// -/// let mut queue = RingBuf::new(); -/// queue.push(1i); -/// queue.push(2i); -/// queue.push(3i); -/// -/// // Will print 1, 2, 3 -/// while !queue.is_empty() { -/// let x = queue.pop_front().unwrap(); -/// println!("{}", x); -/// } -/// ``` -/// -/// We can also simulate a stack: -/// -/// ``` -/// use std::collections::{RingBuf, Deque}; -/// -/// let mut stack = RingBuf::new(); -/// stack.push_front(1i); -/// stack.push_front(2i); -/// stack.push_front(3i); -/// -/// // Will print 3, 2, 1 -/// while !stack.is_empty() { -/// let x = stack.pop_front().unwrap(); -/// println!("{}", x); -/// } -/// ``` -/// -/// And of course we can mix and match: -/// -/// ``` -/// use std::collections::{DList, Deque}; -/// -/// let mut deque = DList::new(); -/// -/// // Init deque with 1, 2, 3, 4 -/// deque.push_front(2i); -/// deque.push_front(1i); -/// deque.push(3i); -/// deque.push(4i); -/// -/// // Will print (1, 4) and (2, 3) -/// while !deque.is_empty() { -/// let f = deque.pop_front().unwrap(); -/// let b = deque.pop().unwrap(); -/// println!("{}", (f, b)); -/// } -/// ``` -pub trait Deque : MutableSeq { - /// Provides a reference to the front element, or `None` if the sequence is - /// empty. - /// - /// # Example - /// - /// ``` - /// use std::collections::{RingBuf, Deque}; - /// - /// let mut d = RingBuf::new(); - /// assert_eq!(d.front(), None); - /// - /// d.push(1i); - /// d.push(2i); - /// assert_eq!(d.front(), Some(&1i)); - /// ``` - fn front<'a>(&'a self) -> Option<&'a T>; - - /// Provides a mutable reference to the front element, or `None` if the - /// sequence is empty. - /// - /// # Example - /// - /// ``` - /// use std::collections::{RingBuf, Deque}; - /// - /// let mut d = RingBuf::new(); - /// assert_eq!(d.front_mut(), None); - /// - /// d.push(1i); - /// d.push(2i); - /// match d.front_mut() { - /// Some(x) => *x = 9i, - /// None => (), - /// } - /// assert_eq!(d.front(), Some(&9i)); - /// ``` - fn front_mut<'a>(&'a mut self) -> Option<&'a mut T>; - - /// Provides a reference to the back element, or `None` if the sequence is - /// empty. - /// - /// # Example - /// - /// ``` - /// use std::collections::{DList, Deque}; - /// - /// let mut d = DList::new(); - /// assert_eq!(d.back(), None); - /// - /// d.push(1i); - /// d.push(2i); - /// assert_eq!(d.back(), Some(&2i)); - /// ``` - fn back<'a>(&'a self) -> Option<&'a T>; - - /// Provides a mutable reference to the back element, or `None` if the - /// sequence is empty. - /// - /// # Example - /// - /// ``` - /// use std::collections::{DList, Deque}; - /// - /// let mut d = DList::new(); - /// assert_eq!(d.back(), None); - /// - /// d.push(1i); - /// d.push(2i); - /// match d.back_mut() { - /// Some(x) => *x = 9i, - /// None => (), - /// } - /// assert_eq!(d.back(), Some(&9i)); - /// ``` - fn back_mut<'a>(&'a mut self) -> Option<&'a mut T>; - - /// Inserts an element first in the sequence. - /// - /// # Example - /// - /// ``` - /// use std::collections::{DList, Deque}; - /// - /// let mut d = DList::new(); - /// d.push_front(1i); - /// d.push_front(2i); - /// assert_eq!(d.front(), Some(&2i)); - /// ``` - fn push_front(&mut self, elt: T); - - /// Removes the first element and returns it, or `None` if the sequence is - /// empty. - /// - /// # Example - /// - /// ``` - /// use std::collections::{RingBuf, Deque}; - /// - /// let mut d = RingBuf::new(); - /// d.push(1i); - /// d.push(2i); - /// - /// assert_eq!(d.pop_front(), Some(1i)); - /// assert_eq!(d.pop_front(), Some(2i)); - /// assert_eq!(d.pop_front(), None); - /// ``` - fn pop_front(&mut self) -> Option; -} +#[cfg(test)] mod bench; // FIXME(#14344) this shouldn't be necessary #[doc(hidden)] @@ -532,8 +79,4 @@ mod std { pub use core::clone; // deriving(Clone) pub use core::cmp; // deriving(Eq, Ord, etc.) pub use hash; // deriving(Hash) - - pub mod collections { - pub use MutableSeq; - } } diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs index 65fd8ce4f54d9..885b5c99c4501 100644 --- a/src/libcollections/priority_queue.rs +++ b/src/libcollections/priority_queue.rs @@ -159,7 +159,6 @@ use core::default::Default; use core::mem::{zeroed, replace, swap}; use core::ptr; -use {Mutable, MutableSeq}; use slice; use vec::Vec; @@ -171,16 +170,6 @@ pub struct PriorityQueue { data: Vec, } -impl Collection for PriorityQueue { - /// Returns the length of the queue. - fn len(&self) -> uint { self.data.len() } -} - -impl Mutable for PriorityQueue { - /// Drops all items from the queue. - fn clear(&mut self) { self.data.truncate(0) } -} - impl Default for PriorityQueue { #[inline] fn default() -> PriorityQueue { PriorityQueue::new() } @@ -504,6 +493,15 @@ impl PriorityQueue { let len = self.len(); self.siftdown_range(pos, len); } + + /// Returns the length of the queue. + pub fn len(&self) -> uint { self.data.len() } + + /// Returns true if the queue contains no elements + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Drops all items from the queue. + pub fn clear(&mut self) { self.data.truncate(0) } } /// `PriorityQueue` iterator. @@ -545,7 +543,6 @@ mod tests { use priority_queue::PriorityQueue; use vec::Vec; - use MutableSeq; #[test] fn test_iterator() { diff --git a/src/libcollections/ringbuf.rs b/src/libcollections/ringbuf.rs index 81e4361ec3949..3c4c3fce61d77 100644 --- a/src/libcollections/ringbuf.rs +++ b/src/libcollections/ringbuf.rs @@ -22,7 +22,6 @@ use core::iter; use core::slice; use std::hash::{Writer, Hash}; -use {Deque, Mutable, MutableSeq}; use vec::Vec; static INITIAL_CAPACITY: uint = 8u; // 2^3 @@ -36,86 +35,6 @@ pub struct RingBuf { elts: Vec> } -impl Collection for RingBuf { - /// Returns the number of elements in the `RingBuf`. - fn len(&self) -> uint { self.nelts } -} - -impl Mutable for RingBuf { - /// Clears the `RingBuf`, removing all values. - fn clear(&mut self) { - for x in self.elts.iter_mut() { *x = None } - self.nelts = 0; - self.lo = 0; - } -} - -impl Deque for RingBuf { - /// Returns a reference to the first element in the `RingBuf`. - fn front<'a>(&'a self) -> Option<&'a T> { - if self.nelts > 0 { Some(&self[0]) } else { None } - } - - /// Returns a mutable reference to the first element in the `RingBuf`. - fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> { - if self.nelts > 0 { Some(&mut self[0]) } else { None } - } - - /// Returns a reference to the last element in the `RingBuf`. - fn back<'a>(&'a self) -> Option<&'a T> { - if self.nelts > 0 { Some(&self[self.nelts - 1]) } else { None } - } - - /// Returns a mutable reference to the last element in the `RingBuf`. - fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> { - let nelts = self.nelts; - if nelts > 0 { Some(&mut self[nelts - 1]) } else { None } - } - - /// Removes and returns the first element in the `RingBuf`, or `None` if it - /// is empty. - fn pop_front(&mut self) -> Option { - let result = self.elts[self.lo].take(); - if result.is_some() { - self.lo = (self.lo + 1u) % self.elts.len(); - self.nelts -= 1u; - } - result - } - - /// Prepends an element to the `RingBuf`. - fn push_front(&mut self, t: T) { - if self.nelts == self.elts.len() { - grow(self.nelts, &mut self.lo, &mut self.elts); - } - if self.lo == 0u { - self.lo = self.elts.len() - 1u; - } else { self.lo -= 1u; } - self.elts[self.lo] = Some(t); - self.nelts += 1u; - } -} - -impl MutableSeq for RingBuf { - fn push(&mut self, t: T) { - if self.nelts == self.elts.len() { - grow(self.nelts, &mut self.lo, &mut self.elts); - } - let hi = self.raw_index(self.nelts); - self.elts[hi] = Some(t); - self.nelts += 1u; - } - fn pop(&mut self) -> Option { - if self.nelts > 0 { - self.nelts -= 1; - let hi = self.raw_index(self.nelts); - self.elts[hi].take() - } else { - None - } - } -} - impl Default for RingBuf { #[inline] fn default() -> RingBuf { RingBuf::new() } @@ -151,7 +70,7 @@ impl RingBuf { /// assert_eq!(buf[1], 7); /// ``` #[deprecated = "use indexing instead: `buf[index] = value`"] - pub fn get_mut<'a>(&'a mut self, i: uint) -> &'a mut T { + pub fn get_mut(&mut self, i: uint) -> &mut T { &mut self[i] } @@ -219,7 +138,7 @@ impl RingBuf { /// let b: &[_] = &[&5, &3, &4]; /// assert_eq!(buf.iter().collect::>().as_slice(), b); /// ``` - pub fn iter<'a>(&'a self) -> Items<'a, T> { + pub fn iter(&self) -> Items { Items{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts.as_slice()} } @@ -240,7 +159,7 @@ impl RingBuf { /// let b: &[_] = &[&mut 3, &mut 1, &mut 2]; /// assert_eq!(buf.iter_mut().collect::>()[], b); /// ``` - pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> { + pub fn iter_mut(&mut self) -> MutItems { let start_index = raw_index(self.lo, self.elts.len(), 0); let end_index = raw_index(self.lo, self.elts.len(), self.nelts); @@ -268,6 +187,230 @@ impl RingBuf { } } } + + /// Returns the number of elements in the `RingBuf`. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut v = RingBuf::new(); + /// assert_eq!(v.len(), 0); + /// v.push(1i); + /// assert_eq!(v.len(), 1); + /// ``` + pub fn len(&self) -> uint { self.nelts } + + /// Returns true if the buffer contains no elements + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut v = RingBuf::new(); + /// assert!(v.is_empty()); + /// v.push_front(1i); + /// assert!(!v.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Clears the buffer, removing all values. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut v = RingBuf::new(); + /// v.push(1i); + /// v.clear(); + /// assert!(v.is_empty()); + /// ``` + pub fn clear(&mut self) { + for x in self.elts.iter_mut() { *x = None } + self.nelts = 0; + self.lo = 0; + } + + /// Provides a reference to the front element, or `None` if the sequence is + /// empty. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut d = RingBuf::new(); + /// assert_eq!(d.front(), None); + /// + /// d.push(1i); + /// d.push(2i); + /// assert_eq!(d.front(), Some(&1i)); + /// ``` + pub fn front(&self) -> Option<&T> { + if self.nelts > 0 { Some(&self[0]) } else { None } + } + + /// Provides a mutable reference to the front element, or `None` if the + /// sequence is empty. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut d = RingBuf::new(); + /// assert_eq!(d.front_mut(), None); + /// + /// d.push(1i); + /// d.push(2i); + /// match d.front_mut() { + /// Some(x) => *x = 9i, + /// None => (), + /// } + /// assert_eq!(d.front(), Some(&9i)); + /// ``` + pub fn front_mut(&mut self) -> Option<&mut T> { + if self.nelts > 0 { Some(&mut self[0]) } else { None } + } + + /// Provides a reference to the back element, or `None` if the sequence is + /// empty. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut d = RingBuf::new(); + /// assert_eq!(d.back(), None); + /// + /// d.push(1i); + /// d.push(2i); + /// assert_eq!(d.back(), Some(&2i)); + /// ``` + pub fn back(&self) -> Option<&T> { + if self.nelts > 0 { Some(&self[self.nelts - 1]) } else { None } + } + + /// Provides a mutable reference to the back element, or `None` if the + /// sequence is empty. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut d = RingBuf::new(); + /// assert_eq!(d.back(), None); + /// + /// d.push(1i); + /// d.push(2i); + /// match d.back_mut() { + /// Some(x) => *x = 9i, + /// None => (), + /// } + /// assert_eq!(d.back(), Some(&9i)); + /// ``` + pub fn back_mut(&mut self) -> Option<&mut T> { + let nelts = self.nelts; + if nelts > 0 { Some(&mut self[nelts - 1]) } else { None } + } + + /// Removes the first element and returns it, or `None` if the sequence is + /// empty. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut d = RingBuf::new(); + /// d.push(1i); + /// d.push(2i); + /// + /// assert_eq!(d.pop_front(), Some(1i)); + /// assert_eq!(d.pop_front(), Some(2i)); + /// assert_eq!(d.pop_front(), None); + /// ``` + pub fn pop_front(&mut self) -> Option { + let result = self.elts[self.lo].take(); + if result.is_some() { + self.lo = (self.lo + 1u) % self.elts.len(); + self.nelts -= 1u; + } + result + } + + /// Inserts an element first in the sequence. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut d = RingBuf::new(); + /// d.push_front(1i); + /// d.push_front(2i); + /// assert_eq!(d.front(), Some(&2i)); + /// ``` + pub fn push_front(&mut self, t: T) { + if self.nelts == self.elts.len() { + grow(self.nelts, &mut self.lo, &mut self.elts); + } + if self.lo == 0u { + self.lo = self.elts.len() - 1u; + } else { self.lo -= 1u; } + self.elts[self.lo] = Some(t); + self.nelts += 1u; + } + + /// Appends an element to the back of a buffer + /// + /// # Example + /// + /// ```rust + /// use std::collections::RingBuf; + /// + /// let mut buf = RingBuf::new(); + /// buf.push(1i); + /// buf.push(3); + /// assert_eq!(3, *buf.back().unwrap()); + /// ``` + pub fn push(&mut self, t: T) { + if self.nelts == self.elts.len() { + grow(self.nelts, &mut self.lo, &mut self.elts); + } + let hi = self.raw_index(self.nelts); + self.elts[hi] = Some(t); + self.nelts += 1u; + } + + /// Removes the last element from a buffer and returns it, or `None` if + /// it is empty. + /// + /// # Example + /// + /// ```rust + /// use std::collections::RingBuf; + /// + /// let mut buf = RingBuf::new(); + /// assert_eq!(buf.pop(), None); + /// buf.push(1i); + /// buf.push(3); + /// assert_eq!(buf.pop(), Some(3)); + /// ``` + pub fn pop(&mut self) -> Option { + if self.nelts > 0 { + self.nelts -= 1; + let hi = self.raw_index(self.nelts); + self.elts[hi].take() + } else { + None + } + } } /// `RingBuf` iterator. @@ -513,7 +656,6 @@ mod tests { use test::Bencher; use test; - use {Deque, Mutable, MutableSeq}; use super::RingBuf; use vec::Vec; diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index a552e4caa2d21..107dc3e5c28b7 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -92,12 +92,11 @@ use core::cmp; use core::kinds::Sized; use core::mem::size_of; use core::mem; -use core::prelude::{Clone, Collection, Greater, Iterator, Less, None, Option}; +use core::prelude::{Clone, Greater, Iterator, Less, None, Option}; use core::prelude::{Ord, Ordering, RawPtr, Some, range}; use core::ptr; use core::iter::{range_step, MultiplicativeIterator}; -use MutableSeq; use vec::Vec; pub use core::slice::{Chunks, AsSlice, ImmutableSlice, ImmutablePartialEqSlice}; @@ -762,7 +761,6 @@ mod tests { use std::rt; use slice::*; - use {Mutable, MutableSeq}; use vec::Vec; fn square(n: uint) -> uint { n * n } @@ -2175,7 +2173,6 @@ mod bench { use test::Bencher; use vec::Vec; - use MutableSeq; #[bench] fn iterator(b: &mut Bencher) { diff --git a/src/libcollections/smallintmap.rs b/src/libcollections/smallintmap.rs index 9e6485103e192..b2e018743da7d 100644 --- a/src/libcollections/smallintmap.rs +++ b/src/libcollections/smallintmap.rs @@ -21,7 +21,6 @@ use core::iter; use core::iter::{Enumerate, FilterMap}; use core::mem::replace; -use {Mutable, Map, MutableMap, MutableSeq}; use {vec, slice}; use vec::Vec; use hash; @@ -65,90 +64,6 @@ pub struct SmallIntMap { v: Vec>, } -impl Collection for SmallIntMap { - /// Returns the number of elements in the map. - fn len(&self) -> uint { - self.v.iter().filter(|elt| elt.is_some()).count() - } - - /// Returns`true` if there are no elements in the map. - fn is_empty(&self) -> bool { - self.v.iter().all(|elt| elt.is_none()) - } -} - -impl Mutable for SmallIntMap { - /// Clears the map, removing all key-value pairs. - fn clear(&mut self) { self.v.clear() } -} - -impl Map for SmallIntMap { - /// Returns a reference to the value corresponding to the key. - fn find<'a>(&'a self, key: &uint) -> Option<&'a V> { - if *key < self.v.len() { - match self.v[*key] { - Some(ref value) => Some(value), - None => None - } - } else { - None - } - } -} - -impl MutableMap for SmallIntMap { - /// Returns a mutable reference to the value corresponding to the key. - fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> { - if *key < self.v.len() { - match *self.v.index_mut(key) { - Some(ref mut value) => Some(value), - None => None - } - } else { - None - } - } - - /// Inserts a key-value pair into the map. An existing value for a - /// key is replaced by the new value. Returns `true` if the key did - /// not already exist in the map. - fn insert(&mut self, key: uint, value: V) -> bool { - let exists = self.contains_key(&key); - let len = self.v.len(); - if len <= key { - self.v.grow_fn(key - len + 1, |_| None); - } - self.v[key] = Some(value); - !exists - } - - /// Removes a key-value pair from the map. Returns `true` if the key - /// was present in the map. - fn remove(&mut self, key: &uint) -> bool { - self.pop(key).is_some() - } - - /// Inserts a key-value pair into the map. If the key already had a value - /// present in the map, that value is returned. Otherwise `None` is returned. - fn swap(&mut self, key: uint, value: V) -> Option { - match self.find_mut(&key) { - Some(loc) => { return Some(replace(loc, value)); } - None => () - } - self.insert(key, value); - return None; - } - - /// Removes a key from the map, returning the value at the key if the key - /// was previously in the map. - fn pop(&mut self, key: &uint) -> Option { - if *key >= self.v.len() { - return None; - } - self.v[*key].take() - } -} - impl Default for SmallIntMap { #[inline] fn default() -> SmallIntMap { SmallIntMap::new() } @@ -295,6 +210,204 @@ impl SmallIntMap { v.map(|v| (i, v)) }) } + + /// Return the number of elements in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut a = SmallIntMap::new(); + /// assert_eq!(a.len(), 0); + /// a.insert(1, "a"); + /// assert_eq!(a.len(), 1); + /// ``` + pub fn len(&self) -> uint { + self.v.iter().filter(|elt| elt.is_some()).count() + } + + /// Return true if the map contains no elements. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut a = SmallIntMap::new(); + /// assert!(a.is_empty()); + /// a.insert(1, "a"); + /// assert!(!a.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { + self.v.iter().all(|elt| elt.is_none()) + } + + /// Clears the map, removing all key-value pairs. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut a = SmallIntMap::new(); + /// a.insert(1, "a"); + /// a.clear(); + /// assert!(a.is_empty()); + /// ``` + pub fn clear(&mut self) { self.v.clear() } + + /// Returns a reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut map = SmallIntMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.find(&1), Some(&"a")); + /// assert_eq!(map.find(&2), None); + /// ``` + pub fn find<'a>(&'a self, key: &uint) -> Option<&'a V> { + if *key < self.v.len() { + match self.v[*key] { + Some(ref value) => Some(value), + None => None + } + } else { + None + } + } + + /// Returns true if the map contains a value for the specified key. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut map = SmallIntMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.contains_key(&1), true); + /// assert_eq!(map.contains_key(&2), false); + /// ``` + #[inline] + pub fn contains_key(&self, key: &uint) -> bool { + self.find(key).is_some() + } + + /// Returns a mutable reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut map = SmallIntMap::new(); + /// map.insert(1, "a"); + /// match map.find_mut(&1) { + /// Some(x) => *x = "b", + /// None => (), + /// } + /// assert_eq!(map[1], "b"); + /// ``` + pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> { + if *key < self.v.len() { + match *(&mut self.v[*key]) { + Some(ref mut value) => Some(value), + None => None + } + } else { + None + } + } + + /// Inserts a key-value pair into the map. An existing value for a + /// key is replaced by the new value. Returns `true` if the key did + /// not already exist in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut map = SmallIntMap::new(); + /// assert_eq!(map.insert(2, "value"), true); + /// assert_eq!(map.insert(2, "value2"), false); + /// assert_eq!(map[2], "value2"); + /// ``` + pub fn insert(&mut self, key: uint, value: V) -> bool { + let exists = self.contains_key(&key); + let len = self.v.len(); + if len <= key { + self.v.grow_fn(key - len + 1, |_| None); + } + self.v[key] = Some(value); + !exists + } + + /// Removes a key-value pair from the map. Returns `true` if the key + /// was present in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut map = SmallIntMap::new(); + /// assert_eq!(map.remove(&1), false); + /// map.insert(1, "a"); + /// assert_eq!(map.remove(&1), true); + /// ``` + pub fn remove(&mut self, key: &uint) -> bool { + self.pop(key).is_some() + } + + /// Inserts a key-value pair from the map. If the key already had a value + /// present in the map, that value is returned. Otherwise, `None` is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut map = SmallIntMap::new(); + /// assert_eq!(map.swap(37, "a"), None); + /// assert_eq!(map.is_empty(), false); + /// + /// map.insert(37, "b"); + /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map[37], "c"); + /// ``` + pub fn swap(&mut self, key: uint, value: V) -> Option { + match self.find_mut(&key) { + Some(loc) => { return Some(replace(loc, value)); } + None => () + } + self.insert(key, value); + return None; + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::SmallIntMap; + /// + /// let mut map = SmallIntMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.pop(&1), Some("a")); + /// assert_eq!(map.pop(&1), None); + /// ``` + pub fn pop(&mut self, key: &uint) -> Option { + if *key >= self.v.len() { + return None; + } + self.v[*key].take() + } } impl SmallIntMap { @@ -499,7 +612,6 @@ mod test_map { use vec::Vec; use hash; - use {Map, MutableMap, Mutable, MutableSeq}; use super::SmallIntMap; #[test] @@ -869,57 +981,72 @@ mod bench { extern crate test; use self::test::Bencher; use super::SmallIntMap; - use deque::bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; + use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; - // Find seq #[bench] pub fn insert_rand_100(b: &mut Bencher) { let mut m : SmallIntMap = SmallIntMap::new(); - insert_rand_n(100, &mut m, b); + insert_rand_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } #[bench] pub fn insert_rand_10_000(b: &mut Bencher) { let mut m : SmallIntMap = SmallIntMap::new(); - insert_rand_n(10_000, &mut m, b); + insert_rand_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } // Insert seq #[bench] pub fn insert_seq_100(b: &mut Bencher) { let mut m : SmallIntMap = SmallIntMap::new(); - insert_seq_n(100, &mut m, b); + insert_seq_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } #[bench] pub fn insert_seq_10_000(b: &mut Bencher) { let mut m : SmallIntMap = SmallIntMap::new(); - insert_seq_n(10_000, &mut m, b); + insert_seq_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } // Find rand #[bench] pub fn find_rand_100(b: &mut Bencher) { let mut m : SmallIntMap = SmallIntMap::new(); - find_rand_n(100, &mut m, b); + find_rand_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } #[bench] pub fn find_rand_10_000(b: &mut Bencher) { let mut m : SmallIntMap = SmallIntMap::new(); - find_rand_n(10_000, &mut m, b); + find_rand_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } // Find seq #[bench] pub fn find_seq_100(b: &mut Bencher) { let mut m : SmallIntMap = SmallIntMap::new(); - find_seq_n(100, &mut m, b); + find_seq_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } #[bench] pub fn find_seq_10_000(b: &mut Bencher) { let mut m : SmallIntMap = SmallIntMap::new(); - find_seq_n(10_000, &mut m, b); + find_seq_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } } diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 86a640d1aeb9b..297ba71d252d7 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -59,12 +59,11 @@ use core::fmt; use core::cmp; use core::iter::AdditiveIterator; use core::kinds::Sized; -use core::prelude::{Char, Clone, Collection, Eq, Equiv, ImmutableSlice}; +use core::prelude::{Char, Clone, Eq, Equiv, ImmutableSlice}; use core::prelude::{Iterator, MutableSlice, None, Option, Ord, Ordering}; use core::prelude::{PartialEq, PartialOrd, Result, AsSlice, Some, Tuple2}; use core::prelude::{range}; -use {Deque, MutableSeq}; use hash; use ringbuf::RingBuf; use string::String; @@ -464,6 +463,14 @@ impl<'a> MaybeOwned<'a> { Owned(_) => false } } + + /// Return the number of bytes in this string. + #[inline] + pub fn len(&self) -> uint { self.as_slice().len() } + + /// Returns true if the string contains no bytes + #[inline] + pub fn is_empty(&self) -> bool { self.len() == 0 } } /// Trait for moving into a `MaybeOwned`. @@ -561,11 +568,6 @@ impl<'a> StrAllocating for MaybeOwned<'a> { } } -impl<'a> Collection for MaybeOwned<'a> { - #[inline] - fn len(&self) -> uint { self.as_slice().len() } -} - impl<'a> Clone for MaybeOwned<'a> { #[inline] fn clone(&self) -> MaybeOwned<'a> { @@ -782,7 +784,6 @@ mod tests { use std::option::{Some, None}; use std::ptr::RawPtr; use std::iter::{Iterator, DoubleEndedIterator}; - use {Collection, MutableSeq}; use super::*; use std::slice::{AsSlice, ImmutableSlice}; @@ -2142,14 +2143,16 @@ mod tests { #[test] fn test_str_container() { - fn sum_len(v: &[S]) -> uint { + fn sum_len(v: &[&str]) -> uint { v.iter().map(|x| x.len()).sum() } let s = String::from_str("01234"); assert_eq!(5, sum_len(["012", "", "34"])); - assert_eq!(5, sum_len([String::from_str("01"), String::from_str("2"), - String::from_str("34"), String::from_str("")])); + assert_eq!(5, sum_len([String::from_str("01").as_slice(), + String::from_str("2").as_slice(), + String::from_str("34").as_slice(), + String::from_str("").as_slice()])); assert_eq!(5, sum_len([s.as_slice()])); } @@ -2232,7 +2235,8 @@ mod bench { use test::black_box; use super::*; use std::iter::{Iterator, DoubleEndedIterator}; - use std::collections::Collection; + use std::str::StrSlice; + use std::slice::ImmutableSlice; #[bench] fn char_iterator(b: &mut Bencher) { diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 507cfbf191c4a..b3c83ba55598b 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -22,7 +22,6 @@ use core::ops; // FIXME: ICE's abound if you import the `Slice` type while importing `Slice` trait use core::raw::Slice as RawSlice; -use {Mutable, MutableSeq}; use hash; use slice::CloneableVector; use str; @@ -626,22 +625,43 @@ impl String { pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec { &mut self.vec } -} -#[experimental = "collection traits will probably be removed"] -impl Collection for String { + /// Return the number of bytes in this string. + /// + /// # Example + /// + /// ``` + /// let a = "foo".to_string(); + /// assert_eq!(a.len(), 3); + /// ``` #[inline] #[stable] - fn len(&self) -> uint { - self.vec.len() - } -} + pub fn len(&self) -> uint { self.vec.len() } -#[experimental = "collection traits will probably be removed"] -impl Mutable for String { + /// Returns true if the string contains no bytes + /// + /// # Example + /// + /// ``` + /// let mut v = String::new(); + /// assert!(v.is_empty()); + /// v.push('a'); + /// assert!(!v.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Truncates the string, returning it to 0 length. + /// + /// # Example + /// + /// ``` + /// let mut s = "foo".to_string(); + /// s.clear(); + /// assert!(s.is_empty()); + /// ``` #[inline] #[stable] - fn clear(&mut self) { + pub fn clear(&mut self) { self.vec.clear() } } @@ -830,7 +850,6 @@ mod tests { use std::prelude::*; use test::Bencher; - use {Mutable, MutableSeq}; use str; use str::{Str, StrSlice, Owned}; use super::{as_string, String}; diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index ea4d541aab94a..7e6efcb3d1266 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -44,7 +44,6 @@ use core::mem::{replace, swap}; use core::ptr; use std::hash::{Writer, Hash}; -use {Mutable, Set, MutableSet, MutableMap, Map, MutableSeq}; use vec::Vec; /// This is implemented as an AA tree, which is a simplified variation of @@ -206,45 +205,6 @@ impl Show for TreeMap { } } -impl Collection for TreeMap { - fn len(&self) -> uint { self.length } -} - -impl Mutable for TreeMap { - fn clear(&mut self) { - self.root = None; - self.length = 0 - } -} - -impl Map for TreeMap { - // See comments on tree_find_with - #[inline] - fn find<'a>(&'a self, key: &K) -> Option<&'a V> { - tree_find_with(&self.root, |k2| key.cmp(k2)) - } -} - -impl MutableMap for TreeMap { - // See comments on tree_find_with_mut - #[inline] - fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> { - tree_find_with_mut(&mut self.root, |x| key.cmp(x)) - } - - fn swap(&mut self, key: K, value: V) -> Option { - let ret = insert(&mut self.root, key, value); - if ret.is_none() { self.length += 1 } - ret - } - - fn pop(&mut self, key: &K) -> Option { - let ret = remove(&mut self.root, key); - if ret.is_some() { self.length -= 1 } - ret - } -} - impl Default for TreeMap { #[inline] fn default() -> TreeMap { TreeMap::new() } @@ -444,6 +404,184 @@ impl TreeMap { remaining: length } } + + /// Return the number of elements in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut a = TreeMap::new(); + /// assert_eq!(a.len(), 0); + /// a.insert(1u, "a"); + /// assert_eq!(a.len(), 1); + /// ``` + pub fn len(&self) -> uint { self.length } + + /// Return true if the map contains no elements. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut a = TreeMap::new(); + /// assert!(a.is_empty()); + /// a.insert(1u, "a"); + /// assert!(!a.is_empty()); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Clears the map, removing all values. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut a = TreeMap::new(); + /// a.insert(1u, "a"); + /// a.clear(); + /// assert!(a.is_empty()); + /// ``` + pub fn clear(&mut self) { + self.root = None; + self.length = 0 + } + + /// Returns a reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// map.insert(1u, "a"); + /// assert_eq!(map.find(&1), Some(&"a")); + /// assert_eq!(map.find(&2), None); + /// ``` + #[inline] + pub fn find<'a>(&'a self, key: &K) -> Option<&'a V> { + tree_find_with(&self.root, |k2| key.cmp(k2)) + } + + /// Returns true if the map contains a value for the specified key. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// map.insert(1u, "a"); + /// assert_eq!(map.contains_key(&1), true); + /// assert_eq!(map.contains_key(&2), false); + /// ``` + #[inline] + pub fn contains_key(&self, key: &K) -> bool { + self.find(key).is_some() + } + + /// Returns a mutable reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// map.insert(1u, "a"); + /// match map.find_mut(&1) { + /// Some(x) => *x = "b", + /// None => (), + /// } + /// assert_eq!(map[1], "b"); + /// ``` + #[inline] + pub fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> { + tree_find_with_mut(&mut self.root, |x| key.cmp(x)) + } + + /// Inserts a key-value pair into the map. An existing value for a + /// key is replaced by the new value. Returns `true` if the key did + /// not already exist in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// assert_eq!(map.insert(2u, "value"), true); + /// assert_eq!(map.insert(2, "value2"), false); + /// assert_eq!(map[2], "value2"); + /// ``` + #[inline] + pub fn insert(&mut self, key: K, value: V) -> bool { + self.swap(key, value).is_none() + } + + /// Removes a key-value pair from the map. Returns `true` if the key + /// was present in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// assert_eq!(map.remove(&1u), false); + /// map.insert(1, "a"); + /// assert_eq!(map.remove(&1), true); + /// ``` + #[inline] + pub fn remove(&mut self, key: &K) -> bool { + self.pop(key).is_some() + } + + /// Inserts a key-value pair from the map. If the key already had a value + /// present in the map, that value is returned. Otherwise, `None` is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// assert_eq!(map.swap(37u, "a"), None); + /// assert_eq!(map.is_empty(), false); + /// + /// map.insert(37, "b"); + /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map[37], "c"); + /// ``` + pub fn swap(&mut self, key: K, value: V) -> Option { + let ret = insert(&mut self.root, key, value); + if ret.is_none() { self.length += 1 } + ret + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// map.insert(1u, "a"); + /// assert_eq!(map.pop(&1), Some("a")); + /// assert_eq!(map.pop(&1), None); + /// ``` + pub fn pop(&mut self, key: &K) -> Option { + let ret = remove(&mut self.root, key); + if ret.is_some() { self.length -= 1 } + ret + } } impl TreeMap { @@ -1062,59 +1200,6 @@ impl Show for TreeSet { } } -impl Collection for TreeSet { - #[inline] - fn len(&self) -> uint { self.map.len() } -} - -impl Mutable for TreeSet { - #[inline] - fn clear(&mut self) { self.map.clear() } -} - -impl Set for TreeSet { - #[inline] - fn contains(&self, value: &T) -> bool { - self.map.contains_key(value) - } - - fn is_disjoint(&self, other: &TreeSet) -> bool { - self.intersection(other).next().is_none() - } - - fn is_subset(&self, other: &TreeSet) -> 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 - } -} - -impl MutableSet for TreeSet { - #[inline] - fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } - - #[inline] - fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } -} - impl Default for TreeSet { #[inline] fn default() -> TreeSet { TreeSet::new() } @@ -1320,6 +1405,184 @@ impl TreeSet { pub fn union<'a>(&'a self, other: &'a TreeSet) -> 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 = [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 = [1i, 2, 3].iter().map(|&x| x).collect(); + /// let mut b: TreeSet = 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) -> 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 = [1i, 2, 3].iter().map(|&x| x).collect(); + /// let mut set: TreeSet = 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) -> 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 = [1i, 2].iter().map(|&x| x).collect(); + /// let mut set: TreeSet = 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) -> 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. @@ -1676,7 +1939,6 @@ mod test_treemap { use std::rand::Rng; use std::rand; - use {Map, MutableMap, Mutable, MutableSeq}; use super::{TreeMap, TreeNode}; #[test] @@ -2195,59 +2457,73 @@ mod bench { use test::{Bencher, black_box}; use super::TreeMap; - use MutableMap; - use deque::bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; + use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n}; - // Find seq #[bench] pub fn insert_rand_100(b: &mut Bencher) { let mut m : TreeMap = TreeMap::new(); - insert_rand_n(100, &mut m, b); + insert_rand_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } #[bench] pub fn insert_rand_10_000(b: &mut Bencher) { let mut m : TreeMap = TreeMap::new(); - insert_rand_n(10_000, &mut m, b); + insert_rand_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } // Insert seq #[bench] pub fn insert_seq_100(b: &mut Bencher) { let mut m : TreeMap = TreeMap::new(); - insert_seq_n(100, &mut m, b); + insert_seq_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } #[bench] pub fn insert_seq_10_000(b: &mut Bencher) { let mut m : TreeMap = TreeMap::new(); - insert_seq_n(10_000, &mut m, b); + insert_seq_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.remove(&i); }); } // Find rand #[bench] pub fn find_rand_100(b: &mut Bencher) { let mut m : TreeMap = TreeMap::new(); - find_rand_n(100, &mut m, b); + find_rand_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } #[bench] pub fn find_rand_10_000(b: &mut Bencher) { let mut m : TreeMap = TreeMap::new(); - find_rand_n(10_000, &mut m, b); + find_rand_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } // Find seq #[bench] pub fn find_seq_100(b: &mut Bencher) { let mut m : TreeMap = TreeMap::new(); - find_seq_n(100, &mut m, b); + find_seq_n(100, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } #[bench] pub fn find_seq_10_000(b: &mut Bencher) { let mut m : TreeMap = TreeMap::new(); - find_seq_n(10_000, &mut m, b); + find_seq_n(10_000, &mut m, b, + |m, i| { m.insert(i, 1); }, + |m, i| { m.find(&i); }); } fn bench_iter(b: &mut Bencher, size: uint) { @@ -2286,7 +2562,6 @@ mod test_set { use std::prelude::*; use std::hash; - use {Set, MutableSet, Mutable, MutableMap, MutableSeq}; use super::{TreeMap, TreeSet}; #[test] diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs index 8c18a6488ba50..7a8cc5df55a27 100644 --- a/src/libcollections/trie.rs +++ b/src/libcollections/trie.rs @@ -29,7 +29,6 @@ use core::uint; use core::iter; use std::hash::{Writer, Hash}; -use {Mutable, Map, MutableMap, Set, MutableSet}; use slice::{Items, MutItems}; use slice; @@ -126,72 +125,6 @@ impl Show for TrieMap { } } -impl Collection for TrieMap { - /// Returns the number of elements in the map. - #[inline] - fn len(&self) -> uint { self.length } -} - -impl Mutable for TrieMap { - /// Clears the map, removing all values. - #[inline] - fn clear(&mut self) { - self.root = TrieNode::new(); - self.length = 0; - } -} - -impl Map for TrieMap { - /// Returns a reference to the value corresponding to the key. - #[inline] - fn find<'a>(&'a self, key: &uint) -> Option<&'a T> { - let mut node: &'a TrieNode = &self.root; - let mut idx = 0; - loop { - match node.children[chunk(*key, idx)] { - Internal(ref x) => node = &**x, - External(stored, ref value) => { - if stored == *key { - return Some(value) - } else { - return None - } - } - Nothing => return None - } - idx += 1; - } - } -} - -impl MutableMap for TrieMap { - /// Returns a mutable reference to the value corresponding to the key. - #[inline] - fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> { - find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1) - } - - /// Inserts a key-value pair from the map. If the key already had a value - /// present in the map, that value is returned. Otherwise, `None` is returned. - fn swap(&mut self, key: uint, value: T) -> Option { - let ret = insert(&mut self.root.count, - &mut self.root.children[chunk(key, 0)], - key, value, 1); - if ret.is_none() { self.length += 1 } - ret - } - - /// Removes a key from the map, returning the value at the key if the key - /// was previously in the map. - fn pop(&mut self, key: &uint) -> Option { - let ret = remove(&mut self.root.count, - &mut self.root.children[chunk(*key, 0)], - *key, 1); - if ret.is_some() { self.length -= 1 } - ret - } -} - impl Default for TrieMap { #[inline] fn default() -> TrieMap { TrieMap::new() } @@ -294,6 +227,205 @@ impl TrieMap { iter } + + /// Return the number of elements in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut a = TrieMap::new(); + /// assert_eq!(a.len(), 0); + /// a.insert(1, "a"); + /// assert_eq!(a.len(), 1); + /// ``` + #[inline] + pub fn len(&self) -> uint { self.length } + + /// Return true if the map contains no elements. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut a = TrieMap::new(); + /// assert!(a.is_empty()); + /// a.insert(1, "a"); + /// assert!(!a.is_empty()); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Clears the map, removing all values. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut a = TrieMap::new(); + /// a.insert(1, "a"); + /// a.clear(); + /// assert!(a.is_empty()); + /// ``` + #[inline] + pub fn clear(&mut self) { + self.root = TrieNode::new(); + self.length = 0; + } + + /// Returns a reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut map = TrieMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.find(&1), Some(&"a")); + /// assert_eq!(map.find(&2), None); + /// ``` + #[inline] + pub fn find<'a>(&'a self, key: &uint) -> Option<&'a T> { + let mut node: &'a TrieNode = &self.root; + let mut idx = 0; + loop { + match node.children[chunk(*key, idx)] { + Internal(ref x) => node = &**x, + External(stored, ref value) => { + if stored == *key { + return Some(value) + } else { + return None + } + } + Nothing => return None + } + idx += 1; + } + } + + /// Returns true if the map contains a value for the specified key. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut map = TrieMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.contains_key(&1), true); + /// assert_eq!(map.contains_key(&2), false); + /// ``` + #[inline] + pub fn contains_key(&self, key: &uint) -> bool { + self.find(key).is_some() + } + + /// Returns a mutable reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut map = TrieMap::new(); + /// map.insert(1, "a"); + /// match map.find_mut(&1) { + /// Some(x) => *x = "b", + /// None => (), + /// } + /// assert_eq!(map[1], "b"); + /// ``` + #[inline] + pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> { + find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1) + } + + /// Inserts a key-value pair into the map. An existing value for a + /// key is replaced by the new value. Returns `true` if the key did + /// not already exist in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut map = TrieMap::new(); + /// assert_eq!(map.insert(2, "value"), true); + /// assert_eq!(map.insert(2, "value2"), false); + /// assert_eq!(map[2], "value2"); + /// ``` + #[inline] + pub fn insert(&mut self, key: uint, value: T) -> bool { + self.swap(key, value).is_none() + } + + /// Removes a key-value pair from the map. Returns `true` if the key + /// was present in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut map = TrieMap::new(); + /// assert_eq!(map.remove(&1), false); + /// map.insert(1, "a"); + /// assert_eq!(map.remove(&1), true); + /// ``` + #[inline] + pub fn remove(&mut self, key: &uint) -> bool { + self.pop(key).is_some() + } + + /// Inserts a key-value pair from the map. If the key already had a value + /// present in the map, that value is returned. Otherwise, `None` is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut map = TrieMap::new(); + /// assert_eq!(map.swap(37, "a"), None); + /// assert_eq!(map.is_empty(), false); + /// + /// map.insert(37, "b"); + /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map[37], "c"); + /// ``` + pub fn swap(&mut self, key: uint, value: T) -> Option { + let ret = insert(&mut self.root.count, + &mut self.root.children[chunk(key, 0)], + key, value, 1); + if ret.is_none() { self.length += 1 } + ret + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::TrieMap; + /// + /// let mut map = TrieMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.pop(&1), Some("a")); + /// assert_eq!(map.pop(&1), None); + /// ``` + pub fn pop(&mut self, key: &uint) -> Option { + let ret = remove(&mut self.root.count, + &mut self.root.children[chunk(*key, 0)], + *key, 1); + if ret.is_some() { self.length -= 1 } + ret + } } // FIXME #5846 we want to be able to choose between &x and &mut x @@ -569,52 +701,6 @@ impl Show for TrieSet { } } -impl Collection for TrieSet { - /// Returns the number of elements in the set. - #[inline] - fn len(&self) -> uint { self.map.len() } -} - -impl Mutable for TrieSet { - /// Clears the set, removing all values. - #[inline] - fn clear(&mut self) { self.map.clear() } -} - -impl Set for TrieSet { - #[inline] - fn contains(&self, value: &uint) -> bool { - self.map.contains_key(value) - } - - #[inline] - fn is_disjoint(&self, other: &TrieSet) -> bool { - self.iter().all(|v| !other.contains(&v)) - } - - #[inline] - fn is_subset(&self, other: &TrieSet) -> bool { - self.iter().all(|v| other.contains(&v)) - } - - #[inline] - fn is_superset(&self, other: &TrieSet) -> bool { - other.is_subset(self) - } -} - -impl MutableSet for TrieSet { - #[inline] - fn insert(&mut self, value: uint) -> bool { - self.map.insert(value, ()) - } - - #[inline] - fn remove(&mut self, value: &uint) -> bool { - self.map.remove(value) - } -} - impl Default for TrieSet { #[inline] fn default() -> TrieSet { TrieSet::new() } @@ -714,6 +800,171 @@ impl TrieSet { 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 for TrieSet { @@ -1026,7 +1277,6 @@ mod test_map { use std::uint; use std::hash; - use {MutableMap, Map, MutableSeq}; use super::{TrieMap, TrieNode, Internal, External, Nothing}; fn check_integrity(trie: &TrieNode) { @@ -1442,7 +1692,6 @@ mod bench_map { use std::rand::{weak_rng, Rng}; use test::{Bencher, black_box}; - use MutableMap; use super::TrieMap; fn bench_iter(b: &mut Bencher, size: uint) { @@ -1559,7 +1808,6 @@ mod test_set { use std::prelude::*; use std::uint; - use {MutableSet, Set, MutableSeq}; use super::TrieSet; #[test] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index b190093bafcb3..d7ec3836eb264 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -27,7 +27,6 @@ use core::ptr; use core::raw::Slice as RawSlice; use core::uint; -use {Mutable, MutableSeq}; use slice::{CloneableVector}; /// An owned, growable vector. @@ -530,15 +529,6 @@ impl Ord for Vec { } } -#[experimental = "waiting on Collection stability"] -impl Collection for Vec { - #[inline] - #[stable] - fn len(&self) -> uint { - self.len - } -} - // FIXME: #13996: need a way to mark the return value as `noalias` #[inline(never)] unsafe fn alloc_or_realloc(ptr: *mut T, old_size: uint, size: uint) -> *mut T { @@ -969,15 +959,107 @@ impl Vec { self.push(f(i)); } } -} -#[experimental = "waiting on Mutable stability"] -impl Mutable for Vec { + /// Appends an element to the back of a collection. + /// + /// # Failure + /// + /// Fails if the number of elements in the vector overflows a `uint`. + /// + /// # Example + /// + /// ```rust + /// let mut vec = vec!(1i, 2); + /// vec.push(3); + /// assert_eq!(vec, vec!(1, 2, 3)); + /// ``` + #[inline] + #[stable] + pub fn push(&mut self, value: T) { + if mem::size_of::() == 0 { + // zero-size types consume no memory, so we can't rely on the address space running out + self.len = self.len.checked_add(&1).expect("length overflow"); + unsafe { mem::forget(value); } + return + } + if self.len == self.cap { + let old_size = self.cap * mem::size_of::(); + let size = max(old_size, 2 * mem::size_of::()) * 2; + if old_size > size { panic!("capacity overflow") } + unsafe { + self.ptr = alloc_or_realloc(self.ptr, old_size, size); + } + self.cap = max(self.cap, 2) * 2; + } + + unsafe { + let end = (self.ptr as *const T).offset(self.len as int) as *mut T; + ptr::write(&mut *end, value); + self.len += 1; + } + } + + /// Removes the last element from a vector and returns it, or `None` if + /// it is empty. + /// + /// # Example + /// + /// ```rust + /// let mut vec = vec![1i, 2, 3]; + /// assert_eq!(vec.pop(), Some(3)); + /// assert_eq!(vec, vec![1, 2]); + /// ``` #[inline] #[stable] - fn clear(&mut self) { + pub fn pop(&mut self) -> Option { + if self.len == 0 { + None + } else { + unsafe { + self.len -= 1; + Some(ptr::read(self.as_slice().unsafe_get(self.len()))) + } + } + } + + /// Clears the vector, removing all values. + /// + /// # Example + /// + /// ``` + /// let mut v = vec![1i, 2, 3]; + /// v.clear(); + /// assert!(v.is_empty()); + /// ``` + #[inline] + #[stable] + pub fn clear(&mut self) { self.truncate(0) } + + /// Return the number of elements in the vector + /// + /// # Example + /// + /// ``` + /// let a = vec![1i, 2, 3]; + /// assert_eq!(a.len(), 3); + /// ``` + #[inline] + #[stable] + pub fn len(&self) -> uint { self.len } + + /// Returns true if the vector contains no elements + /// + /// # Example + /// + /// ``` + /// let mut v = Vec::new(); + /// assert!(v.is_empty()); + /// v.push(1i); + /// assert!(!v.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { self.len() == 0 } } impl Vec { @@ -1141,61 +1223,6 @@ impl fmt::Show for Vec { } } -#[experimental = "waiting on MutableSeq stability"] -impl MutableSeq for Vec { - /// Appends an element to the back of a collection. - /// - /// # Failure - /// - /// Fails if the number of elements in the vector overflows a `uint`. - /// - /// # Example - /// - /// ```rust - /// let mut vec = vec!(1i, 2); - /// vec.push(3); - /// assert_eq!(vec, vec!(1, 2, 3)); - /// ``` - #[inline] - #[stable] - fn push(&mut self, value: T) { - if mem::size_of::() == 0 { - // zero-size types consume no memory, so we can't rely on the address space running out - self.len = self.len.checked_add(&1).expect("length overflow"); - unsafe { mem::forget(value); } - return - } - if self.len == self.cap { - let old_size = self.cap * mem::size_of::(); - let size = max(old_size, 2 * mem::size_of::()) * 2; - if old_size > size { panic!("capacity overflow") } - unsafe { - self.ptr = alloc_or_realloc(self.ptr, old_size, size); - } - self.cap = max(self.cap, 2) * 2; - } - - unsafe { - let end = (self.ptr as *const T).offset(self.len as int) as *mut T; - ptr::write(&mut *end, value); - self.len += 1; - } - } - - #[inline] - #[stable] - fn pop(&mut self) -> Option { - if self.len == 0 { - None - } else { - unsafe { - self.len -= 1; - Some(ptr::read(self.as_slice().unsafe_get(self.len()))) - } - } - } -} - /// An iterator that moves out of a vector. pub struct MoveItems { allocation: *mut T, // the block of memory allocated for the vector @@ -1636,8 +1663,6 @@ mod tests { use test::Bencher; use super::{as_vec, unzip, raw, Vec}; - use MutableSeq; - struct DropCounter<'a> { count: &'a mut int } diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 5d9553cbbbd57..3b9f8f58a2054 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -18,7 +18,7 @@ use mem::transmute; use option::{None, Option, Some}; use iter::range_step; -use collections::Collection; +use slice::ImmutableSlice; // UTF-8 ranges and tags for encoding characters static TAG_CONT: u8 = 0b1000_0000u8; diff --git a/src/libcore/collections.rs b/src/libcore/collections.rs deleted file mode 100644 index 7d87e03c13410..0000000000000 --- a/src/libcore/collections.rs +++ /dev/null @@ -1,38 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Traits for generic collections - -/// A trait to represent the abstract idea of a container. The only concrete -/// knowledge known is the number of elements contained within. -pub trait Collection { - /// Return the number of elements in the container - /// - /// # Example - /// - /// ``` - /// let a = [1i, 2, 3]; - /// assert_eq!(a.len(), 3); - /// ``` - fn len(&self) -> uint; - - /// Return true if the container contains no elements - /// - /// # Example - /// - /// ``` - /// let s = String::new(); - /// assert!(s.is_empty()); - /// ``` - #[inline] - fn is_empty(&self) -> bool { - self.len() == 0 - } -} diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index b8a91a912ba3c..f51d3948757c7 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -11,14 +11,12 @@ #![allow(missing_docs)] use char; -use collections::Collection; use fmt; use iter::{range, DoubleEndedIterator}; use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive}; use num::{Zero, One, cast}; use result::Ok; -use slice::MutableSlice; -use slice; +use slice::{mod, ImmutableSlice, MutableSlice}; use str::StrSlice; /// A flag that specifies whether to use exponential (scientific) notation. diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 5000b020985e5..74b39a7058c0a 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -14,7 +14,6 @@ use any; use cell::{Cell, Ref, RefMut}; -use collections::Collection; use iter::{Iterator, range}; use kinds::{Copy, Sized}; use mem; diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 568528f6ae29e..190e1ecea5921 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -14,11 +14,10 @@ #![allow(unsigned_negation)] -use collections::Collection; use fmt; use iter::DoubleEndedIterator; use num::{Int, cast, zero}; -use slice::{MutableSlice}; +use slice::{ImmutableSlice, MutableSlice}; /// A type that represents a specific radix #[doc(hidden)] diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index e2a4fdfe79bf1..39b319e6ac867 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2155,7 +2155,7 @@ type IterateState<'a, T> = (|T|: 'a -> T, Option, bool); /// from a given seed value. pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>; -/// Creates a new iterator that produces an infinite sequence of +/// Create a new iterator that produces an infinite sequence of /// repeated applications of the given function `f`. pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> { Unfold::new((f, Some(seed), true), |st| { @@ -2174,6 +2174,11 @@ pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> { }) } +/// Create a new iterator that endlessly repeats the element `elt`. +pub fn repeat(elt: T) -> Repeat { + Repeat::new(elt) +} + /// Functions for lexicographical ordering of sequences. /// /// Lexicographical ordering through `<`, `<=`, `>=`, `>` requires diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a7be23e53e074..7c5c54c6d8abc 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -102,7 +102,6 @@ pub mod ops; pub mod cmp; pub mod clone; pub mod default; -pub mod collections; /* Core types and methods on primitives */ diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 680f91945d103..bc734c7f2ddcb 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -41,7 +41,7 @@ pub use option::{Option, Some, None}; pub use result::{Result, Ok, Err}; // Reexported functions -pub use iter::range; +pub use iter::{range, repeat}; pub use mem::drop; // Reexported types and traits @@ -50,7 +50,6 @@ pub use char::Char; pub use clone::Clone; pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; pub use cmp::{Ordering, Less, Equal, Greater, Equiv}; -pub use collections::Collection; pub use iter::{FromIterator, Extendable}; pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator}; pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize}; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index dd51534d31981..317a6e224bce9 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -36,7 +36,6 @@ use mem::transmute; use clone::Clone; -use collections::Collection; use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Less, Equal, Greater, Equiv}; use cmp; use default::Default; @@ -234,6 +233,29 @@ pub trait ImmutableSlice for Sized? { /// ``` #[unstable = "waiting on unboxed closures"] fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult; + + /// Return the number of elements in the slice + /// + /// # Example + /// + /// ``` + /// let a = [1i, 2, 3]; + /// assert_eq!(a.len(), 3); + /// ``` + #[experimental = "not triaged yet"] + fn len(&self) -> uint; + + /// Returns true if the slice has a length of 0 + /// + /// # Example + /// + /// ``` + /// let a = [1i, 2, 3]; + /// assert!(!a.is_empty()); + /// ``` + #[inline] + #[experimental = "not triaged yet"] + fn is_empty(&self) -> bool { self.len() == 0 } } #[unstable] @@ -372,6 +394,9 @@ impl ImmutableSlice for [T] { } return NotFound(base); } + + #[inline] + fn len(&self) -> uint { self.repr().len } } @@ -886,24 +911,6 @@ impl<'a,T> AsSlice for &'a [T] { fn as_slice<'a>(&'a self) -> &'a [T] { *self } } -#[experimental = "trait is experimental"] -impl<'a, T> Collection for &'a [T] { - /// Returns the length of a slice. - #[inline] - fn len(&self) -> uint { - self.repr().len - } -} - -#[experimental = "trait is experimental"] -impl<'a, T> Collection for &'a mut [T] { - /// Returns the length of a slice. - #[inline] - fn len(&self) -> uint { - self.repr().len - } -} - #[unstable = "waiting for DST"] impl<'a, T> Default for &'a [T] { fn default() -> &'a [T] { &[] } @@ -1508,7 +1515,6 @@ pub mod raw { /// Operations on `[u8]`. #[experimental = "needs review"] pub mod bytes { - use collections::Collection; use kinds::Sized; use ptr; use slice::{ImmutableSlice, MutableSlice}; diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 86bbef861c4ce..3b29c25787292 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -22,7 +22,6 @@ use char::Char; use clone::Clone; use cmp; use cmp::{PartialEq, Eq}; -use collections::Collection; use default::Default; use iter::{Map, Iterator}; use iter::{DoubleEndedIterator, ExactSize}; @@ -1057,7 +1056,6 @@ const TAG_CONT_U8: u8 = 0b1000_0000u8; /// Unsafe operations pub mod raw { use mem; - use collections::Collection; use ptr::RawPtr; use raw::Slice; use slice::{ImmutableSlice}; @@ -1121,7 +1119,6 @@ Section: Trait implementations #[allow(missing_docs)] pub mod traits { use cmp::{Ord, Ordering, Less, Equal, Greater, PartialEq, PartialOrd, Equiv, Eq}; - use collections::Collection; use iter::Iterator; use option::{Option, Some}; use ops; @@ -1199,13 +1196,6 @@ impl<'a> Str for &'a str { fn as_slice<'a>(&'a self) -> &'a str { *self } } -impl<'a> Collection for &'a str { - #[inline] - fn len(&self) -> uint { - self.repr().len - } -} - /// Methods for string slices pub trait StrSlice for Sized? { /// Returns true if one string contains another @@ -1536,7 +1526,7 @@ pub trait StrSlice for Sized? { /// ``` fn ends_with(&self, needle: &str) -> bool; - /// Returns a string with characters that match `to_trim` removed. + /// Returns a string with characters that match `to_trim` removed from the left and the right. /// /// # Arguments /// @@ -1827,6 +1817,28 @@ pub trait StrSlice for Sized? { /// Return an iterator of `u16` over the string encoded as UTF-16. fn utf16_units<'a>(&'a self) -> Utf16CodeUnits<'a>; + + /// Return the number of bytes in this string + /// + /// # Example + /// + /// ``` + /// assert_eq!("foo".len(), 3); + /// assert_eq!("Æ’oo".len(), 4); + /// ``` + #[experimental = "not triaged yet"] + fn len(&self) -> uint; + + /// Returns true if this slice contains no bytes + /// + /// # Example + /// + /// ``` + /// assert!("".is_empty()); + /// ``` + #[inline] + #[experimental = "not triaged yet"] + fn is_empty(&self) -> bool { self.len() == 0 } } #[inline(never)] @@ -2179,6 +2191,9 @@ impl StrSlice for str { fn utf16_units(&self) -> Utf16CodeUnits { Utf16CodeUnits{ chars: self.chars(), extra: 0} } + + #[inline] + fn len(&self) -> uint { self.repr().len } } impl<'a> Default for &'a str { diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 98db377b0d576..5d333d48e96d4 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -846,6 +846,14 @@ fn test_iterate() { assert_eq!(it.next(), Some(8u)); } +#[test] +fn test_repeat() { + let mut it = repeat(42u); + assert_eq!(it.next(), Some(42u)); + assert_eq!(it.next(), Some(42u)); + assert_eq!(it.next(), Some(42u)); +} + #[bench] fn bench_rposition(b: &mut Bencher) { let it: Vec = range(0u, 300).collect(); diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs index a4d794d1f99fb..d465d1407513b 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::collections::Collection; use std::default::Default; use std::fmt; use std::iter::FromIterator; @@ -62,6 +61,10 @@ impl<'a,T> MaybeOwnedVector<'a,T> { &Borrowed(ref v) => v.iter(), } } + + pub fn len(&self) -> uint { self.as_slice().len() } + + pub fn is_empty(&self) -> bool { self.len() == 0 } } impl<'a, T: PartialEq> PartialEq for MaybeOwnedVector<'a, T> { @@ -145,12 +148,6 @@ impl<'a, T> Default for MaybeOwnedVector<'a, T> { } } -impl<'a, T> Collection for MaybeOwnedVector<'a, T> { - fn len(&self) -> uint { - self.as_slice().len() - } -} - impl<'a> BytesContainer for MaybeOwnedVector<'a, u8> { fn container_as_bytes<'a>(&'a self) -> &'a [u8] { self.as_slice() diff --git a/src/libregex/re.rs b/src/libregex/re.rs index 08d73d3434fca..df5bfccd18d63 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -772,14 +772,14 @@ impl<'t> Captures<'t> { let re = Regex::new(r"\$\$").unwrap(); re.replace_all(text.as_slice(), NoExpand("$")) } -} -impl<'t> Collection for Captures<'t> { /// Returns the number of captured groups. #[inline] - fn len(&self) -> uint { - self.locs.len() / 2 - } + pub fn len(&self) -> uint { self.locs.len() / 2 } + + /// Returns if there are no captured groups. + #[inline] + pub fn is_empty(&self) -> bool { self.len() == 0 } } /// An iterator over capture groups for a particular match of a regular diff --git a/src/librlibc/lib.rs b/src/librlibc/lib.rs index ca7ce2a8b7153..dd88eb3251b63 100644 --- a/src/librlibc/lib.rs +++ b/src/librlibc/lib.rs @@ -108,7 +108,6 @@ pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: uint) -> i32 { #[cfg(test)] mod test { - use core::collections::Collection; use core::str::StrSlice; use core::slice::{MutableSlice, ImmutableSlice}; diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index ace5ba26fdbaa..efe7de6b94dfc 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -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; @@ -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>, + pub libs: Vec<(String, cstore::NativeLibaryKind)>, pub maybe_sysroot: Option, 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 { 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, } } diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 55e07321c7101..f8e778ce15f6a 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -231,7 +231,7 @@ pub fn build_session_(sopts: config::Options, if path.is_absolute() { path.clone() } else { - os::getcwd().join(path.clone()) + os::getcwd().join(&path) } ); diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 92b2382ae64f4..775b0e777d412 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -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, 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 { let mut ret = None; diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 507aaf137cdf5..93227322c5be8 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -15,6 +15,7 @@ use metadata::common::*; use metadata::cstore; use metadata::decoder; +use middle::def; use middle::lang_items; use middle::resolve; use middle::ty; @@ -115,6 +116,12 @@ pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId, decoder::maybe_get_item_ast(&*cdata, tcx, def.node, decode_inlined_item) } +pub fn get_enum_variant_defs(cstore: &cstore::CStore, enum_id: ast::DefId) + -> Vec<(def::Def, ast::Name, ast::Visibility)> { + let cdata = cstore.get_crate_data(enum_id.krate); + decoder::get_enum_variant_defs(&*cstore.intr, &*cdata, enum_id.node) +} + pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId) -> Vec> { let cstore = &tcx.sess.cstore; diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 1d1012d9e4f04..e8c5f6f4910e0 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -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 diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 22ebaa40eb20b..d0715da1c8e65 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -662,6 +662,24 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI } } +pub fn get_enum_variant_defs(intr: &IdentInterner, + cdata: Cmd, + id: ast::NodeId) + -> Vec<(def::Def, ast::Name, ast::Visibility)> { + let data = cdata.data(); + let items = reader::get_doc(rbml::Doc::new(data), tag_items); + let item = find_item(id, items); + enum_variant_ids(item, cdata).iter().map(|did| { + let item = find_item(did.node, items); + let name = item_name(intr, item); + let visibility = item_visibility(item); + match item_to_def_like(item, *did, cdata.cnum) { + DlDef(def @ def::DefVariant(..)) => (def, name, visibility), + _ => unreachable!() + } + }).collect() +} + pub fn get_enum_variants(intr: Rc, cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> Vec> { let data = cdata.data(); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 383a60e51da7b..67dfe2b27456c 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -492,6 +492,7 @@ enum ModuleKind { NormalModuleKind, TraitModuleKind, ImplModuleKind, + EnumModuleKind, AnonymousModuleKind, } @@ -568,10 +569,19 @@ impl Module { } } +bitflags! { + #[deriving(Show)] + flags DefModifiers: u8 { + const PUBLIC = 0b0000_0001, + const IMPORTABLE = 0b0000_0010, + const ENUM_STAGING_HACK = 0b0000_0100, + } +} + // Records a possibly-private type definition. #[deriving(Clone)] struct TypeNsDef { - is_public: bool, // see note in ImportResolution about how to use this + modifiers: DefModifiers, // see note in ImportResolution about how to use this module_def: Option>, type_def: Option, type_span: Option @@ -580,7 +590,7 @@ struct TypeNsDef { // Records a possibly-private value definition. #[deriving(Clone, Show)] struct ValueNsDef { - is_public: bool, // see note in ImportResolution about how to use this + modifiers: DefModifiers, // see note in ImportResolution about how to use this def: Def, value_span: Option, } @@ -616,13 +626,14 @@ impl NameBindings { is_public: bool, sp: Span) { // Merges the module with the existing type def or creates a new one. + let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE; let module_ = Rc::new(Module::new(parent_link, def_id, kind, external, is_public)); let type_def = self.type_def.borrow().clone(); match type_def { None => { *self.type_def.borrow_mut() = Some(TypeNsDef { - is_public: is_public, + modifiers: modifiers, module_def: Some(module_), type_def: None, type_span: Some(sp) @@ -630,7 +641,7 @@ impl NameBindings { } Some(type_def) => { *self.type_def.borrow_mut() = Some(TypeNsDef { - is_public: is_public, + modifiers: modifiers, module_def: Some(module_), type_span: Some(sp), type_def: type_def.type_def @@ -647,13 +658,14 @@ impl NameBindings { external: bool, is_public: bool, _sp: Span) { + let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE; let type_def = self.type_def.borrow().clone(); match type_def { None => { let module = Module::new(parent_link, def_id, kind, external, is_public); *self.type_def.borrow_mut() = Some(TypeNsDef { - is_public: is_public, + modifiers: modifiers, module_def: Some(Rc::new(module)), type_def: None, type_span: None, @@ -668,7 +680,7 @@ impl NameBindings { external, is_public); *self.type_def.borrow_mut() = Some(TypeNsDef { - is_public: is_public, + modifiers: modifiers, module_def: Some(Rc::new(module)), type_def: type_def.type_def, type_span: None, @@ -681,7 +693,8 @@ impl NameBindings { } /// Records a type definition. - fn define_type(&self, def: Def, sp: Span, is_public: bool) { + fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) { + debug!("defining type for def {} with modifiers {}", def, modifiers); // Merges the type with the existing type def or creates a new one. let type_def = self.type_def.borrow().clone(); match type_def { @@ -690,7 +703,7 @@ impl NameBindings { module_def: None, type_def: Some(def), type_span: Some(sp), - is_public: is_public, + modifiers: modifiers, }); } Some(type_def) => { @@ -698,18 +711,19 @@ impl NameBindings { type_def: Some(def), type_span: Some(sp), module_def: type_def.module_def, - is_public: is_public, + modifiers: modifiers, }); } } } /// Records a value definition. - fn define_value(&self, def: Def, sp: Span, is_public: bool) { + fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) { + debug!("defining value for def {} with modifiers {}", def, modifiers); *self.value_def.borrow_mut() = Some(ValueNsDef { def: def, value_span: Some(sp), - is_public: is_public, + modifiers: modifiers, }); } @@ -743,12 +757,16 @@ impl NameBindings { } fn defined_in_public_namespace(&self, namespace: Namespace) -> bool { + self.defined_in_namespace_with(namespace, PUBLIC) + } + + fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool { match namespace { TypeNS => match *self.type_def.borrow() { - Some(ref def) => def.is_public, None => false + Some(ref def) => def.modifiers.contains(modifiers), None => false }, ValueNS => match *self.value_def.borrow() { - Some(ref def) => def.is_public, None => false + Some(ref def) => def.modifiers.contains(modifiers), None => false } } } @@ -1214,6 +1232,7 @@ impl<'a> Resolver<'a> { let name = item.ident.name; let sp = item.span; let is_public = item.vis == ast::Public; + let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE; match item.node { ItemMod(..) => { @@ -1241,13 +1260,13 @@ impl<'a> Resolver<'a> { let mutbl = m == ast::MutMutable; name_bindings.define_value - (DefStatic(local_def(item.id), mutbl), sp, is_public); + (DefStatic(local_def(item.id), mutbl), sp, modifiers); parent } ItemConst(_, _) => { self.add_child(name, parent.clone(), ForbidDuplicateValues, sp) .define_value(DefConst(local_def(item.id)), - sp, is_public); + sp, modifiers); parent } ItemFn(_, fn_style, _, _, _) => { @@ -1255,7 +1274,7 @@ impl<'a> Resolver<'a> { self.add_child(name, parent.clone(), ForbidDuplicateValues, sp); let def = DefFn(local_def(item.id), fn_style, false); - name_bindings.define_value(def, sp, is_public); + name_bindings.define_value(def, sp, modifiers); parent } @@ -1268,7 +1287,7 @@ impl<'a> Resolver<'a> { sp); name_bindings.define_type - (DefTy(local_def(item.id), false), sp, is_public); + (DefTy(local_def(item.id), false), sp, modifiers); parent } @@ -1280,14 +1299,32 @@ impl<'a> Resolver<'a> { sp); name_bindings.define_type - (DefTy(local_def(item.id), true), sp, is_public); + (DefTy(local_def(item.id), true), sp, modifiers); + + let parent_link = self.get_parent_link(parent.clone(), name); + // We want to make sure the module type is EnumModuleKind + // even if there's already an ImplModuleKind module defined, + // since that's how we prevent duplicate enum definitions + name_bindings.set_module_kind(parent_link, + Some(local_def(item.id)), + EnumModuleKind, + false, + is_public, + sp); for variant in (*enum_definition).variants.iter() { + self.build_reduced_graph_for_variant( + &**variant, + local_def(item.id), + ModuleReducedGraphParent(name_bindings.get_module()), + modifiers); + + // Temporary staging hack self.build_reduced_graph_for_variant( &**variant, local_def(item.id), parent.clone(), - is_public); + modifiers | ENUM_STAGING_HACK); } parent } @@ -1303,14 +1340,14 @@ impl<'a> Resolver<'a> { let name_bindings = self.add_child(name, parent.clone(), forbid, sp); // Define a name in the type namespace. - name_bindings.define_type(DefTy(local_def(item.id), false), sp, is_public); + name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers); // If this is a newtype or unit-like struct, define a name // in the value namespace as well match ctor_id { Some(cid) => { name_bindings.define_value(DefStruct(local_def(cid)), - sp, is_public); + sp, modifiers); } None => {} } @@ -1347,6 +1384,12 @@ impl<'a> Resolver<'a> { ImplModuleKind => { ModuleReducedGraphParent(child.get_module()) } + Some(ref child) if child.get_module_if_available() + .is_some() && + child.get_module().kind.get() == + EnumModuleKind => { + ModuleReducedGraphParent(child.get_module()) + } // Create the module _ => { let name_bindings = @@ -1404,12 +1447,16 @@ impl<'a> Resolver<'a> { } }; - let is_public = - method.pe_vis() == ast::Public; + // NB: not IMPORTABLE + let modifiers = if method.pe_vis() == ast::Public { + PUBLIC + } else { + DefModifiers::empty() + }; method_name_bindings.define_value( def, method.span, - is_public); + modifiers); } TypeImplItem(ref typedef) => { // Add the typedef to the module. @@ -1422,12 +1469,16 @@ impl<'a> Resolver<'a> { typedef.span); let def = DefAssociatedTy(local_def( typedef.id)); - let is_public = typedef.vis == - ast::Public; + // NB: not IMPORTABLE + let modifiers = if typedef.vis == ast::Public { + PUBLIC + } else { + DefModifiers::empty() + }; typedef_name_bindings.define_type( def, typedef.span, - is_public); + modifiers); } } } @@ -1501,9 +1552,10 @@ impl<'a> Resolver<'a> { module_parent.clone(), ForbidDuplicateTypesAndValues, ty_m.span); + // NB: not IMPORTABLE method_name_bindings.define_value(def, ty_m.span, - true); + PUBLIC); (name, static_flag) } @@ -1516,9 +1568,10 @@ impl<'a> Resolver<'a> { module_parent.clone(), ForbidDuplicateTypesAndValues, associated_type.span); + // NB: not IMPORTABLE name_bindings.define_type(def, associated_type.span, - true); + PUBLIC); (associated_type.ident.name, TypeTraitItemKind) } @@ -1527,7 +1580,7 @@ impl<'a> Resolver<'a> { self.trait_item_map.insert((name, def_id), kind); } - name_bindings.define_type(DefTrait(def_id), sp, is_public); + name_bindings.define_type(DefTrait(def_id), sp, modifiers); parent } ItemMac(..) => parent @@ -1540,7 +1593,7 @@ impl<'a> Resolver<'a> { variant: &Variant, item_id: DefId, parent: ReducedGraphParent, - is_public: bool) { + modifiers: DefModifiers) { let name = variant.node.name.name; let is_exported = match variant.node.kind { TupleVariantKind(_) => false, @@ -1556,10 +1609,10 @@ impl<'a> Resolver<'a> { variant.span); child.define_value(DefVariant(item_id, local_def(variant.node.id), is_exported), - variant.span, is_public); + variant.span, modifiers); child.define_type(DefVariant(item_id, local_def(variant.node.id), is_exported), - variant.span, is_public); + variant.span, modifiers); } /// Constructs the reduced graph for one 'view item'. View items consist @@ -1705,6 +1758,7 @@ impl<'a> Resolver<'a> { f: |&mut Resolver|) { let name = foreign_item.ident.name; let is_public = foreign_item.vis == ast::Public; + let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE; let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, foreign_item.span); @@ -1712,7 +1766,7 @@ impl<'a> Resolver<'a> { match foreign_item.node { ForeignItemFn(_, ref generics) => { let def = DefFn(local_def(foreign_item.id), UnsafeFn, false); - name_bindings.define_value(def, foreign_item.span, is_public); + name_bindings.define_value(def, foreign_item.span, modifiers); self.with_type_parameter_rib( HasTypeParameters(generics, @@ -1723,7 +1777,7 @@ impl<'a> Resolver<'a> { } ForeignItemStatic(_, m) => { let def = DefStatic(local_def(foreign_item.id), m); - name_bindings.define_value(def, foreign_item.span, is_public); + name_bindings.define_value(def, foreign_item.span, modifiers); f(self) } @@ -1768,6 +1822,7 @@ impl<'a> Resolver<'a> { external crate) building external def, priv {}", vis); let is_public = vis == ast::Public; + let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE; let is_exported = is_public && match new_parent { ModuleReducedGraphParent(ref module) => { match module.def_id.get() { @@ -1781,6 +1836,7 @@ impl<'a> Resolver<'a> { } let kind = match def { + DefTy(_, true) => EnumModuleKind, DefStruct(..) | DefTy(..) => ImplModuleKind, _ => NormalModuleKind }; @@ -1815,6 +1871,7 @@ impl<'a> Resolver<'a> { match def { DefMod(_) | DefForeignMod(_) => {} + // Still here for staging DefVariant(enum_did, variant_id, is_struct) => { debug!("(building reduced graph for external crate) building \ variant {}", @@ -1824,23 +1881,36 @@ impl<'a> Resolver<'a> { // definition. let is_exported = is_public || self.external_exports.contains(&enum_did); + let modifiers = IMPORTABLE | ENUM_STAGING_HACK | if is_exported { + PUBLIC + } else { + DefModifiers::empty() + }; if is_struct { - child_name_bindings.define_type(def, DUMMY_SP, is_exported); + child_name_bindings.define_type(def, DUMMY_SP, modifiers); // Not adding fields for variants as they are not accessed with a self receiver self.structs.insert(variant_id, Vec::new()); } else { - child_name_bindings.define_value(def, DUMMY_SP, is_exported); + child_name_bindings.define_value(def, DUMMY_SP, modifiers); } } DefFn(ctor_id, _, true) => { child_name_bindings.define_value( csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id) - .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, is_public); + .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers); } DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) => { debug!("(building reduced graph for external \ crate) building value (fn/static) {}", final_ident); - child_name_bindings.define_value(def, DUMMY_SP, is_public); + // impl methods have already been defined with the correct importability modifier + let mut modifiers = match *child_name_bindings.value_def.borrow() { + Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE), + None => modifiers + }; + if new_parent.module().kind.get() != NormalModuleKind { + modifiers = modifiers & !IMPORTABLE; + } + child_name_bindings.define_value(def, DUMMY_SP, modifiers); } DefTrait(def_id) => { debug!("(building reduced graph for external \ @@ -1869,7 +1939,7 @@ impl<'a> Resolver<'a> { } } - child_name_bindings.define_type(def, DUMMY_SP, is_public); + child_name_bindings.define_type(def, DUMMY_SP, modifiers); // Define a module if necessary. let parent_link = self.get_parent_link(new_parent, name); @@ -1880,23 +1950,57 @@ impl<'a> Resolver<'a> { is_public, DUMMY_SP) } + DefTy(def_id, true) => { // enums + debug!("(building reduced graph for external crate) building enum {}", final_ident); + child_name_bindings.define_type(def, DUMMY_SP, modifiers); + let enum_module = ModuleReducedGraphParent(child_name_bindings.get_module()); + + let variants = csearch::get_enum_variant_defs(&self.session.cstore, def_id); + for &(v_def, name, vis) in variants.iter() { + let (variant_id, is_struct) = match v_def { + DefVariant(_, variant_id, is_struct) => (variant_id, is_struct), + _ => unreachable!() + }; + let child = self.add_child(name, enum_module.clone(), + OverwriteDuplicates, + DUMMY_SP); + + // If this variant is public, then it was publicly reexported, + // otherwise we need to inherit the visibility of the enum + // definition. + let variant_exported = vis == ast::Public || is_exported; + let modifiers = IMPORTABLE | if variant_exported { + PUBLIC + } else { + DefModifiers::empty() + }; + if is_struct { + child.define_type(v_def, DUMMY_SP, modifiers); + // Not adding fields for variants as they are not accessed with a self + // receiver + self.structs.insert(variant_id, Vec::new()); + } else { + child.define_value(v_def, DUMMY_SP, modifiers); + } + } + } DefTy(..) | DefAssociatedTy(..) => { debug!("(building reduced graph for external \ crate) building type {}", final_ident); - child_name_bindings.define_type(def, DUMMY_SP, is_public); + child_name_bindings.define_type(def, DUMMY_SP, modifiers); } DefStruct(def_id) => { debug!("(building reduced graph for external \ crate) building type and value for {}", final_ident); - child_name_bindings.define_type(def, DUMMY_SP, is_public); + child_name_bindings.define_type(def, DUMMY_SP, modifiers); let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| { f.name }).collect::>(); if fields.len() == 0 { - child_name_bindings.define_value(def, DUMMY_SP, is_public); + child_name_bindings.define_value(def, DUMMY_SP, modifiers); } // Record the def ID and fields of this struct. @@ -2033,9 +2137,14 @@ impl<'a> Resolver<'a> { static_method_info.fn_style, false); + // NB: not IMPORTABLE + let modifiers = if visibility == ast::Public { + PUBLIC + } else { + DefModifiers::empty() + }; method_name_bindings.define_value( - def, DUMMY_SP, - visibility == ast::Public); + def, DUMMY_SP, modifiers); } } @@ -2406,7 +2515,7 @@ impl<'a> Resolver<'a> { fn create_name_bindings_from_module(module: Rc) -> NameBindings { NameBindings { type_def: RefCell::new(Some(TypeNsDef { - is_public: false, + modifiers: IMPORTABLE, module_def: Some(module), type_def: None, type_span: None @@ -2608,6 +2717,12 @@ impl<'a> Resolver<'a> { target, ValueNS); + self.check_that_import_is_importable( + &**name_bindings, + directive.span, + target, + ValueNS); + import_resolution.value_target = Some(Target::new(target_module.clone(), name_bindings.clone(), @@ -2631,6 +2746,12 @@ impl<'a> Resolver<'a> { target, TypeNS); + self.check_that_import_is_importable( + &**name_bindings, + directive.span, + target, + TypeNS); + import_resolution.type_target = Some(Target::new(target_module.clone(), name_bindings.clone(), @@ -2841,7 +2962,7 @@ impl<'a> Resolver<'a> { self.module_to_string(module_)); // Merge the child item into the import resolution. - if name_bindings.defined_in_public_namespace(ValueNS) { + if name_bindings.defined_in_namespace_with(ValueNS, IMPORTABLE | PUBLIC) { debug!("(resolving glob import) ... for value target"); dest_import_resolution.value_target = Some(Target::new(containing_module.clone(), @@ -2849,7 +2970,7 @@ impl<'a> Resolver<'a> { import_directive.shadowable)); dest_import_resolution.value_id = id; } - if name_bindings.defined_in_public_namespace(TypeNS) { + if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) { debug!("(resolving glob import) ... for type target"); dest_import_resolution.type_target = Some(Target::new(containing_module, @@ -2891,6 +3012,19 @@ impl<'a> Resolver<'a> { } } + /// Checks that an import is actually importable + fn check_that_import_is_importable(&mut self, + name_bindings: &NameBindings, + import_span: Span, + name: Name, + namespace: Namespace) { + if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) { + let msg = format!("`{}` is not directly importable", + token::get_name(name)); + self.session.span_err(import_span, msg.as_slice()); + } + } + /// Checks that imported names and items don't have the same name. fn check_for_conflicts_between_imports_and_items(&mut self, module: &Module, @@ -2930,8 +3064,8 @@ impl<'a> Resolver<'a> { match import_resolution.value_target { Some(ref target) if !target.shadowable => { match *name_bindings.value_def.borrow() { - None => {} - Some(ref value) => { + // We want to allow the "flat" def of enum variants to be shadowed + Some(ref value) if !value.modifiers.contains(ENUM_STAGING_HACK) => { let msg = format!("import `{}` conflicts with value \ in this module", token::get_name(name).get()); @@ -2945,6 +3079,7 @@ impl<'a> Resolver<'a> { } } } + _ => {} } } Some(_) | None => {} @@ -2953,8 +3088,8 @@ impl<'a> Resolver<'a> { match import_resolution.type_target { Some(ref target) if !target.shadowable => { match *name_bindings.type_def.borrow() { - None => {} - Some(ref ty) => { + // We want to allow the "flat" def of enum variants to be shadowed + Some(ref ty) if !ty.modifiers.contains(ENUM_STAGING_HACK) => { match ty.module_def { None => { let msg = format!("import `{}` conflicts with type in \ @@ -3005,6 +3140,7 @@ impl<'a> Resolver<'a> { } } } + _ => {} } } Some(_) | None => {} @@ -3143,43 +3279,28 @@ impl<'a> Resolver<'a> { return Failed(Some((span, msg))); } Some(ref module_def) => { - // If we're doing the search for an - // import, do not allow traits and impls - // to be selected. - match (name_search_type, - module_def.kind.get()) { - (ImportSearch, TraitModuleKind) | - (ImportSearch, ImplModuleKind) => { - let msg = - "Cannot import from a trait or \ - type implementation".to_string(); - return Failed(Some((span, msg))); + search_module = module_def.clone(); + + // track extern crates for unused_extern_crate lint + match module_def.def_id.get() { + Some(did) => { + self.used_crates.insert(did.krate); } - (_, _) => { - search_module = module_def.clone(); - - // track extern crates for unused_extern_crates lint - match module_def.def_id.get() { - Some(did) => { - self.used_crates.insert(did.krate); - } - _ => {} - } + _ => {} + } - // Keep track of the closest - // private module used when - // resolving this import chain. - if !used_proxy && - !search_module.is_public { - match search_module.def_id - .get() { - Some(did) => { - closest_private = - LastMod(DependsOn(did)); - } - None => {} - } + // Keep track of the closest + // private module used when + // resolving this import chain. + if !used_proxy && + !search_module.is_public { + match search_module.def_id + .get() { + Some(did) => { + closest_private = + LastMod(DependsOn(did)); } + None => {} } } } @@ -3400,6 +3521,7 @@ impl<'a> Resolver<'a> { } TraitModuleKind | ImplModuleKind | + EnumModuleKind | AnonymousModuleKind => { search_module = parent_module_node.upgrade().unwrap(); } @@ -3497,6 +3619,7 @@ impl<'a> Resolver<'a> { NormalModuleKind => return Some(new_module), TraitModuleKind | ImplModuleKind | + EnumModuleKind | AnonymousModuleKind => module_ = new_module, } } @@ -3512,6 +3635,7 @@ impl<'a> Resolver<'a> { NormalModuleKind => return module_, TraitModuleKind | ImplModuleKind | + EnumModuleKind | AnonymousModuleKind => { match self.get_nearest_normal_module_parent(module_.clone()) { None => module_, diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 98d02dfb8d7a8..7dbddd3f5df33 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -45,7 +45,6 @@ #![allow(unsigned_negation)] -use std::collections::Map; use std::num::Int; use std::rc::Rc; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index ed38f6f871d79..cf807cb22bc2a 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -184,8 +184,8 @@ pub fn can_reach,T:Eq+Clone+Hash>( /// } /// ``` #[inline(always)] -pub fn memoized>( - cache: &RefCell, +pub fn memoized + Eq, U: Clone, S, H: Hasher>( + cache: &RefCell>, arg: T, f: |T| -> U ) -> U { @@ -193,8 +193,8 @@ pub fn memoized>( } #[inline(always)] -pub fn memoized_with_key>( - cache: &RefCell, +pub fn memoized_with_key + Eq, U: Clone, S, H: Hasher>( + cache: &RefCell>, arg: T, f: |T| -> U, k: |&T| -> K diff --git a/src/librustrt/at_exit_imp.rs b/src/librustrt/at_exit_imp.rs index c54afb241aebb..ce27decb136c0 100644 --- a/src/librustrt/at_exit_imp.rs +++ b/src/librustrt/at_exit_imp.rs @@ -15,7 +15,6 @@ use core::prelude::*; use alloc::boxed::Box; -use collections::MutableSeq; use collections::vec::Vec; use core::atomic; use core::mem; diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index ddb4df4fdc538..6a2e09c3ac6db 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -74,9 +74,9 @@ fn main() { use collections::string::String; use collections::hash; use core::fmt; -use core::kinds::marker; +use core::kinds::{Sized, marker}; use core::mem; -use core::prelude::{Clone, Collection, Drop, Eq, ImmutableSlice, Iterator}; +use core::prelude::{Clone, Drop, Eq, ImmutableSlice, Iterator}; use core::prelude::{MutableSlice, None, Option, Ordering, PartialEq}; use core::prelude::{PartialOrd, RawPtr, Some, StrSlice, range}; use core::ptr; @@ -259,6 +259,16 @@ impl CString { self.buf } + /// Return the number of bytes in the CString (not including the NUL + /// terminator). + #[inline] + pub fn len(&self) -> uint { + unsafe { libc::strlen(self.buf) as uint } + } + + /// Returns if there are no bytes in this string + #[inline] + pub fn is_empty(&self) -> bool { self.len() == 0 } } impl Drop for CString { @@ -271,14 +281,6 @@ impl Drop for CString { } } -impl Collection for CString { - /// Return the number of bytes in the CString (not including the NUL terminator). - #[inline] - fn len(&self) -> uint { - unsafe { libc::strlen(self.buf) as uint } - } -} - impl fmt::Show for CString { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { String::from_utf8_lossy(self.as_bytes_no_nul()).fmt(f) @@ -286,7 +288,7 @@ impl fmt::Show for CString { } /// A generic trait for converting a value to a CString. -pub trait ToCStr { +pub trait ToCStr for Sized? { /// Copy the receiver into a CString. /// /// # Failure @@ -329,15 +331,7 @@ pub trait ToCStr { } } -// FIXME (#12938): Until DST lands, we cannot decompose &str into & -// and str, so we cannot usefully take ToCStr arguments by reference -// (without forcing an additional & around &str). So we are instead -// temporarily adding an instance for ~str and String, so that we can -// take ToCStr as owned. When DST lands, the string instances should -// be revisited, and arguments bound by ToCStr should be passed by -// reference. - -impl<'a> ToCStr for &'a str { +impl ToCStr for str { #[inline] fn to_c_str(&self) -> CString { self.as_bytes().to_c_str() @@ -384,10 +378,10 @@ impl ToCStr for String { // The length of the stack allocated buffer for `vec.with_c_str()` const BUF_LEN: uint = 128; -impl<'a> ToCStr for &'a [u8] { +impl ToCStr for [u8] { fn to_c_str(&self) -> CString { let mut cs = unsafe { self.to_c_str_unchecked() }; - check_for_null(*self, cs.as_mut_ptr()); + check_for_null(self, cs.as_mut_ptr()); cs } @@ -403,11 +397,33 @@ impl<'a> ToCStr for &'a [u8] { } fn with_c_str(&self, f: |*const libc::c_char| -> T) -> T { - unsafe { with_c_str(*self, true, f) } + unsafe { with_c_str(self, true, f) } + } + + unsafe fn with_c_str_unchecked(&self, f: |*const libc::c_char| -> T) -> T { + with_c_str(self, false, f) + } +} + +impl<'a, Sized? T: ToCStr> ToCStr for &'a T { + #[inline] + fn to_c_str(&self) -> CString { + (**self).to_c_str() + } + + #[inline] + unsafe fn to_c_str_unchecked(&self) -> CString { + (**self).to_c_str_unchecked() + } + + #[inline] + fn with_c_str(&self, f: |*const libc::c_char| -> T) -> T { + (**self).with_c_str(f) } + #[inline] unsafe fn with_c_str_unchecked(&self, f: |*const libc::c_char| -> T) -> T { - with_c_str(*self, false, f) + (**self).with_c_str_unchecked(f) } } diff --git a/src/librustrt/local_data.rs b/src/librustrt/local_data.rs index 14275d070f0c9..796f9af659630 100644 --- a/src/librustrt/local_data.rs +++ b/src/librustrt/local_data.rs @@ -42,7 +42,6 @@ use core::prelude::*; use alloc::heap; use collections::treemap::TreeMap; -use collections::MutableMap; use core::cmp; use core::kinds::marker; use core::mem; @@ -261,8 +260,6 @@ impl KeyValue { /// assert_eq!(*key.get().unwrap(), 3); /// ``` pub fn get(&'static self) -> Option> { - use collections::Map; - let map = match unsafe { get_local_map() } { Some(map) => map, None => return None, diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 31f37a8a1bbda..6b64959a8436b 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -14,7 +14,6 @@ #![experimental] -use collections::Collection; use core::kinds::Sized; use fmt; use iter::Iterator; diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index bb7de168898f0..fd605bb2b5cc2 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -35,7 +35,6 @@ #![experimental] -use collections::Collection; use kinds::Send; use mem; use ops::Drop; @@ -143,6 +142,12 @@ impl CVec { self.dtor = None; self.base } + + /// Returns the number of items in this vector. + pub fn len(&self) -> uint { self.len } + + /// Returns whether this vector is empty. + pub fn is_empty(&self) -> bool { self.len() == 0 } } impl AsSlice for CVec { @@ -154,10 +159,6 @@ impl AsSlice for CVec { } } -impl Collection for CVec { - fn len(&self) -> uint { self.len } -} - #[cfg(test)] mod tests { use prelude::*; diff --git a/src/libstd/collections/hashmap/map.rs b/src/libstd/collections/hashmap/map.rs index 881ffd21d710b..596e483c2f6d3 100644 --- a/src/libstd/collections/hashmap/map.rs +++ b/src/libstd/collections/hashmap/map.rs @@ -12,7 +12,6 @@ use clone::Clone; use cmp::{max, Eq, Equiv, PartialEq}; -use collections::{Collection, Mutable, MutableSet, Map, MutableMap}; use default::Default; use fmt::{mod, Show}; use hash::{Hash, Hasher, RandomSipHasher}; @@ -471,86 +470,6 @@ impl, V, S, H: Hasher> HashMap { } } -impl, V, S, H: Hasher> Collection for HashMap { - /// Return the number of elements in the map. - fn len(&self) -> uint { self.table.size() } -} - -impl, V, S, H: Hasher> Mutable for HashMap { - /// Clear the map, removing all key-value pairs. Keeps the allocated memory - /// for reuse. - fn clear(&mut self) { - // Prevent reallocations from happening from now on. Makes it possible - // for the map to be reused but has a downside: reserves permanently. - self.resize_policy.reserve(self.table.size()); - - let cap = self.table.capacity(); - let mut buckets = Bucket::first(&mut self.table); - - while buckets.index() != cap { - buckets = match buckets.peek() { - Empty(b) => b.next(), - Full(full) => { - let (b, _, _) = full.take(); - b.next() - } - }; - } - } -} - -impl, V, S, H: Hasher> Map for HashMap { - fn find<'a>(&'a self, k: &K) -> Option<&'a V> { - self.search(k).map(|bucket| { - let (_, v) = bucket.into_refs(); - v - }) - } - - fn contains_key(&self, k: &K) -> bool { - self.search(k).is_some() - } -} - -impl, V, S, H: Hasher> MutableMap for HashMap { - fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> { - match self.search_mut(k) { - Some(bucket) => { - let (_, v) = bucket.into_mut_refs(); - Some(v) - } - _ => None - } - } - - fn swap(&mut self, k: K, v: V) -> Option { - let hash = self.make_hash(&k); - let potential_new_size = self.table.size() + 1; - self.make_some_room(potential_new_size); - - let mut retval = None; - self.insert_or_replace_with(hash, k, v, |_, val_ref, val| { - retval = Some(replace(val_ref, val)); - }); - retval - } - - - fn pop(&mut self, k: &K) -> Option { - if self.table.size() == 0 { - return None - } - - let potential_new_size = self.table.size() - 1; - self.make_some_room(potential_new_size); - - self.search_mut(k).map(|bucket| { - let (_k, val) = pop_internal(bucket); - val - }) - } -} - impl HashMap { /// Create an empty HashMap. /// @@ -1064,6 +983,219 @@ impl, V, S, H: Hasher> HashMap { let hash = self.make_hash(&key); search_entry_hashed(&mut self.table, hash, key) } + + /// Return the number of elements in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// assert_eq!(a.len(), 0); + /// a.insert(1u, "a"); + /// assert_eq!(a.len(), 1); + /// ``` + pub fn len(&self) -> uint { self.table.size() } + + /// Return true if the map contains no elements. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// assert!(a.is_empty()); + /// a.insert(1u, "a"); + /// assert!(!a.is_empty()); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Clears the map, removing all key-value pairs. Keeps the allocated memory + /// for reuse. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut a = HashMap::new(); + /// a.insert(1u, "a"); + /// a.clear(); + /// assert!(a.is_empty()); + /// ``` + pub fn clear(&mut self) { + // Prevent reallocations from happening from now on. Makes it possible + // for the map to be reused but has a downside: reserves permanently. + self.resize_policy.reserve(self.table.size()); + + let cap = self.table.capacity(); + let mut buckets = Bucket::first(&mut self.table); + + while buckets.index() != cap { + buckets = match buckets.peek() { + Empty(b) => b.next(), + Full(full) => { + let (b, _, _) = full.take(); + b.next() + } + }; + } + } + + /// Returns a reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1u, "a"); + /// assert_eq!(map.find(&1), Some(&"a")); + /// assert_eq!(map.find(&2), None); + /// ``` + pub fn find<'a>(&'a self, k: &K) -> Option<&'a V> { + self.search(k).map(|bucket| { + let (_, v) = bucket.into_refs(); + v + }) + } + + /// Returns true if the map contains a value for the specified key. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1u, "a"); + /// assert_eq!(map.contains_key(&1), true); + /// assert_eq!(map.contains_key(&2), false); + /// ``` + pub fn contains_key(&self, k: &K) -> bool { + self.search(k).is_some() + } + + /// Returns a mutable reference to the value corresponding to the key. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1u, "a"); + /// match map.find_mut(&1) { + /// Some(x) => *x = "b", + /// None => (), + /// } + /// assert_eq!(map[1], "b"); + /// ``` + pub fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> { + match self.search_mut(k) { + Some(bucket) => { + let (_, v) = bucket.into_mut_refs(); + Some(v) + } + _ => None + } + } + + /// Inserts a key-value pair into the map. An existing value for a + /// key is replaced by the new value. Returns `true` if the key did + /// not already exist in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// assert_eq!(map.insert(2u, "value"), true); + /// assert_eq!(map.insert(2, "value2"), false); + /// assert_eq!(map[2], "value2"); + /// ``` + #[inline] + pub fn insert(&mut self, key: K, value: V) -> bool { + self.swap(key, value).is_none() + } + + /// Removes a key-value pair from the map. Returns `true` if the key + /// was present in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// assert_eq!(map.remove(&1u), false); + /// map.insert(1, "a"); + /// assert_eq!(map.remove(&1), true); + /// ``` + #[inline] + pub fn remove(&mut self, key: &K) -> bool { + self.pop(key).is_some() + } + + /// Inserts a key-value pair from the map. If the key already had a value + /// present in the map, that value is returned. Otherwise, `None` is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// assert_eq!(map.swap(37u, "a"), None); + /// assert_eq!(map.is_empty(), false); + /// + /// map.insert(37, "b"); + /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map[37], "c"); + /// ``` + pub fn swap(&mut self, k: K, v: V) -> Option { + let hash = self.make_hash(&k); + let potential_new_size = self.table.size() + 1; + self.make_some_room(potential_new_size); + + let mut retval = None; + self.insert_or_replace_with(hash, k, v, |_, val_ref, val| { + retval = Some(replace(val_ref, val)); + }); + retval + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1u, "a"); + /// assert_eq!(map.pop(&1), Some("a")); + /// assert_eq!(map.pop(&1), None); + /// ``` + pub fn pop(&mut self, k: &K) -> Option { + if self.table.size() == 0 { + return None + } + + let potential_new_size = self.table.size() - 1; + self.make_some_room(potential_new_size); + + self.search_mut(k).map(|bucket| { + let (_k, val) = pop_internal(bucket); + val + }) + } } fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable, hash: SafeHash, k: K) diff --git a/src/libstd/collections/hashmap/set.rs b/src/libstd/collections/hashmap/set.rs index e4016c7032066..69f3812425f64 100644 --- a/src/libstd/collections/hashmap/set.rs +++ b/src/libstd/collections/hashmap/set.rs @@ -12,7 +12,6 @@ use clone::Clone; use cmp::{Eq, Equiv, PartialEq}; -use collections::{Collection, Mutable, Set, MutableSet, Map, MutableMap}; use core::kinds::Sized; use default::Default; use fmt::Show; @@ -376,44 +375,170 @@ impl, S, H: Hasher> HashSet { -> Chain, SetAlgebraItems<'a, T, H>> { self.iter().chain(other.difference(self)) } -} -impl, S, H: Hasher> PartialEq for HashSet { - fn eq(&self, other: &HashSet) -> bool { - if self.len() != other.len() { return false; } - - self.iter().all(|key| other.contains(key)) - } -} - -impl, S, H: Hasher> Eq for HashSet {} + /// Return the number of elements in the set + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut v = HashSet::new(); + /// assert_eq!(v.len(), 0); + /// v.insert(1u); + /// assert_eq!(v.len(), 1); + /// ``` + pub fn len(&self) -> uint { self.map.len() } -impl, S, H: Hasher> Collection for HashSet { - fn len(&self) -> uint { self.map.len() } -} + /// Returns true if the set contains no elements + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut v = HashSet::new(); + /// assert!(v.is_empty()); + /// v.insert(1u); + /// assert!(!v.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { self.map.len() == 0 } -impl, S, H: Hasher> Mutable for HashSet { - fn clear(&mut self) { self.map.clear() } -} + /// Clears the set, removing all values. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let mut v = HashSet::new(); + /// v.insert(1u); + /// v.clear(); + /// assert!(v.is_empty()); + /// ``` + pub fn clear(&mut self) { self.map.clear() } -impl, S, H: Hasher> Set for HashSet { - fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } + /// Returns `true` if the set contains a value. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let set: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// assert_eq!(set.contains(&1), true); + /// assert_eq!(set.contains(&4), false); + /// ``` + pub fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } - fn is_disjoint(&self, other: &HashSet) -> bool { + /// 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::HashSet; + /// + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let mut b: HashSet = HashSet::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: &HashSet) -> bool { self.iter().all(|v| !other.contains(v)) } - fn is_subset(&self, other: &HashSet) -> bool { + /// Returns `true` if the set is a subset of another. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let sup: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let mut set: HashSet = HashSet::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: &HashSet) -> bool { self.iter().all(|v| other.contains(v)) } + + /// Returns `true` if the set is a superset of another. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let sub: HashSet = [1, 2].iter().map(|&x| x).collect(); + /// let mut set: HashSet = HashSet::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: &HashSet) -> 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::HashSet; + /// + /// let mut set = HashSet::new(); + /// + /// assert_eq!(set.insert(2u), true); + /// assert_eq!(set.insert(2), false); + /// assert_eq!(set.len(), 1); + /// ``` + 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::HashSet; + /// + /// let mut set = HashSet::new(); + /// + /// set.insert(2u); + /// assert_eq!(set.remove(&2), true); + /// assert_eq!(set.remove(&2), false); + /// ``` + pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } } -impl, S, H: Hasher> MutableSet for HashSet { - fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } +impl, S, H: Hasher> PartialEq for HashSet { + fn eq(&self, other: &HashSet) -> bool { + if self.len() != other.len() { return false; } - fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } + self.iter().all(|key| other.contains(key)) + } } +impl, S, H: Hasher> Eq for HashSet {} + impl + fmt::Show, S, H: Hasher> fmt::Show for HashSet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "{{")); @@ -471,7 +596,6 @@ mod test_set { use super::HashSet; use slice::ImmutablePartialEqSlice; - use collections::Collection; #[test] fn test_disjoint() { diff --git a/src/libstd/collections/lru_cache.rs b/src/libstd/collections/lru_cache.rs index 5408e50f2bda3..93e649f9355dd 100644 --- a/src/libstd/collections/lru_cache.rs +++ b/src/libstd/collections/lru_cache.rs @@ -38,7 +38,7 @@ //! ``` use cmp::{PartialEq, Eq}; -use collections::{HashMap, Collection, Mutable, MutableMap}; +use collections::HashMap; use fmt; use hash::Hash; use iter::{range, Iterator}; @@ -288,6 +288,15 @@ impl LruCache { (*(*node).next).prev = node; } } + + /// Return the number of key-value pairs in the cache. + pub fn len(&self) -> uint { self.map.len() } + + /// Returns whether the cache is currently empty. + pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Clear the cache of all key-value pairs. + pub fn clear(&mut self) { self.map.clear(); } } impl fmt::Show for LruCache { @@ -311,20 +320,6 @@ impl fmt::Show for LruCache { } } -impl Collection for LruCache { - /// Return the number of key-value pairs in the cache. - fn len(&self) -> uint { - self.map.len() - } -} - -impl Mutable for LruCache { - /// Clear the cache of all key-value pairs. - fn clear(&mut self) { - self.map.clear(); - } -} - #[unsafe_destructor] impl Drop for LruCache { fn drop(&mut self) { diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index c227aa65b48f2..be9e22ee9d14c 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -328,8 +328,6 @@ #![experimental] -pub use core_collections::{Collection, Mutable, Map, MutableMap}; -pub use core_collections::{Set, MutableSet, Deque, MutableSeq}; 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}; diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index ec6eef07c9541..4c133fc739739 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -20,7 +20,6 @@ A simple wrapper over the platform's dynamic library facilities #![allow(missing_docs)] use clone::Clone; -use collections::MutableSeq; use c_str::ToCStr; use iter::Iterator; use mem; @@ -280,7 +279,6 @@ pub mod dl { #[cfg(target_os = "windows")] pub mod dl { use c_str::ToCStr; - use collections::MutableSeq; use iter::Iterator; use libc; use os; diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index a01787c286bb9..49c688da31cbf 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -13,7 +13,6 @@ //! Buffering wrappers for I/O traits use cmp; -use collections::Collection; use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult}; use iter::ExactSize; use ops::Drop; diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index 91f3f38f89dcb..c925208c3eee7 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -10,7 +10,6 @@ use clone::Clone; use cmp; -use collections::Collection; use comm::{Sender, Receiver}; use io; use option::{None, Some}; diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs index 06ed183e93679..6d0b8ebc3d9c4 100644 --- a/src/libstd/io/extensions.rs +++ b/src/libstd/io/extensions.rs @@ -15,7 +15,6 @@ // FIXME: Not sure how this should be structured // FIXME: Iteration should probably be considered separately -use collections::{Collection, MutableSeq}; use io::{IoError, IoResult, Reader}; use io; use iter::Iterator; @@ -502,7 +501,6 @@ mod test { mod bench { extern crate test; - use collections::Collection; use prelude::*; use self::test::Bencher; diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index f193ce8cffacb..c8524676a6dd4 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -54,7 +54,6 @@ fs::unlink(&path); use c_str::ToCStr; use clone::Clone; -use collections::{Collection, MutableSeq}; use io::standard_error; use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode}; use io::{IoResult, IoError, FileStat, SeekStyle, Seek, Writer, Reader}; diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index 2f6dd7e47955f..6010436581764 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -13,13 +13,11 @@ //! Readers and Writers for in-memory buffers use cmp::min; -use collections::Collection; use option::None; use result::{Err, Ok}; use io; use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult}; -use slice; -use slice::AsSlice; +use slice::{mod, AsSlice, ImmutableSlice}; use vec::Vec; const BUF_CAPACITY: uint = 128; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 6d6c0c0dd758b..c6f237ff1da34 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -222,7 +222,6 @@ responding to errors that may occur while attempting to read the numbers. #![deny(unused_must_use)] use char::Char; -use collections::Collection; use default::Default; use fmt; use int; diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index e93af7446990a..f4f3be13f6675 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -15,13 +15,12 @@ #![allow(missing_docs)] -use collections::Collection; use fmt; use from_str::FromStr; use iter::Iterator; use option::{Option, None, Some}; use str::StrSlice; -use slice::{MutableCloneableSlice, MutableSlice}; +use slice::{MutableCloneableSlice, MutableSlice, ImmutableSlice}; pub type Port = u16; diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index 4e5f8822acb40..312a4c41ac9a6 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -918,7 +918,7 @@ mod tests { let prog = pwd_cmd().cwd(&parent_dir).spawn().unwrap(); let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap(); - let child_dir = Path::new(output.as_slice().trim().into_string()); + let child_dir = Path::new(output.as_slice().trim()); let parent_stat = parent_dir.stat().unwrap(); let child_stat = child_dir.stat().unwrap(); diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index 3b17f0bc79fa7..30ecf2284df76 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -14,7 +14,6 @@ use char; use clone::Clone; -use collections::{Collection, MutableSeq}; use num::{NumCast, Zero, One, cast, Int}; use num::{Float, FPNaN, FPInfinite, ToPrimitive}; use num; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index d4e6251cebeb0..5b3c872d2b726 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -32,7 +32,6 @@ #![allow(non_snake_case)] use clone::Clone; -use collections::{Collection, MutableSeq}; use fmt; use io::{IoResult, IoError}; use iter::Iterator; diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 6a1229902464e..8949a881c9de6 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -67,7 +67,7 @@ println!("path exists: {}", path.exists()); #![experimental] -use collections::{Collection, MutableSeq}; +use core::kinds::Sized; use c_str::CString; use clone::Clone; use fmt; @@ -627,7 +627,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// ``` #[inline] fn push_many(&mut self, paths: &[T]) { - let t: Option = None; + let t: Option<&T> = None; if BytesContainer::is_str(t) { for p in paths.iter() { self.push(p.container_as_str().unwrap()) @@ -792,14 +792,9 @@ pub trait GenericPath: Clone + GenericPathUnsafe { } /// A trait that represents something bytes-like (e.g. a &[u8] or a &str) -pub trait BytesContainer { +pub trait BytesContainer for Sized? { /// Returns a &[u8] representing the receiver fn container_as_bytes<'a>(&'a self) -> &'a [u8]; - /// Consumes the receiver and converts it into Vec - #[inline] - fn container_into_owned_bytes(self) -> Vec { - self.container_as_bytes().to_vec() - } /// Returns the receiver interpreted as a utf-8 string, if possible #[inline] fn container_as_str<'a>(&'a self) -> Option<&'a str> { @@ -808,7 +803,7 @@ pub trait BytesContainer { /// Returns whether .container_as_str() is guaranteed to not fail // FIXME (#8888): Remove unused arg once :: works #[inline] - fn is_str(_: Option) -> bool { false } + fn is_str(_: Option<&Self>) -> bool { false } } /// A trait that represents the unsafe operations on GenericPaths @@ -860,48 +855,44 @@ impl<'a, P: GenericPath> Display<'a, P> { } } -impl<'a> BytesContainer for &'a str { +impl BytesContainer for str { #[inline] - fn container_as_bytes<'a>(&'a self) -> &'a [u8] { + fn container_as_bytes(&self) -> &[u8] { self.as_bytes() } #[inline] - fn container_as_str<'a>(&'a self) -> Option<&'a str> { - Some(*self) + fn container_as_str(&self) -> Option<&str> { + Some(self) } #[inline] - fn is_str(_: Option<&'a str>) -> bool { true } + fn is_str(_: Option<&str>) -> bool { true } } impl BytesContainer for String { #[inline] - fn container_as_bytes<'a>(&'a self) -> &'a [u8] { + fn container_as_bytes(&self) -> &[u8] { self.as_bytes() } #[inline] - fn container_as_str<'a>(&'a self) -> Option<&'a str> { + fn container_as_str(&self) -> Option<&str> { Some(self.as_slice()) } #[inline] - fn is_str(_: Option) -> bool { true } + fn is_str(_: Option<&String>) -> bool { true } } -impl<'a> BytesContainer for &'a [u8] { +impl BytesContainer for [u8] { #[inline] - fn container_as_bytes<'a>(&'a self) -> &'a [u8] { - *self + fn container_as_bytes(&self) -> &[u8] { + self } } impl BytesContainer for Vec { #[inline] - fn container_as_bytes<'a>(&'a self) -> &'a [u8] { + fn container_as_bytes(&self) -> &[u8] { self.as_slice() } - #[inline] - fn container_into_owned_bytes(self) -> Vec { - self - } } impl BytesContainer for CString { @@ -921,7 +912,20 @@ impl<'a> BytesContainer for str::MaybeOwned<'a> { Some(self.as_slice()) } #[inline] - fn is_str(_: Option) -> bool { true } + fn is_str(_: Option<&str::MaybeOwned>) -> bool { true } +} + +impl<'a, Sized? T: BytesContainer> BytesContainer for &'a T { + #[inline] + fn container_as_bytes(&self) -> &[u8] { + (**self).container_as_bytes() + } + #[inline] + fn container_as_str(&self) -> Option<&str> { + (**self).container_as_str() + } + #[inline] + fn is_str(_: Option<& &'a T>) -> bool { BytesContainer::is_str(None::<&T>) } } #[inline(always)] diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 0d7a467b313f2..60cfa7a13de94 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -13,7 +13,6 @@ use c_str::{CString, ToCStr}; use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; -use collections::{Collection, MutableSeq}; use from_str::FromStr; use hash; use io::Writer; @@ -106,18 +105,6 @@ impl ToCStr for Path { } } -impl<'a> ToCStr for &'a Path { - #[inline] - fn to_c_str(&self) -> CString { - (*self).to_c_str() - } - - #[inline] - unsafe fn to_c_str_unchecked(&self) -> CString { - (*self).to_c_str_unchecked() - } -} - impl hash::Hash for Path { #[inline] fn hash(&self, state: &mut S) { @@ -130,17 +117,6 @@ impl BytesContainer for Path { fn container_as_bytes<'a>(&'a self) -> &'a [u8] { self.as_vec() } - #[inline] - fn container_into_owned_bytes(self) -> Vec { - self.into_vec() - } -} - -impl<'a> BytesContainer for &'a Path { - #[inline] - fn container_as_bytes<'a>(&'a self) -> &'a [u8] { - self.as_vec() - } } impl GenericPathUnsafe for Path { diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 1ddc027a07eab..3ef142a2e824c 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -16,7 +16,6 @@ use ascii::AsciiCast; use c_str::{CString, ToCStr}; use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; -use collections::{Collection, MutableSeq}; use from_str::FromStr; use hash; use io::Writer; @@ -130,18 +129,6 @@ impl ToCStr for Path { } } -impl<'a> ToCStr for &'a Path { - #[inline] - fn to_c_str(&self) -> CString { - (*self).to_c_str() - } - - #[inline] - unsafe fn to_c_str_unchecked(&self) -> CString { - (*self).to_c_str_unchecked() - } -} - impl hash::Hash for Path { #[cfg(not(test))] #[inline] @@ -157,23 +144,6 @@ impl hash::Hash for Path { } impl BytesContainer for Path { - #[inline] - fn container_as_bytes<'a>(&'a self) -> &'a [u8] { - self.as_vec() - } - #[inline] - fn container_into_owned_bytes(self) -> Vec { - self.into_vec() - } - #[inline] - fn container_as_str<'a>(&'a self) -> Option<&'a str> { - self.as_str() - } - #[inline] - fn is_str(_: Option) -> bool { true } -} - -impl<'a> BytesContainer for &'a Path { #[inline] fn container_as_bytes<'a>(&'a self) -> &'a [u8] { self.as_vec() @@ -183,7 +153,7 @@ impl<'a> BytesContainer for &'a Path { self.as_str() } #[inline] - fn is_str(_: Option<&'a Path>) -> bool { true } + fn is_str(_: Option<&Path>) -> bool { true } } impl GenericPathUnsafe for Path { diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 48be404b0d02a..31e559459165d 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -53,7 +53,7 @@ // Reexported functions #[doc(no_inline)] pub use from_str::from_str; -#[doc(no_inline)] pub use iter::range; +#[doc(no_inline)] pub use iter::{range, repeat}; #[doc(no_inline)] pub use mem::drop; // Reexported types and traits @@ -65,8 +65,6 @@ #[doc(no_inline)] pub use clone::Clone; #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; #[doc(no_inline)] pub use cmp::{Ordering, Less, Equal, Greater, Equiv}; -#[doc(no_inline)] pub use collections::{Collection, Mutable, Map, MutableMap, MutableSeq}; -#[doc(no_inline)] pub use collections::{Set, MutableSet}; #[doc(no_inline)] pub use iter::{FromIterator, Extendable, ExactSize}; #[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator}; #[doc(no_inline)] pub use iter::{RandomAccessIterator, CloneableIterator}; diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index bf5bdc8a308e3..b7b0858123042 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -62,7 +62,6 @@ mod imp { mod imp { extern crate libc; - use collections::Collection; use io::{IoResult}; use kinds::marker; use mem; @@ -70,7 +69,7 @@ mod imp { use rand::Rng; use result::{Ok}; use self::libc::{c_int, size_t}; - use slice::MutableSlice; + use slice::{ImmutableSlice, MutableSlice}; /// A random number generator that retrieves randomness straight from /// the operating system. Platform sources: @@ -130,7 +129,6 @@ mod imp { mod imp { extern crate libc; - use core_collections::Collection; use io::{IoResult, IoError}; use mem; use ops::Drop; @@ -139,7 +137,7 @@ mod imp { use result::{Ok, Err}; use self::libc::{DWORD, BYTE, LPCSTR, BOOL}; use self::libc::types::os::arch::extra::{LONG_PTR}; - use slice::MutableSlice; + use slice::{ImmutableSlice, MutableSlice}; type HCRYPTPROV = LONG_PTR; diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs index 4f2205312373c..c1bb6970f7150 100644 --- a/src/libstd/rand/reader.rs +++ b/src/libstd/rand/reader.rs @@ -10,10 +10,10 @@ //! A wrapper around any Reader to treat it as an RNG. -use collections::Collection; use io::Reader; use rand::Rng; use result::{Ok, Err}; +use slice::ImmutableSlice; /// An RNG that reads random bytes straight from a `Reader`. This will /// work best with an infinite reader, but this is not required. diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index 5bd3927727574..5d7aa0509c5d8 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -12,7 +12,6 @@ #![allow(non_camel_case_types)] -use collections::Collection; use from_str::from_str; use io::{IoResult, Writer}; use iter::Iterator; @@ -390,7 +389,6 @@ mod imp { #[cfg(not(any(target_os = "macos", target_os = "ios")))] fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { - use collections::Collection; use iter::Iterator; use os; use path::GenericPath; @@ -659,7 +657,6 @@ mod imp { #[allow(dead_code, non_snake_case)] mod imp { use c_str::CString; - use core_collections::Collection; use intrinsics; use io::{IoResult, Writer}; use libc; diff --git a/src/libsync/deque.rs b/src/libsync/deque.rs index 31889a36dd7ab..11b8b974dcf79 100644 --- a/src/libsync/deque.rs +++ b/src/libsync/deque.rs @@ -55,7 +55,7 @@ use core::prelude::*; use alloc::arc::Arc; use alloc::heap::{allocate, deallocate}; use alloc::boxed::Box; -use collections::{Vec, MutableSeq}; +use collections::Vec; use core::kinds::marker; use core::mem::{forget, min_align_of, size_of, transmute}; use core::ptr; diff --git a/src/libsync/raw.rs b/src/libsync/raw.rs index 1410091b924ba..facf204983b42 100644 --- a/src/libsync/raw.rs +++ b/src/libsync/raw.rs @@ -22,7 +22,7 @@ use core::finally::Finally; use core::kinds::marker; use core::mem; use core::cell::UnsafeCell; -use collections::{Vec, MutableSeq}; +use collections::Vec; use mutex; use comm::{Receiver, Sender, channel}; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index e641abbfeee64..bd6df9cb4971b 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -675,26 +675,19 @@ 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 { - 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); + 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()); } - None + 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 diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 41967b0680cff..f192308440998 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -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 { +pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) + -> Box { 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>) -> Option> { + Some(self.p.parse_expr()) + } + fn make_items(mut self: Box>) + -> Option>> { + 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 diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index 4f09b34557c74..f622e2d611276 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -112,6 +112,10 @@ impl OwnedSlice { pub fn map(&self, f: |&T| -> U) -> OwnedSlice { self.iter().map(f).collect() } + + pub fn len(&self) -> uint { self.len } + + pub fn is_empty(&self) -> bool { self.len == 0 } } impl Default for OwnedSlice { @@ -140,10 +144,6 @@ impl PartialEq for OwnedSlice { impl Eq for OwnedSlice {} -impl Collection for OwnedSlice { - fn len(&self) -> uint { self.len } -} - impl FromIterator for OwnedSlice { fn from_iter>(mut iter: I) -> OwnedSlice { OwnedSlice::from_vec(iter.collect()) diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 422c2d5c75bd7..56ee6c7b9158c 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -25,16 +25,6 @@ enum SmallVectorRepr { Many(Vec), } -impl Collection for SmallVector { - fn len(&self) -> uint { - match self.repr { - Zero => 0, - One(..) => 1, - Many(ref vals) => vals.len() - } - } -} - impl FromIterator for SmallVector { fn from_iter>(iter: I) -> SmallVector { let mut v = SmallVector::zero(); @@ -131,6 +121,16 @@ impl SmallVector { }; MoveItems { repr: repr } } + + pub fn len(&self) -> uint { + match self.repr { + Zero => 0, + One(..) => 1, + Many(ref vals) => vals.len() + } + } + + pub fn is_empty(&self) -> bool { self.len() == 0 } } pub struct MoveItems { diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index a89afab505b8d..61ff88a2fa338 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -41,7 +41,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option> { if i == "" { dirs_to_search.push(Path::new("/usr/share/terminfo")); } else { - dirs_to_search.push(Path::new(i.to_string())); + dirs_to_search.push(Path::new(i)); } }, // Found nothing in TERMINFO_DIRS, use the default paths: diff --git a/src/libterm/win.rs b/src/libterm/win.rs index 7ce6fb658b56d..9a67ee8836bae 100644 --- a/src/libterm/win.rs +++ b/src/libterm/win.rs @@ -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 WinConsole { diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs index e4148440252af..4bad631798fb2 100644 --- a/src/libunicode/u_str.rs +++ b/src/libunicode/u_str.rs @@ -19,7 +19,7 @@ use core::clone::Clone; use core::cmp; -use core::collections::Collection; +use core::slice::ImmutableSlice; use core::iter::{Filter, AdditiveIterator, Iterator, DoubleEndedIterator}; use core::kinds::Sized; use core::option::{Option, None, Some}; diff --git a/src/test/auxiliary/macro-include-items-expr.rs b/src/test/auxiliary/macro-include-items-expr.rs new file mode 100644 index 0000000000000..aea3c749930b6 --- /dev/null +++ b/src/test/auxiliary/macro-include-items-expr.rs @@ -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 or the MIT license +// , 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 diff --git a/src/test/auxiliary/macro-include-items-item.rs b/src/test/auxiliary/macro-include-items-item.rs new file mode 100644 index 0000000000000..da72aaef80591 --- /dev/null +++ b/src/test/auxiliary/macro-include-items-item.rs @@ -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 or the MIT license +// , 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() } diff --git a/src/test/auxiliary/namespaced_enum_emulate_flat.rs b/src/test/auxiliary/namespaced_enum_emulate_flat.rs new file mode 100644 index 0000000000000..3a11f30049c6a --- /dev/null +++ b/src/test/auxiliary/namespaced_enum_emulate_flat.rs @@ -0,0 +1,38 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(globs, struct_variant)] + +pub use Foo::*; + +pub enum Foo { + A, + B(int), + C { a: int }, +} + +impl Foo { + pub fn foo() {} +} + +pub mod nest { + pub use self::Bar::*; + + pub enum Bar { + D, + E(int), + F { a: int }, + } + + impl Bar { + pub fn foo() {} + } +} + + diff --git a/src/test/auxiliary/namespaced_enums.rs b/src/test/auxiliary/namespaced_enums.rs new file mode 100644 index 0000000000000..a6e6f9b019160 --- /dev/null +++ b/src/test/auxiliary/namespaced_enums.rs @@ -0,0 +1,22 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(struct_variant)] + +pub enum Foo { + A, + B(int), + C { a: int }, +} + +impl Foo { + pub fn foo() {} + pub fn bar(&self) {} +} + diff --git a/src/test/auxiliary/use_from_trait_xc.rs b/src/test/auxiliary/use_from_trait_xc.rs index 8c547c2800204..22e0d3168cadc 100644 --- a/src/test/auxiliary/use_from_trait_xc.rs +++ b/src/test/auxiliary/use_from_trait_xc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::sub::Bar; +pub use self::sub::{Bar, Baz}; pub trait Trait { fn foo(); @@ -26,4 +26,10 @@ mod sub { impl Bar { pub fn new() {} } + + pub enum Baz {} + + impl Baz { + pub fn new() {} + } } diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index f68ace395aaa5..3933a33446d63 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -22,7 +22,29 @@ fn timed(label: &str, f: ||) { println!(" {}: {}", label, end - start); } -fn ascending>(map: &mut M, n_keys: uint) { +trait MutableMap { + fn insert(&mut self, k: uint, v: uint); + fn remove(&mut self, k: &uint) -> bool; + fn find(&self, k: &uint) -> Option<&uint>; +} + +impl MutableMap for TreeMap { + fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); } + fn remove(&mut self, k: &uint) -> bool { self.remove(k) } + fn find(&self, k: &uint) -> Option<&uint> { self.find(k) } +} +impl MutableMap for HashMap { + fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); } + fn remove(&mut self, k: &uint) -> bool { self.remove(k) } + fn find(&self, k: &uint) -> Option<&uint> { self.find(k) } +} +impl MutableMap for TrieMap { + fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); } + fn remove(&mut self, k: &uint) -> bool { self.remove(k) } + fn find(&self, k: &uint) -> Option<&uint> { self.find(k) } +} + +fn ascending(map: &mut M, n_keys: uint) { println!(" Ascending integers:"); timed("insert", || { @@ -44,7 +66,7 @@ fn ascending>(map: &mut M, n_keys: uint) { }); } -fn descending>(map: &mut M, n_keys: uint) { +fn descending(map: &mut M, n_keys: uint) { println!(" Descending integers:"); timed("insert", || { @@ -66,7 +88,7 @@ fn descending>(map: &mut M, n_keys: uint) { }); } -fn vector>(map: &mut M, n_keys: uint, dist: &[uint]) { +fn vector(map: &mut M, n_keys: uint, dist: &[uint]) { timed("insert", || { for i in range(0u, n_keys) { map.insert(dist[i], i + 1); diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index 7f85bc1d700af..4833467922b76 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -16,6 +16,7 @@ extern crate time; use std::collections::bitv::BitvSet; use std::collections::TreeSet; +use std::hash::Hash; use std::collections::HashSet; use std::os; use std::uint; @@ -37,6 +38,28 @@ fn timed(result: &mut f64, op: ||) { *result = (end - start); } +trait MutableSet { + fn insert(&mut self, k: T); + fn remove(&mut self, k: &T) -> bool; + fn contains(&self, k: &T) -> bool; +} + +impl MutableSet for HashSet { + 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) } +} +impl MutableSet for TreeSet { + 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) } +} +impl MutableSet for BitvSet { + fn insert(&mut self, k: uint) { self.insert(k); } + fn remove(&mut self, k: &uint) -> bool { self.remove(k) } + fn contains(&self, k: &uint) -> bool { self.contains(k) } +} + impl Results { pub fn bench_int, R: rand::Rng>( diff --git a/src/test/compile-fail/enum-and-module-in-same-scope.rs b/src/test/compile-fail/enum-and-module-in-same-scope.rs index 7464764666cd9..7526c6753e632 100644 --- a/src/test/compile-fail/enum-and-module-in-same-scope.rs +++ b/src/test/compile-fail/enum-and-module-in-same-scope.rs @@ -13,7 +13,7 @@ mod Foo { } enum Foo { //~ ERROR duplicate definition of type or module `Foo` - X + X //~ ERROR duplicate definition of value `X` } fn main() {} diff --git a/src/test/compile-fail/issue-16562.rs b/src/test/compile-fail/issue-16562.rs index 2207e10add451..3c784c3b770e4 100644 --- a/src/test/compile-fail/issue-16562.rs +++ b/src/test/compile-fail/issue-16562.rs @@ -15,6 +15,8 @@ struct Col { col: C, } +trait Collection { fn len(&self) -> uint; } + impl Collection for Col { //~^ ERROR unable to infer enough type information fn len(&self) -> uint { diff --git a/src/test/compile-fail/issue-16747.rs b/src/test/compile-fail/issue-16747.rs index 012dc01ca97a8..134f58951bab2 100644 --- a/src/test/compile-fail/issue-16747.rs +++ b/src/test/compile-fail/issue-16747.rs @@ -12,6 +12,8 @@ trait ListItem<'a> { fn list_name() -> &'a str; } +trait Collection { fn len(&self) -> uint; } + struct List<'a, T: ListItem<'a>> { //~^ ERROR the parameter type `T` may not live long enough; consider adding an explicit lifetime bo //~^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at diff --git a/src/test/compile-fail/manual-link-bad-form.rs b/src/test/compile-fail/manual-link-bad-form.rs new file mode 100644 index 0000000000000..bd2a3eba0b5b8 --- /dev/null +++ b/src/test/compile-fail/manual-link-bad-form.rs @@ -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 or the MIT license +// , 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() { +} + + diff --git a/src/test/compile-fail/manual-link-bad-kind.rs b/src/test/compile-fail/manual-link-bad-kind.rs new file mode 100644 index 0000000000000..4614440ddafd5 --- /dev/null +++ b/src/test/compile-fail/manual-link-bad-kind.rs @@ -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 or the MIT license +// , 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() { +} + diff --git a/src/test/compile-fail/manual-link-framework.rs b/src/test/compile-fail/manual-link-framework.rs new file mode 100644 index 0000000000000..96cc35049ee40 --- /dev/null +++ b/src/test/compile-fail/manual-link-framework.rs @@ -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 or the MIT license +// , 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() { +} diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs index 6f032c5b1f089..80818e06f8b23 100644 --- a/src/test/compile-fail/map-types.rs +++ b/src/test/compile-fail/map-types.rs @@ -12,11 +12,15 @@ extern crate collections; use std::collections::HashMap; +trait Map {} + +impl Map for HashMap {} + // Test that trait types printed in error msgs include the type arguments. fn main() { let x: Box> = box HashMap::new(); let x: Box> = x; let y: Box> = box x; - //~^ ERROR the trait `collections::Map` is not implemented + //~^ ERROR the trait `Map` is not implemented } diff --git a/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs b/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs new file mode 100644 index 0000000000000..09916a11f72e7 --- /dev/null +++ b/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs @@ -0,0 +1,28 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:namespaced_enums.rs +#![feature(struct_variant, globs)] + +extern crate namespaced_enums; + +mod m { + pub use namespaced_enums::Foo::*; +} + +pub fn main() { + use namespaced_enums::Foo::*; + + foo(); //~ ERROR unresolved name `foo` + m::foo(); //~ ERROR unresolved name `m::foo` + bar(); //~ ERROR unresolved name `bar` + m::bar(); //~ ERROR unresolved name `m::bar` +} + diff --git a/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs b/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs new file mode 100644 index 0000000000000..1554d410070d6 --- /dev/null +++ b/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(struct_variant, globs)] + +mod m2 { + pub enum Foo { + A, + B(int), + C { a: int }, + } + + impl Foo { + pub fn foo() {} + pub fn bar(&self) {} + } +} + +mod m { + pub use m2::Foo::*; +} + +pub fn main() { + use m2::Foo::*; + + foo(); //~ ERROR unresolved name `foo` + m::foo(); //~ ERROR unresolved name `m::foo` + bar(); //~ ERROR unresolved name `bar` + m::bar(); //~ ERROR unresolved name `m::bar` +} diff --git a/src/test/compile-fail/use-from-trait-xc.rs b/src/test/compile-fail/use-from-trait-xc.rs index cea85955d3795..ff2824135801a 100644 --- a/src/test/compile-fail/use-from-trait-xc.rs +++ b/src/test/compile-fail/use-from-trait-xc.rs @@ -13,12 +13,15 @@ extern crate use_from_trait_xc; use use_from_trait_xc::Trait::foo; -//~^ ERROR unresolved import `use_from_trait_xc::Trait::foo`. Cannot import from a trait or type imp +//~^ ERROR `foo` is not directly importable use use_from_trait_xc::Foo::new; -//~^ ERROR unresolved import `use_from_trait_xc::Foo::new`. Cannot import from a trait or type imple +//~^ ERROR `new` is not directly importable -use use_from_trait_xc::Bar::new; -//~^ ERROR unresolved import `use_from_trait_xc::Bar::new`. Cannot import from a trait or type +use use_from_trait_xc::Bar::new as bnew; +//~^ ERROR `bnew` is not directly importable + +use use_from_trait_xc::Baz::new as baznew; +//~^ ERROR `baznew` is not directly importable fn main() {} diff --git a/src/test/compile-fail/use-from-trait.rs b/src/test/compile-fail/use-from-trait.rs index c9eea3c5df255..2a97155dd2efb 100644 --- a/src/test/compile-fail/use-from-trait.rs +++ b/src/test/compile-fail/use-from-trait.rs @@ -9,9 +9,9 @@ // except according to those terms. use Trait::foo; -//~^ ERROR unresolved import `Trait::foo`. Cannot import from a trait or type implementation +//~^ ERROR `foo` is not directly importable use Foo::new; -//~^ ERROR unresolved import `Foo::new`. Cannot import from a trait or type implementation +//~^ ERROR `new` is not directly importable pub trait Trait { fn foo(); diff --git a/src/test/run-make/manual-link/Makefile b/src/test/run-make/manual-link/Makefile new file mode 100644 index 0000000000000..d2a02adc9d4a4 --- /dev/null +++ b/src/test/run-make/manual-link/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: $(TMPDIR)/libbar.a + $(RUSTC) foo.rs -lbar:static + $(RUSTC) main.rs + $(call RUN,main) + diff --git a/src/test/run-make/manual-link/bar.c b/src/test/run-make/manual-link/bar.c new file mode 100644 index 0000000000000..e42599986781f --- /dev/null +++ b/src/test/run-make/manual-link/bar.c @@ -0,0 +1 @@ +void bar() {} diff --git a/src/test/run-make/manual-link/foo.c b/src/test/run-make/manual-link/foo.c new file mode 100644 index 0000000000000..e42599986781f --- /dev/null +++ b/src/test/run-make/manual-link/foo.c @@ -0,0 +1 @@ +void bar() {} diff --git a/src/test/run-make/manual-link/foo.rs b/src/test/run-make/manual-link/foo.rs new file mode 100644 index 0000000000000..d67a4057afbfc --- /dev/null +++ b/src/test/run-make/manual-link/foo.rs @@ -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 or the MIT license +// , 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(); } +} diff --git a/src/test/run-make/manual-link/main.rs b/src/test/run-make/manual-link/main.rs new file mode 100644 index 0000000000000..756a47f386ae3 --- /dev/null +++ b/src/test/run-make/manual-link/main.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate foo; + +fn main() { + foo::foo(); +} diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index aab06c0339be2..b5892c3f12305 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -46,18 +46,9 @@ impl cat { return false; } } -} - -impl Collection for cat { fn len(&self) -> uint { self.meows as uint } fn is_empty(&self) -> bool { self.meows == 0 } -} - -impl Mutable for cat { fn clear(&mut self) {} -} - -impl Map for cat { fn contains_key(&self, k: &int) -> bool { *k <= self.meows } fn find(&self, k: &int) -> Option<&T> { @@ -67,9 +58,6 @@ impl Map for cat { None } } -} - -impl MutableMap for cat { fn insert(&mut self, k: int, _: T) -> bool { self.meows += k; true diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs index 9a00868cc1259..39995db5a2f54 100644 --- a/src/test/run-pass/issue-2383.rs +++ b/src/test/run-pass/issue-2383.rs @@ -11,7 +11,6 @@ extern crate collections; use std::collections::RingBuf; -use std::collections::Deque; pub fn main() { let mut q = RingBuf::new(); diff --git a/src/test/run-pass/macro-include-items.rs b/src/test/run-pass/macro-include-items.rs new file mode 100644 index 0000000000000..03eec668edde8 --- /dev/null +++ b/src/test/run-pass/macro-include-items.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn bar() {} + +include!(concat!("", "", "../auxiliary/", "macro-include-items-item.rs")) + +fn main() { + foo(); + assert_eq!(include!(concat!("", "../auxiliary/", "macro-include-items-expr.rs")), 1u); +} diff --git a/src/test/run-pass/namespaced-enum-emulate-flat-xc.rs b/src/test/run-pass/namespaced-enum-emulate-flat-xc.rs new file mode 100644 index 0000000000000..540a0acb12316 --- /dev/null +++ b/src/test/run-pass/namespaced-enum-emulate-flat-xc.rs @@ -0,0 +1,32 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:namespaced_enum_emulate_flat.rs +#![feature(struct_variant)] + +extern crate namespaced_enum_emulate_flat; + +use namespaced_enum_emulate_flat::{Foo, A, B, C}; +use namespaced_enum_emulate_flat::nest::{Bar, D, E, F}; + +fn _f(f: Foo) { + match f { + A | B(_) | C { .. } => {} + } +} + +fn _f2(f: Bar) { + match f { + D | E(_) | F { .. } => {} + } +} + +pub fn main() {} + diff --git a/src/test/run-pass/namespaced-enum-emulate-flat.rs b/src/test/run-pass/namespaced-enum-emulate-flat.rs new file mode 100644 index 0000000000000..2aad9bcff5613 --- /dev/null +++ b/src/test/run-pass/namespaced-enum-emulate-flat.rs @@ -0,0 +1,51 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(globs, struct_variant)] + +pub use Foo::*; +use nest::{Bar, D, E, F}; + +pub enum Foo { + A, + B(int), + C { a: int }, +} + +impl Foo { + pub fn foo() {} +} + +fn _f(f: Foo) { + match f { + A | B(_) | C { .. } => {} + } +} + +mod nest { + pub use self::Bar::*; + + pub enum Bar { + D, + E(int), + F { a: int }, + } + + impl Bar { + pub fn foo() {} + } +} + +fn _f2(f: Bar) { + match f { + D | E(_) | F { .. } => {} + } +} + +fn main() {} diff --git a/src/test/run-pass/namespaced-enum-glob-import-xcrate.rs b/src/test/run-pass/namespaced-enum-glob-import-xcrate.rs new file mode 100644 index 0000000000000..35fb66769543b --- /dev/null +++ b/src/test/run-pass/namespaced-enum-glob-import-xcrate.rs @@ -0,0 +1,34 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:namespaced_enums.rs +#![feature(globs, struct_variant)] + +extern crate namespaced_enums; + +fn _f(f: namespaced_enums::Foo) { + use namespaced_enums::Foo::*; + + match f { + A | B(_) | C { .. } => {} + } +} + +mod m { + pub use namespaced_enums::Foo::*; +} + +fn _f2(f: namespaced_enums::Foo) { + match f { + m::A | m::B(_) | m::C { .. } => {} + } +} + +pub fn main() {} diff --git a/src/test/run-pass/namespaced-enum-glob-import.rs b/src/test/run-pass/namespaced-enum-glob-import.rs new file mode 100644 index 0000000000000..fe6f342738360 --- /dev/null +++ b/src/test/run-pass/namespaced-enum-glob-import.rs @@ -0,0 +1,42 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(globs, struct_variant)] + +mod m2 { + pub enum Foo { + A, + B(int), + C { a: int }, + } + + impl Foo { + pub fn foo() {} + } +} + +mod m { + pub use m2::Foo::*; +} + +fn _f(f: m2::Foo) { + use m2::Foo::*; + + match f { + A | B(_) | C { .. } => {} + } +} + +fn _f2(f: m2::Foo) { + match f { + m::A | m::B(_) | m::C { .. } => {} + } +} + +pub fn main() {} diff --git a/src/test/run-pass/namespaced-enums-xcrate.rs b/src/test/run-pass/namespaced-enums-xcrate.rs new file mode 100644 index 0000000000000..c5f80eaea5a31 --- /dev/null +++ b/src/test/run-pass/namespaced-enums-xcrate.rs @@ -0,0 +1,25 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:namespaced_enums.rs +#![feature(struct_variant)] + +extern crate namespaced_enums; + +use namespaced_enums::Foo; + +fn _foo (f: Foo) { + match f { + Foo::A | Foo::B(_) | Foo::C { .. } => {} + } +} + +pub fn main() {} + diff --git a/src/test/run-pass/namespaced-enums.rs b/src/test/run-pass/namespaced-enums.rs new file mode 100644 index 0000000000000..afa39c326b60c --- /dev/null +++ b/src/test/run-pass/namespaced-enums.rs @@ -0,0 +1,24 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(struct_variant)] + +enum Foo { + A, + B(int), + C { a: int }, +} + +fn _foo (f: Foo) { + match f { + Foo::A | Foo::B(_) | Foo::C { .. } => {} + } +} + +pub fn main() {} diff --git a/src/test/run-pass/process-spawn-with-unicode-params.rs b/src/test/run-pass/process-spawn-with-unicode-params.rs index 9716d79f4c82a..490614ef12144 100644 --- a/src/test/run-pass/process-spawn-with-unicode-params.rs +++ b/src/test/run-pass/process-spawn-with-unicode-params.rs @@ -48,7 +48,7 @@ fn main() { let child_filestem = Path::new(child_name); let child_filename = child_filestem.with_extension(my_ext); - let child_path = cwd.join(child_filename.clone()); + let child_path = cwd.join(child_filename); // make a separate directory for the child drop(fs::mkdir(&cwd, io::USER_RWX).is_ok()); diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs index 163cf194a3cc5..1edce811bcb21 100644 --- a/src/test/run-pass/send_str_hashmap.rs +++ b/src/test/run-pass/send_str_hashmap.rs @@ -10,7 +10,6 @@ extern crate collections; -use std::collections::{Map, MutableMap}; use std::str::{SendStr, Owned, Slice}; use std::collections::HashMap; use std::option::Some; diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs index c6b872efa030c..f73ab8f52d7ed 100644 --- a/src/test/run-pass/send_str_treemap.rs +++ b/src/test/run-pass/send_str_treemap.rs @@ -10,7 +10,6 @@ extern crate collections; -use std::collections::{ Map, MutableMap}; use std::str::{SendStr, Owned, Slice}; use std::to_string::ToString; use self::collections::TreeMap;