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 #ifndef _GLIBCXX_DEBUG_UNORDERED_MAP
00031 #define _GLIBCXX_DEBUG_UNORDERED_MAP 1
00032
00033 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00034 # include <bits/c++0x_warning.h>
00035 #else
00036 # include <unordered_map>
00037
00038 #include <debug/safe_sequence.h>
00039 #include <debug/safe_iterator.h>
00040
00041 namespace std
00042 {
00043 namespace __debug
00044 {
00045
00046 template<typename _Key, typename _Tp,
00047 typename _Hash = std::hash<_Key>,
00048 typename _Pred = std::equal_to<_Key>,
00049 typename _Alloc = std::allocator<_Key> >
00050 class unordered_map
00051 : public _GLIBCXX_STD_D::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
00052 public __gnu_debug::_Safe_sequence<unordered_map<_Key, _Tp, _Hash,
00053 _Pred, _Alloc> >
00054 {
00055 typedef _GLIBCXX_STD_D::unordered_map<_Key, _Tp, _Hash,
00056 _Pred, _Alloc> _Base;
00057 typedef __gnu_debug::_Safe_sequence<unordered_map> _Safe_base;
00058
00059 public:
00060 typedef typename _Base::size_type size_type;
00061 typedef typename _Base::hasher hasher;
00062 typedef typename _Base::key_equal key_equal;
00063 typedef typename _Base::allocator_type allocator_type;
00064
00065 typedef typename _Base::key_type key_type;
00066 typedef typename _Base::value_type value_type;
00067
00068 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,
00069 unordered_map> iterator;
00070 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
00071 unordered_map> const_iterator;
00072
00073 explicit
00074 unordered_map(size_type __n = 10,
00075 const hasher& __hf = hasher(),
00076 const key_equal& __eql = key_equal(),
00077 const allocator_type& __a = allocator_type())
00078 : _Base(__n, __hf, __eql, __a) { }
00079
00080 template<typename _InputIterator>
00081 unordered_map(_InputIterator __first, _InputIterator __last,
00082 size_type __n = 0,
00083 const hasher& __hf = hasher(),
00084 const key_equal& __eql = key_equal(),
00085 const allocator_type& __a = allocator_type())
00086 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
00087 __last)),
00088 __gnu_debug::__base(__last), __n,
00089 __hf, __eql, __a), _Safe_base() { }
00090
00091 unordered_map(const unordered_map& __x)
00092 : _Base(__x), _Safe_base() { }
00093
00094 unordered_map(const _Base& __x)
00095 : _Base(__x), _Safe_base() { }
00096
00097 unordered_map(unordered_map&& __x)
00098 : _Base(std::move(__x)), _Safe_base() { }
00099
00100 unordered_map(initializer_list<value_type> __l,
00101 size_type __n = 0,
00102 const hasher& __hf = hasher(),
00103 const key_equal& __eql = key_equal(),
00104 const allocator_type& __a = allocator_type())
00105 : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
00106
00107 unordered_map&
00108 operator=(const unordered_map& __x)
00109 {
00110 *static_cast<_Base*>(this) = __x;
00111 this->_M_invalidate_all();
00112 return *this;
00113 }
00114
00115 unordered_map&
00116 operator=(unordered_map&& __x)
00117 {
00118
00119
00120 clear();
00121 swap(__x);
00122 return *this;
00123 }
00124
00125 unordered_map&
00126 operator=(initializer_list<value_type> __l)
00127 {
00128 this->clear();
00129 this->insert(__l);
00130 return *this;
00131 }
00132
00133 void
00134 swap(unordered_map& __x)
00135 {
00136 _Base::swap(__x);
00137 _Safe_base::_M_swap(__x);
00138 }
00139
00140 void
00141 clear()
00142 {
00143 _Base::clear();
00144 this->_M_invalidate_all();
00145 }
00146
00147 iterator
00148 begin()
00149 { return iterator(_Base::begin(), this); }
00150
00151 const_iterator
00152 begin() const
00153 { return const_iterator(_Base::begin(), this); }
00154
00155 iterator
00156 end()
00157 { return iterator(_Base::end(), this); }
00158
00159 const_iterator
00160 end() const
00161 { return const_iterator(_Base::end(), this); }
00162
00163 const_iterator
00164 cbegin() const
00165 { return const_iterator(_Base::begin(), this); }
00166
00167 const_iterator
00168 cend() const
00169 { return const_iterator(_Base::end(), this); }
00170
00171
00172 using _Base::begin;
00173 using _Base::end;
00174 using _Base::cbegin;
00175 using _Base::cend;
00176
00177 std::pair<iterator, bool>
00178 insert(const value_type& __obj)
00179 {
00180 typedef std::pair<typename _Base::iterator, bool> __pair_type;
00181 __pair_type __res = _Base::insert(__obj);
00182 return std::make_pair(iterator(__res.first, this), __res.second);
00183 }
00184
00185 iterator
00186 insert(const_iterator, const value_type& __obj)
00187 {
00188 typedef std::pair<typename _Base::iterator, bool> __pair_type;
00189 __pair_type __res = _Base::insert(__obj);
00190 return iterator(__res.first, this);
00191 }
00192
00193 void
00194 insert(std::initializer_list<value_type> __l)
00195 { _Base::insert(__l); }
00196
00197 template<typename _InputIterator>
00198 void
00199 insert(_InputIterator __first, _InputIterator __last)
00200 {
00201 __glibcxx_check_valid_range(__first, __last);
00202 _Base::insert(__gnu_debug::__base(__first),
00203 __gnu_debug::__base(__last));
00204 }
00205
00206 iterator
00207 find(const key_type& __key)
00208 { return iterator(_Base::find(__key), this); }
00209
00210 const_iterator
00211 find(const key_type& __key) const
00212 { return const_iterator(_Base::find(__key), this); }
00213
00214 std::pair<iterator, iterator>
00215 equal_range(const key_type& __key)
00216 {
00217 typedef typename _Base::iterator _Base_iterator;
00218 typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
00219 __pair_type __res = _Base::equal_range(__key);
00220 return std::make_pair(iterator(__res.first, this),
00221 iterator(__res.second, this));
00222 }
00223
00224 std::pair<const_iterator, const_iterator>
00225 equal_range(const key_type& __key) const
00226 {
00227 typedef typename _Base::const_iterator _Base_iterator;
00228 typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
00229 __pair_type __res = _Base::equal_range(__key);
00230 return std::make_pair(const_iterator(__res.first, this),
00231 const_iterator(__res.second, this));
00232 }
00233
00234 size_type
00235 erase(const key_type& __key)
00236 {
00237 size_type __ret(0);
00238 iterator __victim(_Base::find(__key), this);
00239 if (__victim != end())
00240 {
00241 this->erase(__victim);
00242 __ret = 1;
00243 }
00244 return __ret;
00245 }
00246
00247 iterator
00248 erase(const_iterator __it)
00249 {
00250 __glibcxx_check_erase(__it);
00251 __it._M_invalidate();
00252 return iterator(_Base::erase(__it.base()), this);
00253 }
00254
00255 iterator
00256 erase(const_iterator __first, const_iterator __last)
00257 {
00258 __glibcxx_check_erase_range(__first, __last);
00259 for (const_iterator __tmp = __first; __tmp != __last;)
00260 {
00261 const_iterator __victim = __tmp++;
00262 __victim._M_invalidate();
00263 }
00264 return iterator(_Base::erase(__first.base(),
00265 __last.base()), this);
00266 }
00267
00268 _Base&
00269 _M_base() { return *this; }
00270
00271 const _Base&
00272 _M_base() const { return *this; }
00273
00274 private:
00275 void
00276 _M_invalidate_all()
00277 {
00278 typedef typename _Base::const_iterator _Base_const_iterator;
00279 typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
00280 this->_M_invalidate_if(_Not_equal(_M_base().end()));
00281 }
00282 };
00283
00284 template<typename _Key, typename _Tp, typename _Hash,
00285 typename _Pred, typename _Alloc>
00286 inline void
00287 swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00288 unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00289 { __x.swap(__y); }
00290
00291 template<typename _Key, typename _Tp, typename _Hash,
00292 typename _Pred, typename _Alloc>
00293 inline bool
00294 operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00295 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00296 { return __x._M_equal(__y); }
00297
00298 template<typename _Key, typename _Tp, typename _Hash,
00299 typename _Pred, typename _Alloc>
00300 inline bool
00301 operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00302 const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00303 { return !(__x == __y); }
00304
00305
00306
00307 template<typename _Key, typename _Tp,
00308 typename _Hash = std::hash<_Key>,
00309 typename _Pred = std::equal_to<_Key>,
00310 typename _Alloc = std::allocator<_Key> >
00311 class unordered_multimap
00312 : public _GLIBCXX_STD_D::unordered_multimap<_Key, _Tp, _Hash,
00313 _Pred, _Alloc>,
00314 public __gnu_debug::_Safe_sequence<unordered_multimap<_Key, _Tp, _Hash,
00315 _Pred, _Alloc> >
00316 {
00317 typedef _GLIBCXX_STD_D::unordered_multimap<_Key, _Tp, _Hash,
00318 _Pred, _Alloc> _Base;
00319 typedef __gnu_debug::_Safe_sequence<unordered_multimap> _Safe_base;
00320
00321 public:
00322 typedef typename _Base::size_type size_type;
00323 typedef typename _Base::hasher hasher;
00324 typedef typename _Base::key_equal key_equal;
00325 typedef typename _Base::allocator_type allocator_type;
00326
00327 typedef typename _Base::key_type key_type;
00328 typedef typename _Base::value_type value_type;
00329
00330 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,
00331 unordered_multimap> iterator;
00332 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
00333 unordered_multimap> const_iterator;
00334
00335 explicit
00336 unordered_multimap(size_type __n = 10,
00337 const hasher& __hf = hasher(),
00338 const key_equal& __eql = key_equal(),
00339 const allocator_type& __a = allocator_type())
00340 : _Base(__n, __hf, __eql, __a) { }
00341
00342 template<typename _InputIterator>
00343 unordered_multimap(_InputIterator __first, _InputIterator __last,
00344 size_type __n = 0,
00345 const hasher& __hf = hasher(),
00346 const key_equal& __eql = key_equal(),
00347 const allocator_type& __a = allocator_type())
00348 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
00349 __last)),
00350 __gnu_debug::__base(__last), __n,
00351 __hf, __eql, __a), _Safe_base() { }
00352
00353 unordered_multimap(const unordered_multimap& __x)
00354 : _Base(__x), _Safe_base() { }
00355
00356 unordered_multimap(const _Base& __x)
00357 : _Base(__x), _Safe_base() { }
00358
00359 unordered_multimap(unordered_multimap&& __x)
00360 : _Base(std::move(__x)), _Safe_base() { }
00361
00362 unordered_multimap(initializer_list<value_type> __l,
00363 size_type __n = 0,
00364 const hasher& __hf = hasher(),
00365 const key_equal& __eql = key_equal(),
00366 const allocator_type& __a = allocator_type())
00367 : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
00368
00369 unordered_multimap&
00370 operator=(const unordered_multimap& __x)
00371 {
00372 *static_cast<_Base*>(this) = __x;
00373 this->_M_invalidate_all();
00374 return *this;
00375 }
00376
00377 unordered_multimap&
00378 operator=(unordered_multimap&& __x)
00379 {
00380
00381
00382 clear();
00383 swap(__x);
00384 return *this;
00385 }
00386
00387 unordered_multimap&
00388 operator=(initializer_list<value_type> __l)
00389 {
00390 this->clear();
00391 this->insert(__l);
00392 return *this;
00393 }
00394
00395 void
00396 swap(unordered_multimap& __x)
00397 {
00398 _Base::swap(__x);
00399 _Safe_base::_M_swap(__x);
00400 }
00401
00402 void
00403 clear()
00404 {
00405 _Base::clear();
00406 this->_M_invalidate_all();
00407 }
00408
00409 iterator
00410 begin()
00411 { return iterator(_Base::begin(), this); }
00412
00413 const_iterator
00414 begin() const
00415 { return const_iterator(_Base::begin(), this); }
00416
00417 iterator
00418 end()
00419 { return iterator(_Base::end(), this); }
00420
00421 const_iterator
00422 end() const
00423 { return const_iterator(_Base::end(), this); }
00424
00425 const_iterator
00426 cbegin() const
00427 { return const_iterator(_Base::begin(), this); }
00428
00429 const_iterator
00430 cend() const
00431 { return const_iterator(_Base::end(), this); }
00432
00433
00434 using _Base::begin;
00435 using _Base::end;
00436 using _Base::cbegin;
00437 using _Base::cend;
00438
00439 iterator
00440 insert(const value_type& __obj)
00441 { return iterator(_Base::insert(__obj), this); }
00442
00443 iterator
00444 insert(const_iterator, const value_type& __obj)
00445 { return iterator(_Base::insert(__obj), this); }
00446
00447 void
00448 insert(std::initializer_list<value_type> __l)
00449 { _Base::insert(__l); }
00450
00451 template<typename _InputIterator>
00452 void
00453 insert(_InputIterator __first, _InputIterator __last)
00454 {
00455 __glibcxx_check_valid_range(__first, __last);
00456 _Base::insert(__gnu_debug::__base(__first),
00457 __gnu_debug::__base(__last));
00458 }
00459
00460 iterator
00461 find(const key_type& __key)
00462 { return iterator(_Base::find(__key), this); }
00463
00464 const_iterator
00465 find(const key_type& __key) const
00466 { return const_iterator(_Base::find(__key), this); }
00467
00468 std::pair<iterator, iterator>
00469 equal_range(const key_type& __key)
00470 {
00471 typedef typename _Base::iterator _Base_iterator;
00472 typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
00473 __pair_type __res = _Base::equal_range(__key);
00474 return std::make_pair(iterator(__res.first, this),
00475 iterator(__res.second, this));
00476 }
00477
00478 std::pair<const_iterator, const_iterator>
00479 equal_range(const key_type& __key) const
00480 {
00481 typedef typename _Base::const_iterator _Base_iterator;
00482 typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
00483 __pair_type __res = _Base::equal_range(__key);
00484 return std::make_pair(const_iterator(__res.first, this),
00485 const_iterator(__res.second, this));
00486 }
00487
00488 size_type
00489 erase(const key_type& __key)
00490 {
00491 size_type __ret(0);
00492 iterator __victim(_Base::find(__key), this);
00493 if (__victim != end())
00494 {
00495 this->erase(__victim);
00496 __ret = 1;
00497 }
00498 return __ret;
00499 }
00500
00501 iterator
00502 erase(const_iterator __it)
00503 {
00504 __glibcxx_check_erase(__it);
00505 __it._M_invalidate();
00506 return iterator(_Base::erase(__it.base()), this);
00507 }
00508
00509 iterator
00510 erase(const_iterator __first, const_iterator __last)
00511 {
00512 __glibcxx_check_erase_range(__first, __last);
00513 for (const_iterator __tmp = __first; __tmp != __last;)
00514 {
00515 const_iterator __victim = __tmp++;
00516 __victim._M_invalidate();
00517 }
00518 return iterator(_Base::erase(__first.base(),
00519 __last.base()), this);
00520 }
00521
00522 _Base&
00523 _M_base() { return *this; }
00524
00525 const _Base&
00526 _M_base() const { return *this; }
00527
00528 private:
00529 void
00530 _M_invalidate_all()
00531 {
00532 typedef typename _Base::const_iterator _Base_const_iterator;
00533 typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
00534 this->_M_invalidate_if(_Not_equal(_M_base().end()));
00535 }
00536 };
00537
00538 template<typename _Key, typename _Tp, typename _Hash,
00539 typename _Pred, typename _Alloc>
00540 inline void
00541 swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00542 unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00543 { __x.swap(__y); }
00544
00545 template<typename _Key, typename _Tp, typename _Hash,
00546 typename _Pred, typename _Alloc>
00547 inline bool
00548 operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00549 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00550 { return __x._M_equal(__y); }
00551
00552 template<typename _Key, typename _Tp, typename _Hash,
00553 typename _Pred, typename _Alloc>
00554 inline bool
00555 operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
00556 const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
00557 { return !(__x == __y); }
00558
00559 }
00560 }
00561
00562 #endif // __GXX_EXPERIMENTAL_CXX0X__
00563
00564 #endif