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
00043 #ifndef RC_HASH_MAP_H_
00044 #define RC_HASH_MAP_H_
00045
00046 #include <boost/multi_index_container.hpp>
00047 #include <boost/multi_index/hashed_index.hpp>
00048 #include <boost/multi_index/member.hpp>
00049
00050 namespace ReChannel {
00051
00052 namespace internals {
00053 namespace hash_map {
00054
00062 template<class T1, class T2>
00063 struct pair
00064 {
00065 typedef T1 first_type;
00066 typedef T2 second_type;
00067
00068 pair()
00069 : first(T1()), second(T2())
00070 { }
00071 pair(const T1& f, const T2& s)
00072 : first(f), second(s)
00073 { }
00074 pair(const std::pair<T1, T2>& p)
00075 : first(p.first), second(p.second)
00076 { }
00077
00078 operator std::pair<T1, T2>() const
00079 { return std::pair<T1, T2>(first, second); }
00080
00081 T1 first;
00082 mutable T2 second;
00083 };
00084
00085 }
00086 }
00087
00095 template<
00096 class key_, class data_,
00097 class hash_=boost::hash<key_>,
00098 class pred_=std::equal_to<key_>,
00099 class alloc_=std::allocator<internals::hash_map::pair<key_, data_> >
00100 >
00101 class rc_hash_map
00102 {
00103 private:
00104 typedef rc_hash_map<key_, data_, hash_, pred_, alloc_> this_type;
00105
00106 public:
00108 typedef key_ key_type;
00110 typedef data_ data_type;
00112 typedef typename internals::hash_map::pair<key_, data_> value_type;
00113
00114 private:
00117 struct index_1 {};
00120 typedef typename boost::template multi_index_container<
00121 value_type,
00122 typename boost::multi_index::template indexed_by<
00123 typename boost::multi_index::template hashed_unique<
00124 typename boost::multi_index::template tag<index_1>,
00125 BOOST_MULTI_INDEX_MEMBER(value_type, key_type, first),
00126 hash_, pred_
00127 >
00128 >,
00129 alloc_
00130 >
00131 hash_map_type;
00136 typedef typename hash_map_type::template index<index_1>::type
00137 index_type;
00138
00139 public:
00140 typedef typename index_type::pointer pointer;
00141 typedef typename index_type::const_pointer const_pointer;
00142 typedef typename index_type::reference reference;
00143 typedef typename index_type::const_reference const_reference;
00144 typedef typename index_type::size_type size_type;
00145 typedef typename index_type::difference_type difference_type;
00146 typedef typename index_type::iterator iterator;
00147 typedef typename index_type::const_iterator const_iterator;
00148 typedef typename index_type::hasher hasher;
00149 typedef typename index_type::key_equal key_equal;
00150 typedef typename index_type::allocator_type allocator_type;
00151
00152 public:
00153
00154 rc_hash_map() { }
00155 rc_hash_map(const this_type& other)
00156 : p_hash_map(other)
00157 { }
00158 inline this_type& operator=(const this_type& other)
00159 { p_hash_map = other; }
00160
00161 inline bool empty() const
00162 { return p_hash_map.template get<index_1>().empty(); }
00163 inline size_type size() const
00164 { return p_hash_map.template get<index_1>().size(); }
00165 inline size_type max_size() const
00166 { return p_hash_map.template get<index_1>().max_size(); }
00167
00168 inline iterator begin()
00169 { return p_hash_map.template get<index_1>().begin(); }
00170 inline iterator end()
00171 { return p_hash_map.template get<index_1>().end(); }
00172 inline const_iterator begin() const
00173 { return p_hash_map.template get<index_1>().begin(); }
00174 inline const_iterator end() const
00175 { return p_hash_map.template get<index_1>().end(); }
00176
00177 inline std::pair<iterator, bool> insert(const value_type& x)
00178 { return p_hash_map.template get<index_1>().insert(x); }
00179 inline iterator insert(iterator position, const value_type& x)
00180 { return p_hash_map.template get<index_1>().insert(position, x); }
00181 template<typename InputIterator>
00182 inline void insert(InputIterator first, InputIterator last)
00183 { p_hash_map.template get<index_1>().insert(first, last); }
00184
00185 inline iterator erase(iterator position)
00186 { return p_hash_map.template get<index_1>().erase(position); }
00187 inline size_type erase(const key_type& x)
00188 { return p_hash_map.template get<index_1>().erase(x); }
00189 inline iterator erase(iterator first, iterator last)
00190 { return p_hash_map.template get<index_1>().erase(first, last); }
00191
00192 inline void clear()
00193 { p_hash_map.template get<index_1>().clear(); }
00194 inline void swap(this_type& x)
00195 {
00196 p_hash_map.template get<index_1>().swap(
00197 x.p_hash_map.template get<index_1>());
00198 }
00199
00200 inline hasher hash_funct() const
00201 { return p_hash_map.template get<index_1>().hash_function(); }
00202 inline key_equal key_eq() const
00203 { return p_hash_map.template get<index_1>().key_eq(); }
00204
00205 inline iterator find(const key_type& k) const
00206 { return p_hash_map.template get<index_1>().find(k); }
00207
00208 inline size_type count(const key_type& k) const
00209 { return p_hash_map.template get<index_1>().count(k); }
00210 inline std::pair<iterator, iterator> equal_range(
00211 const key_type& k) const
00212 { return p_hash_map.template get<index_1>().equal_range(k); }
00213
00214 inline size_type bucket_count() const
00215 { return p_hash_map.template get<index_1>().bucket_count(); }
00216 inline void resize(size_type n)
00217 { p_hash_map.template get<index_1>().rehash(n); }
00218
00219 data_type& operator[](const key_type& k);
00220
00221 private:
00222 hash_map_type p_hash_map;
00223 };
00224
00232 template<
00233 class key_,
00234 class data_,
00235 class hash_=boost::hash<key_>,
00236 class pred_=std::equal_to<key_>,
00237 class alloc_=std::allocator<internals::hash_map::pair<key_, data_> >
00238 >
00239 class rc_hash_multimap
00240 {
00241 private:
00242 typedef rc_hash_map<key_, data_, hash_, pred_, alloc_> this_type;
00243
00244 public:
00246 typedef key_ key_type;
00248 typedef data_ data_type;
00250 typedef typename internals::hash_map::pair<key_, data_> value_type;
00251
00252 private:
00255 struct index_1 {};
00258 typedef typename boost::template multi_index_container<
00259 value_type,
00260 typename boost::multi_index::template indexed_by<
00261 typename boost::multi_index::template hashed_non_unique<
00262 typename boost::multi_index::template tag<index_1>,
00263 BOOST_MULTI_INDEX_MEMBER(value_type, key_type, first),
00264 hash_, pred_
00265 >
00266 >,
00267 alloc_
00268 >
00269 hash_multimap_type;
00274 typedef typename hash_multimap_type::template index<index_1>::type
00275 index_type;
00276
00277 public:
00278 typedef typename index_type::pointer pointer;
00279 typedef typename index_type::const_pointer const_pointer;
00280 typedef typename index_type::reference reference;
00281 typedef typename index_type::const_reference const_reference;
00282 typedef typename index_type::size_type size_type;
00283 typedef typename index_type::difference_type difference_type;
00284 typedef typename index_type::iterator iterator;
00285 typedef typename index_type::const_iterator const_iterator;
00286 typedef typename index_type::hasher hasher;
00287 typedef typename index_type::key_equal key_equal;
00288 typedef typename index_type::allocator_type allocator_type;
00289
00290 public:
00291
00292 rc_hash_multimap() { }
00293 rc_hash_multimap(const this_type& other)
00294 : p_hash_multimap(other)
00295 { }
00296 inline this_type& operator=(const this_type& other)
00297 { p_hash_multimap = other; }
00298
00299 inline bool empty() const
00300 { return p_hash_multimap.template get<index_1>().empty(); }
00301 inline size_type size() const
00302 { return p_hash_multimap.template get<index_1>().size(); }
00303 inline size_type max_size() const
00304 { return p_hash_multimap.template get<index_1>().max_size(); }
00305
00306 inline iterator begin()
00307 { return p_hash_multimap.template get<index_1>().begin(); }
00308 inline iterator end()
00309 { return p_hash_multimap.template get<index_1>().end(); }
00310 inline const_iterator begin() const
00311 { return p_hash_multimap.template get<index_1>().begin(); }
00312 inline const_iterator end() const
00313 { return p_hash_multimap.template get<index_1>().end(); }
00314
00315 inline std::pair<iterator, bool> insert(const value_type& x)
00316 { return p_hash_multimap.template get<index_1>().insert(x); }
00317 inline iterator insert(iterator position, const value_type& x)
00318 { return p_hash_multimap.template get<index_1>().insert(position, x); }
00319 template<typename InputIterator>
00320 inline void insert(InputIterator first, InputIterator last)
00321 { p_hash_multimap.template get<index_1>().insert(first, last); }
00322
00323 inline iterator erase(iterator position)
00324 { return p_hash_multimap.template get<index_1>().erase(position); }
00325 inline size_type erase(const key_type& x)
00326 { return p_hash_multimap.template get<index_1>().erase(x); }
00327 inline iterator erase(iterator first, iterator last)
00328 { return p_hash_multimap.template get<index_1>().erase(first, last); }
00329
00330 inline void clear()
00331 { p_hash_multimap.template get<index_1>().clear(); }
00332 inline void swap(this_type& x)
00333 {
00334 p_hash_multimap.template get<index_1>().swap(
00335 x.p_hash_multimap.template get<index_1>());
00336 }
00337
00338 inline hasher hash_funct() const
00339 { return p_hash_multimap.template get<index_1>().hash_function(); }
00340 inline key_equal key_eq() const
00341 { return p_hash_multimap.template get<index_1>().key_eq(); }
00342
00343 inline iterator find(const key_type& k) const
00344 { return p_hash_multimap.template get<index_1>().find(k); }
00345
00346 inline size_type count(const key_type& k) const
00347 { return p_hash_multimap.template get<index_1>().count(k); }
00348 inline std::pair<iterator, iterator> equal_range(
00349 const key_type& k) const
00350 { return p_hash_multimap.template get<index_1>().equal_range(k); }
00351
00352 inline size_type bucket_count() const
00353 { return p_hash_multimap.template get<index_1>().bucket_count(); }
00354 inline void resize(size_type n)
00355 { p_hash_multimap.template get<index_1>().rehash(n); }
00356
00357 private:
00358 hash_multimap_type p_hash_multimap;
00359 };
00360
00361
00362
00363 template<class key_, class data_, class hash_, class pred_, class alloc_>
00364 typename rc_hash_map<key_, data_, hash_, pred_, alloc_>::data_type&
00365 rc_hash_map<key_, data_, hash_, pred_, alloc_>::operator[](
00366 const key_type& k)
00367 {
00368 iterator it = this->find(k);
00369 if (it != this->end()) {
00370 return it->second;
00371 } else {
00372 typename std::template pair<iterator,bool> ret =
00373 this->insert(value_type(k, data_type()));
00374 return ret.first->second;
00375 }
00376 }
00377
00378 }
00379
00380 #endif // RC_HASH_MAP_H_
00381
00382
00383
00384
00385