Skip to content

Commit e02449c

Browse files
committed
Merge pull request #4571 from thestinger/container
more work on container traits
2 parents 0c276da + 6f4d86e commit e02449c

File tree

4 files changed

+191
-120
lines changed

4 files changed

+191
-120
lines changed

src/libcore/container.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,46 @@
1010

1111
//! Container traits
1212
13-
pub trait Set<T> {
13+
#[forbid(deprecated_mode)];
14+
#[forbid(deprecated_pattern)];
15+
16+
pub trait Container {
17+
/// Return the number of elements in the container
18+
pure fn len(&self) -> uint;
19+
20+
/// Return true if the container contains no elements
21+
pure fn is_empty(&self) -> bool;
22+
}
23+
24+
pub trait Mutable: Container {
25+
/// Clear the container, removing all values.
26+
fn clear(&mut self);
27+
}
28+
29+
pub trait Map<K, V>: Mutable {
30+
/// Return true if the map contains a value for the specified key
31+
pure fn contains_key(&self, key: &K) -> bool;
32+
33+
/// Visit all key-value pairs
34+
pure fn each(&self, f: fn(&K, &V) -> bool);
35+
36+
/// Visit all keys
37+
pure fn each_key(&self, f: fn(&K) -> bool);
38+
39+
/// Visit all values
40+
pure fn each_value(&self, f: fn(&V) -> bool);
41+
42+
/// Insert a key-value pair into the map. An existing value for a
43+
/// key is replaced by the new value. Return true if the key did
44+
/// not already exist in the map.
45+
fn insert(&mut self, key: K, value: V) -> bool;
46+
47+
/// Remove a key-value pair from the map. Return true if the key
48+
/// was present in the map, otherwise false.
49+
fn remove(&mut self, key: &K) -> bool;
50+
}
51+
52+
pub trait Set<T>: Mutable {
1453
/// Return true if the set contains a value
1554
pure fn contains(&self, value: &T) -> bool;
1655

src/libcore/send_map.rs

Lines changed: 54 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -23,31 +23,10 @@ use hash::Hash;
2323
use prelude::*;
2424
use to_bytes::IterBytes;
2525

26-
pub trait SendMap<K:Eq Hash, V: Copy> {
27-
// FIXME(#3148) ^^^^ once find_ref() works, we can drop V:copy
28-
29-
fn insert(&mut self, k: K, +v: V) -> bool;
30-
fn remove(&mut self, k: &K) -> bool;
31-
fn pop(&mut self, k: &K) -> Option<V>;
32-
fn swap(&mut self, k: K, +v: V) -> Option<V>;
33-
fn consume(&mut self, f: fn(K, V));
34-
fn clear(&mut self);
35-
pure fn len(&const self) -> uint;
36-
pure fn is_empty(&const self) -> bool;
37-
pure fn contains_key(&const self, k: &K) -> bool;
38-
pure fn each(&self, blk: fn(k: &K, v: &V) -> bool);
39-
pure fn each_key_ref(&self, blk: fn(k: &K) -> bool);
40-
pure fn each_value_ref(&self, blk: fn(v: &V) -> bool);
41-
pure fn find(&const self, k: &K) -> Option<V>;
42-
pure fn get(&const self, k: &K) -> V;
43-
pure fn find_ref(&self, k: &K) -> Option<&self/V>;
44-
pure fn get_ref(&self, k: &K) -> &self/V;
45-
}
46-
4726
/// Open addressing with linear probing.
4827
pub mod linear {
4928
use iter::BaseIter;
50-
use container::Set;
29+
use container::{Container, Mutable, Map, Set};
5130
use cmp::Eq;
5231
use cmp;
5332
use hash::Hash;
@@ -279,7 +258,48 @@ pub mod linear {
279258
}
280259
}
281260

282-
impl<K:Hash IterBytes Eq,V> LinearMap<K,V> {
261+
impl <K: Hash IterBytes Eq, V> LinearMap<K, V>: Container {
262+
pure fn len(&self) -> uint { self.size }
263+
pure fn is_empty(&self) -> bool { self.len() == 0 }
264+
}
265+
266+
impl <K: Hash IterBytes Eq, V> LinearMap<K, V>: Mutable {
267+
fn clear(&mut self) {
268+
for uint::range(0, self.buckets.len()) |idx| {
269+
self.buckets[idx] = None;
270+
}
271+
self.size = 0;
272+
}
273+
}
274+
275+
impl <K: Hash IterBytes Eq, V> LinearMap<K, V>: Map<K, V> {
276+
pure fn contains_key(&self, k: &K) -> bool {
277+
match self.bucket_for_key(self.buckets, k) {
278+
FoundEntry(_) => {true}
279+
TableFull | FoundHole(_) => {false}
280+
}
281+
}
282+
283+
pure fn each(&self, blk: fn(k: &K, v: &V) -> bool) {
284+
for vec::each(self.buckets) |slot| {
285+
let mut broke = false;
286+
do slot.iter |bucket| {
287+
if !blk(&bucket.key, &bucket.value) {
288+
broke = true; // FIXME(#3064) just write "break;"
289+
}
290+
}
291+
if broke { break; }
292+
}
293+
}
294+
295+
pure fn each_key(&self, blk: fn(k: &K) -> bool) {
296+
self.each(|k, _v| blk(k))
297+
}
298+
299+
pure fn each_value(&self, blk: fn(v: &V) -> bool) {
300+
self.each(|_k, v| blk(v))
301+
}
302+
283303
fn insert(&mut self, k: K, v: V) -> bool {
284304
if self.size >= self.resize_at {
285305
// n.b.: We could also do this after searching, so
@@ -301,7 +321,9 @@ pub mod linear {
301321
None => false,
302322
}
303323
}
324+
}
304325

326+
impl<K:Hash IterBytes Eq,V> LinearMap<K,V> {
305327
fn pop(&mut self, k: &K) -> Option<V> {
306328
let hash = k.hash_keyed(self.k0, self.k1) as uint;
307329
self.pop_internal(hash, k)
@@ -347,29 +369,6 @@ pub mod linear {
347369
}
348370
}
349371

350-
fn clear(&mut self) {
351-
for uint::range(0, self.buckets.len()) |idx| {
352-
self.buckets[idx] = None;
353-
}
354-
self.size = 0;
355-
}
356-
357-
pure fn len(&const self) -> uint {
358-
self.size
359-
}
360-
361-
pure fn is_empty(&const self) -> bool {
362-
self.len() == 0
363-
}
364-
365-
pure fn contains_key(&const self,
366-
k: &K) -> bool {
367-
match self.bucket_for_key(self.buckets, k) {
368-
FoundEntry(_) => {true}
369-
TableFull | FoundHole(_) => {false}
370-
}
371-
}
372-
373372
pure fn find_ref(&self, k: &K) -> Option<&self/V> {
374373
match self.bucket_for_key(self.buckets, k) {
375374
FoundEntry(idx) => {
@@ -396,26 +395,6 @@ pub mod linear {
396395
None => fail fmt!("No entry found for key: %?", k),
397396
}
398397
}
399-
400-
pure fn each(&self, blk: fn(k: &K, v: &V) -> bool) {
401-
for vec::each(self.buckets) |slot| {
402-
let mut broke = false;
403-
do slot.iter |bucket| {
404-
if !blk(&bucket.key, &bucket.value) {
405-
broke = true; // FIXME(#3064) just write "break;"
406-
}
407-
}
408-
if broke { break; }
409-
}
410-
}
411-
412-
pure fn each_key(&self, blk: fn(k: &K) -> bool) {
413-
self.each(|k, _v| blk(k))
414-
}
415-
416-
pure fn each_value(&self, blk: fn(v: &V) -> bool) {
417-
self.each(|_k, v| blk(v))
418-
}
419398
}
420399

421400
impl<K:Hash IterBytes Eq, V: Copy> LinearMap<K,V> {
@@ -482,6 +461,15 @@ pub mod linear {
482461
}
483462
}
484463

464+
impl <T: Hash IterBytes Eq> LinearSet<T>: Container {
465+
pure fn len(&self) -> uint { self.map.len() }
466+
pure fn is_empty(&self) -> bool { self.map.is_empty() }
467+
}
468+
469+
impl <T: Hash IterBytes Eq> LinearSet<T>: Mutable {
470+
fn clear(&mut self) { self.map.clear() }
471+
}
472+
485473
impl <T: Hash IterBytes Eq> LinearSet<T>: Set<T> {
486474
/// Return true if the set contains a value
487475
pure fn contains(&self, value: &T) -> bool {
@@ -500,12 +488,6 @@ pub mod linear {
500488
impl <T: Hash IterBytes Eq> LinearSet<T> {
501489
/// Create an empty LinearSet
502490
static fn new() -> LinearSet<T> { LinearSet{map: LinearMap()} }
503-
504-
/// Return the number of elements in the set
505-
pure fn len(&self) -> uint { self.map.len() }
506-
507-
/// Return true if the set contains no elements
508-
pure fn is_empty(&self) -> bool { self.map.is_empty() }
509491
}
510492
}
511493

src/libstd/priority_queue.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
//! A priority queue implemented with a binary heap
1212
13+
use core::container::{Container, Mutable};
1314
use core::cmp::Ord;
1415
use core::prelude::*;
1516
use core::ptr::addr_of;
@@ -24,6 +25,19 @@ pub struct PriorityQueue <T: Ord>{
2425
priv data: ~[T],
2526
}
2627

28+
impl <T: Ord> PriorityQueue<T>: Container {
29+
/// Returns the length of the queue
30+
pure fn len(&self) -> uint { self.data.len() }
31+
32+
/// Returns true if a queue contains no elements
33+
pure fn is_empty(&self) -> bool { self.data.is_empty() }
34+
}
35+
36+
impl <T: Ord> PriorityQueue<T>: Mutable {
37+
/// Drop all items from the queue
38+
fn clear(&mut self) { self.data.truncate(0) }
39+
}
40+
2741
impl <T: Ord> PriorityQueue<T> {
2842
/// Returns the greatest item in the queue - fails if empty
2943
pure fn top(&self) -> &self/T { &self.data[0] }
@@ -33,12 +47,6 @@ impl <T: Ord> PriorityQueue<T> {
3347
if self.is_empty() { None } else { Some(self.top()) }
3448
}
3549

36-
/// Returns the length of the queue
37-
pure fn len(&self) -> uint { self.data.len() }
38-
39-
/// Returns true if a queue contains no elements
40-
pure fn is_empty(&self) -> bool { self.data.is_empty() }
41-
4250
/// Returns true if a queue contains some elements
4351
pure fn is_not_empty(&self) -> bool { self.data.is_not_empty() }
4452

@@ -51,9 +59,6 @@ impl <T: Ord> PriorityQueue<T> {
5159
vec::reserve_at_least(&mut self.data, n)
5260
}
5361

54-
/// Drop all items from the queue
55-
fn clear(&mut self) { self.data.truncate(0) }
56-
5762
/// Pop the greatest item from the queue - fails if empty
5863
fn pop(&mut self) -> T {
5964
let mut item = self.data.pop();

0 commit comments

Comments
 (0)