1 // Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 // Free Software Foundation, Inc.
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 // <http://www.gnu.org/licenses/>.
26 /** @file debug/unordered_set
27 * This file is a GNU debug extension to the Standard C++ Library.
30 #ifndef _GLIBCXX_DEBUG_UNORDERED_SET
31 #define _GLIBCXX_DEBUG_UNORDERED_SET 1
33 #ifndef __GXX_EXPERIMENTAL_CXX0X__
34 # include <bits/c++0x_warning.h>
36 # include <unordered_set>
38 #include <debug/safe_sequence.h>
39 #include <debug/safe_iterator.h>
45 /// Class std::unordered_set with safety/checking/debug instrumentation.
46 template<typename _Value,
47 typename _Hash = std::hash<_Value>,
48 typename _Pred = std::equal_to<_Value>,
49 typename _Alloc = std::allocator<_Value> >
51 : public _GLIBCXX_STD_D::unordered_set<_Value, _Hash, _Pred, _Alloc>,
52 public __gnu_debug::_Safe_sequence<unordered_set<_Value, _Hash,
55 typedef _GLIBCXX_STD_D::unordered_set<_Value, _Hash,
57 typedef __gnu_debug::_Safe_sequence<unordered_set> _Safe_base;
58 typedef typename _Base::const_iterator _Base_const_iterator;
59 typedef typename _Base::iterator _Base_iterator;
60 typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
63 typedef typename _Base::size_type size_type;
64 typedef typename _Base::hasher hasher;
65 typedef typename _Base::key_equal key_equal;
66 typedef typename _Base::allocator_type allocator_type;
68 typedef typename _Base::key_type key_type;
69 typedef typename _Base::value_type value_type;
71 typedef __gnu_debug::_Safe_iterator<_Base_iterator,
72 unordered_set> iterator;
73 typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
74 unordered_set> const_iterator;
77 unordered_set(size_type __n = 10,
78 const hasher& __hf = hasher(),
79 const key_equal& __eql = key_equal(),
80 const allocator_type& __a = allocator_type())
81 : _Base(__n, __hf, __eql, __a) { }
83 template<typename _InputIterator>
84 unordered_set(_InputIterator __first, _InputIterator __last,
86 const hasher& __hf = hasher(),
87 const key_equal& __eql = key_equal(),
88 const allocator_type& __a = allocator_type())
89 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
91 __gnu_debug::__base(__last), __n,
92 __hf, __eql, __a), _Safe_base() { }
94 unordered_set(const unordered_set& __x)
95 : _Base(__x), _Safe_base() { }
97 unordered_set(const _Base& __x)
98 : _Base(__x), _Safe_base() { }
100 unordered_set(unordered_set&& __x)
101 : _Base(std::move(__x)), _Safe_base() { }
103 unordered_set(initializer_list<value_type> __l,
105 const hasher& __hf = hasher(),
106 const key_equal& __eql = key_equal(),
107 const allocator_type& __a = allocator_type())
108 : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
111 operator=(const unordered_set& __x)
113 *static_cast<_Base*>(this) = __x;
114 this->_M_invalidate_all();
119 operator=(unordered_set&& __x)
129 operator=(initializer_list<value_type> __l)
137 swap(unordered_set& __x)
140 _Safe_base::_M_swap(__x);
147 this->_M_invalidate_all();
152 { return iterator(_Base::begin(), this); }
156 { return const_iterator(_Base::begin(), this); }
160 { return iterator(_Base::end(), this); }
164 { return const_iterator(_Base::end(), this); }
168 { return const_iterator(_Base::begin(), this); }
172 { return const_iterator(_Base::end(), this); }
180 std::pair<iterator, bool>
181 insert(const value_type& __obj)
183 typedef std::pair<_Base_iterator, bool> __pair_type;
184 __pair_type __res = _Base::insert(__obj);
185 return std::make_pair(iterator(__res.first, this), __res.second);
189 insert(const_iterator __hint, const value_type& __obj)
191 __glibcxx_check_insert(__hint);
192 return iterator(_Base::insert(__hint.base(), __obj), this);
195 std::pair<iterator, bool>
196 insert(value_type&& __obj)
198 typedef std::pair<typename _Base::iterator, bool> __pair_type;
199 __pair_type __res = _Base::insert(std::move(__obj));
200 return std::make_pair(iterator(__res.first, this), __res.second);
204 insert(const_iterator __hint, value_type&& __obj)
206 __glibcxx_check_insert(__hint);
207 return iterator(_Base::insert(__hint.base(), std::move(__obj)), this);
211 insert(std::initializer_list<value_type> __l)
212 { _Base::insert(__l); }
214 template<typename _InputIterator>
216 insert(_InputIterator __first, _InputIterator __last)
218 __glibcxx_check_valid_range(__first, __last);
219 _Base::insert(__gnu_debug::__base(__first),
220 __gnu_debug::__base(__last));
224 find(const key_type& __key)
225 { return iterator(_Base::find(__key), this); }
228 find(const key_type& __key) const
229 { return const_iterator(_Base::find(__key), this); }
231 std::pair<iterator, iterator>
232 equal_range(const key_type& __key)
234 typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
235 __pair_type __res = _Base::equal_range(__key);
236 return std::make_pair(iterator(__res.first, this),
237 iterator(__res.second, this));
240 std::pair<const_iterator, const_iterator>
241 equal_range(const key_type& __key) const
243 std::pair<_Base_const_iterator, _Base_const_iterator>
244 __res = _Base::equal_range(__key);
245 return std::make_pair(const_iterator(__res.first, this),
246 const_iterator(__res.second, this));
250 erase(const key_type& __key)
253 _Base_iterator __victim(_Base::find(__key));
254 if (__victim != _Base::end())
256 this->_M_invalidate_if(_Equal(__victim));
257 _Base::erase(__victim);
264 erase(const_iterator __it)
266 __glibcxx_check_erase(__it);
267 this->_M_invalidate_if(_Equal(__it.base()));
268 return iterator(_Base::erase(__it.base()), this);
272 erase(const_iterator __first, const_iterator __last)
274 __glibcxx_check_erase_range(__first, __last);
275 for (_Base_const_iterator __tmp = __first.base();
276 __tmp != __last.base(); ++__tmp)
278 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
279 _M_message(__gnu_debug::__msg_valid_range)
280 ._M_iterator(__first, "first")
281 ._M_iterator(__last, "last"));
282 this->_M_invalidate_if(_Equal(__tmp));
284 return iterator(_Base::erase(__first.base(),
285 __last.base()), this);
289 _M_base() { return *this; }
292 _M_base() const { return *this; }
298 typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
299 this->_M_invalidate_if(_Not_equal(_Base::end()));
303 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
305 swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
306 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
309 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
311 operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
312 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
313 { return __x._M_equal(__y); }
315 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
317 operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
318 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
319 { return !(__x == __y); }
322 /// Class std::unordered_multiset with safety/checking/debug instrumentation.
323 template<typename _Value,
324 typename _Hash = std::hash<_Value>,
325 typename _Pred = std::equal_to<_Value>,
326 typename _Alloc = std::allocator<_Value> >
327 class unordered_multiset
328 : public _GLIBCXX_STD_D::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
329 public __gnu_debug::_Safe_sequence<unordered_multiset<_Value, _Hash,
332 typedef _GLIBCXX_STD_D::unordered_multiset<_Value, _Hash,
333 _Pred, _Alloc> _Base;
334 typedef __gnu_debug::_Safe_sequence<unordered_multiset> _Safe_base;
335 typedef typename _Base::const_iterator _Base_const_iterator;
336 typedef typename _Base::iterator _Base_iterator;
337 typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
340 typedef typename _Base::size_type size_type;
341 typedef typename _Base::hasher hasher;
342 typedef typename _Base::key_equal key_equal;
343 typedef typename _Base::allocator_type allocator_type;
345 typedef typename _Base::key_type key_type;
346 typedef typename _Base::value_type value_type;
348 typedef __gnu_debug::_Safe_iterator<_Base_iterator,
349 unordered_multiset> iterator;
350 typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
351 unordered_multiset> const_iterator;
354 unordered_multiset(size_type __n = 10,
355 const hasher& __hf = hasher(),
356 const key_equal& __eql = key_equal(),
357 const allocator_type& __a = allocator_type())
358 : _Base(__n, __hf, __eql, __a) { }
360 template<typename _InputIterator>
361 unordered_multiset(_InputIterator __first, _InputIterator __last,
363 const hasher& __hf = hasher(),
364 const key_equal& __eql = key_equal(),
365 const allocator_type& __a = allocator_type())
366 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
368 __gnu_debug::__base(__last), __n,
369 __hf, __eql, __a), _Safe_base() { }
371 unordered_multiset(const unordered_multiset& __x)
372 : _Base(__x), _Safe_base() { }
374 unordered_multiset(const _Base& __x)
375 : _Base(__x), _Safe_base() { }
377 unordered_multiset(unordered_multiset&& __x)
378 : _Base(std::move(__x)), _Safe_base() { }
380 unordered_multiset(initializer_list<value_type> __l,
382 const hasher& __hf = hasher(),
383 const key_equal& __eql = key_equal(),
384 const allocator_type& __a = allocator_type())
385 : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
388 operator=(const unordered_multiset& __x)
390 *static_cast<_Base*>(this) = __x;
391 this->_M_invalidate_all();
396 operator=(unordered_multiset&& __x)
406 operator=(initializer_list<value_type> __l)
414 swap(unordered_multiset& __x)
417 _Safe_base::_M_swap(__x);
424 this->_M_invalidate_all();
429 { return iterator(_Base::begin(), this); }
433 { return const_iterator(_Base::begin(), this); }
437 { return iterator(_Base::end(), this); }
441 { return const_iterator(_Base::end(), this); }
445 { return const_iterator(_Base::begin(), this); }
449 { return const_iterator(_Base::end(), this); }
458 insert(const value_type& __obj)
459 { return iterator(_Base::insert(__obj), this); }
462 insert(const_iterator __hint, const value_type& __obj)
464 __glibcxx_check_insert(__hint);
465 return iterator(_Base::insert(__hint.base(), __obj), this);
469 insert(value_type&& __obj)
470 { return iterator(_Base::insert(std::move(__obj)), this); }
473 insert(const_iterator __hint, value_type&& __obj)
475 __glibcxx_check_insert(__hint);
476 return iterator(_Base::insert(__hint.base(), std::move(__obj)), this);
480 insert(std::initializer_list<value_type> __l)
481 { _Base::insert(__l); }
483 template<typename _InputIterator>
485 insert(_InputIterator __first, _InputIterator __last)
487 __glibcxx_check_valid_range(__first, __last);
488 _Base::insert(__gnu_debug::__base(__first),
489 __gnu_debug::__base(__last));
493 find(const key_type& __key)
494 { return iterator(_Base::find(__key), this); }
497 find(const key_type& __key) const
498 { return const_iterator(_Base::find(__key), this); }
500 std::pair<iterator, iterator>
501 equal_range(const key_type& __key)
503 typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
504 __pair_type __res = _Base::equal_range(__key);
505 return std::make_pair(iterator(__res.first, this),
506 iterator(__res.second, this));
509 std::pair<const_iterator, const_iterator>
510 equal_range(const key_type& __key) const
512 std::pair<_Base_const_iterator, _Base_const_iterator>
513 __res = _Base::equal_range(__key);
514 return std::make_pair(const_iterator(__res.first, this),
515 const_iterator(__res.second, this));
519 erase(const key_type& __key)
522 std::pair<_Base_iterator, _Base_iterator> __pair =
523 _Base::equal_range(__key);
524 for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
526 this->_M_invalidate_if(_Equal(__victim));
527 _Base::erase(__victim++);
534 erase(const_iterator __it)
536 __glibcxx_check_erase(__it);
537 this->_M_invalidate_if(_Equal(__it.base()));
538 return iterator(_Base::erase(__it.base()), this);
542 erase(const_iterator __first, const_iterator __last)
544 __glibcxx_check_erase_range(__first, __last);
545 for (_Base_const_iterator __tmp = __first.base();
546 __tmp != __last.base(); ++__tmp)
548 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
549 _M_message(__gnu_debug::__msg_valid_range)
550 ._M_iterator(__first, "first")
551 ._M_iterator(__last, "last"));
552 this->_M_invalidate_if(_Equal(__tmp));
554 return iterator(_Base::erase(__first.base(),
555 __last.base()), this);
559 _M_base() { return *this; }
562 _M_base() const { return *this; }
568 typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
569 this->_M_invalidate_if(_Not_equal(_Base::end()));
573 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
575 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
576 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
579 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
581 operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
582 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
583 { return __x._M_equal(__y); }
585 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
587 operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
588 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
589 { return !(__x == __y); }
591 } // namespace __debug
594 #endif // __GXX_EXPERIMENTAL_CXX0X__