CASM  1.1.0
A Clusters Approach to Statistical Mechanics
unique_map.hh
Go to the documentation of this file.
1 #ifndef CASM_unique_map_HH
2 #define CASM_unique_map_HH
3 
4 #include <functional>
5 #include <map>
6 
7 #include "casm/misc/CASM_TMP.hh"
9 
10 namespace notstd {
11 
18 template <typename TransformFunc, typename MapIteratorType>
20  public:
21  typedef std::bidirectional_iterator_tag iterator_category;
22  typedef typename MapIteratorType::difference_type difference_type;
23  typedef typename std::result_of<TransformFunc(
24  typename MapIteratorType::reference)>::type reference;
25  typedef typename std::remove_reference<reference>::type value_type;
26  typedef value_type *pointer;
27 
29 
30  explicit UniqueMapIterator(MapIteratorType map_it)
31  : m_it(map_it), m_transform(TransformFunc()) {}
32 
33  template <typename T, typename M>
34  UniqueMapIterator(const UniqueMapIterator<T, M> &umap_it)
35  : m_it(umap_it.base()), m_transform(TransformFunc()) {}
36 
37  template <typename T, typename M>
38  bool operator==(const UniqueMapIterator<T, M> &B) const {
39  return (!operator!=(B));
40  }
41 
42  template <typename T, typename M>
43  bool operator!=(const UniqueMapIterator<T, M> &B) const {
44  return m_it != B.base();
45  }
46 
47  int type() const { return m_it->first; }
48 
49  reference operator*() const { return m_transform(*m_it); }
50 
51  pointer operator->() const { return &(this->operator*()); }
52 
53  // prefix
55  ++m_it;
56  return *this;
57  }
58 
59  // postfix
61  UniqueMapIterator result(*this);
62  ++m_it;
63  return result;
64  }
65 
66  // prefix
68  --m_it;
69  return *this;
70  }
71 
72  // postfix
74  UniqueMapIterator result(*this);
75  --m_it;
76  return result;
77  }
78 
79  MapIteratorType base() const { return m_it; }
80 
81  private:
82  MapIteratorType m_it;
83  TransformFunc m_transform;
84 };
85 
86 template <typename MapType>
87 struct GetSecond {
88  typedef typename MapType::iterator::reference reference;
89  typedef typename MapType::iterator::value_type::second_type &result_type;
90 
91  GetSecond() {}
92 
93  result_type operator()(reference pair) const { return pair.second; }
94 };
95 
96 template <typename MapType>
98  typedef typename MapType::const_iterator::reference reference;
99  typedef const typename MapType::const_iterator::value_type::second_type
101 
103 
104  result_type operator()(reference pair) const { return pair.second; }
105 };
106 
120 template <typename KeyType, typename ValueType,
121  typename MapType = std::map<KeyType, ValueType>,
122  typename TransformFunction = GetSecond<MapType>,
123  typename ConstTransformFunction = GetSecondConst<MapType> >
124 class unique_map {
125  public:
126  typedef ValueType value_type;
127  typedef KeyType key_type;
128  typedef std::function<KeyType(const ValueType &)> KeyFuncType;
129  typedef std::function<typename MapType::mapped_type(const ValueType &)>
131  typedef ValueType &reference;
132  typedef ValueType *pointer;
133 
134  typedef typename MapType::iterator MapIterator;
135  typedef typename MapType::const_iterator ConstMapIterator;
136 
140 
141  typedef typename MapType::size_type size_type;
142 
143  explicit unique_map(KeyFuncType keyfunc, ConvertType _converter)
144  : m_keyfunc(keyfunc), m_converter(_converter) {}
145 
146  key_type key(const value_type &value) const { return m_keyfunc(value); }
147 
149  std::pair<iterator, bool> insert(const value_type &value) {
150  return _insert(value);
151  }
152 
154  iterator insert(const_iterator hint, const value_type &value) {
155  return iterator(m_map.insert(
156  hint.base(),
157  std::make_pair(key(value), std::move(m_converter(value)))));
158  }
159 
161  iterator insert(iterator hint, const value_type &value) {
162  return iterator(m_map.insert(
163  hint.base(),
164  std::make_pair(key(value), std::move(m_converter(value)))));
165  }
166 
168  template <typename... ValuesOrMaps>
169  void insert(const ValuesOrMaps &... more) {
171  }
172 
174  template <typename Iterator>
175  void insert(
176  Iterator begin, Iterator end,
178  for (auto it = begin; it != end; ++it) {
179  _insert(*it);
180  }
181  }
182 
184  // insert if not existing
185  m_map[key];
186 
187  // return reference
188  return *find(key);
189  }
190 
191  iterator find(const key_type &key) { return iterator(m_map.find(key)); }
192 
193  const_iterator find(const key_type &key) const {
194  return const_iterator(m_map.find(key));
195  }
196 
197  void clear() { m_map.clear(); }
198 
200  return iterator(m_map.erase(pos.base()));
201  }
202 
204  return iterator(m_map.erase(first.base(), last.base()));
205  }
206 
207  size_type erase(const key_type &key) { return m_map.erase(key); }
208 
209  size_type size() const { return m_map.size(); }
210 
211  bool empty() const { return m_map.empty(); }
212 
213  iterator begin() { return iterator(m_map.begin()); }
214 
215  const_iterator begin() const { return const_iterator(m_map.begin()); }
216 
217  const_iterator cbegin() const { return const_iterator(m_map.cbegin()); }
218 
219  iterator end() { return iterator(m_map.end()); }
220 
221  const_iterator end() const { return const_iterator(m_map.end()); }
222 
223  const_iterator cend() const { return const_iterator(m_map.cend()); }
224 
225  private:
227  std::pair<iterator, bool> _insert(const value_type &value) {
228  auto result =
229  m_map.insert(std::make_pair(key(value), std::move(m_converter(value))));
230  return std::make_pair(iterator(result.first), result.second);
231  }
232 
234  template <typename A, typename B, typename C, typename D, typename E>
235  int _insert(const unique_map<A, B, C, D, E> &value) {
236  insert(value.begin(), value.end());
237  return 0;
238  }
239 
240  MapType m_map;
243 };
244 
245 } // namespace notstd
246 
247 #endif
An iterator over a UniqueMap.
Definition: unique_map.hh:19
bool operator==(const UniqueMapIterator< T, M > &B) const
Definition: unique_map.hh:38
MapIteratorType m_it
Definition: unique_map.hh:82
pointer operator->() const
Definition: unique_map.hh:51
UniqueMapIterator operator++(int)
Definition: unique_map.hh:60
std::result_of< TransformFunc(typename MapIteratorType::reference)>::type reference
Definition: unique_map.hh:24
UniqueMapIterator & operator++()
Definition: unique_map.hh:54
reference operator*() const
Definition: unique_map.hh:49
TransformFunc m_transform
Definition: unique_map.hh:83
MapIteratorType::difference_type difference_type
Definition: unique_map.hh:22
MapIteratorType base() const
Definition: unique_map.hh:79
bool operator!=(const UniqueMapIterator< T, M > &B) const
Definition: unique_map.hh:43
std::remove_reference< reference >::type value_type
Definition: unique_map.hh:25
UniqueMapIterator(MapIteratorType map_it)
Definition: unique_map.hh:30
std::bidirectional_iterator_tag iterator_category
Definition: unique_map.hh:21
UniqueMapIterator operator--(int)
Definition: unique_map.hh:73
UniqueMapIterator & operator--()
Definition: unique_map.hh:67
std::map wrapper to enforce a 1-1 ValueType->KeyType relationship
Definition: unique_map.hh:124
unique_map(KeyFuncType keyfunc, ConvertType _converter)
Definition: unique_map.hh:143
MapType::size_type size_type
Definition: unique_map.hh:141
const_iterator cbegin() const
Definition: unique_map.hh:217
iterator insert(iterator hint, const value_type &value)
Insert single value.
Definition: unique_map.hh:161
iterator erase(const_iterator pos)
Definition: unique_map.hh:199
value_type & operator[](const key_type &key)
Definition: unique_map.hh:183
KeyFuncType m_keyfunc
Definition: unique_map.hh:241
std::pair< iterator, bool > _insert(const value_type &value)
Copy insert.
Definition: unique_map.hh:227
ConvertType m_converter
Definition: unique_map.hh:242
key_type key(const value_type &value) const
Definition: unique_map.hh:146
ValueType * pointer
Definition: unique_map.hh:132
iterator find(const key_type &key)
Definition: unique_map.hh:191
iterator erase(const_iterator first, const_iterator last)
Definition: unique_map.hh:203
void insert(const ValuesOrMaps &... more)
Variadic insert accepts as const UniqueMap& or const ValueType&.
Definition: unique_map.hh:169
UniqueMapIterator< TransformFunction, MapIterator > iterator
Definition: unique_map.hh:137
const_iterator end() const
Definition: unique_map.hh:221
const_iterator begin() const
Definition: unique_map.hh:215
std::function< typename MapType::mapped_type(const ValueType &)> ConvertType
Definition: unique_map.hh:130
MapType::const_iterator ConstMapIterator
Definition: unique_map.hh:135
size_type erase(const key_type &key)
Definition: unique_map.hh:207
MapType::iterator MapIterator
Definition: unique_map.hh:134
std::pair< iterator, bool > insert(const value_type &value)
Insert single value.
Definition: unique_map.hh:149
ValueType value_type
Definition: unique_map.hh:126
size_type size() const
Definition: unique_map.hh:209
ValueType & reference
Definition: unique_map.hh:131
bool empty() const
Definition: unique_map.hh:211
std::function< KeyType(const ValueType &)> KeyFuncType
Definition: unique_map.hh:128
iterator insert(const_iterator hint, const value_type &value)
Insert single value.
Definition: unique_map.hh:154
UniqueMapIterator< ConstTransformFunction, ConstMapIterator > const_iterator
Definition: unique_map.hh:139
void insert(Iterator begin, Iterator end, typename CASM::CASM_TMP::enable_if_iterator< Iterator >::type *=nullptr)
Iterator range insert.
Definition: unique_map.hh:175
const_iterator cend() const
Definition: unique_map.hh:223
int _insert(const unique_map< A, B, C, D, E > &value)
Dictionary insert.
Definition: unique_map.hh:235
const_iterator find(const key_type &key) const
Definition: unique_map.hh:193
iterator begin()
Definition: unique_map.hh:213
std::enable_if< is_iterator< T >::type::value, void > enable_if_iterator
Template alias to enable a template function via SFINAE for any iterator.
Definition: CASM_TMP.hh:63
void ignore_returnvalues(Args &&...)
Enables calling a function on each argument in a parameter pack.
Definition: CASM_TMP.hh:26
Non-std smart pointer classes and functions.
result_type operator()(reference pair) const
Definition: unique_map.hh:104
const MapType::const_iterator::value_type::second_type & result_type
Definition: unique_map.hh:100
MapType::const_iterator::reference reference
Definition: unique_map.hh:98
result_type operator()(reference pair) const
Definition: unique_map.hh:93
MapType::iterator::value_type::second_type & result_type
Definition: unique_map.hh:89
MapType::iterator::reference reference
Definition: unique_map.hh:88