diff --git a/src/libcore/container.rs b/src/libcore/container.rs index 619622ceb95..062416838cc 100644 --- a/src/libcore/container.rs +++ b/src/libcore/container.rs @@ -10,7 +10,46 @@ //! Container traits -pub trait Set { +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + +pub trait Container { + /// Return the number of elements in the container + pure fn len(&self) -> uint; + + /// Return true if the container contains no elements + pure fn is_empty(&self) -> bool; +} + +pub trait Mutable: Container { + /// Clear the container, removing all values. + fn clear(&mut self); +} + +pub trait Map: Mutable { + /// Return true if the map contains a value for the specified key + pure fn contains_key(&self, key: &K) -> bool; + + /// Visit all key-value pairs + pure fn each(&self, f: fn(&K, &V) -> bool); + + /// Visit all keys + pure fn each_key(&self, f: fn(&K) -> bool); + + /// Visit all values + pure fn each_value(&self, f: fn(&V) -> bool); + + /// Insert a key-value pair into the map. An existing value for a + /// key is replaced by the new value. Return true if the key did + /// not already exist in the map. + fn insert(&mut self, key: K, value: V) -> bool; + + /// Remove a key-value pair from the map. Return true if the key + /// was present in the map, otherwise false. + fn remove(&mut self, key: &K) -> bool; +} + +pub trait Set: Mutable { /// Return true if the set contains a value pure fn contains(&self, value: &T) -> bool; diff --git a/src/libcore/send_map.rs b/src/libcore/send_map.rs index 1e526c5d08f..dc4e24c4f8a 100644 --- a/src/libcore/send_map.rs +++ b/src/libcore/send_map.rs @@ -23,31 +23,10 @@ use hash::Hash; use prelude::*; use to_bytes::IterBytes; -pub trait SendMap { - // FIXME(#3148) ^^^^ once find_ref() works, we can drop V:copy - - fn insert(&mut self, k: K, +v: V) -> bool; - fn remove(&mut self, k: &K) -> bool; - fn pop(&mut self, k: &K) -> Option; - fn swap(&mut self, k: K, +v: V) -> Option; - fn consume(&mut self, f: fn(K, V)); - fn clear(&mut self); - pure fn len(&const self) -> uint; - pure fn is_empty(&const self) -> bool; - pure fn contains_key(&const self, k: &K) -> bool; - pure fn each(&self, blk: fn(k: &K, v: &V) -> bool); - pure fn each_key_ref(&self, blk: fn(k: &K) -> bool); - pure fn each_value_ref(&self, blk: fn(v: &V) -> bool); - pure fn find(&const self, k: &K) -> Option; - pure fn get(&const self, k: &K) -> V; - pure fn find_ref(&self, k: &K) -> Option<&self/V>; - pure fn get_ref(&self, k: &K) -> &self/V; -} - /// Open addressing with linear probing. pub mod linear { use iter::BaseIter; - use container::Set; + use container::{Container, Mutable, Map, Set}; use cmp::Eq; use cmp; use hash::Hash; @@ -279,7 +258,48 @@ pub mod linear { } } - impl LinearMap { + impl LinearMap: Container { + pure fn len(&self) -> uint { self.size } + pure fn is_empty(&self) -> bool { self.len() == 0 } + } + + impl LinearMap: Mutable { + fn clear(&mut self) { + for uint::range(0, self.buckets.len()) |idx| { + self.buckets[idx] = None; + } + self.size = 0; + } + } + + impl LinearMap: Map { + pure fn contains_key(&self, k: &K) -> bool { + match self.bucket_for_key(self.buckets, k) { + FoundEntry(_) => {true} + TableFull | FoundHole(_) => {false} + } + } + + pure fn each(&self, blk: fn(k: &K, v: &V) -> bool) { + for vec::each(self.buckets) |slot| { + let mut broke = false; + do slot.iter |bucket| { + if !blk(&bucket.key, &bucket.value) { + broke = true; // FIXME(#3064) just write "break;" + } + } + if broke { break; } + } + } + + pure fn each_key(&self, blk: fn(k: &K) -> bool) { + self.each(|k, _v| blk(k)) + } + + pure fn each_value(&self, blk: fn(v: &V) -> bool) { + self.each(|_k, v| blk(v)) + } + fn insert(&mut self, k: K, v: V) -> bool { if self.size >= self.resize_at { // n.b.: We could also do this after searching, so @@ -301,7 +321,9 @@ pub mod linear { None => false, } } + } + impl LinearMap { fn pop(&mut self, k: &K) -> Option { let hash = k.hash_keyed(self.k0, self.k1) as uint; self.pop_internal(hash, k) @@ -347,29 +369,6 @@ pub mod linear { } } - fn clear(&mut self) { - for uint::range(0, self.buckets.len()) |idx| { - self.buckets[idx] = None; - } - self.size = 0; - } - - pure fn len(&const self) -> uint { - self.size - } - - pure fn is_empty(&const self) -> bool { - self.len() == 0 - } - - pure fn contains_key(&const self, - k: &K) -> bool { - match self.bucket_for_key(self.buckets, k) { - FoundEntry(_) => {true} - TableFull | FoundHole(_) => {false} - } - } - pure fn find_ref(&self, k: &K) -> Option<&self/V> { match self.bucket_for_key(self.buckets, k) { FoundEntry(idx) => { @@ -396,26 +395,6 @@ pub mod linear { None => fail fmt!("No entry found for key: %?", k), } } - - pure fn each(&self, blk: fn(k: &K, v: &V) -> bool) { - for vec::each(self.buckets) |slot| { - let mut broke = false; - do slot.iter |bucket| { - if !blk(&bucket.key, &bucket.value) { - broke = true; // FIXME(#3064) just write "break;" - } - } - if broke { break; } - } - } - - pure fn each_key(&self, blk: fn(k: &K) -> bool) { - self.each(|k, _v| blk(k)) - } - - pure fn each_value(&self, blk: fn(v: &V) -> bool) { - self.each(|_k, v| blk(v)) - } } impl LinearMap { @@ -482,6 +461,15 @@ pub mod linear { } } + impl LinearSet: Container { + pure fn len(&self) -> uint { self.map.len() } + pure fn is_empty(&self) -> bool { self.map.is_empty() } + } + + impl LinearSet: Mutable { + fn clear(&mut self) { self.map.clear() } + } + impl LinearSet: Set { /// Return true if the set contains a value pure fn contains(&self, value: &T) -> bool { @@ -500,12 +488,6 @@ pub mod linear { impl LinearSet { /// Create an empty LinearSet static fn new() -> LinearSet { LinearSet{map: LinearMap()} } - - /// Return the number of elements in the set - pure fn len(&self) -> uint { self.map.len() } - - /// Return true if the set contains no elements - pure fn is_empty(&self) -> bool { self.map.is_empty() } } } diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index b9c040de42a..ee78fafb60b 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -10,6 +10,7 @@ //! A priority queue implemented with a binary heap +use core::container::{Container, Mutable}; use core::cmp::Ord; use core::prelude::*; use core::ptr::addr_of; @@ -24,6 +25,19 @@ pub struct PriorityQueue { priv data: ~[T], } +impl PriorityQueue: Container { + /// Returns the length of the queue + pure fn len(&self) -> uint { self.data.len() } + + /// Returns true if a queue contains no elements + pure fn is_empty(&self) -> bool { self.data.is_empty() } +} + +impl PriorityQueue: Mutable { + /// Drop all items from the queue + fn clear(&mut self) { self.data.truncate(0) } +} + impl PriorityQueue { /// Returns the greatest item in the queue - fails if empty pure fn top(&self) -> &self/T { &self.data[0] } @@ -33,12 +47,6 @@ impl PriorityQueue { if self.is_empty() { None } else { Some(self.top()) } } - /// Returns the length of the queue - pure fn len(&self) -> uint { self.data.len() } - - /// Returns true if a queue contains no elements - pure fn is_empty(&self) -> bool { self.data.is_empty() } - /// Returns true if a queue contains some elements pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() } @@ -51,9 +59,6 @@ impl PriorityQueue { vec::reserve_at_least(&mut self.data, n) } - /// Drop all items from the queue - fn clear(&mut self) { self.data.truncate(0) } - /// Pop the greatest item from the queue - fails if empty fn pop(&mut self) -> T { let mut item = self.data.pop(); diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 1b20b35bda1..0bb8738773c 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -14,7 +14,7 @@ #[forbid(deprecated_mode)]; -use core::container::Set; +use core::container::{Container, Mutable, Map, Set}; use core::cmp::{Eq, Ord}; use core::option::{Option, Some, None}; use core::prelude::*; @@ -64,23 +64,30 @@ impl TreeMap: Eq { true } } - pure fn ne(&self, other: &TreeMap) -> bool { - !self.eq(other) - } + pure fn ne(&self, other: &TreeMap) -> bool { !self.eq(other) } } -impl TreeMap { - /// Create an empty TreeMap - static pure fn new() -> TreeMap { TreeMap{root: None, length: 0} } - +impl TreeMap: Container { /// Return the number of elements in the map pure fn len(&self) -> uint { self.length } /// Return true if the map contains no elements pure fn is_empty(&self) -> bool { self.root.is_none() } +} - /// Return true if the map contains some elements - pure fn is_not_empty(&self) -> bool { self.root.is_some() } +impl TreeMap: Mutable { + /// Clear the map, removing all key-value pairs. + fn clear(&mut self) { + self.root = None; + self.length = 0 + } +} + +impl TreeMap: Map { + /// Return true if the map contains a value for the specified key + pure fn contains_key(&self, key: &K) -> bool { + self.find(key).is_some() + } /// Visit all key-value pairs in order pure fn each(&self, f: fn(&K, &V) -> bool) { each(&self.root, f) } @@ -91,6 +98,31 @@ impl TreeMap { /// Visit all values in order pure fn each_value(&self, f: fn(&V) -> bool) { self.each(|_, v| f(v)) } + /// Insert a key-value pair into the map. An existing value for a + /// key is replaced by the new value. Return true if the key did + /// not already exist in the map. + fn insert(&mut self, key: K, value: V) -> bool { + let ret = insert(&mut self.root, key, value); + if ret { self.length += 1 } + ret + } + + /// Remove a key-value pair from the map. Return true if the key + /// was present in the map, otherwise false. + fn remove(&mut self, key: &K) -> bool { + let ret = remove(&mut self.root, key); + if ret { self.length -= 1 } + ret + } +} + +impl TreeMap { + /// Create an empty TreeMap + static pure fn new() -> TreeMap { TreeMap{root: None, length: 0} } + + /// Return true if the map contains some elements + pure fn is_not_empty(&self) -> bool { self.root.is_some() } + /// Visit all key-value pairs in reverse order pure fn each_reverse(&self, f: fn(&K, &V) -> bool) { each_reverse(&self.root, f); @@ -106,11 +138,6 @@ impl TreeMap { self.each_reverse(|_, v| f(v)) } - /// Return true if the map contains a value for the specified key - pure fn contains_key(&self, key: &K) -> bool { - self.find(key).is_some() - } - /// Return the value corresponding to the key in the map pure fn find(&self, key: &K) -> Option<&self/V> { let mut current: &self/Option<~TreeNode> = &self.root; @@ -131,23 +158,6 @@ impl TreeMap { } } - /// Insert a key-value pair into the map. An existing value for a - /// key is replaced by the new value. Return true if the key did - /// not already exist in the map. - fn insert(&mut self, key: K, value: V) -> bool { - let ret = insert(&mut self.root, key, value); - if ret { self.length += 1 } - ret - } - - /// Remove a key-value pair from the map. Return true if the key - /// was present in the map, otherwise false. - fn remove(&mut self, key: &K) -> bool { - let ret = remove(&mut self.root, key); - if ret { self.length -= 1 } - ret - } - /// Get a lazy iterator over the key-value pairs in the map. /// Requires that it be frozen (immutable). pure fn iter(&self) -> TreeMapIterator/&self { @@ -198,6 +208,19 @@ impl TreeSet: Eq { pure fn ne(&self, other: &TreeSet) -> bool { self.map != other.map } } +impl TreeSet: Container { + /// Return the number of elements in the map + pure fn len(&self) -> uint { self.map.len() } + + /// Return true if the map contains no elements + pure fn is_empty(&self) -> bool { self.map.is_empty() } +} + +impl TreeSet: Mutable { + /// Clear the set, removing all values. + fn clear(&mut self) { self.map.clear() } +} + impl TreeSet: Set { /// Return true if the set contains a value pure fn contains(&self, value: &T) -> bool { @@ -217,12 +240,6 @@ impl TreeSet { /// Create an empty TreeSet static pure fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } - /// Return the number of elements in the set - pure fn len(&self) -> uint { self.map.len() } - - /// Return true if the set contains no elements - pure fn is_empty(&self) -> bool { self.map.is_empty() } - /// Return true if the set contains some elements pure fn is_not_empty(&self) -> bool { self.map.is_not_empty() } @@ -626,6 +643,20 @@ mod test_treemap { assert m.find(&2).unwrap() == &11; } + #[test] + fn test_clear() { + let mut m = TreeMap::new(); + m.clear(); + assert m.insert(5, 11); + assert m.insert(12, -3); + assert m.insert(19, 2); + m.clear(); + assert m.find(&5).is_none(); + assert m.find(&12).is_none(); + assert m.find(&19).is_none(); + assert m.is_empty(); + } + #[test] fn u8_map() { let mut m = TreeMap::new(); @@ -846,6 +877,20 @@ mod test_treemap { mod test_set { use super::*; + #[test] + fn test_clear() { + let mut s = TreeSet::new(); + s.clear(); + assert s.insert(5); + assert s.insert(12); + assert s.insert(19); + s.clear(); + assert !s.contains(&5); + assert !s.contains(&12); + assert !s.contains(&19); + assert s.is_empty(); + } + #[test] fn test_disjoint() { let mut xs = TreeSet::new();