00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __TBB_concurrent_unordered_map_H
00025 #define __TBB_concurrent_unordered_map_H
00026
00027 #include "_concurrent_unordered_internal.h"
00028
00029 namespace tbb
00030 {
00031
00032
00033 template<typename Key>
00034 class tbb_hash
00035 {
00036 public:
00037 tbb_hash() {}
00038
00039 size_t operator()(const Key& key) const
00040 {
00041 return tbb_hasher(key);
00042 }
00043 };
00044
00045 namespace interface5 {
00046
00047
00048 template<typename Key, typename T, typename Hash_compare, typename Allocator, bool Allow_multimapping>
00049 class concurrent_unordered_map_traits
00050 {
00051 protected:
00052 typedef std::pair<const Key, T> value_type;
00053 typedef Key key_type;
00054 typedef Hash_compare hash_compare;
00055 typedef typename Allocator::template rebind<value_type>::other allocator_type;
00056 enum { allow_multimapping = Allow_multimapping };
00057
00058 concurrent_unordered_map_traits() : my_hash_compare() {}
00059 concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {}
00060
00061 class value_compare : public std::binary_function<value_type, value_type, bool>
00062 {
00063 friend class concurrent_unordered_map_traits<Key, T, Hash_compare, Allocator, Allow_multimapping>;
00064
00065 public:
00066 bool operator()(const value_type& left, const value_type& right) const
00067 {
00068 return (my_hash_compare(left.first, right.first));
00069 }
00070
00071 value_compare(const hash_compare& comparator) : my_hash_compare(comparator) {}
00072
00073 protected:
00074 hash_compare my_hash_compare;
00075 };
00076
00077 template<class Type1, class Type2>
00078 static const Key& get_key(const std::pair<Type1, Type2>& value) {
00079 return (value.first);
00080 }
00081
00082 hash_compare my_hash_compare;
00083 };
00084
00085 template <typename Key, typename T, typename Hasher = tbb_hash<Key>, typename Key_equality = std::equal_to<Key>, typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
00086 class concurrent_unordered_map : public internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T, internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> >
00087 {
00088
00089 typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
00090 typedef internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T, hash_compare, Allocator, false> > base_type;
00091 typedef concurrent_unordered_map_traits<Key, T, internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> traits_type;
00092 using traits_type::my_hash_compare;
00093 #if __TBB_EXTRA_DEBUG
00094 public:
00095 #endif
00096 using traits_type::allow_multimapping;
00097 public:
00098 using base_type::end;
00099 using base_type::find;
00100 using base_type::insert;
00101
00102
00103 typedef Key key_type;
00104 typedef typename base_type::value_type value_type;
00105 typedef T mapped_type;
00106 typedef Hasher hasher;
00107 typedef Key_equality key_equal;
00108 typedef hash_compare key_compare;
00109
00110 typedef typename base_type::allocator_type allocator_type;
00111 typedef typename base_type::pointer pointer;
00112 typedef typename base_type::const_pointer const_pointer;
00113 typedef typename base_type::reference reference;
00114 typedef typename base_type::const_reference const_reference;
00115
00116 typedef typename base_type::size_type size_type;
00117 typedef typename base_type::difference_type difference_type;
00118
00119 typedef typename base_type::iterator iterator;
00120 typedef typename base_type::const_iterator const_iterator;
00121 typedef typename base_type::iterator local_iterator;
00122 typedef typename base_type::const_iterator const_local_iterator;
00123
00124
00125 explicit concurrent_unordered_map(size_type n_of_buckets = 8, const hasher& a_hasher = hasher(),
00126 const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
00127 : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
00128 {
00129 }
00130
00131 concurrent_unordered_map(const Allocator& a) : base_type(8, key_compare(), a)
00132 {
00133 }
00134
00135 template <typename Iterator>
00136 concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = 8, const hasher& a_hasher = hasher(),
00137 const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
00138 : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), 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 }
00228
00229 using interface5::concurrent_unordered_map;
00230
00231 }
00232
00233 #endif// __TBB_concurrent_unordered_map_H