16 #ifndef PAAL_BIMAP_HPP
17 #define PAAL_BIMAP_HPP
22 #include <boost/multi_index_container.hpp>
23 #include <boost/multi_index/random_access_index.hpp>
24 #include <boost/multi_index/hashed_index.hpp>
25 #include <boost/functional/hash.hpp>
27 #include <unordered_map>
30 namespace data_structures {
40 template <
typename T,
typename Idx =
int>
class bimap_mic {
51 template <
typename Range>
bimap_mic(Range && range) {
52 std::size_t s = boost::distance(range);
54 for (
const T &t : range) {
67 auto const &idx = m_index.template get<1>();
68 return m_index.template project<0>(idx.find(t)) - m_index.begin();
91 std::size_t
size()
const {
return m_index.size(); }
101 m_index.push_back(t);
102 return m_index.size() - 1;
106 typedef boost::multi_index_container<
107 T, boost::multi_index::indexed_by<boost::multi_index::random_access<>,
108 boost::multi_index::hashed_unique<
109 boost::multi_index::identity<T>>>>
123 template <
typename T,
typename Idx =
int>
class bimap {
124 typedef std::unordered_map<T, Idx, boost::hash<T>> TToID;
127 typedef typename TToID::const_iterator Iterator;
137 template <
typename Range>
bimap(Range && range) {
138 std::size_t s = boost::distance(range);
141 for (
const T &t : range) {
218 template <
typename T,
typename Idx =
int>
233 Idx idx = iter->second;
253 static const Idx INVALID_IDX = -1;
256 static_assert(std::is_integral<T>::value,
"Type T has to be integral");
269 std::size_t
size = std::distance(b, e);
270 m_id_to_t.resize(size);
271 std::copy(b, e, m_id_to_t.begin());
273 m_t_to_id.resize(size, INVALID_IDX);
274 rank(m_id_to_t, m_t_to_id, INVALID_IDX);
284 Idx
get_idx(
const T &t)
const {
return m_t_to_id[t]; }
293 const T &
get_val(Idx i)
const {
return m_id_to_t[i]; }
300 std::size_t
size()
const {
return m_id_to_t.size(); }
303 std::vector<T> m_id_to_t;
304 std::vector<Idx> m_t_to_id;
324 template <
typename ValT,
typename IdxT>
336 template <
typename ValT,
typename IdxT>
348 template <
typename ValT,
typename IdxT>
363 template <
typename T,
typename Idx =
int>
364 void rank(std::vector<T>
const &m_id_to_t, std::vector<Idx> &m_t_to_id,
365 int INVALID_IDX = 0) {
366 static_assert(std::is_integral<T>::value,
"Type T has to be integral");
367 unsigned long size = m_t_to_id.size();
368 for (
auto i :
irange(size)) {
369 Idx &idx = m_t_to_id[m_id_to_t[i]];
370 assert(m_id_to_t[i] <
int(size) && idx == INVALID_IDX);
377 #endif // PAAL_BIMAP_HPP
std::vector< T > m_id_to_t
mapping from id to element
const T & get_val(Idx i) const
get element on index i
TToID m_t_to_id
mapping from elements to ids
implements both sides mapping from the collection to (0,size(collection)) interval.
Idx get_idx(const T &t) const
get_idx on element t
std::size_t size() const
number of elements
Idx get_idx(const T &t) const
gets index of element t
Idx get_idx(const T &t) const
gets index of element t
const T & get_val(Idx i) const
get value for index i
Computes size of TypesVector.
std::size_t size() const
number of elements
the same as Bimap, but implemented using boost::multi_index_container. Unfortunately slower ...
std::size_t size() const
number of elements
const T & get_val(Idx i) const
gets value for index i
Idx add(const T &t)
adds element to collection
auto irange(T begin, T end)
irange
bimap_mic(Range &&range)
constructor
Idx add(const T &t)
adds alement to bimap
in this bimap we know that elements forms permutation this allows optimization
std::pair< Iterator, Iterator > get_range() const
get range of all element, index pairs
void erase(const T &t)
erases element (takes linear time)
bimap(Range &&range)
constructor
this maps support erasing elements, Alert inefficient!!
bimap_of_consecutive(Iter b, Iter e)
constructor
void rank(std::vector< T > const &m_id_to_t, std::vector< Idx > &m_t_to_id, int INVALID_IDX=0)
computes rank i.e. index of element in range