1 module nxt.bimap;
2
3 @safe pure:
4
5 /** Bidirectional map between key-and-values of type `X` and `Y` inspired by C++
6 Boost Bimap (`boost::bimap`).
7
8 See_Also: http://www.boost.org/doc/libs/1_65_1/libs/bimap/doc/html/boost_bimap/one_minute_tutorial.html
9 */
10 struct BiMap(X, Y,
11 alias Map = Y[X])
12 {
13 @safe pure nothrow:
14 alias LeftMap = Map!(X, Y);
15 alias RightMap = Map!(Y, X);
16
17 /// Insert (`x`, `y`).
18 void insert(X x, Y y)
19 {
20 version(D_Coverage) {} else pragma(inline, true);
21 _left[x] = y;
22 _right[y] = x;
23 }
24
25 /// Check if (`x`, `y`) is stored.
26 bool contains(scope const X x,
27 scope const Y y) const
28 {
29 version(LDC) pragma(inline, true);
30 // TODO do this symmetric?
31 if (const hitPtr = x in _left)
32 {
33 return *hitPtr == y;
34 }
35 return false;
36 }
37
38 /// Clear contents.
39 void clear() @trusted // TODO ok for this to be `@trusted`?
40 {
41 version(D_Coverage) {} else pragma(inline, true);
42 _left.clear();
43 _right.clear();
44 }
45
46 @nogc:
47
48 /// Check if empty.
49 bool empty() const
50 {
51 version(D_Coverage) {} else pragma(inline, true);
52 return length == 0;
53 }
54
55 /// Get length.
56 size_t length() const
57 {
58 version(D_Coverage) {} else pragma(inline, true);
59 return _left.length;
60 }
61
62 /// Access to left map must be non-mutating.
63 ref const(LeftMap) left() const
64 {
65 version(D_Coverage) {} else pragma(inline, true);
66 return _left;
67 }
68
69 /// Access to right map must be non-mutating.
70 ref const(RightMap) right() const
71 {
72 version(D_Coverage) {} else pragma(inline, true);
73 return _right;
74 }
75
76 private:
77 LeftMap _left; ///< Left map.
78 RightMap _right; ///< Right map.
79 }
80
81 @safe pure nothrow:
82
83 /// test with builtin associative arrays
84 unittest
85 {
86 alias HashMap(Key, Value) = Value[Key];
87 BiMap!(size_t, string, HashMap) bm;
88
89 bm.insert(42, "42");
90
91 assert(bm.left.length == 1);
92 assert(bm.right.length == 1);
93
94 assert(bm.contains(42, "42"));
95
96 bm.clear();
97 assert(bm.empty);
98 }