Skip to content

Split mutable methods out of Set and Map #7768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 14, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 34 additions & 32 deletions src/libextra/bitv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,38 +718,6 @@ impl Set<uint> for BitvSet {
*value < self.bitv.storage.len() * uint::bits && self.bitv.get(*value)
}

fn insert(&mut self, value: uint) -> bool {
if self.contains(&value) {
return false;
}
let nbits = self.capacity();
if value >= nbits {
let newsize = num::max(value, nbits * 2) / uint::bits + 1;
assert!(newsize > self.bitv.storage.len());
self.bitv.storage.grow(newsize, &0);
}
self.size += 1;
self.bitv.set(value, true);
return true;
}

fn remove(&mut self, value: &uint) -> bool {
if !self.contains(value) {
return false;
}
self.size -= 1;
self.bitv.set(*value, false);

// Attempt to truncate our storage
let mut i = self.bitv.storage.len();
while i > 1 && self.bitv.storage[i - 1] == 0 {
i -= 1;
}
self.bitv.storage.truncate(i);

return true;
}

fn is_disjoint(&self, other: &BitvSet) -> bool {
for self.intersection(other) |_| {
return false;
Expand Down Expand Up @@ -816,6 +784,40 @@ impl Set<uint> for BitvSet {
}
}

impl MutableSet<uint> for BitvSet {
fn insert(&mut self, value: uint) -> bool {
if self.contains(&value) {
return false;
}
let nbits = self.capacity();
if value >= nbits {
let newsize = num::max(value, nbits * 2) / uint::bits + 1;
assert!(newsize > self.bitv.storage.len());
self.bitv.storage.grow(newsize, &0);
}
self.size += 1;
self.bitv.set(value, true);
return true;
}

fn remove(&mut self, value: &uint) -> bool {
if !self.contains(value) {
return false;
}
self.size -= 1;
self.bitv.set(*value, false);

// Attempt to truncate our storage
let mut i = self.bitv.storage.len();
while i > 1 && self.bitv.storage[i - 1] == 0 {
i -= 1;
}
self.bitv.storage.truncate(i);

return true;
}
}

impl BitvSet {
/// Visits each of the words that the two bit vectors (self and other)
/// both have in common. The three yielded arguments are (bit location,
Expand Down
23 changes: 13 additions & 10 deletions src/libextra/smallintmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@


use std::cmp;
use std::container::{Container, Mutable, Map, Set};
use std::iterator::*;
use std::iterator::{Iterator,IteratorUtil,ZipIterator,Counter,EnumerateIterator,FilterMapIterator};
use std::uint;
use std::util::replace;
use std::vec::{VecIterator,VecMutIterator,VecRevIterator,VecMutRevIterator};
Expand Down Expand Up @@ -68,7 +67,9 @@ impl<V> Map<uint, V> for SmallIntMap<V> {
None
}
}
}

impl<V> MutableMap<uint, V> for SmallIntMap<V> {
/// Return 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() {
Expand Down Expand Up @@ -349,14 +350,6 @@ impl Set<uint> for SmallIntSet {
/// Return true if the set contains a value
fn contains(&self, value: &uint) -> bool { self.map.contains_key(value) }

/// Add a value to the set. Return true if the value was not already
/// present in the set.
fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) }

/// Remove a value from the set. Return true if the value was
/// present in the set.
fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) }

/// Return true if the set has no elements in common with `other`.
/// This is equivalent to checking for an empty uintersection.
fn is_disjoint(&self, other: &SmallIntSet) -> bool {
Expand Down Expand Up @@ -412,6 +405,16 @@ impl Set<uint> for SmallIntSet {
}
}

impl MutableSet<uint> for SmallIntSet {
/// Add a value to the set. Return true if the value was not already
/// present in the set.
fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) }

/// Remove a value from the set. Return true if the value was
/// present in the set.
fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) }
}

