OSDN Git Service

2010-11-10 Paolo Carlini <paolo.carlini@oracle.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / debug / map.h
1 // Debugging map implementation -*- C++ -*-
2
3 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 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/map.h
27  *  This file is a GNU debug extension to the Standard C++ Library.
28  */
29
30 #ifndef _GLIBCXX_DEBUG_MAP_H
31 #define _GLIBCXX_DEBUG_MAP_H 1
32
33 #include <debug/safe_sequence.h>
34 #include <debug/safe_iterator.h>
35 #include <utility>
36
37 namespace std
38 {
39 namespace __debug
40 {
41   /// Class std::map with safety/checking/debug instrumentation.
42   template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
43            typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
44     class map
45     : public _GLIBCXX_STD_D::map<_Key, _Tp, _Compare, _Allocator>,
46       public __gnu_debug::_Safe_sequence<map<_Key, _Tp, _Compare, _Allocator> >
47     {
48       typedef _GLIBCXX_STD_D::map<_Key, _Tp, _Compare, _Allocator> _Base;
49       typedef __gnu_debug::_Safe_sequence<map> _Safe_base;
50
51     public:
52       // types:
53       typedef _Key                                  key_type;
54       typedef _Tp                                   mapped_type;
55       typedef std::pair<const _Key, _Tp>            value_type;
56       typedef _Compare                              key_compare;
57       typedef _Allocator                            allocator_type;
58       typedef typename _Base::reference             reference;
59       typedef typename _Base::const_reference       const_reference;
60
61       typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, map>
62                                                     iterator;
63       typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, map>
64                                                     const_iterator;
65
66       typedef typename _Base::size_type             size_type;
67       typedef typename _Base::difference_type       difference_type;
68       typedef typename _Base::pointer               pointer;
69       typedef typename _Base::const_pointer         const_pointer;
70       typedef std::reverse_iterator<iterator>       reverse_iterator;
71       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
72
73       using _Base::value_compare;
74
75       // 23.3.1.1 construct/copy/destroy:
76       explicit map(const _Compare& __comp = _Compare(),
77                    const _Allocator& __a = _Allocator())
78       : _Base(__comp, __a) { }
79
80       template<typename _InputIterator>
81         map(_InputIterator __first, _InputIterator __last,
82             const _Compare& __comp = _Compare(),
83             const _Allocator& __a = _Allocator())
84         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
85                                                                      __last)),
86                 __gnu_debug::__base(__last),
87                 __comp, __a), _Safe_base() { }
88
89       map(const map& __x)
90       : _Base(__x), _Safe_base() { }
91
92       map(const _Base& __x)
93       : _Base(__x), _Safe_base() { }
94
95 #ifdef __GXX_EXPERIMENTAL_CXX0X__
96       map(map&& __x)
97       : _Base(std::move(__x)), _Safe_base()
98       { this->_M_swap(__x); }
99
100       map(initializer_list<value_type> __l,
101           const _Compare& __c = _Compare(),
102           const allocator_type& __a = allocator_type())
103       : _Base(__l, __c, __a), _Safe_base() { }
104 #endif
105
106       ~map() { }
107
108       map&
109       operator=(const map& __x)
110       {
111         *static_cast<_Base*>(this) = __x;
112         this->_M_invalidate_all();
113         return *this;
114       }
115
116 #ifdef __GXX_EXPERIMENTAL_CXX0X__
117       map&
118       operator=(map&& __x)
119       {
120         // NB: DR 1204.
121         // NB: DR 675.
122         clear();
123         swap(__x);
124         return *this;
125       }
126
127       map&
128       operator=(initializer_list<value_type> __l)
129       {
130         this->clear();
131         this->insert(__l);
132         return *this;
133       }
134 #endif
135
136       // _GLIBCXX_RESOLVE_LIB_DEFECTS
137       // 133. map missing get_allocator()
138       using _Base::get_allocator;
139
140       // iterators:
141       iterator 
142       begin()
143       { return iterator(_Base::begin(), this); }
144
145       const_iterator
146       begin() const
147       { return const_iterator(_Base::begin(), this); }
148
149       iterator
150       end()
151       { return iterator(_Base::end(), this); }
152
153       const_iterator
154       end() const
155       { return const_iterator(_Base::end(), this); }
156
157       reverse_iterator
158       rbegin()
159       { return reverse_iterator(end()); }
160
161       const_reverse_iterator
162       rbegin() const
163       { return const_reverse_iterator(end()); }
164
165       reverse_iterator
166       rend()
167       { return reverse_iterator(begin()); }
168
169       const_reverse_iterator
170       rend() const
171       { return const_reverse_iterator(begin()); }
172
173 #ifdef __GXX_EXPERIMENTAL_CXX0X__
174       const_iterator
175       cbegin() const
176       { return const_iterator(_Base::begin(), this); }
177
178       const_iterator
179       cend() const
180       { return const_iterator(_Base::end(), this); }
181
182       const_reverse_iterator
183       crbegin() const
184       { return const_reverse_iterator(end()); }
185
186       const_reverse_iterator
187       crend() const
188       { return const_reverse_iterator(begin()); }
189 #endif
190
191       // capacity:
192       using _Base::empty;
193       using _Base::size;
194       using _Base::max_size;
195
196       // 23.3.1.2 element access:
197       using _Base::operator[];
198
199       // _GLIBCXX_RESOLVE_LIB_DEFECTS
200       // DR 464. Suggestion for new member functions in standard containers.
201       using _Base::at;
202
203       // modifiers:
204       std::pair<iterator, bool>
205       insert(const value_type& __x)
206       {
207         typedef typename _Base::iterator _Base_iterator;
208         std::pair<_Base_iterator, bool> __res = _Base::insert(__x);
209         return std::pair<iterator, bool>(iterator(__res.first, this),
210                                          __res.second);
211       }
212
213 #ifdef __GXX_EXPERIMENTAL_CXX0X__
214       template<typename _Pair, typename = typename
215                std::enable_if<std::is_convertible<_Pair,
216                                                   value_type>::value>::type>
217         std::pair<iterator, bool>
218         insert(_Pair&& __x)
219         {
220           typedef typename _Base::iterator _Base_iterator;
221           std::pair<_Base_iterator, bool> __res
222             = _Base::insert(std::forward<_Pair>(__x));
223           return std::pair<iterator, bool>(iterator(__res.first, this),
224                                            __res.second);
225         }
226 #endif
227
228 #ifdef __GXX_EXPERIMENTAL_CXX0X__
229       void
230       insert(std::initializer_list<value_type> __list)
231       { _Base::insert(__list); }
232 #endif
233
234       iterator
235       insert(iterator __position, const value_type& __x)
236       {
237         __glibcxx_check_insert(__position);
238         return iterator(_Base::insert(__position.base(), __x), this);
239       }
240
241 #ifdef __GXX_EXPERIMENTAL_CXX0X__
242       template<typename _Pair, typename = typename
243                std::enable_if<std::is_convertible<_Pair,
244                                                   value_type>::value>::type>
245         iterator
246         insert(const_iterator __position, _Pair&& __x)
247         {
248           __glibcxx_check_insert(__position);
249           return iterator(_Base::insert(__position.base(),
250                                         std::forward<_Pair>(__x)), this);
251         }
252 #endif
253
254       template<typename _InputIterator>
255         void
256         insert(_InputIterator __first, _InputIterator __last)
257         {
258           __glibcxx_check_valid_range(__first, __last);
259           _Base::insert(__gnu_debug::__base(__first),
260                         __gnu_debug::__base(__last));
261         }
262
263 #ifdef __GXX_EXPERIMENTAL_CXX0X__
264       iterator
265       erase(iterator __position)
266       {
267         __glibcxx_check_erase(__position);
268         __position._M_invalidate();
269         return iterator(_Base::erase(__position.base()), this);
270       }
271 #else
272       void
273       erase(iterator __position)
274       {
275         __glibcxx_check_erase(__position);
276         __position._M_invalidate();
277         _Base::erase(__position.base());
278       }
279 #endif
280
281       size_type
282       erase(const key_type& __x)
283       {
284         iterator __victim = find(__x);
285         if (__victim == end())
286           return 0;
287         else
288         {
289           __victim._M_invalidate();
290           _Base::erase(__victim.base());
291           return 1;
292         }
293       }
294
295 #ifdef __GXX_EXPERIMENTAL_CXX0X__
296       iterator
297       erase(iterator __first, iterator __last)
298       {
299         // _GLIBCXX_RESOLVE_LIB_DEFECTS
300         // 151. can't currently clear() empty container
301         __glibcxx_check_erase_range(__first, __last);
302         while (__first != __last)
303           this->erase(__first++);
304         return __last;
305       }
306 #else
307       void
308       erase(iterator __first, iterator __last)
309       {
310         // _GLIBCXX_RESOLVE_LIB_DEFECTS
311         // 151. can't currently clear() empty container
312         __glibcxx_check_erase_range(__first, __last);
313         while (__first != __last)
314           this->erase(__first++);
315       }
316 #endif
317
318       void
319       swap(map& __x)
320       {
321         _Base::swap(__x);
322         this->_M_swap(__x);
323       }
324
325       void
326       clear()
327       { this->erase(begin(), end()); }
328
329       // observers:
330       using _Base::key_comp;
331       using _Base::value_comp;
332
333       // 23.3.1.3 map operations:
334       iterator
335       find(const key_type& __x)
336       { return iterator(_Base::find(__x), this); }
337
338       const_iterator
339       find(const key_type& __x) const
340       { return const_iterator(_Base::find(__x), this); }
341
342       using _Base::count;
343
344       iterator
345       lower_bound(const key_type& __x)
346       { return iterator(_Base::lower_bound(__x), this); }
347
348       const_iterator
349       lower_bound(const key_type& __x) const
350       { return const_iterator(_Base::lower_bound(__x), this); }
351
352       iterator
353       upper_bound(const key_type& __x)
354       { return iterator(_Base::upper_bound(__x), this); }
355
356       const_iterator
357       upper_bound(const key_type& __x) const
358       { return const_iterator(_Base::upper_bound(__x), this); }
359
360       std::pair<iterator,iterator>
361       equal_range(const key_type& __x)
362       {
363         typedef typename _Base::iterator _Base_iterator;
364         std::pair<_Base_iterator, _Base_iterator> __res =
365         _Base::equal_range(__x);
366         return std::make_pair(iterator(__res.first, this),
367                               iterator(__res.second, this));
368       }
369
370       std::pair<const_iterator,const_iterator>
371       equal_range(const key_type& __x) const
372       {
373         typedef typename _Base::const_iterator _Base_const_iterator;
374         std::pair<_Base_const_iterator, _Base_const_iterator> __res =
375         _Base::equal_range(__x);
376         return std::make_pair(const_iterator(__res.first, this),
377                               const_iterator(__res.second, this));
378       }
379
380       _Base& 
381       _M_base() { return *this; }
382
383       const _Base&
384       _M_base() const { return *this; }
385
386     private:
387       void
388       _M_invalidate_all()
389       {
390         typedef typename _Base::const_iterator _Base_const_iterator;
391         typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
392         this->_M_invalidate_if(_Not_equal(_M_base().end()));
393       }
394     };
395
396   template<typename _Key, typename _Tp,
397            typename _Compare, typename _Allocator>
398     inline bool
399     operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
400                const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
401     { return __lhs._M_base() == __rhs._M_base(); }
402
403   template<typename _Key, typename _Tp,
404            typename _Compare, typename _Allocator>
405     inline bool
406     operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
407                const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
408     { return __lhs._M_base() != __rhs._M_base(); }
409
410   template<typename _Key, typename _Tp,
411            typename _Compare, typename _Allocator>
412     inline bool
413     operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
414               const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
415     { return __lhs._M_base() < __rhs._M_base(); }
416
417   template<typename _Key, typename _Tp,
418            typename _Compare, typename _Allocator>
419     inline bool
420     operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
421                const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
422     { return __lhs._M_base() <= __rhs._M_base(); }
423
424   template<typename _Key, typename _Tp,
425            typename _Compare, typename _Allocator>
426     inline bool
427     operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
428                const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
429     { return __lhs._M_base() >= __rhs._M_base(); }
430
431   template<typename _Key, typename _Tp,
432            typename _Compare, typename _Allocator>
433     inline bool
434     operator>(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
435               const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
436     { return __lhs._M_base() > __rhs._M_base(); }
437
438   template<typename _Key, typename _Tp,
439            typename _Compare, typename _Allocator>
440     inline void
441     swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs,
442          map<_Key, _Tp, _Compare, _Allocator>& __rhs)
443     { __lhs.swap(__rhs); }
444
445 } // namespace __debug
446 } // namespace std
447
448 #endif