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
import core::option;
B
Brian Anderson 已提交
6
import core::option::{Some, None};
7
import dvec::DVec;
8
import map::map;
9

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

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) {
P
Paul Stansifer 已提交
30
    //io::println(fmt!("%?", key));
B
Brian Anderson 已提交
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
 */
B
Brian Anderson 已提交
38
pure fn find<T: copy>(self: smallintmap<T>, key: uint) -> Option<T> {
B
Brian Anderson 已提交
39
    if key < self.v.len() { return self.v.get_elt(key); }
B
Brian Anderson 已提交
40
    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 {
51
    match find(self, key) {
B
Brian Anderson 已提交
52
      None => {
P
Paul Stansifer 已提交
53
        error!("smallintmap::get(): key not present");
B
Brian Anderson 已提交
54 55
        fail;
      }
B
Brian Anderson 已提交
56
      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
B
Brian Anderson 已提交
66
impl<V: copy> smallintmap<V>: map::map<uint, V> {
67
    pure fn size() -> uint {
68
        let mut sz = 0u;
B
Brian Anderson 已提交
69
        for self.v.each |item| {
70
            match item {
B
Brian Anderson 已提交
71
              Some(_) => sz += 1u,
B
Brian Anderson 已提交
72 73
              _ => ()
            }
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
    fn remove(+key: uint) -> bool {
84
        if key >= self.v.len() {
85
            return false;
86
        }
N
Niko Matsakis 已提交
87
        let old = self.v.get_elt(key);
B
Brian Anderson 已提交
88
        self.v.set_elt(key, None);
89
        old.is_some()
90
    }
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
    fn contains_key_ref(key: &uint) -> bool {
        contains_key(self, *key)
    }
    fn get(+key: uint) -> V { get(self, key) }
101
    pure fn find(+key: uint) -> Option<V> { find(self, key) }
102
    fn rehash() { fail }
103
    pure fn each(it: fn(+key: uint, +value: V) -> bool) {
104 105
        let mut idx = 0u, l = self.v.len();
        while idx < l {
106
            match 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
    pure fn each_key(it: fn(+key: uint) -> bool) {
114 115
        self.each(|k, _v| it(k))
    }
116
    pure fn each_value(it: fn(+value: V) -> bool) {
117 118
        self.each(|_k, v| it(v))
    }
119
    pure fn each_ref(it: fn(key: &uint, value: &V) -> bool) {
120 121
        let mut idx = 0u, l = self.v.len();
        while idx < l {
122
            match 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
    pure fn each_key_ref(blk: fn(key: &uint) -> bool) {
130 131
        self.each_ref(|k, _v| blk(k))
    }
132
    pure fn each_value_ref(blk: fn(value: &V) -> bool) {
133
        self.each_ref(|_k, v| blk(v))
134 135 136
    }
}

B
Brian Anderson 已提交
137
impl<V: copy> smallintmap<V>: ops::index<uint, V> {
138 139 140 141 142 143 144
    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>
}