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>
41 namespace std _GLIBCXX_VISIBILITY(default)
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_C::unordered_set<_Value, _Hash, _Pred, _Alloc>,
52 public __gnu_debug::_Safe_sequence<unordered_set<_Value, _Hash,
55 typedef _GLIBCXX_STD_C::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);
273 { return erase(const_iterator(__it)); }
276 erase(const_iterator __first, const_iterator __last)
278 __glibcxx_check_erase_range(__first, __last);
279 for (_Base_const_iterator __tmp = __first.base();
280 __tmp != __last.base(); ++__tmp)
282 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
283 _M_message(__gnu_debug::__msg_valid_range)
284 ._M_iterator(__first, "first")
285 ._M_iterator(__last, "last"));
286 this->_M_invalidate_if(_Equal(__tmp));
288 return iterator(_Base::erase(__first.base(),
289 __last.base()), this);
293 _M_base() { return *this; }
296 _M_base() const { return *this; }
302 typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
303 this->_M_invalidate_if(_Not_equal(_Base::end()));
307 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
309 swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
310 unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
313 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
315 operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
316 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
317 { return __x._M_equal(__y); }
319 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
321 operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
322 const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
323 { return !(__x == __y); }
326 /// Class std::unordered_multiset with safety/checking/debug instrumentation.
327 template<typename _Value,
328 typename _Hash = std::hash<_Value>,
329 typename _Pred = std::equal_to<_Value>,
330 typename _Alloc = std::allocator<_Value> >
331 class unordered_multiset
332 : public _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
333 public __gnu_debug::_Safe_sequence<unordered_multiset<_Value, _Hash,
336 typedef _GLIBCXX_STD_C::unordered_multiset<_Value, _Hash,
337 _Pred, _Alloc> _Base;
338 typedef __gnu_debug::_Safe_sequence<unordered_multiset> _Safe_base;
339 typedef typename _Base::const_iterator _Base_const_iterator;
340 typedef typename _Base::iterator _Base_iterator;
341 typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
344 typedef typename _Base::size_type size_type;
345 typedef typename _Base::hasher hasher;
346 typedef typename _Base::key_equal key_equal;
347 typedef typename _Base::allocator_type allocator_type;
349 typedef typename _Base::key_type key_type;
350 typedef typename _Base::value_type value_type;
352 typedef __gnu_debug::_Safe_iterator<_Base_iterator,
353 unordered_multiset> iterator;
354 typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
355 unordered_multiset> const_iterator;
358 unordered_multiset(size_type __n = 10,
359 const hasher& __hf = hasher(),
360 const key_equal& __eql = key_equal(),
361 const allocator_type& __a = allocator_type())
362 : _Base(__n, __hf, __eql, __a) { }
364 template<typename _InputIterator>
365 unordered_multiset(_InputIterator __first, _InputIterator __last,
367 const hasher& __hf = hasher(),
368 const key_equal& __eql = key_equal(),
369 const allocator_type& __a = allocator_type())
370 : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
372 __gnu_debug::__base(__last), __n,
373 __hf, __eql, __a), _Safe_base() { }
375 unordered_multiset(const unordered_multiset& __x)
376 : _Base(__x), _Safe_base() { }
378 unordered_multiset(const _Base& __x)
379 : _Base(__x), _Safe_base() { }
381 unordered_multiset(unordered_multiset&& __x)
382 : _Base(std::move(__x)), _Safe_base() { }
384 unordered_multiset(initializer_list<value_type> __l,
386 const hasher& __hf = hasher(),
387 const key_equal& __eql = key_equal(),
388 const allocator_type& __a = allocator_type())
389 : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
392 operator=(const unordered_multiset& __x)
394 *static_cast<_Base*>(this) = __x;
395 this->_M_invalidate_all();
400 operator=(unordered_multiset&& __x)
410 operator=(initializer_list<value_type> __l)
418 swap(unordered_multiset& __x)
421 _Safe_base::_M_swap(__x);
428 this->_M_invalidate_all();
433 { return iterator(_Base::begin(), this); }
437 { return const_iterator(_Base::begin(), this); }
441 { return iterator(_Base::end(), this); }
445 { return const_iterator(_Base::end(), this); }
449 { return const_iterator(_Base::begin(), this); }
453 { return const_iterator(_Base::end(), this); }
462 insert(const value_type& __obj)
463 { return iterator(_Base::insert(__obj), this); }
466 insert(const_iterator __hint, const value_type& __obj)
468 __glibcxx_check_insert(__hint);
469 return iterator(_Base::insert(__hint.base(), __obj), this);
473 insert(value_type&& __obj)
474 { return iterator(_Base::insert(std::move(__obj)), this); }
477 insert(const_iterator __hint, value_type&& __obj)
479 __glibcxx_check_insert(__hint);
480 return iterator(_Base::insert(__hint.base(), std::move(__obj)), this);
484 insert(std::initializer_list<value_type> __l)
485 { _Base::insert(__l); }
487 template<typename _InputIterator>
489 insert(_InputIterator __first, _InputIterator __last)
491 __glibcxx_check_valid_range(__first, __last);
492 _Base::insert(__gnu_debug::__base(__first),
493 __gnu_debug::__base(__last));
497 find(const key_type& __key)
498 { return iterator(_Base::find(__key), this); }
501 find(const key_type& __key) const
502 { return const_iterator(_Base::find(__key), this); }
504 std::pair<iterator, iterator>
505 equal_range(const key_type& __key)
507 typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
508 __pair_type __res = _Base::equal_range(__key);
509 return std::make_pair(iterator(__res.first, this),
510 iterator(__res.second, this));
513 std::pair<const_iterator, const_iterator>
514 equal_range(const key_type& __key) const
516 std::pair<_Base_const_iterator, _Base_const_iterator>
517 __res = _Base::equal_range(__key);
518 return std::make_pair(const_iterator(__res.first, this),
519 const_iterator(__res.second, this));
523 erase(const key_type& __key)
526 std::pair<_Base_iterator, _Base_iterator> __pair =
527 _Base::equal_range(__key);
528 for (_Base_iterator __victim = __pair.first; __victim != __pair.second;)
530 this->_M_invalidate_if(_Equal(__victim));
531 _Base::erase(__victim++);
538 erase(const_iterator __it)
540 __glibcxx_check_erase(__it);
541 this->_M_invalidate_if(_Equal(__it.base()));
542 return iterator(_Base::erase(__it.base()), this);
547 { return erase(const_iterator(__it)); }
550 erase(const_iterator __first, const_iterator __last)
552 __glibcxx_check_erase_range(__first, __last);
553 for (_Base_const_iterator __tmp = __first.base();
554 __tmp != __last.base(); ++__tmp)
556 _GLIBCXX_DEBUG_VERIFY(__tmp != _Base::end(),
557 _M_message(__gnu_debug::__msg_valid_range)
558 ._M_iterator(__first, "first")
559 ._M_iterator(__last, "last"));
560 this->_M_invalidate_if(_Equal(__tmp));
562 return iterator(_Base::erase(__first.base(),
563 __last.base()), this);
567 _M_base() { return *this; }
570 _M_base() const { return *this; }
576 typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
577 this->_M_invalidate_if(_Not_equal(_Base::end()));
581 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
583 swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
584 unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
587 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
589 operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
590 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
591 { return __x._M_equal(__y); }
593 template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
595 operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
596 const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
597 { return !(__x == __y); }
599 } // namespace __debug
602 #endif // __GXX_EXPERIMENTAL_CXX0X__