OSDN Git Service

0159bcb79f7cda3df8e4f6d0f0bcec5bcd73f4a9
[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       void
215       insert(std::initializer_list<value_type> __list)
216       { _Base::insert(__list); }
217 #endif
218
219       iterator
220       insert(iterator __position, const value_type& __x)
221       {
222         __glibcxx_check_insert(__position);
223         return iterator(_Base::insert(__position.base(), __x), this);
224       }
225
226       template<typename _InputIterator>
227         void
228         insert(_InputIterator __first, _InputIterator __last)
229         {
230           __glibcxx_check_valid_range(__first, __last);
231           _Base::insert(__gnu_debug::__base(__first),
232                         __gnu_debug::__base(__last));
233         }
234
235 #ifdef __GXX_EXPERIMENTAL_CXX0X__
236       iterator
237       erase(iterator __position)
238       {
239         __glibcxx_check_erase(__position);
240         __position._M_invalidate();
241         return iterator(_Base::erase(__position.base()), this);
242       }
243 #else
244       void
245       erase(iterator __position)
246       {
247         __glibcxx_check_erase(__position);
248         __position._M_invalidate();
249         _Base::erase(__position.base());
250       }
251 #endif
252
253       size_type
254       erase(const key_type& __x)
255       {
256         iterator __victim = find(__x);
257         if (__victim == end())
258           return 0;
259         else
260         {
261           __victim._M_invalidate();
262           _Base::erase(__victim.base());
263           return 1;
264         }
265       }
266
267 #ifdef __GXX_EXPERIMENTAL_CXX0X__
268       iterator
269       erase(iterator __first, iterator __last)
270       {
271         // _GLIBCXX_RESOLVE_LIB_DEFECTS
272         // 151. can't currently clear() empty container
273         __glibcxx_check_erase_range(__first, __last);
274         while (__first != __last)
275           this->erase(__first++);
276         return __last;
277       }
278 #else
279       void
280       erase(iterator __first, iterator __last)
281       {
282         // _GLIBCXX_RESOLVE_LIB_DEFECTS
283         // 151. can't currently clear() empty container
284         __glibcxx_check_erase_range(__first, __last);
285         while (__first != __last)
286           this->erase(__first++);
287       }
288 #endif
289
290       void
291       swap(map& __x)
292       {
293         _Base::swap(__x);
294         this->_M_swap(__x);
295       }
296
297       void
298       clear()
299       { this->erase(begin(), end()); }
300
301       // observers:
302       using _Base::key_comp;
303       using _Base::value_comp;
304
305       // 23.3.1.3 map operations:
306       iterator
307       find(const key_type& __x)
308       { return iterator(_Base::find(__x), this); }
309
310       const_iterator
311       find(const key_type& __x) const
312       { return const_iterator(_Base::find(__x), this); }
313
314       using _Base::count;
315
316       iterator
317       lower_bound(const key_type& __x)
318       { return iterator(_Base::lower_bound(__x), this); }
319
320       const_iterator
321       lower_bound(const key_type& __x) const
322       { return const_iterator(_Base::lower_bound(__x), this); }
323
324       iterator
325       upper_bound(const key_type& __x)
326       { return iterator(_Base::upper_bound(__x), this); }
327
328       const_iterator
329       upper_bound(const key_type& __x) const
330       { return const_iterator(_Base::upper_bound(__x), this); }
331
332       std::pair<iterator,iterator>
333       equal_range(const key_type& __x)
334       {
335         typedef typename _Base::iterator _Base_iterator;
336         std::pair<_Base_iterator, _Base_iterator> __res =
337         _Base::equal_range(__x);
338         return std::make_pair(iterator(__res.first, this),
339                               iterator(__res.second, this));
340       }
341
342       std::pair<const_iterator,const_iterator>
343       equal_range(const key_type& __x) const
344       {
345         typedef typename _Base::const_iterator _Base_const_iterator;
346         std::pair<_Base_const_iterator, _Base_const_iterator> __res =
347         _Base::equal_range(__x);
348         return std::make_pair(const_iterator(__res.first, this),
349                               const_iterator(__res.second, this));
350       }
351
352       _Base& 
353       _M_base() { return *this; }
354
355       const _Base&
356       _M_base() const { return *this; }
357
358     private:
359       void
360       _M_invalidate_all()
361       {
362         typedef typename _Base::const_iterator _Base_const_iterator;
363         typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
364         this->_M_invalidate_if(_Not_equal(_M_base().end()));
365       }
366     };
367
368   template<typename _Key, typename _Tp,
369            typename _Compare, typename _Allocator>
370     inline bool
371     operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
372                const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
373     { return __lhs._M_base() == __rhs._M_base(); }
374
375   template<typename _Key, typename _Tp,
376            typename _Compare, typename _Allocator>
377     inline bool
378     operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
379                const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
380     { return __lhs._M_base() != __rhs._M_base(); }
381
382   template<typename _Key, typename _Tp,
383            typename _Compare, typename _Allocator>
384     inline bool
385     operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
386               const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
387     { return __lhs._M_base() < __rhs._M_base(); }
388
389   template<typename _Key, typename _Tp,
390            typename _Compare, typename _Allocator>
391     inline bool
392     operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs,
393                const map<_Key, _Tp, _Compare, _Allocator>& __rhs)
394     { return __lhs._M_base() <= __rhs._M_base(); }
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 void
413     swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs,
414          map<_Key, _Tp, _Compare, _Allocator>& __rhs)
415     { __lhs.swap(__rhs); }
416
417 } // namespace __debug
418 } // namespace std
419
420 #endif