add a container::Map trait

This commit is contained in:
Daniel Micay 2013-01-21 18:22:03 -05:00
parent ffb9049274
commit d635a6e506
3 changed files with 91 additions and 82 deletions

View File

@ -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<K, V>: 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<T>: Mutable {
/// Return true if the set contains a value
pure fn contains(&self, value: &T) -> bool;

View File

@ -23,30 +23,10 @@ use hash::Hash;
use prelude::*;
use to_bytes::IterBytes;
pub trait SendMap<K:Eq Hash, V: Copy> {
// 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<V>;
fn swap(&mut self, k: K, +v: V) -> Option<V>;
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<V>;
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<K:Hash IterBytes Eq,V> LinearMap<K,V> {
impl <K: Hash IterBytes Eq, V> LinearMap<K, V>: Map<K, V> {
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<K:Hash IterBytes Eq,V> LinearMap<K,V> {
fn pop(&mut self, k: &K) -> Option<V> {
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<K:Hash IterBytes Eq, V: Copy> LinearMap<K,V> {

View File

@ -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 <K: Ord, V> TreeMap<K, V>: Mutable {
}
}
impl <K: Ord, V> TreeMap<K, V>: Map<K, 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()
}
/// 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 <K: Ord, V> TreeMap<K, V> {
/// Create an empty TreeMap
static pure fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
@ -88,15 +121,6 @@ impl <K: Ord, V> TreeMap<K, V> {
/// 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 <K: Ord, V> TreeMap<K, V> {
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<K, V>> = &self.root;
@ -137,23 +156,6 @@ impl <K: Ord, V> TreeMap<K, 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
}
/// Get a lazy iterator over the key-value pairs in the map.
/// Requires that it be frozen (immutable).
pure fn iter(&self) -> TreeMapIterator/&self<K, V> {