impl SmallIntSet {
/// Create an empty SmallIntSet
pub fn new() -> SmallIntSet { SmallIntSet{map: SmallIntMap::new()} }
Expand Down
24 changes: 14 additions & 10 deletions src/libextra/treemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> {
}
}
}
}

impl<K: TotalOrd, V> MutableMap<K, V> for TreeMap<K, V> {
/// Return a mutable reference to the value corresponding to the key
#[inline]
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
Expand Down Expand Up @@ -293,16 +295,6 @@ impl<T: TotalOrd> Set<T> for TreeSet<T> {
self.map.contains_key(value)
}

/// Add a value to the set. Return true if the value was not already
/// present in the set.
#[inline]
fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }

/// Remove a value from the set. Return true if the value was
/// present in the set.
#[inline]
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }

/// Return true if the set has no elements in common with `other`.
/// This is equivalent to checking for an empty intersection.
fn is_disjoint(&self, other: &TreeSet<T>) -> bool {
Expand Down Expand Up @@ -475,6 +467,18 @@ impl<T: TotalOrd> Set<T> for TreeSet<T> {
}
}

impl<T: TotalOrd> MutableSet<T> for TreeSet<T> {
/// Add a value to the set. Return true if the value was not already
/// present in the set.
#[inline]
fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }

/// Remove a value from the set. Return true if the value was
/// present in the set.
#[inline]
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
}

impl<T: TotalOrd> TreeSet<T> {
/// Create an empty TreeSet
#[inline]
Expand Down
37 changes: 22 additions & 15 deletions src/libstd/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ pub trait Mutable: Container {

/// A map is 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<K, V>: Mutable {
pub trait Map<K, V>: Container {
/// Return true if the map contains a value for the specified key
fn contains_key(&self, key: &K) -> bool;

/// Return a reference to the value corresponding to the key
fn find<'a>(&'a self, key: &K) -> Option<&'a V>;
}

/// Return a mutable reference to the value corresponding to the key
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>;

/// This trait provides basic operations to modify the contents of a map.
pub trait MutableMap<K, V>: Map<K, V> + Mutable {
/// 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.
Expand All @@ -56,23 +56,18 @@ pub trait Map<K, V>: Mutable {
/// Removes a key from the map, returning the value at the key if the key
/// was previously in the map.
fn pop(&mut self, k: &K) -> Option<V>;

/// Return a mutable reference to the value corresponding to the key
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>;
}

/// A set is a group of objects which are each distinct from one another. This
/// trait represents actions which can be performed on sets to manipulate and
/// iterate over them.
pub trait Set<T>: Mutable {
/// trait represents actions which can be performed on sets to iterate over
/// them.
pub trait Set<T>: Container {
/// Return true if the set contains a value
fn contains(&self, value: &T) -> bool;

/// Add a value to the set. Return true if the value was not already
/// present in the set.
fn insert(&mut self, value: T) -> bool;

/// Remove a value from the set. Return true if the value was
/// present in the set.
fn remove(&mut self, value: &T) -> bool;

/// Return true if the set has no elements in common with `other`.
/// This is equivalent to checking for an empty intersection.
fn is_disjoint(&self, other: &Self) -> bool;
Expand All @@ -95,3 +90,15 @@ pub trait Set<T>: Mutable {
/// Visit the values representing the union
fn union(&self, other: &Self, f: &fn(&T) -> bool) -> bool;
}

/// This trait represents actions which can be performed on sets to mutate
/// them.
pub trait MutableSet<T>: Set<T> + Mutable {
/// Add a value to the set. Return true if the value was not already
/// present in the set.
fn insert(&mut self, value: T) -> bool;

/// Remove a value from the set. Return true if the value was
/// present in the set.
fn remove(&mut self, value: &T) -> bool;
}
2 changes: 1 addition & 1 deletion src/libstd/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ with destructors.
*/

use cast;
use container::{Map, Set};
use container::{Set, MutableSet};
use io;
use libc::{uintptr_t};
use option::{None, Option, Some};
Expand Down
22 changes: 13 additions & 9 deletions src/libstd/hashmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#[mutable_doc];

use container::{Container, Mutable, Map, Set};
use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
use cmp::{Eq, Equiv};
use hash::Hash;
use iterator::{Iterator, IteratorUtil};
Expand Down Expand Up @@ -316,7 +316,9 @@ impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> {
TableFull | FoundHole(_) => None,
}
}
}

impl<K:Hash + Eq,V> MutableMap<K, V> for HashMap<K, V> {
/// Return a mutable reference to the value corresponding to the key
fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
let idx = match self.bucket_for_key(k) {
Expand Down Expand Up @@ -640,14 +642,6 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
/// Return true if the set contains a value
fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }

/// Add a value to the set. Return true if the value was not already
/// present in the set.
fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }

/// Remove a value from the set. Return true if the value was
/// present in the set.
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }

/// Return true if the set has no elements in common with `other`.
/// This is equivalent to checking for an empty intersection.
fn is_disjoint(&self, other: &HashSet<T>) -> bool {
Expand Down Expand Up @@ -688,6 +682,16 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
}
}

