Flow123d  release_3.0.0-955-g4db4b48
bidirectional_map.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file bidirectional_map.hh
15  * @brief Implementation of bidirectional map.
16  */
17 
18 #ifndef BIDIRECTIONAL_MAP_HH_
19 #define BIDIRECTIONAL_MAP_HH_
20 
21 #include <vector>
22 #include <map>
23 #include "system/asserts.hh"
24 
25 
26 /**
27  * @brief Bidirectional map templated by <T, unsigned int>.
28  *
29  * Store pairs of value and its position (index) and allow bidirectional search.
30  * Items of both (values, positions) must be unique.
31  */
32 template<typename T>
34 {
35 public:
36  /// Constructor
38 
39  /// Return size of map.
40  unsigned int size() const;
41 
42  /**
43  * Set value of given position.
44  *
45  * Position must be in interval set in \p reinit method <0, init_size-1>.
46  * Element on every position can be set only once.
47  */
48  void set_item(T val, unsigned int pos);
49 
50  /// Add new item at the end position of map.
51  unsigned int add_item(T val);
52 
53  /// Return position of item of given value.
54  int get_position(T val) const;
55 
56  /// Reset data of map, allow reserve size.
57  void reinit(unsigned int init_size = 0);
58 
59  /// Resizes to given @p new_size if new size is smaller than the actual.
60  /// The rest of data are thrown away and removed from the map.
61  void resize(unsigned int new_size);
62 
63  /// Return value on given position.
64  T operator[](unsigned int pos) const;
65 
66 private:
67  std::vector<T> vals_vec_; ///< Space to save values.
68  std::map<T, unsigned int> vals_map_; ///< Maps values to indexes into vals_vec_.
69 };
70 
71 // --------------------------------------------------- BidirectionalMap INLINE implementation -----------
72 template<typename T>
74 {}
75 
76 template<typename T>
77 inline unsigned int BidirectionalMap<T>::size() const {
78  return vals_map_.size();
79 }
80 
81 template<typename T>
82 inline void BidirectionalMap<T>::set_item(T val, unsigned int pos) {
83  ASSERT_LT_DBG( pos, vals_vec_.size() )(pos)(vals_vec_.size()).error("Value id is out of vector size.");
84  //ASSERT( vals_vec_[pos] == -1 )(pos).error("Repeated setting of item.");
85  // auto it = vals_map_.find(vals_vec_[pos]);
86  // if (it != vals_map_.end()) {
87  // DebugOut() << print_var(vals_map_.size()) << print_var(pos) << print_var(vals_vec_[pos]) << "\n";
88  // vals_map_.erase(it);
89  // }
90  vals_map_[val] = pos;
91  vals_vec_[pos] = val;
92 }
93 
94 template<typename T>
95 inline unsigned int BidirectionalMap<T>::add_item(T val) {
96  ASSERT( vals_map_.find(val) == vals_map_.end() )(val).error("Can not add item since it already exists.");
97  vals_map_[val] = vals_vec_.size();
98  vals_vec_.push_back(val);
99  return vals_map_[val];
100 }
101 
102 template<typename T>
103 inline int BidirectionalMap<T>::get_position(T val) const {
104  typename std::map<T, unsigned int>::const_iterator iter = vals_map_.find(val);
105  if (iter == vals_map_.end()) return -1;
106  else return iter->second;
107 }
108 
109 template<typename T>
110 inline void BidirectionalMap<T>::reinit(unsigned int init_size) {
111  vals_map_.clear();
112  vals_vec_.clear();
113  vals_vec_.resize(init_size, -1);
114 }
115 
116 /// Reset data of map, reserve space for given size.
117 template<typename T>
118 inline void BidirectionalMap<T>::resize(unsigned int new_size)
119 {
120  ASSERT_LT_DBG(new_size, vals_vec_.size());
121  for(uint pos = new_size; pos < vals_vec_.size(); pos++){
122  vals_map_.erase(vals_vec_[pos]);
123  }
124  vals_vec_.resize(new_size);
125  ASSERT_DBG(vals_vec_.size() == vals_map_.size())(vals_vec_.size())(vals_map_.size());
126 }
127 
128 template<typename T>
129 inline T BidirectionalMap<T>::operator[](unsigned int pos) const {
130  ASSERT( pos < vals_vec_.size() )(pos)(vals_vec_.size());
131  return vals_vec_[pos];
132 }
133 
134 
135 #endif // BIDIRECTIONAL_MAP_HH_
BidirectionalMap()
Constructor.
unsigned int size() const
Return size of map.
std::vector< T > vals_vec_
Space to save values.
unsigned int uint
Definitions of ASSERTS.
std::map< T, unsigned int > vals_map_
Maps values to indexes into vals_vec_.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
void resize(unsigned int new_size)
Reset data of map, reserve space for given size.
unsigned int add_item(T val)
Add new item at the end position of map.
void set_item(T val, unsigned int pos)
void reinit(unsigned int init_size=0)
Reset data of map, allow reserve size.
#define ASSERT_DBG(expr)
Definition: asserts.hh:349
int get_position(T val) const
Return position of item of given value.
T operator[](unsigned int pos) const
Return value on given position.
Bidirectional map templated by <T, unsigned int>.
#define ASSERT_LT_DBG(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:299