1 /** bidirectional map */
2 
3 module re.util.dual_map;
4 
5 class DualMap(T1, T2) {
6     public T2[T1] map1;
7     public T1[T2] map2;
8 
9     public void set(T1 key1, T2 key2) {
10         map1[key1] = key2;
11         map2[key2] = key1;
12     }
13 
14     public T2 get(T1 key1) {
15         return map1[key1];
16     }
17 
18     public T1 get(T2 key2) {
19         return map2[key2];
20     }
21 
22     public bool has(T1 key1) {
23         return cast(bool)(key1 in map1);
24     }
25 
26     public bool has(T2 key2) {
27         return cast(bool)(key2 in map2);
28     }
29 
30     public bool remove(T1 key1, T2 key2) {
31         return map1.remove(key1) && map2.remove(key2);
32     }
33 
34     public bool remove(T1 key1) {
35         auto key2 = get(key1);
36         return remove(key1, key2);
37     }
38 
39     public bool remove(T2 key2) {
40         auto key1 = get(key2);
41         return remove(key1, key2);
42     }
43 
44     public void clear() {
45         map1.clear();
46         map2.clear();
47     }
48 
49     @property public size_t count() {
50         assert(map1.length == map2.length, "maps are out of sync");
51         return map1.length;
52     }
53 }
54 
55 @("util-dualmap")
56 unittest {
57     auto dm = new DualMap!(string, int)();
58 
59     dm.set("sunday", 0);
60     dm.set("monday", 1);
61     dm.set("tuesday", 2);
62 
63     assert(dm.get(1) == "monday");
64     assert(dm.get("tuesday") == 2);
65     assert(dm.count == 3);
66 
67     assert(dm.has("monday"));
68     assert(dm.has(2));
69 
70     assert(dm.remove("tuesday"));
71     assert(dm.remove(1));
72 
73     assert(dm.count == 1);
74     assert(!dm.has(1));
75 
76     dm.clear();
77     assert(dm.count == 0);
78 }