impl<T:Hash + Eq> MutableSet<T> for HashSet<T> {
/// Add a value to the set. Return true if the value was not already
/// present in the set.
fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }

/// Remove a value from the set. Return true if the value was
/// present in the set.
fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
}

impl<T:Hash + Eq> HashSet<T> {
/// Create an empty HashSet
pub fn new() -> HashSet<T> {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub use io::{print, println};
pub use clone::{Clone, DeepClone};
pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv};
pub use char::Char;
pub use container::{Container, Mutable, Map, Set};
pub use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
pub use hash::Hash;
pub use iter::Times;
pub use iterator::{Iterator, IteratorUtil, DoubleEndedIterator, DoubleEndedIteratorUtil};
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/task/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ use prelude::*;
use cast::transmute;
use cast;
use cell::Cell;
use container::Map;
use container::MutableMap;
use comm::{Chan, GenericChan};
use hashmap::HashSet;
use task::local_data_priv::{local_get, local_set, OldHandle};
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/to_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl<A:ToStr> ToStr for @[A] {
mod tests {
use hashmap::HashMap;
use hashmap::HashSet;
use container::{Set, Map};
use container::{Set, Map, MutableSet, MutableMap};
#[test]
fn test_simple_types() {
assert_eq!(1i.to_str(), ~"1");
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ impl<T> Map<uint, T> for TrieMap<T> {
idx += 1;
}
}
}

impl<T> MutableMap<uint, T> for TrieMap<T> {
/// Return a mutable reference to the value corresponding to the key
#[inline]
fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
Expand Down
6 changes: 3 additions & 3 deletions src/test/bench/core-map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn timed(label: &str, f: &fn()) {
io::println(fmt!(" %s: %f", label, end - start));
}

fn ascending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
fn ascending<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint) {
io::println(" Ascending integers:");

do timed("insert") {
Expand All @@ -49,7 +49,7 @@ fn ascending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
}
}

fn descending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
fn descending<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint) {
io::println(" Descending integers:");

do timed("insert") {
Expand All @@ -71,7 +71,7 @@ fn descending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
}
}

fn vector<M: Map<uint, uint>>(map: &mut M, n_keys: uint, dist: &[uint]) {
fn vector<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint, dist: &[uint]) {

do timed("insert") {
for uint::range(0, n_keys) |i| {
Expand Down
4 changes: 2 additions & 2 deletions src/test/bench/core-set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn timed(result: &mut float, op: &fn()) {
}

impl Results {
pub fn bench_int<T:Set<uint>,
pub fn bench_int<T:MutableSet<uint>,
R: rand::Rng>(
&mut self,
rng: &mut R,
Expand Down Expand Up @@ -79,7 +79,7 @@ impl Results {
}
}

pub fn bench_str<T:Set<~str>,
pub fn bench_str<T:MutableSet<~str>,
R:rand::Rng>(
&mut self,
rng: &mut R,
Expand Down
Loading