00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_concurrent_unordered_map_H
00022 #define __TBB_concurrent_unordered_map_H
00023
00024 #include "_concurrent_unordered_internal.h"
00025
00026 namespace tbb
00027 {
00028
00029
00030 template<typename Key>
00031 class tbb_hash
00032 {
00033 public:
00034 tbb_hash() {}
00035
00036 size_t operator()(const Key& key) const
00037 {
00038 return tbb_hasher(key);
00039 }
00040 };
00041
00042 namespace interface5 {
00043
00044
00045 template<typename Key, typename T, typename Hash_compare, typename Allocator, bool Allow_multimapping>
00046 class concurrent_unordered_map_traits
00047 {
00048 protected:
00049 typedef std::pair<const Key, T> value_type;
00050 typedef Key key_type;
00051 typedef Hash_compare hash_compare;
00052 typedef typename Allocator::template rebind<value_type>::other allocator_type;
00053 enum { allow_multimapping = Allow_multimapping };
00054
00055 concurrent_unordered_map_traits() : my_hash_compare() {}
00056 concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {}
00057
00058 class value_compare : public std::binary_function<value_type, value_type, bool>
00059 {
00060 friend class concurrent_unordered_map_traits<Key, T, Hash_compare, Allocator, Allow_multimapping>;
00061
00062 public:
00063 bool operator()(const value_type& left, const value_type& right) const
00064 {
00065 return (my_hash_compare(left.first, right.first));
00066 }
00067
00068 value_compare(const hash_compare& comparator) : my_hash_compare(comparator) {}
00069
00070 protected:
00071 hash_compare my_hash_compare;
00072 };
00073
00074 template<class Type1, class Type2>
00075 static const Key& get_key(const std::pair<Type1, Type2>& value) {
00076 return (value.first);
00077 }
00078
00079 hash_compare my_hash_compare;
00080 };
00081
00082 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> > >
00083 class concurrent_unordered_map : public internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T, internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> >
00084 {
00085
00086 typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
00087 typedef internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T, hash_compare, Allocator, false> > base_type;
00088 typedef concurrent_unordered_map_traits<Key, T, internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> traits_type;
00089 using traits_type::my_hash_compare;
00090 #if __TBB_EXTRA_DEBUG
00091 public:
00092 #endif
00093 using traits_type::allow_multimapping;
00094 public:
00095 using base_type::end;
00096 using base_type::find;
00097 using base_type::insert;
00098
00099
00100 typedef Key key_type;
00101 typedef typename base_type::value_type value_type;
00102 typedef T mapped_type;
00103 typedef Hasher hasher;
00104 typedef Key_equality key_equal;
00105 typedef hash_compare key_compare;
00106
00107 typedef typename base_type::allocator_type allocator_type;
00108 typedef typename base_type::pointer pointer;
00109 typedef typename base_type::const_pointer const_pointer;
00110 typedef typename base_type::reference reference;
00111 typedef typename base_type::const_reference const_reference;
00112
00113 typedef typename base_type::size_type size_type;
00114 typedef typename base_type::difference_type difference_type;
00115
00116 typedef typename base_type::iterator iterator;
00117 typedef typename base_type::const_iterator const_iterator;
00118 typedef typename base_type::iterator local_iterator;
00119 typedef typename base_type::const_iterator const_local_iterator;
00120
00121
00122 explicit concurrent_unordered_map(size_type n_of_buckets = 8, const hasher& a_hasher = hasher(),
00123 const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
00124 : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
00125 {
00126 }
00127
00128 concurrent_unordered_map(const Allocator& a) : base_type(8, key_compare(), a)
00129 {
00130 }
00131
00132 template <typename Iterator>
00133 concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = 8, const hasher& a_hasher = hasher(),
00134 const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
00135 : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
00136 {
00137 for (; first != last; ++first)
00138 base_type::insert(*first);
00139 }
00140
00141 concurrent_unordered_map(const concurrent_unordered_map& table) : base_type(table)
00142 {
00143 }
00144
00145 concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a)
00146 : base_type(table, a)
00147 {
00148 }
00149
00150 concurrent_unordered_map& operator=(const concurrent_unordered_map& table)
00151 {
00152 base_type::operator=(table);
00153 return (*this);
00154 }
00155
00156 iterator unsafe_erase(const_iterator where)
00157 {
00158 return base_type::unsafe_erase(where);
00159 }
00160
00161 size_type unsafe_erase(const key_type& key)
00162 {
00163 return base_type::unsafe_erase(key);
00164 }
00165
00166 iterator unsafe_erase(const_iterator first, const_iterator last)
00167 {
00168 return base_type::unsafe_erase(first, last);
00169 }
00170
00171 void swap(concurrent_unordered_map& table)
00172 {
00173 base_type::swap(table);
00174 }
00175
00176
00177 hasher hash_function() const
00178 {
00179 return my_hash_compare.my_hash_object;
00180 }
00181
00182 key_equal key_eq() const
00183 {
00184 return my_hash_compare.my_key_compare_object;
00185 }
00186
00187 mapped_type& operator[](const key_type& key)
00188 {
00189 iterator where = find(key);
00190
00191 if (where == end())
00192 {
00193 where = insert(std::pair<key_type, mapped_type>(key, mapped_type())).first;
00194 }
00195
00196 return ((*where).second);
00197 }
00198
00199 mapped_type& at(const key_type& key)
00200 {
00201 iterator where = find(key);
00202
00203 if (where == end())
00204 {
00205 tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
00206 }
00207
00208 return ((*where).second);
00209 }
00210
00211 const mapped_type& at(const key_type& key) const
00212 {
00213 const_iterator where = find(key);
00214
00215 if (where == end())
00216 {
00217 tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
00218 }
00219
00220 return ((*where).second);
00221 }
00222 };
00223
00224 }
00225
00226 using interface5::concurrent_unordered_map;
00227
00228 }
00229
00230 #endif// __TBB_concurrent_unordered_map_H