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