OSDN Git Service

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