Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FlatMap.h
Go to the documentation of this file.
1 /*
2  * This file belongs to the Galois project, a C++ library for exploiting
3  * parallelism. The code is being released under the terms of the 3-Clause BSD
4  * License (a copy is located in LICENSE.txt at the top-level directory).
5  *
6  * Copyright (C) 2018, The University of Texas at Austin. All rights reserved.
7  * UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING THIS
8  * SOFTWARE AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF MERCHANTABILITY,
9  * FITNESS FOR ANY PARTICULAR PURPOSE, NON-INFRINGEMENT AND WARRANTIES OF
10  * PERFORMANCE, AND ANY WARRANTY THAT MIGHT OTHERWISE ARISE FROM COURSE OF
11  * DEALING OR USAGE OF TRADE. NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH
12  * RESPECT TO THE USE OF THE SOFTWARE OR DOCUMENTATION. Under no circumstances
13  * shall University be liable for incidental, special, indirect, direct or
14  * consequential damages or loss of profits, interruption of business, or
15  * related expenses which may arise from use of Software or Documentation,
16  * including but not limited to those resulting from defects in Software and/or
17  * Documentation, or loss or inaccuracy of data of any kind.
18  */
19 
20 #ifndef GALOIS_FLATMAP_H
21 #define GALOIS_FLATMAP_H
22 
23 #include <algorithm>
24 #include <stdexcept>
25 #include <type_traits>
26 #include <vector>
27 
28 #include "galois/config.h"
29 
30 namespace galois {
31 
33 template <class _Key, class _Tp, class _Compare = std::less<_Key>,
34  class _Alloc = std::allocator<std::pair<_Key, _Tp>>,
35  class _Store = std::vector<std::pair<_Key, _Tp>, _Alloc>>
36 class flat_map {
37 public:
38  typedef _Key key_type;
39  typedef _Tp mapped_type;
40  typedef std::pair<_Key, _Tp> value_type;
41  typedef _Compare key_compare;
42  typedef _Alloc allocator_type;
43 
45  : public std::binary_function<value_type, value_type, bool> {
46  friend class flat_map<_Key, _Tp, _Compare, _Alloc, _Store>;
47 
48  protected:
49  _Compare comp;
50 
51  value_compare(_Compare __c) : comp(__c) {}
52 
53  public:
54  bool operator()(const value_type& __x, const value_type& __y) const {
55  return comp(__x.first, __y.first);
56  }
57  };
58 
59 private:
61  typedef typename _Alloc::template rebind<value_type>::other _Pair_alloc_type;
62 
63  typedef _Store _VectTy;
64  _VectTy _data;
65  _Compare _comp;
66 
67  class value_key_compare
68  : public std::binary_function<value_type, key_type, bool> {
69  friend class flat_map<_Key, _Tp, _Compare, _Alloc, _Store>;
70 
71  protected:
72  _Compare comp;
73 
74  value_key_compare(_Compare __c) : comp(__c) {}
75 
76  public:
77  bool operator()(const value_type& __x, const key_type& __y) const {
78  return comp(__x.first, __y);
79  }
80  };
81 
82  value_key_compare value_key_comp() const {
83  return value_key_compare(key_comp());
84  }
85 
86  bool key_eq(const key_type& k1, const key_type& k2) const {
87  return !key_comp()(k1, k2) && !key_comp()(k2, k1);
88  }
89 
90  void resort() { std::sort(_data.begin(), _data.end(), value_comp()); }
91 
92 public:
93  typedef typename _Pair_alloc_type::pointer pointer;
94  typedef typename _Pair_alloc_type::const_pointer const_pointer;
95  typedef typename _Pair_alloc_type::reference reference;
96  typedef typename _Pair_alloc_type::const_reference const_reference;
97  typedef typename _VectTy::iterator iterator;
98  typedef typename _VectTy::const_iterator const_iterator;
99  typedef typename _VectTy::size_type size_type;
100  typedef typename _VectTy::difference_type difference_type;
101  typedef typename _VectTy::reverse_iterator reverse_iterator;
102  typedef typename _VectTy::const_reverse_iterator const_reverse_iterator;
103 
104  flat_map() : _data(), _comp() {}
105 
106  explicit flat_map(const _Compare& __comp,
107  const allocator_type& = allocator_type())
108  // XXX :_data(_Pair_alloc_type(__a)), _comp(__comp) {}
109  : _data(), _comp(__comp) {}
110 
111  flat_map(const flat_map& __x) : _data(__x._data), _comp(__x._comp) {}
112 
113  flat_map(flat_map&& __x)
114  /* noexcept(std::is_nothrow_copy_constructible<_Compare>::value) */
115  : _data(std::move(__x._data)), _comp(std::move(__x._comp)) {}
116 
117  /*
118  flat_map(std::initializer_list<value_type> __l,
119  const _Compare& __comp = _Compare(),
120  const allocator_type& __a = allocator_type())
121  : _data(__l, _Pair_alloc_type(__a)), _comp(__comp) { resort(); }
122  */
123 
124  template <typename _InputIterator>
125  flat_map(_InputIterator __first, _InputIterator __last)
126  : _data(__first, __last), _comp() {
127  resort();
128  }
129 
130  template <typename _InputIterator>
131  flat_map(_InputIterator __first, _InputIterator __last, const _Compare&,
132  const allocator_type& __a = allocator_type())
133  : _data(__first, __last, _Pair_alloc_type(__a)) {
134  resort();
135  }
136 
137  flat_map& operator=(const flat_map& __x) {
138  _data = __x._data;
139  _comp = __x._comp;
140  return *this;
141  }
142 
144  clear();
145  swap(__x);
146  return *this;
147  }
148 
149  /*
150  flat_map& operator=(std::initializer_list<value_type> __l) {
151  clear();
152  insert(__l.begin(), __l.end());
153  return *this;
154  }
155  */
156 
157  allocator_type get_allocator() const /* noexcept */ {
158  return allocator_type(_data.get_allocator());
159  }
160 
161  // iterators
162 
163  iterator begin() /* noexcept */ { return _data.begin(); }
164  const_iterator begin() const /* noexcept */ { return _data.begin(); }
165  iterator end() /* noexcept */ { return _data.end(); }
166  const_iterator end() const /* noexcept */ { return _data.end(); }
167  reverse_iterator rbegin() /* noexcept */ { return _data.rbegin(); }
168  const_reverse_iterator rbegin() const /* noexcept */ {
169  return _data.rbegin();
170  }
171  reverse_iterator rend() /* noexcept */ { return _data.rend(); }
172  const_reverse_iterator rend() const /* noexcept */ { return _data.rend(); }
173  const_iterator cbegin() const /* noexcept */ { return _data.begin(); }
174  const_iterator cend() const /* noexcept */ { return _data.end(); }
175  const_reverse_iterator crbegin() const /* noexcept */ {
176  return _data.rbegin();
177  }
178  const_reverse_iterator crend() const /* noexcept */ { return _data.rend(); }
179 
180  bool empty() const /* noexcept */ { return _data.empty(); }
181  size_type size() const /* noexcept */ { return _data.size(); }
182  size_type max_size() const /* noexcept */ { return _data.max_size(); }
183 
184  template <typename... Args>
185  std::pair<iterator, bool> emplace(Args&&... args) {
186  // assert(std::adjacent_find(_data.begin(), _data.end(), [&](const
187  // value_type& a, const value_type& b) {
188  // return key_comp()(b.first, a.first);
189  //}) == _data.end());
190  _data.emplace_back(std::forward<Args>(args)...);
191  value_type& v = _data.back();
192  auto ee = _data.end();
193  --ee;
194  auto __i = std::lower_bound(_data.begin(), ee, v.first, value_key_comp());
195  // key < __i->first
196  bool retval = __i == ee || key_comp()(v.first, (*__i).first);
197  if (retval) {
198  if (__i != ee) {
199  value_type tmp = std::move(v);
200  __i = _data.emplace(__i, std::move(tmp));
201  _data.pop_back();
202  }
203  } else {
204  // key == __i->first
205  _data.pop_back();
206  }
207  return std::make_pair(__i, retval);
208  }
209 
211  iterator __i = lower_bound(__k);
212  // __i->first is greater than or equivalent to __k.
213  if (__i == end() || key_comp()(__k, (*__i).first))
214  __i = _data.emplace(__i, std::piecewise_construct,
215  std::forward_as_tuple(__k), std::tuple<>());
216  return (*__i).second;
217  }
218 
220  iterator __i = lower_bound(__k);
221  // __i->first is greater than or equivalent to __k.
222  if (__i == end() || key_comp()(__k, (*__i).first))
223  __i =
224  _data.emplace(__i, std::piecewise_construct,
225  std::forward_as_tuple(std::move(__k)), std::tuple<>());
226  return (*__i).second;
227  }
228 
229  mapped_type& at(const key_type& __k) {
230  iterator __i = lower_bound(__k);
231  if (__i == end() || key_comp()(__k, (*__i).first))
232  throw std::out_of_range("flat_map::at");
233  return (*__i).second;
234  }
235 
236  const mapped_type& at(const key_type& __k) const {
237  const_iterator __i = lower_bound(__k);
238  if (__i == end() || key_comp()(__k, (*__i).first))
239  throw std::out_of_range("flat_map::at");
240  return (*__i).second;
241  }
242 
243  template <typename PairTy,
244  typename = typename std::enable_if<
245  std::is_constructible<value_type, PairTy&&>::value>::type>
246  std::pair<iterator, bool> insert(PairTy&& __x) {
247  return emplace(std::forward<PairTy>(__x));
248  }
249 
250  /*
251  void insert(std::initializer_list<value_type> __list) {
252  insert(__list.begin(), __list.end());
253  }
254  */
255 
256  template <typename _InputIterator>
257  void insert(_InputIterator __first, _InputIterator __last) {
258  while (__first != __last)
259  insert(*__first++);
260  }
261 
262  iterator erase(const_iterator __position) { return _data.erase(__position); }
263  iterator erase(iterator __position) { return _data.erase(__position); }
264 
265  size_type erase(const key_type& __x) {
266  auto i = find(__x);
267  if (i != end()) {
268  _data.erase(i);
269  return 1;
270  }
271  return 0;
272  }
273 
275  return _data.erase(__first, __last);
276  }
277 
278  void swap(flat_map& __x) {
279  _data.swap(__x._data);
280  std::swap(_comp, __x._comp);
281  }
282 
283  void clear() /* noexcept */ { _data.clear(); }
284 
285  key_compare key_comp() const { return _comp; }
286  value_compare value_comp() const { return value_compare(key_comp()); }
287 
288  iterator find(const key_type& __x) {
289  auto i = lower_bound(__x);
290  if (i != end() && key_eq(i->first, __x))
291  return i;
292  return end();
293  }
294 
295  const_iterator find(const key_type& __x) const {
296  auto i = lower_bound(__x);
297  if (i != end() && key_eq(i->first, __x))
298  return i;
299  return end();
300  }
301 
302  size_type count(const key_type& __x) const {
303  return find(__x) == end() ? 0 : 1;
304  }
305 
307  return std::lower_bound(_data.begin(), _data.end(), __x, value_key_comp());
308  }
309  const_iterator lower_bound(const key_type& __x) const {
310  return std::lower_bound(_data.begin(), _data.end(), __x, value_key_comp());
311  }
312 
314  return std::upper_bound(_data.begin(), _data.end(), __x, value_key_comp());
315  }
316  const_iterator upper_bound(const key_type& __x) const {
317  return std::upper_bound(_data.begin(), _data.end(), __x, value_key_comp());
318  }
319 
320  std::pair<iterator, iterator> equal_range(const key_type& __x) {
321  return std::make_pair(lower_bound(__x), upper_bound(__x));
322  }
323 
324  std::pair<const_iterator, const_iterator>
325  equal_range(const key_type& __x) const {
326  return std::make_pair(lower_bound(__x), upper_bound(__x));
327  }
328 };
329 
330 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
333  return __x._data == __y._data;
334 }
335 
336 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
337 inline bool operator<(const flat_map<_Key, _Tp, _Compare, _Alloc>& __x,
339  return __x._data < __y._data;
340 }
341 
343 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
346  return !(__x == __y);
347 }
348 
350 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
353  return __y < __x;
354 }
355 
357 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
358 inline bool operator<=(const flat_map<_Key, _Tp, _Compare, _Alloc>& __x,
360  return !(__y < __x);
361 }
362 
364 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
367  return !(__x < __y);
368 }
369 
370 } // namespace galois
371 
372 namespace std {
373 
375 template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
378  __x.swap(__y);
379 }
380 
381 } // namespace std
382 
383 #endif
const_iterator cbegin() const
Definition: FlatMap.h:173
flat_map(_InputIterator __first, _InputIterator __last, const _Compare &, const allocator_type &__a=allocator_type())
Definition: FlatMap.h:131
size_type count(const key_type &__x) const
Definition: FlatMap.h:302
void clear()
Definition: FlatMap.h:283
std::pair< iterator, bool > emplace(Args &&...args)
Definition: FlatMap.h:185
flat_map(const _Compare &__comp, const allocator_type &=allocator_type())
Definition: FlatMap.h:106
_Key key_type
Definition: FlatMap.h:38
_VectTy::const_iterator const_iterator
Definition: FlatMap.h:98
const_iterator begin() const
Definition: FlatMap.h:164
const_iterator end() const
Definition: FlatMap.h:166
const_iterator upper_bound(const key_type &__x) const
Definition: FlatMap.h:316
const_iterator find(const key_type &__x) const
Definition: FlatMap.h:295
flat_map & operator=(const flat_map &__x)
Definition: FlatMap.h:137
std::pair< _Key, _Tp > value_type
Definition: FlatMap.h:40
_Alloc allocator_type
Definition: FlatMap.h:42
std::pair< const_iterator, const_iterator > equal_range(const key_type &__x) const
Definition: FlatMap.h:325
mapped_type & operator[](const key_type &__k)
Definition: FlatMap.h:210
value_compare value_comp() const
Definition: FlatMap.h:286
bool operator!=(const flat_map< _Key, _Tp, _Compare, _Alloc > &__x, const flat_map< _Key, _Tp, _Compare, _Alloc > &__y)
Based on operator==.
Definition: FlatMap.h:344
const_iterator cend() const
Definition: FlatMap.h:174
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
Definition: ParallelSTL.h:247
value_compare(_Compare __c)
Definition: FlatMap.h:51
bool operator()(const value_type &__x, const value_type &__y) const
Definition: FlatMap.h:54
std::pair< iterator, bool > insert(PairTy &&__x)
Definition: FlatMap.h:246
std::pair< iterator, iterator > equal_range(const key_type &__x)
Definition: FlatMap.h:320
const_reverse_iterator rend() const
Definition: FlatMap.h:172
iterator lower_bound(const key_type &__x)
Definition: FlatMap.h:306
iterator upper_bound(const key_type &__x)
Definition: FlatMap.h:313
_Pair_alloc_type::const_reference const_reference
Definition: FlatMap.h:96
_Pair_alloc_type::reference reference
Definition: FlatMap.h:95
_Pair_alloc_type::pointer pointer
Definition: FlatMap.h:93
_Compare key_compare
Definition: FlatMap.h:41
Definition: FlatMap.h:44
Simple map data structure, based off a single array.
Definition: FlatMap.h:36
const_reverse_iterator rbegin() const
Definition: FlatMap.h:168
iterator erase(const_iterator __first, const_iterator __last)
Definition: FlatMap.h:274
key_compare key_comp() const
Definition: FlatMap.h:285
_VectTy::size_type size_type
Definition: FlatMap.h:99
flat_map()
Definition: FlatMap.h:104
_VectTy::const_reverse_iterator const_reverse_iterator
Definition: FlatMap.h:102
void operator()(void)
Definition: Executor_ParaMeter.h:417
const mapped_type & at(const key_type &__k) const
Definition: FlatMap.h:236
_Pair_alloc_type::const_pointer const_pointer
Definition: FlatMap.h:94
size_type erase(const key_type &__x)
Definition: FlatMap.h:265
const_reverse_iterator crend() const
Definition: FlatMap.h:178
size_type size() const
Definition: FlatMap.h:181
_VectTy::iterator iterator
Definition: FlatMap.h:97
bool operator>=(const flat_map< _Key, _Tp, _Compare, _Alloc > &__x, const flat_map< _Key, _Tp, _Compare, _Alloc > &__y)
Based on operator&lt;.
Definition: FlatMap.h:365
void insert(_InputIterator __first, _InputIterator __last)
Definition: FlatMap.h:257
const_iterator lower_bound(const key_type &__x) const
Definition: FlatMap.h:309
bool operator==(const flat_map< _Key, _Tp, _Compare, _Alloc > &__x, const flat_map< _Key, _Tp, _Compare, _Alloc > &__y)
Definition: FlatMap.h:331
_VectTy::reverse_iterator reverse_iterator
Definition: FlatMap.h:101
bool operator>(const flat_map< _Key, _Tp, _Compare, _Alloc > &__x, const flat_map< _Key, _Tp, _Compare, _Alloc > &__y)
Based on operator&lt;.
Definition: FlatMap.h:351
iterator find(const key_type &__x)
Definition: FlatMap.h:288
reverse_iterator rbegin()
Definition: FlatMap.h:167
mapped_type & operator[](key_type &&__k)
Definition: FlatMap.h:219
size_type max_size() const
Definition: FlatMap.h:182
iterator erase(const_iterator __position)
Definition: FlatMap.h:262
_Compare comp
Definition: FlatMap.h:49
mapped_type & at(const key_type &__k)
Definition: FlatMap.h:229
_VectTy::difference_type difference_type
Definition: FlatMap.h:100
allocator_type get_allocator() const
Definition: FlatMap.h:157
flat_map(_InputIterator __first, _InputIterator __last)
Definition: FlatMap.h:125
iterator end()
Definition: FlatMap.h:165
flat_map & operator=(flat_map &&__x)
Definition: FlatMap.h:143
T value_type
Definition: Executor_ParaMeter.h:111
const_reverse_iterator crbegin() const
Definition: FlatMap.h:175
_Tp mapped_type
Definition: FlatMap.h:39
reverse_iterator rend()
Definition: FlatMap.h:171
iterator erase(iterator __position)
Definition: FlatMap.h:263
bool empty() const
Definition: FlatMap.h:180
void swap(flat_map &__x)
Definition: FlatMap.h:278
flat_map(const flat_map &__x)
Definition: FlatMap.h:111
iterator begin()
Definition: FlatMap.h:163