smallintmap.rs 3.8 KB
Newer Older
1 2 3 4
/*!
 * A simple map based on a vector for small integer keys. Space requirements
 * are O(highest integer key).
 */
5 6
import core::option;
import core::option::{some, none};
N
Niko Matsakis 已提交
7
import dvec::{dvec, extensions};
8
import map::map;
9

10 11
// FIXME (#2347): Should not be @; there's a bug somewhere in rustc that
// requires this to be.
12 13 14 15 16
type smallintmap_<T: copy> = {v: dvec<option<T>>};

enum smallintmap<T:copy> {
    smallintmap_(@smallintmap_<T>)
}
17

18
/// Create a smallintmap
19
fn mk<T: copy>() -> smallintmap<T> {
20
    let v = dvec();
B
Brian Anderson 已提交
21
    return smallintmap_(@{v: v});
22 23
}

24 25 26 27
/**
 * Add a value to the map. If the map already contains a value for
 * the specified key then the original value is replaced.
 */
E
Eric Holk 已提交
28
#[inline(always)]
N
Niko Matsakis 已提交
29
fn insert<T: copy>(self: smallintmap<T>, key: uint, val: T) {
30
    //io::println(fmt!{"%?", key});
N
Niko Matsakis 已提交
31
    self.v.grow_set_elt(key, none, some(val));
32 33
}

34 35 36 37
/**
 * Get the value for the specified key. If the key does not exist
 * in the map then returns none
 */
38
pure fn find<T: copy>(self: smallintmap<T>, key: uint) -> option<T> {
B
Brian Anderson 已提交
39 40
    if key < self.v.len() { return self.v.get_elt(key); }
    return none::<T>;
41 42
}

43 44 45 46 47 48 49
/**
 * Get the value for the specified key
 *
 * # Failure
 *
 * If the key does not exist in the map
 */
50
pure fn get<T: copy>(self: smallintmap<T>, key: uint) -> T {
N
Niko Matsakis 已提交
51
    alt find(self, key) {
B
Brian Anderson 已提交
52 53 54 55 56
      none => {
        error!{"smallintmap::get(): key not present"};
        fail;
      }
      some(v) => return v
57 58 59
    }
}

60
/// Returns true if the map contains a value for the specified key
N
Niko Matsakis 已提交
61
fn contains_key<T: copy>(self: smallintmap<T>, key: uint) -> bool {
B
Brian Anderson 已提交
62
    return !option::is_none(find(self, key));
M
Marijn Haverbeke 已提交
63
}
64

65
/// Implements the map::map interface for smallintmap
66 67
impl <V: copy> of map::map<uint, V> for smallintmap<V> {
    fn size() -> uint {
68
        let mut sz = 0u;
B
Brian Anderson 已提交
69
        for self.v.each |item| {
B
Brian Anderson 已提交
70 71 72 73
            alt item {
              some(_) => sz += 1u,
              _ => ()
            }
74 75 76
        }
        sz
    }
E
Eric Holk 已提交
77
    #[inline(always)]
78
    fn insert(+key: uint, +value: V) -> bool {
79 80
        let exists = contains_key(self, key);
        insert(self, key, value);
B
Brian Anderson 已提交
81
        return !exists;
82
    }
83 84 85 86
    fn remove(+key: uint) -> option<V> {
        if key >= self.v.len() {
            return none;
        }
N
Niko Matsakis 已提交
87 88
        let old = self.v.get_elt(key);
        self.v.set_elt(key, none);
89 90
        old
    }
G
Glenn Willen 已提交
91 92 93
    fn clear() {
        self.v.set(~[mut]);
    }
94
    fn contains_key(+key: uint) -> bool {
95 96
        contains_key(self, key)
    }
97 98 99 100 101
    fn contains_key_ref(key: &uint) -> bool {
        contains_key(self, *key)
    }
    fn get(+key: uint) -> V { get(self, key) }
    fn find(+key: uint) -> option<V> { find(self, key) }
102
    fn rehash() { fail }
103
    fn each(it: fn(+key: uint, +value: V) -> bool) {
104 105
        let mut idx = 0u, l = self.v.len();
        while idx < l {
N
Niko Matsakis 已提交
106
            alt self.v.get_elt(idx) {
B
Brian Anderson 已提交
107 108
              some(elt) => if !it(idx, elt) { break }
              none => ()
109 110 111 112
            }
            idx += 1u;
        }
    }
113 114 115 116 117 118 119
    fn each_key(it: fn(+key: uint) -> bool) {
        self.each(|k, _v| it(k))
    }
    fn each_value(it: fn(+value: V) -> bool) {
        self.each(|_k, v| it(v))
    }
    fn each_ref(it: fn(key: &uint, value: &V) -> bool) {
120 121
        let mut idx = 0u, l = self.v.len();
        while idx < l {
122
            alt self.v.get_elt(idx) {
B
Brian Anderson 已提交
123 124
              some(elt) => if !it(&idx, &elt) { break }
              none => ()
125
            }
126 127 128
            idx += 1u;
        }
    }
129 130 131 132 133
    fn each_key_ref(blk: fn(key: &uint) -> bool) {
        self.each_ref(|k, _v| blk(k))
    }
    fn each_value_ref(blk: fn(value: &V) -> bool) {
        self.each_ref(|_k, v| blk(v))
134 135 136
    }
}

137 138 139 140 141 142 143 144
impl extensions<V: copy> of ops::index<uint, V> for smallintmap<V> {
    pure fn index(&&key: uint) -> V {
        unchecked {
            get(self, key)
        }
    }
}

145
/// Cast the given smallintmap to a map::map
146
fn as_map<V: copy>(s: smallintmap<V>) -> map::map<uint, V> {
147 148
    s as map::map::<uint, V>
}