00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef __TBB_concurrent_unordered_map_H
00033 #define __TBB_concurrent_unordered_map_H
00034
00035 #include "internal/_concurrent_unordered_impl.h"
00036
00037 namespace tbb
00038 {
00039
00040 namespace interface5 {
00041
00042
00043 template<typename Key, typename T, typename Hash_compare, typename Allocator, bool Allow_multimapping>
00044 class concurrent_unordered_map_traits
00045 {
00046 protected:
00047 typedef std::pair<const Key, T> value_type;
00048 typedef Key key_type;
00049 typedef Hash_compare hash_compare;
00050 typedef typename Allocator::template rebind<value_type>::other allocator_type;
00051 enum { allow_multimapping = Allow_multimapping };
00052
00053 concurrent_unordered_map_traits() : my_hash_compare() {}
00054 concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {}
00055
00056 class value_compare : public std::binary_function<value_type, value_type, bool>
00057 {
00058 friend class concurrent_unordered_map_traits<Key, T, Hash_compare, Allocator, Allow_multimapping>;
00059
00060 public:
00061 bool operator()(const value_type& left, const value_type& right) const
00062 {
00063 return (my_hash_compare(left.first, right.first));
00064 }
00065
00066 value_compare(const hash_compare& comparator) : my_hash_compare(comparator) {}
00067
00068 protected:
00069 hash_compare my_hash_compare;
00070 };
00071
00072 template<class Type1, class Type2>
00073 static const Key& get_key(const std::pair<Type1, Type2>& value) {
00074 return (value.first);
00075 }
00076
00077 hash_compare my_hash_compare;
00078 };
00079
00080 template <typename Key, typename T, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>,
00081 typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
00082 class concurrent_unordered_map :
00083 public internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T,
00084 internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> >
00085 {
00086
00087 typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
00088 typedef concurrent_unordered_map_traits<Key, T, hash_compare, Allocator, false> traits_type;
00089 typedef internal::concurrent_unordered_base< traits_type > base_type;
00090 using traits_type::my_hash_compare;
00091 #if __TBB_EXTRA_DEBUG
00092 public:
00093 #endif
00094 using traits_type::allow_multimapping;
00095 public:
00096 using base_type::end;
00097 using base_type::find;
00098 using base_type::insert;
00099
00100
00101 typedef Key key_type;
00102 typedef typename base_type::value_type value_type;
00103 typedef T mapped_type;
00104 typedef Hasher hasher;
00105 typedef Key_equality key_equal;
00106 typedef hash_compare key_compare;
00107
00108 typedef typename base_type::allocator_type allocator_type;
00109 typedef typename base_type::pointer pointer;
00110 typedef typename base_type::const_pointer const_pointer;
00111 typedef typename base_type::reference reference;
00112 typedef typename base_type::const_reference const_reference;
00113
00114 typedef typename base_type::size_type size_type;
00115 typedef typename base_type::difference_type difference_type;
00116
00117 typedef typename base_type::iterator iterator;
00118 typedef typename base_type::const_iterator const_iterator;
00119 typedef typename base_type::iterator local_iterator;
00120 typedef typename base_type::const_iterator const_local_iterator;
00121
00122
00123 explicit concurrent_unordered_map(size_type n_of_buckets = 8,
00124 const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
00125 const allocator_type& a = allocator_type())
00126 : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
00127 {
00128 }
00129
00130 concurrent_unordered_map(const Allocator& a) : base_type(8, key_compare(), a)
00131 {
00132 }
00133
00134 template <typename Iterator>
00135 concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = 8,
00136 const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
00137 const allocator_type& a = allocator_type())
00138 : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
00139 {
00140 for (; first != last; ++first)
00141 base_type::insert(*first);
00142 }
00143
00144 concurrent_unordered_map(const concurrent_unordered_map& table) : base_type(table)
00145 {
00146 }
00147
00148 concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a)
00149 : base_type(table, a)
00150 {
00151 }
00152
00153 concurrent_unordered_map& operator=(const concurrent_unordered_map& table)
00154 {
00155 base_type::operator=(table);
00156 return (*this);
00157 }
00158
00159 iterator unsafe_erase(const_iterator where)
00160 {
00161 return base_type::unsafe_erase(where);
00162 }
00163
00164 size_type unsafe_erase(const key_type& key)
00165 {
00166 return base_type::unsafe_erase(key);
00167 }
00168
00169 iterator unsafe_erase(const_iterator first, const_iterator last)
00170 {
00171 return base_type::unsafe_erase(first, last);
00172 }
00173
00174 void swap(concurrent_unordered_map& table)
00175 {
00176 base_type::swap(table);
00177 }
00178
00179
00180 hasher hash_function() const
00181 {
00182 return my_hash_compare.my_hash_object;
00183 }
00184
00185 key_equal key_eq() const
00186 {
00187 return my_hash_compare.my_key_compare_object;
00188 }
00189
00190 mapped_type& operator[](const key_type& key)
00191 {
00192 iterator where = find(key);
00193
00194 if (where == end())
00195 {
00196 where = insert(std::pair<key_type, mapped_type>(key, mapped_type())).first;
00197 }
00198
00199 return ((*where).second);
00200 }
00201
00202 mapped_type& at(const key_type& key)
00203 {
00204 iterator where = find(key);
00205
00206 if (where == end())
00207 {
00208 tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
00209 }
00210
00211 return ((*where).second);
00212 }
00213
00214 const mapped_type& at(const key_type& key) const
00215 {
00216 const_iterator where = find(key);
00217
00218 if (where == end())
00219 {
00220 tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
00221 }
00222
00223 return ((*where).second);
00224 }
00225 };
00226
00227 template < typename Key, typename T, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>,
00228 typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
00229 class concurrent_unordered_multimap :
00230 public internal::concurrent_unordered_base< concurrent_unordered_map_traits< Key, T,
00231 internal::hash_compare<Key, Hasher, Key_equality>, Allocator, true> >
00232 {
00233
00234 typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
00235 typedef concurrent_unordered_map_traits<Key, T, hash_compare, Allocator, true> traits_type;
00236 typedef internal::concurrent_unordered_base< traits_type > base_type;
00237 using traits_type::my_hash_compare;
00238 #if __TBB_EXTRA_DEBUG
00239 public:
00240 #endif
00241 using traits_type::allow_multimapping;
00242 public:
00243 using base_type::end;
00244 using base_type::find;
00245 using base_type::insert;
00246
00247
00248 typedef Key key_type;
00249 typedef typename base_type::value_type value_type;
00250 typedef T mapped_type;
00251 typedef Hasher hasher;
00252 typedef Key_equality key_equal;
00253 typedef hash_compare key_compare;
00254
00255 typedef typename base_type::allocator_type allocator_type;
00256 typedef typename base_type::pointer pointer;
00257 typedef typename base_type::const_pointer const_pointer;
00258 typedef typename base_type::reference reference;
00259 typedef typename base_type::const_reference const_reference;
00260
00261 typedef typename base_type::size_type size_type;
00262 typedef typename base_type::difference_type difference_type;
00263
00264 typedef typename base_type::iterator iterator;
00265 typedef typename base_type::const_iterator const_iterator;
00266 typedef typename base_type::iterator local_iterator;
00267 typedef typename base_type::const_iterator const_local_iterator;
00268
00269
00270 explicit concurrent_unordered_multimap(size_type n_of_buckets = 8,
00271 const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
00272 const allocator_type& a = allocator_type())
00273 : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
00274 {
00275 }
00276
00277 concurrent_unordered_multimap(const Allocator& a) : base_type(8, key_compare(), a)
00278 {
00279 }
00280
00281 template <typename Iterator>
00282 concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets = 8,
00283 const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
00284 const allocator_type& a = allocator_type())
00285 : base_type(n_of_buckets,key_compare(_Hasher,_Key_equality), a)
00286 {
00287 for (; first != last; ++first)
00288 base_type::insert(*first);
00289 }
00290
00291 concurrent_unordered_multimap(const concurrent_unordered_multimap& table) : base_type(table)
00292 {
00293 }
00294
00295 concurrent_unordered_multimap(const concurrent_unordered_multimap& table, const Allocator& a)
00296 : base_type(table, a)
00297 {
00298 }
00299
00300 concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& table)
00301 {
00302 base_type::operator=(table);
00303 return (*this);
00304 }
00305
00306 iterator unsafe_erase(const_iterator where)
00307 {
00308 return base_type::unsafe_erase(where);
00309 }
00310
00311 size_type unsafe_erase(const key_type& key)
00312 {
00313 return base_type::unsafe_erase(key);
00314 }
00315
00316 iterator unsafe_erase(const_iterator first, const_iterator last)
00317 {
00318 return base_type::unsafe_erase(first, last);
00319 }
00320
00321 void swap(concurrent_unordered_multimap& table)
00322 {
00323 base_type::swap(table);
00324 }
00325
00326
00327 hasher hash_function() const
00328 {
00329 return my_hash_compare.my_hash_object;
00330 }
00331
00332 key_equal key_eq() const
00333 {
00334 return my_hash_compare.my_key_compare_object;
00335 }
00336 };
00337 }
00338
00339 using interface5::concurrent_unordered_map;
00340 using interface5::concurrent_unordered_multimap;
00341
00342 }
00343
00344 #endif// __TBB_concurrent_unordered_map_H