diff --git a/src/libcore/container.rs b/src/libcore/container.rs index f8ccd0148ab7..dd556aec45f8 100644 --- a/src/libcore/container.rs +++ b/src/libcore/container.rs @@ -10,11 +10,37 @@ //! Container traits +#[forbid(deprecated_mode)]; +#[forbid(deprecated_pattern)]; + pub trait Mutable { /// 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 5f440aa6d37b..812b138097a8 100644 --- a/src/libcore/send_map.rs +++ b/src/libcore/send_map.rs @@ -23,30 +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)); - 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::{Mutable, Set}; + use container::{Mutable, Map, Set}; use cmp::Eq; use cmp; use hash::Hash; @@ -287,7 +267,34 @@ pub mod linear { } } - impl LinearMap { + 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 @@ -309,7 +316,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) @@ -363,14 +372,6 @@ pub mod linear { 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) => { @@ -397,26 +398,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 { diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 74a14b7903cc..ff60d7d1c2bd 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -14,7 +14,7 @@ #[forbid(deprecated_mode)]; -use core::container::{Mutable, Set}; +use core::container::{Mutable, Map, Set}; use core::cmp::{Eq, Ord}; use core::option::{Option, Some, None}; use core::prelude::*; @@ -75,6 +75,39 @@ impl TreeMap: Mutable { } } +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) } + + /// Visit all keys in order + pure fn each_key(&self, f: fn(&K) -> bool) { self.each(|k, _| f(k)) } + + /// 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} } @@ -88,15 +121,6 @@ impl TreeMap { /// 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 order - pure fn each(&self, f: fn(&K, &V) -> bool) { each(&self.root, f) } - - /// Visit all keys in order - pure fn each_key(&self, f: fn(&K) -> bool) { self.each(|k, _| f(k)) } - - /// Visit all values in order - pure fn each_value(&self, f: fn(&V) -> bool) { self.each(|_, v| f(v)) } - /// Visit all key-value pairs in reverse order pure fn each_reverse(&self, f: fn(&K, &V) -> bool) { each_reverse(&self.root, f); @@ -112,11 +136,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; @@ -137,23 +156,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 {