1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
* This file is part of the source code of the software program
* Vampire. It is protected by applicable
* copyright laws.
*
* This source code is distributed under the licence found here
* https://vprover.github.io/license.html
* and in the source directory
*/
/**
* Defines a bi-directional HashMap. This data structure is just a convenient abstraction using two `Map`s under the hood.
*/
#ifndef __LIB__BI_MAP__HPP__
#define __LIB__BI_MAP__HPP__
#include "Lib/Map.hpp"
namespace Lib{
/**
* A bidirectional hash map, implemented using two @c Map s under the hood.
* The methods behave the same as their counterparts in @c Map, with the exception that BiMap
* asserts that every key, as well as every value is unique in this map (which is necessary to do a bijective mapping.) */
template<class A, class B, class HashA, class HashB>
class BiMap : Map<A,B, HashA>, Map<B, A, HashB> {
using Into = Map<A,B,HashA>;
using From = Map<B,A,HashB>;
public:
BiMap() : Into(), From() {}
/** @see Map::get */
using From::get;
/** @see Map::get */
using Into::get;
/** @see Map::tryGet */
using From::tryGet;
/** @see Map::tryGet */
using Into::tryGet;
/** @see Map::find */
using From::find;
/** @see Map::find */
using Into::find;
/** @see Map::getOrInit */
template<class InitFn>
B& getOrInit(A key, InitFn init)
{
return Into::getOrInit(key, [&]() {
auto val = init();
From::insert(val, key);
return val;
});
}
/** @see Map::clear */
void clear()
{
From::clear();
Into::clear();
}
/**
* @see Map::insert
* @pre Asserts that both key and value do not yet exist in this BiMap.
*/
inline void insert(A key, B val)
{
ASS(!find(key))
ASS(!find(val))
From::insert(val, key);
Into::insert(key, val);
}
/**
* @see Map::size
*/
inline unsigned size()
{
ASS_EQ(From::size(), Into::size());
return From::size();
}
friend std::ostream& operator<<(std::ostream& out, BiMap const& self)
{ return out << static_cast<Into const&>(self); }
};
} // namespace Lib
#endif // __LIB__BI_MAP__HPP__