Skip to content

Instantly share code, notes, and snippets.

@toffaletti
Created September 30, 2013 20:55
Show Gist options
  • Save toffaletti/6770126 to your computer and use it in GitHub Desktop.
Save toffaletti/6770126 to your computer and use it in GitHub Desktop.
use std::vec;
use std::util::replace;
pub struct FlatMap<K, V> {
priv data: ~[(K, V)],
}
impl<K, V> FlatMap<K, V> {
fn new(capacity: uint) -> FlatMap<K, V> {
FlatMap{data: vec::with_capacity(capacity)}
}
fn capacity(&self) -> uint {
self.data.capacity()
}
}
impl<K, V> Container for FlatMap<K, V> {
fn len(&self) -> uint {
self.data.len()
}
}
impl<K, V> Mutable for FlatMap<K, V> {
fn clear(&mut self) {
self.data.clear();
}
}
impl<K: Eq, V> Map<K, V> for FlatMap<K, V> {
fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
for &(ref k, ref v) in self.data.iter() {
if key == k {
return Some(v)
}
}
None
}
fn contains_key(&self, key: &K) -> bool {
match self.find(key) {
Some(_) => true,
None => false
}
}
}
impl<K: Eq, V> MutableMap<K, V> for FlatMap<K, V> {
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
for &(ref k, ref mut v) in self.data.mut_iter() {
if key == k {
return Some(v)
}
}
None
}
fn swap(&mut self, k: K, v: V) -> Option<V> {
let result = self.find_mut(&k);
match result {
Some(val) => {
Some(replace(val, v))
}
None => {
self.data.push((k, v));
None
}
}
}
fn pop(&mut self, k: &K) -> Option<V> {
None
}
}
#[test]
fn test_init() {
let m: FlatMap<int, int> = FlatMap::new(10);
assert!(10 == m.capacity());
assert!(0 == m.len());
}
#[test]
fn test_map() {
let m: FlatMap<int, int> = FlatMap::new(10);
assert!(m.find(&0) == None);
assert!(m.contains_key(&0) == false);
}
@toffaletti
Copy link
Author

I tried letting the result of self.find_mut go out of scope before using self.data.push.

fn swap(&mut self, k: K, v: V) -> Option<V> {
    let result = match self.find_mut(&k) {
        Some(val) => {                        
            Some(replace(val, v))             
        }                                     
        None => None                          
    };                                        
    if result.is_none() {                     
        self.data.push((k, v));               
    }                                         
    result                                    
}

but it wouldn't let me use v because it might have been moved in the Some(replace(val, v)) branch.

@toffaletti
Copy link
Author

I ended up with this ugly work-around:

fn swap(&mut self, k: K, v: V) -> Option<V> {
    match self.contains_key(&k) {            
        true => {                            
            match self.find_mut(&k) {        
                Some(val) => {               
                    Some(replace(val, v))    
                }                            
                None => {                    
                    None                     
                }                            
            }                                
        }                                    
        false => {                           
            self.data.push((k, v));          
            None                             
        }                                    
    }                                        
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment