smallintmap.rs 3.1 KB
Newer Older
B
Brian Anderson 已提交
1
#[doc = "
B
Brian Anderson 已提交
2 3
A simple map based on a vector for small integer keys. Space requirements
are O(highest integer key).
B
Brian Anderson 已提交
4
"];
5 6
import core::option;
import core::option::{some, none};
7

8 9
// FIXME: Should not be @; there's a bug somewhere in rustc that requires this
// to be.
T
Tim Chevalier 已提交
10
type smallintmap<T> = @{mutable v: [mutable option<T>]};
11

B
Brian Anderson 已提交
12
#[doc = "Create a smallintmap"]
13
fn mk<T>() -> smallintmap<T> {
T
Tim Chevalier 已提交
14
    let v: [mutable option<T>] = [mutable];
M
Marijn Haverbeke 已提交
15
    ret @{mutable v: v};
16 17
}

B
Brian Anderson 已提交
18
#[doc = "
B
Brian Anderson 已提交
19 20
Add a value to the map. If the map already contains a value for
the specified key then the original value is replaced.
B
Brian Anderson 已提交
21
"]
22
fn insert<T: copy>(m: smallintmap<T>, key: uint, val: T) {
T
Tim Chevalier 已提交
23
    vec::grow_set::<option<T>>(m.v, key, none::<T>, some::<T>(val));
24 25
}

B
Brian Anderson 已提交
26
#[doc = "
B
Brian Anderson 已提交
27
Get the value for the specified key. If the key does not exist
28
in the map then returns none
B
Brian Anderson 已提交
29
"]
T
Tim Chevalier 已提交
30 31
fn find<T: copy>(m: smallintmap<T>, key: uint) -> option<T> {
    if key < vec::len::<option<T>>(m.v) { ret m.v[key]; }
32
    ret none::<T>;
33 34
}

B
Brian Anderson 已提交
35
#[doc = "
B
Brian Anderson 已提交
36 37
Get the value for the specified key

B
Brian Anderson 已提交
38
# Failure
B
Brian Anderson 已提交
39 40

If the key does not exist in the map
B
Brian Anderson 已提交
41
"]
42
fn get<T: copy>(m: smallintmap<T>, key: uint) -> T {
43
    alt find(m, key) {
44
      none { #error("smallintmap::get(): key not present"); fail; }
45
      some(v) { ret v; }
46 47 48
    }
}

B
Brian Anderson 已提交
49
#[doc = "
B
Brian Anderson 已提交
50
Returns true if the map contains a value for the specified key
B
Brian Anderson 已提交
51
"]
52
fn contains_key<T: copy>(m: smallintmap<T>, key: uint) -> bool {
53
    ret !option::is_none(find::<T>(m, key));
54 55
}

B
Brian Anderson 已提交
56 57
// FIXME: Are these really useful?

58
fn truncate<T: copy>(m: smallintmap<T>, len: uint) {
59
    m.v = vec::to_mut(vec::slice::<option<T>>(m.v, 0u, len));
60 61
}

62
fn max_key<T>(m: smallintmap<T>) -> uint {
T
Tim Chevalier 已提交
63
    ret vec::len::<option<T>>(m.v);
M
Marijn Haverbeke 已提交
64
}
65

B
Brian Anderson 已提交
66
#[doc = "Implements the map::map interface for smallintmap"]
67 68 69 70 71 72 73 74 75 76 77 78 79
impl <V: copy> of map::map<uint, V> for smallintmap<V> {
    fn size() -> uint {
        let sz = 0u;
        for item in self.v {
            alt item { some(_) { sz += 1u; } _ {} }
        }
        sz
    }
    fn insert(&&key: uint, value: V) -> bool {
        let exists = contains_key(self, key);
        insert(self, key, value);
        ret !exists;
    }
T
Tim Chevalier 已提交
80
    fn remove(&&key: uint) -> option<V> {
81 82 83 84 85 86 87 88 89
        if key >= vec::len(self.v) { ret none; }
        let old = self.v[key];
        self.v[key] = none;
        old
    }
    fn contains_key(&&key: uint) -> bool {
        contains_key(self, key)
    }
    fn get(&&key: uint) -> V { get(self, key) }
T
Tim Chevalier 已提交
90
    fn find(&&key: uint) -> option<V> { find(self, key) }
91
    fn rehash() { fail }
N
Niko Matsakis 已提交
92
    fn items(it: fn(&&uint, V)) {
93 94 95 96 97 98
        let idx = 0u;
        for item in self.v {
            alt item {
              some(elt) {
                it(idx, elt);
              }
99
              none { }
100 101 102 103
            }
            idx += 1u;
        }
    }
N
Niko Matsakis 已提交
104
    fn keys(it: fn(&&uint)) {
105 106 107 108 109 110
        let idx = 0u;
        for item in self.v {
            if item != none { it(idx); }
            idx += 1u;
        }
    }
N
Niko Matsakis 已提交
111
    fn values(it: fn(V)) {
112 113 114 115 116 117
        for item in self.v {
            alt item { some(elt) { it(elt); } _ {} }
        }
    }
}

B
Brian Anderson 已提交
118
#[doc = "Cast the given smallintmap to a map::map"]
119 120 121
fn as_map<V>(s: smallintmap<V>) -> map::map<uint, V> {
    s as map::map::<uint, V>
}