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 }