OSDN Git Service

2010-01-08 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / debug / unordered_set
1 // Debugging unordered_set/unordered_multiset implementation -*- C++ -*-
2
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 // Free Software Foundation, Inc.
5 //
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)
10 // any later version.
11
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.
16
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.
20
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/>.
25
26 /** @file debug/unordered_set
27  *  This file is a GNU debug extension to the Standard C++ Library.
28  */
29
30 #ifndef _GLIBCXX_DEBUG_UNORDERED_SET
31 #define _GLIBCXX_DEBUG_UNORDERED_SET 1
32
33 #ifdef __GXX_EXPERIMENTAL_CXX0X__
34 # include <unordered_set>
35 #else
36 # include <c++0x_warning.h>
37 #endif
38
39 #include <debug/safe_sequence.h>
40 #include <debug/safe_iterator.h>
41 #include <initializer_list>
42
43 namespace std
44 {
45 namespace __debug
46 {
47   /// Class std::unordered_set with safety/checking/debug instrumentation.
48   template<typename _Value,
49            typename _Hash = std::hash<_Value>,
50            typename _Pred = std::equal_to<_Value>,
51            typename _Alloc = std::allocator<_Value> >
52     class unordered_set
53     : public _GLIBCXX_STD_D::unordered_set<_Value, _Hash, _Pred, _Alloc>,
54       public __gnu_debug::_Safe_sequence<unordered_set<_Value, _Hash,
55                                                        _Pred, _Alloc> >
56     {
57       typedef _GLIBCXX_STD_D::unordered_set<_Value, _Hash,
58                                             _Pred, _Alloc> _Base;
59       typedef __gnu_debug::_Safe_sequence<unordered_set> _Safe_base;
60
61     public:
62       typedef typename _Base::size_type       size_type;
63       typedef typename _Base::hasher          hasher;
64       typedef typename _Base::key_equal       key_equal;
65       typedef typename _Base::allocator_type  allocator_type;
66
67       typedef typename _Base::key_type        key_type;
68       typedef typename _Base::value_type      value_type;
69
70       typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,
71                                           unordered_set> iterator;
72       typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
73                                           unordered_set> const_iterator;
74
75       explicit
76       unordered_set(size_type __n = 10,
77                     const hasher& __hf = hasher(),
78                     const key_equal& __eql = key_equal(),
79                     const allocator_type& __a = allocator_type())
80       : _Base(__n, __hf, __eql, __a) { }
81
82       template<typename _InputIterator>
83         unordered_set(_InputIterator __f, _InputIterator __l, 
84                       size_type __n = 10,
85                       const hasher& __hf = hasher(), 
86                       const key_equal& __eql = key_equal(), 
87                       const allocator_type& __a = allocator_type())
88         : _Base(__gnu_debug::__check_valid_range(__f, __l), __l, __n,
89                 __hf, __eql, __a), _Safe_base() { }
90
91       unordered_set(const unordered_set& __x) 
92       : _Base(__x), _Safe_base() { }
93
94       unordered_set(const _Base& __x) 
95       : _Base(__x), _Safe_base() { }
96
97       unordered_set(unordered_set&& __x) 
98       : _Base(std::forward<unordered_set>(__x)), _Safe_base() { }
99
100       unordered_set(initializer_list<value_type> __l,
101                     size_type __n = 10,
102                     const hasher& __hf = hasher(),
103                     const key_equal& __eql = key_equal(),
104                     const allocator_type& __a = allocator_type())
105       : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
106
107       unordered_set&
108       operator=(const unordered_set& __x)
109       {
110         *static_cast<_Base*>(this) = __x;
111         this->_M_invalidate_all();
112         return *this;
113       }
114
115       unordered_set&
116       operator=(unordered_set&& __x)
117       {
118         if (this != &__x)
119           {
120             // NB: DR 675.
121             clear();
122             swap(__x);
123           }
124         return *this;
125       }
126
127       unordered_set&
128       operator=(initializer_list<value_type> __l)
129       {
130         this->clear();
131         this->insert(__l);
132         return *this;
133       }
134
135       void
136       swap(unordered_set& __x)
137       {
138         _Base::swap(__x);
139         _Safe_base::_M_swap(__x);
140       }
141
142       void
143       clear()
144       {
145         _Base::clear();
146         this->_M_invalidate_all();
147       }
148
149       iterator 
150       begin()
151       { return iterator(_Base::begin(), this); }
152
153       const_iterator
154       begin() const
155       { return const_iterator(_Base::begin(), this); }
156
157       iterator
158       end()
159       { return iterator(_Base::end(), this); }
160
161       const_iterator
162       end() const
163       { return const_iterator(_Base::end(), this); }
164
165       const_iterator
166       cbegin() const
167       { return const_iterator(_Base::begin(), this); }
168
169       const_iterator
170       cend() const
171       { return const_iterator(_Base::end(), this); }
172
173       // local versions
174       using _Base::begin;
175       using _Base::end;
176       using _Base::cbegin;
177       using _Base::cend;
178
179       std::pair<iterator, bool>
180       insert(const value_type& __obj)
181       {
182         typedef std::pair<typename _Base::iterator, bool> __pair_type;
183         __pair_type __res = _Base::insert(__obj);
184         return std::make_pair(iterator(__res.first, this), __res.second);
185       }
186
187       iterator
188       insert(iterator, const value_type& __obj)
189       {
190         typedef std::pair<typename _Base::iterator, bool> __pair_type;
191         __pair_type __res = _Base::insert(__obj);
192         return iterator(__res.first, this);
193       }
194
195       const_iterator
196       insert(const_iterator, const value_type& __obj)
197       {
198         typedef std::pair<typename _Base::iterator, bool> __pair_type;
199         __pair_type __res = _Base::insert(__obj);
200         return const_iterator(__res.first, this);
201       }
202
203       void
204       insert(std::initializer_list<value_type> __l)
205       { _Base::insert(__l); }
206
207       template<typename _InputIterator>
208         void
209         insert(_InputIterator __first, _InputIterator __last)
210         {
211           __glibcxx_check_valid_range(__first, __last);
212           _Base::insert(__first, __last);
213         }
214
215       iterator
216       find(const key_type& __key)
217       { return iterator(_Base::find(__key), this); }
218
219       const_iterator
220       find(const key_type& __key) const
221       { return const_iterator(_Base::find(__key), this); }
222
223       std::pair<iterator, iterator>
224       equal_range(const key_type& __key)
225       {
226         typedef typename _Base::iterator _Base_iterator;
227         typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
228         __pair_type __res = _Base::equal_range(__key);
229         return std::make_pair(iterator(__res.first, this),
230                               iterator(__res.second, this));
231       }
232
233       std::pair<const_iterator, const_iterator>
234       equal_range(const key_type& __key) const
235       {
236         typedef typename _Base::const_iterator _Base_iterator;
237         typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
238         __pair_type __res = _Base::equal_range(__key);
239         return std::make_pair(const_iterator(__res.first, this),
240                               const_iterator(__res.second, this));
241       }
242
243       size_type
244       erase(const key_type& __key)
245       {
246         size_type __ret(0);
247         iterator __victim(_Base::find(__key), this);
248         if (__victim != end())
249           {
250             this->erase(__victim);
251             __ret = 1;
252           }
253         return __ret;
254       }
255
256       iterator
257       erase(iterator __it)
258       {
259         __glibcxx_check_erase(__it);
260         __it._M_invalidate();
261         return iterator(_Base::erase(__it.base()), this);
262       }
263
264       const_iterator
265       erase(const_iterator __it)
266       {
267         __glibcxx_check_erase(__it);
268         __it._M_invalidate();
269         return const_iterator(_Base::erase(__it.base()), this);
270       }
271
272       iterator
273       erase(iterator __first, iterator __last)
274       {
275         __glibcxx_check_erase_range(__first, __last);
276         for (iterator __tmp = __first; __tmp != __last;)
277         {
278           iterator __victim = __tmp++;
279           __victim._M_invalidate();
280         }
281         return iterator(_Base::erase(__first.base(),
282                                      __last.base()), this);
283       }
284
285       const_iterator
286       erase(const_iterator __first, const_iterator __last)
287       {
288         __glibcxx_check_erase_range(__first, __last);
289         for (const_iterator __tmp = __first; __tmp != __last;)
290         {
291           const_iterator __victim = __tmp++;
292           __victim._M_invalidate();
293         }
294         return const_iterator(_Base::erase(__first.base(),
295                                            __last.base()), this);
296       }
297
298       _Base&
299       _M_base() { return *this; }
300
301       const _Base&
302       _M_base() const { return *this; }
303
304     private:
305       void
306       _M_invalidate_all()
307       {
308         typedef typename _Base::const_iterator _Base_const_iterator;
309         typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
310         this->_M_invalidate_if(_Not_equal(_M_base().end()));
311       }
312     };
313
314   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
315     inline void
316     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
317          unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
318     { __x.swap(__y); }
319
320
321   /// Class std::unordered_multiset with safety/checking/debug instrumentation.
322   template<typename _Value,
323            typename _Hash = std::hash<_Value>,
324            typename _Pred = std::equal_to<_Value>,
325            typename _Alloc = std::allocator<_Value> >
326     class unordered_multiset
327     : public _GLIBCXX_STD_D::unordered_multiset<_Value, _Hash, _Pred, _Alloc>,
328       public __gnu_debug::_Safe_sequence<unordered_multiset<_Value, _Hash,
329                                                             _Pred, _Alloc> >
330     {
331       typedef _GLIBCXX_STD_D::unordered_multiset<_Value, _Hash,
332                                                  _Pred, _Alloc> _Base;
333       typedef __gnu_debug::_Safe_sequence<unordered_multiset> _Safe_base;
334
335     public:
336       typedef typename _Base::size_type       size_type;
337       typedef typename _Base::hasher          hasher;
338       typedef typename _Base::key_equal       key_equal;
339       typedef typename _Base::allocator_type  allocator_type;
340
341       typedef typename _Base::key_type        key_type;
342       typedef typename _Base::value_type      value_type;
343
344       typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,
345                                           unordered_multiset> iterator;
346       typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
347                                           unordered_multiset> const_iterator;
348
349       explicit
350       unordered_multiset(size_type __n = 10,
351                          const hasher& __hf = hasher(),
352                          const key_equal& __eql = key_equal(),
353                          const allocator_type& __a = allocator_type())
354       : _Base(__n, __hf, __eql, __a) { }
355
356       template<typename _InputIterator>
357         unordered_multiset(_InputIterator __f, _InputIterator __l, 
358                            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(__gnu_debug::__check_valid_range(__f, __l), __l, __n,
363                 __hf, __eql, __a), _Safe_base() { }
364
365       unordered_multiset(const unordered_multiset& __x) 
366       : _Base(__x), _Safe_base() { }
367
368       unordered_multiset(const _Base& __x) 
369       : _Base(__x), _Safe_base() { }
370
371       unordered_multiset(unordered_multiset&& __x) 
372       : _Base(std::forward<unordered_multiset>(__x)), _Safe_base() { }
373
374       unordered_multiset(initializer_list<value_type> __l,
375                          size_type __n = 10,
376                          const hasher& __hf = hasher(),
377                          const key_equal& __eql = key_equal(),
378                          const allocator_type& __a = allocator_type())
379       : _Base(__l, __n, __hf, __eql, __a), _Safe_base() { }
380
381       unordered_multiset&
382       operator=(const unordered_multiset& __x)
383       {
384         *static_cast<_Base*>(this) = __x;
385         this->_M_invalidate_all();
386         return *this;
387       }
388
389       unordered_multiset&
390       operator=(unordered_multiset&& __x)
391       {
392         // NB: DR 675.
393         clear();
394         swap(__x);
395         return *this;
396       }
397
398       unordered_multiset&
399       operator=(initializer_list<value_type> __l)
400       {
401         this->clear();
402         this->insert(__l);
403         return *this;
404       }
405
406       void
407       swap(unordered_multiset& __x)
408       {
409         _Base::swap(__x);
410         _Safe_base::_M_swap(__x);
411       }
412
413       void
414       clear()
415       {
416         _Base::clear();
417         this->_M_invalidate_all();
418       }
419
420       iterator
421       begin()
422       { return iterator(_Base::begin(), this); }
423
424       const_iterator
425       begin() const
426       { return const_iterator(_Base::begin(), this); }
427
428       iterator
429       end()
430       { return iterator(_Base::end(), this); }
431
432       const_iterator
433       end() const
434       { return const_iterator(_Base::end(), this); }
435
436       const_iterator
437       cbegin() const
438       { return const_iterator(_Base::begin(), this); }
439
440       const_iterator
441       cend() const
442       { return const_iterator(_Base::end(), this); }
443
444       // local versions
445       using _Base::begin;
446       using _Base::end;
447       using _Base::cbegin;
448       using _Base::cend;
449
450       iterator
451       insert(const value_type& __obj)
452       { return iterator(_Base::insert(__obj), this); }
453
454       iterator
455       insert(iterator, const value_type& __obj)
456       { return iterator(_Base::insert(__obj), this); }
457
458       const_iterator
459       insert(const_iterator, const value_type& __obj)
460       { return const_iterator(_Base::insert(__obj), this); }
461
462       void
463       insert(std::initializer_list<value_type> __l)
464       { _Base::insert(__l); }
465
466       template<typename _InputIterator>
467         void
468         insert(_InputIterator __first, _InputIterator __last)
469         {
470           __glibcxx_check_valid_range(__first, __last);
471           _Base::insert(__first, __last);
472         }
473
474       iterator
475       find(const key_type& __key)
476       { return iterator(_Base::find(__key), this); }
477
478       const_iterator
479       find(const key_type& __key) const
480       { return const_iterator(_Base::find(__key), this); }
481
482       std::pair<iterator, iterator>
483       equal_range(const key_type& __key)
484       {
485         typedef typename _Base::iterator _Base_iterator;
486         typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
487         __pair_type __res = _Base::equal_range(__key);
488         return std::make_pair(iterator(__res.first, this),
489                               iterator(__res.second, this));
490       }
491
492       std::pair<const_iterator, const_iterator>
493       equal_range(const key_type& __key) const
494       {
495         typedef typename _Base::const_iterator _Base_iterator;
496         typedef std::pair<_Base_iterator, _Base_iterator> __pair_type;
497         __pair_type __res = _Base::equal_range(__key);
498         return std::make_pair(const_iterator(__res.first, this),
499                               const_iterator(__res.second, this));
500       }
501
502       size_type
503       erase(const key_type& __key)
504       {
505         size_type __ret(0);
506         iterator __victim(_Base::find(__key), this);
507         if (__victim != end())
508           {
509             this->erase(__victim);
510             __ret = 1;
511           }
512         return __ret;
513       }
514
515       iterator
516       erase(iterator __it)
517       {
518         __glibcxx_check_erase(__it);
519         __it._M_invalidate();
520         return iterator(_Base::erase(__it.base()), this);
521       }
522
523       const_iterator
524       erase(const_iterator __it)
525       {
526         __glibcxx_check_erase(__it);
527         __it._M_invalidate();
528         return const_iterator(_Base::erase(__it.base()), this);
529       }
530
531       iterator
532       erase(iterator __first, iterator __last)
533       {
534         __glibcxx_check_erase_range(__first, __last);
535         for (iterator __tmp = __first; __tmp != __last;)
536         {
537           iterator __victim = __tmp++;
538           __victim._M_invalidate();
539         }
540         return iterator(_Base::erase(__first.base(),
541                                      __last.base()), this);
542       }
543
544       const_iterator
545       erase(const_iterator __first, const_iterator __last)
546       {
547         __glibcxx_check_erase_range(__first, __last);
548         for (const_iterator __tmp = __first; __tmp != __last;)
549         {
550           const_iterator __victim = __tmp++;
551           __victim._M_invalidate();
552         }
553         return const_iterator(_Base::erase(__first.base(),
554                                            __last.base()), this);
555       }
556
557       _Base&
558       _M_base() { return *this; }
559
560       const _Base&
561       _M_base() const { return *this; }
562
563     private:
564       void
565       _M_invalidate_all()
566       {
567         typedef typename _Base::const_iterator _Base_const_iterator;
568         typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
569         this->_M_invalidate_if(_Not_equal(_M_base().end()));
570       }
571     };
572
573   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
574     inline void
575     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
576          unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
577     { __x.swap(__y); }
578
579 } // namespace __debug
580 } // namespace std
581
582 #endif