BRE12
concurrent_unordered_map.h
1 /*
2  Copyright 2005-2016 Intel Corporation. All Rights Reserved.
3 
4  This file is part of Threading Building Blocks. Threading Building Blocks is free software;
5  you can redistribute it and/or modify it under the terms of the GNU General Public License
6  version 2 as published by the Free Software Foundation. Threading Building Blocks is
7  distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  See the GNU General Public License for more details. You should have received a copy of
10  the GNU General Public License along with Threading Building Blocks; if not, write to the
11  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12 
13  As a special exception, you may use this file as part of a free software library without
14  restriction. Specifically, if other files instantiate templates or use macros or inline
15  functions from this file, or you compile this file and link it with other files to produce
16  an executable, this file does not by itself cause the resulting executable to be covered
17  by the GNU General Public License. This exception does not however invalidate any other
18  reasons why the executable file might be covered by the GNU General Public License.
19 */
20 
21 /* Container implementations in this header are based on PPL implementations
22  provided by Microsoft. */
23 
24 #ifndef __TBB_concurrent_unordered_map_H
25 #define __TBB_concurrent_unordered_map_H
26 
27 #include "internal/_concurrent_unordered_impl.h"
28 
29 namespace tbb
30 {
31 
32 namespace interface5 {
33 
34 // Template class for hash map traits
35 template<typename Key, typename T, typename Hash_compare, typename Allocator, bool Allow_multimapping>
37 {
38 protected:
39  typedef std::pair<const Key, T> value_type;
40  typedef Key key_type;
41  typedef Hash_compare hash_compare;
42  typedef typename Allocator::template rebind<value_type>::other allocator_type;
43  enum { allow_multimapping = Allow_multimapping };
44 
45  concurrent_unordered_map_traits() : my_hash_compare() {}
46  concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {}
47 
48  class value_compare : public std::binary_function<value_type, value_type, bool>
49  {
50  friend class concurrent_unordered_map_traits<Key, T, Hash_compare, Allocator, Allow_multimapping>;
51 
52  public:
53  bool operator()(const value_type& left, const value_type& right) const
54  {
55  return (my_hash_compare(left.first, right.first));
56  }
57 
58  value_compare(const hash_compare& comparator) : my_hash_compare(comparator) {}
59 
60  protected:
61  hash_compare my_hash_compare; // the comparator predicate for keys
62  };
63 
64  template<class Type1, class Type2>
65  static const Key& get_key(const std::pair<Type1, Type2>& value) {
66  return (value.first);
67  }
68 
69  hash_compare my_hash_compare; // the comparator predicate for keys
70 };
71 
72 template <typename Key, typename T, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>,
73  typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
75  public internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T,
76  internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> >
77 {
78  // Base type definitions
81  typedef internal::concurrent_unordered_base< traits_type > base_type;
82 #if __TBB_EXTRA_DEBUG
83 public:
84 #endif
85  using traits_type::allow_multimapping;
86 public:
87  using base_type::end;
88  using base_type::find;
89  using base_type::insert;
90 
91  // Type definitions
92  typedef Key key_type;
93  typedef typename base_type::value_type value_type;
94  typedef T mapped_type;
95  typedef Hasher hasher;
96  typedef Key_equality key_equal;
97  typedef hash_compare key_compare;
98 
99  typedef typename base_type::allocator_type allocator_type;
100  typedef typename base_type::pointer pointer;
101  typedef typename base_type::const_pointer const_pointer;
102  typedef typename base_type::reference reference;
103  typedef typename base_type::const_reference const_reference;
104 
105  typedef typename base_type::size_type size_type;
106  typedef typename base_type::difference_type difference_type;
107 
108  typedef typename base_type::iterator iterator;
109  typedef typename base_type::const_iterator const_iterator;
110  typedef typename base_type::iterator local_iterator;
111  typedef typename base_type::const_iterator const_local_iterator;
112 
113  // Construction/destruction/copying
114  explicit concurrent_unordered_map(size_type n_of_buckets = base_type::initial_bucket_number,
115  const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
116  const allocator_type& a = allocator_type())
117  : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
118  {
119  }
120 
121  concurrent_unordered_map(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
122  {
123  }
124 
125  template <typename Iterator>
126  concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
127  const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
128  const allocator_type& a = allocator_type())
129  : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
130  {
131  insert(first, last);
132  }
133 
134 #if __TBB_INITIALIZER_LISTS_PRESENT
135  concurrent_unordered_map(std::initializer_list<value_type> il, size_type n_of_buckets = base_type::initial_bucket_number,
137  const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
138  const allocator_type& a = allocator_type())
139  : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
140  {
141  this->insert(il.begin(),il.end());
142  }
143 #endif //# __TBB_INITIALIZER_LISTS_PRESENT
144 
145 #if __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN
147  : base_type(table)
148  {
149  }
150 
151  concurrent_unordered_map& operator=(const concurrent_unordered_map& table)
152  {
153  return static_cast<concurrent_unordered_map&>(base_type::operator=(table));
154  }
155 
156  concurrent_unordered_map(concurrent_unordered_map&& table)
157  : base_type(std::move(table))
158  {
159  }
160 
161  concurrent_unordered_map& operator=(concurrent_unordered_map&& table)
162  {
163  return static_cast<concurrent_unordered_map&>(base_type::operator=(std::move(table)));
164  }
165 #endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN
166 
167  concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a)
168  : base_type(table, a)
169  {
170  }
171 
172 #if __TBB_CPP11_RVALUE_REF_PRESENT
173  concurrent_unordered_map(concurrent_unordered_map&& table, const Allocator& a) : base_type(std::move(table), a)
174  {
175  }
176 #endif
177  // Observers
178  mapped_type& operator[](const key_type& key)
179  {
180  iterator where = find(key);
181 
182  if (where == end())
183  {
184  where = insert(std::pair<key_type, mapped_type>(key, mapped_type())).first;
185  }
186 
187  return ((*where).second);
188  }
189 
190  mapped_type& at(const key_type& key)
191  {
192  iterator where = find(key);
193 
194  if (where == end())
195  {
196  tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
197  }
198 
199  return ((*where).second);
200  }
201 
202  const mapped_type& at(const key_type& key) const
203  {
204  const_iterator where = find(key);
205 
206  if (where == end())
207  {
208  tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
209  }
210 
211  return ((*where).second);
212  }
213 };
214 
215 template < typename Key, typename T, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>,
216  typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
218  public internal::concurrent_unordered_base< concurrent_unordered_map_traits< Key, T,
219  internal::hash_compare<Key, Hasher, Key_equality>, Allocator, true> >
220 {
221  // Base type definitions
224  typedef internal::concurrent_unordered_base<traits_type> base_type;
225 #if __TBB_EXTRA_DEBUG
226 public:
227 #endif
228  using traits_type::allow_multimapping;
229 public:
230  using base_type::insert;
231 
232  // Type definitions
233  typedef Key key_type;
234  typedef typename base_type::value_type value_type;
235  typedef T mapped_type;
236  typedef Hasher hasher;
237  typedef Key_equality key_equal;
238  typedef hash_compare key_compare;
239 
240  typedef typename base_type::allocator_type allocator_type;
241  typedef typename base_type::pointer pointer;
242  typedef typename base_type::const_pointer const_pointer;
243  typedef typename base_type::reference reference;
244  typedef typename base_type::const_reference const_reference;
245 
246  typedef typename base_type::size_type size_type;
247  typedef typename base_type::difference_type difference_type;
248 
249  typedef typename base_type::iterator iterator;
250  typedef typename base_type::const_iterator const_iterator;
251  typedef typename base_type::iterator local_iterator;
252  typedef typename base_type::const_iterator const_local_iterator;
253 
254  // Construction/destruction/copying
255  explicit concurrent_unordered_multimap(size_type n_of_buckets = base_type::initial_bucket_number,
256  const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
257  const allocator_type& a = allocator_type())
258  : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
259  {
260  }
261 
262  concurrent_unordered_multimap(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
263  {
264  }
265 
266  template <typename Iterator>
267  concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
268  const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
269  const allocator_type& a = allocator_type())
270  : base_type(n_of_buckets,key_compare(_Hasher,_Key_equality), a)
271  {
272  insert(first, last);
273  }
274 
275 #if __TBB_INITIALIZER_LISTS_PRESENT
276  concurrent_unordered_multimap(std::initializer_list<value_type> il, size_type n_of_buckets = base_type::initial_bucket_number,
278  const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
279  const allocator_type& a = allocator_type())
280  : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
281  {
282  this->insert(il.begin(),il.end());
283  }
284 #endif //# __TBB_INITIALIZER_LISTS_PRESENT
285 
286 #if __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN
288  : base_type(table)
289  {
290  }
291 
292  concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& table)
293  {
294  return static_cast<concurrent_unordered_multimap&>(base_type::operator=(table));
295  }
296 
297  concurrent_unordered_multimap(concurrent_unordered_multimap&& table)
298  : base_type(std::move(table))
299  {
300  }
301 
302  concurrent_unordered_multimap& operator=(concurrent_unordered_multimap&& table)
303  {
304  return static_cast<concurrent_unordered_multimap&>(base_type::operator=(std::move(table)));
305  }
306 #endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_BROKEN
307 
308  concurrent_unordered_multimap(const concurrent_unordered_multimap& table, const Allocator& a)
309  : base_type(table, a)
310  {
311  }
312 
313 #if __TBB_CPP11_RVALUE_REF_PRESENT
314  concurrent_unordered_multimap(concurrent_unordered_multimap&& table, const Allocator& a) : base_type(std::move(table), a)
315  {
316  }
317 #endif
318 };
319 } // namespace interface5
320 
323 
324 } // namespace tbb
325 
326 #endif// __TBB_concurrent_unordered_map_H
Definition: concurrent_unordered_map.h:217
Definition: concurrent_unordered_map.h:74
Definition: concurrent_unordered_map.h:36
The namespace tbb contains all components of the library.
Definition: parallel_for.h:44
Definition: _tbb_hash_compare_impl.h:33