smallintmap.rs 3.9 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).
 */
K
Kevin Cantu 已提交
5 6 7
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

P
Patrick Walton 已提交
8 9 10 11
use core::option;
use core::option::{Some, None};
use dvec::DVec;
use map::map;
12

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

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

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

27 28 29 30
/**
 * 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 已提交
31
#[inline(always)]
K
Kevin Cantu 已提交
32
fn insert<T: copy>(self: smallintmap<T>, key: uint, +val: T) {
P
Paul Stansifer 已提交
33
    //io::println(fmt!("%?", key));
B
Brian Anderson 已提交
34
    self.v.grow_set_elt(key, None, Some(val));
35 36
}

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

46 47 48 49 50 51 52
/**
 * Get the value for the specified key
 *
 * # Failure
 *
 * If the key does not exist in the map
 */
53
pure fn get<T: copy>(self: smallintmap<T>, key: uint) -> T {
54
    match find(self, key) {
B
Brian Anderson 已提交
55
      None => {
P
Paul Stansifer 已提交
56
        error!("smallintmap::get(): key not present");
B
Brian Anderson 已提交
57 58
        fail;
      }
B
Brian Anderson 已提交
59
      Some(v) => return v
60 61 62
    }
}

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

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

B
Brian Anderson 已提交
140
impl<V: copy> smallintmap<V>: ops::Index<uint, V> {
141 142 143 144 145 146 147
    pure fn index(&&key: uint) -> V {
        unchecked {
            get(self, key)
        }
    }
}

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