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