1169691Skan// Debugging multimap implementation -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2003, 2004, 2005
4169691Skan// Free Software Foundation, Inc.
5169691Skan//
6169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
7169691Skan// software; you can redistribute it and/or modify it under the
8169691Skan// terms of the GNU General Public License as published by the
9169691Skan// Free Software Foundation; either version 2, or (at your option)
10169691Skan// any later version.
11169691Skan
12169691Skan// This library is distributed in the hope that it will be useful,
13169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
14169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15169691Skan// GNU General Public License for more details.
16169691Skan
17169691Skan// You should have received a copy of the GNU General Public License along
18169691Skan// with this library; see the file COPYING.  If not, write to the Free
19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20169691Skan// USA.
21169691Skan
22169691Skan// As a special exception, you may use this file as part of a free software
23169691Skan// library without restriction.  Specifically, if other files instantiate
24169691Skan// templates or use macros or inline functions from this file, or you compile
25169691Skan// this file and link it with other files to produce an executable, this
26169691Skan// file does not by itself cause the resulting executable to be covered by
27169691Skan// the GNU General Public License.  This exception does not however
28169691Skan// invalidate any other reasons why the executable file might be covered by
29169691Skan// the GNU General Public License.
30169691Skan
31169691Skan#ifndef _GLIBCXX_DEBUG_MULTIMAP_H
32169691Skan#define _GLIBCXX_DEBUG_MULTIMAP_H 1
33169691Skan
34169691Skan#include <debug/safe_sequence.h>
35169691Skan#include <debug/safe_iterator.h>
36169691Skan#include <utility>
37169691Skan
38169691Skannamespace __gnu_debug_def
39169691Skan{
40169691Skan  template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
41169691Skan	   typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
42169691Skan    class multimap
43169691Skan    : public _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator>,
44169691Skan    public __gnu_debug::_Safe_sequence<multimap<_Key,_Tp,_Compare,_Allocator> >
45169691Skan    {
46169691Skan      typedef _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
47169691Skan      typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base;
48169691Skan
49169691Skan    public:
50169691Skan      // types:
51169691Skan      typedef _Key				     key_type;
52169691Skan      typedef _Tp				     mapped_type;
53169691Skan      typedef std::pair<const _Key, _Tp>             value_type;
54169691Skan      typedef _Compare                               key_compare;
55169691Skan      typedef _Allocator                             allocator_type;
56169691Skan      typedef typename _Base::reference              reference;
57169691Skan      typedef typename _Base::const_reference        const_reference;
58169691Skan
59169691Skan      typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multimap>
60169691Skan                                                     iterator;
61169691Skan      typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
62169691Skan                                           multimap> const_iterator;
63169691Skan
64169691Skan      typedef typename _Base::size_type              size_type;
65169691Skan      typedef typename _Base::difference_type        difference_type;
66169691Skan      typedef typename _Base::pointer                pointer;
67169691Skan      typedef typename _Base::const_pointer          const_pointer;
68169691Skan      typedef std::reverse_iterator<iterator>        reverse_iterator;
69169691Skan      typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
70169691Skan
71169691Skan      using _Base::value_compare;
72169691Skan
73169691Skan      // 23.3.1.1 construct/copy/destroy:
74169691Skan      explicit multimap(const _Compare& __comp = _Compare(),
75169691Skan			const _Allocator& __a = _Allocator())
76169691Skan      : _Base(__comp, __a) { }
77169691Skan
78169691Skan      template<typename _InputIterator>
79169691Skan      multimap(_InputIterator __first, _InputIterator __last,
80169691Skan	       const _Compare& __comp = _Compare(),
81169691Skan	       const _Allocator& __a = _Allocator())
82169691Skan      : _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
83169691Skan	      __comp, __a) { }
84169691Skan
85169691Skan      multimap(const multimap<_Key,_Tp,_Compare,_Allocator>& __x)
86169691Skan      : _Base(__x), _Safe_base() { }
87169691Skan
88169691Skan      multimap(const _Base& __x) : _Base(__x), _Safe_base() { }
89169691Skan
90169691Skan      ~multimap() { }
91169691Skan
92169691Skan      multimap<_Key,_Tp,_Compare,_Allocator>&
93169691Skan      operator=(const multimap<_Key,_Tp,_Compare,_Allocator>& __x)
94169691Skan      {
95169691Skan	*static_cast<_Base*>(this) = __x;
96169691Skan	this->_M_invalidate_all();
97169691Skan	return *this;
98169691Skan      }
99169691Skan
100169691Skan      using _Base::get_allocator;
101169691Skan
102169691Skan      // iterators:
103169691Skan      iterator
104169691Skan      begin()
105169691Skan      { return iterator(_Base::begin(), this); }
106169691Skan
107169691Skan      const_iterator
108169691Skan      begin() const
109169691Skan      { return const_iterator(_Base::begin(), this); }
110169691Skan
111169691Skan      iterator
112169691Skan      end()
113169691Skan      { return iterator(_Base::end(), this); }
114169691Skan
115169691Skan      const_iterator
116169691Skan      end() const
117169691Skan      { return const_iterator(_Base::end(), this); }
118169691Skan
119169691Skan      reverse_iterator
120169691Skan      rbegin()
121169691Skan      { return reverse_iterator(end()); }
122169691Skan
123169691Skan      const_reverse_iterator
124169691Skan      rbegin() const
125169691Skan      { return const_reverse_iterator(end()); }
126169691Skan
127169691Skan      reverse_iterator
128169691Skan      rend()
129169691Skan      { return reverse_iterator(begin()); }
130169691Skan
131169691Skan      const_reverse_iterator
132169691Skan      rend() const
133169691Skan      { return const_reverse_iterator(begin()); }
134169691Skan
135169691Skan      // capacity:
136169691Skan      using _Base::empty;
137169691Skan      using _Base::size;
138169691Skan      using _Base::max_size;
139169691Skan
140169691Skan      // modifiers:
141169691Skan      iterator
142169691Skan      insert(const value_type& __x)
143169691Skan      { return iterator(_Base::insert(__x), this); }
144169691Skan
145169691Skan      iterator
146169691Skan      insert(iterator __position, const value_type& __x)
147169691Skan      {
148169691Skan	__glibcxx_check_insert(__position);
149169691Skan	return iterator(_Base::insert(__position.base(), __x), this);
150169691Skan      }
151169691Skan
152169691Skan      template<typename _InputIterator>
153169691Skan        void
154169691Skan        insert(_InputIterator __first, _InputIterator __last)
155169691Skan        {
156169691Skan	  __glibcxx_check_valid_range(__first, __last);
157	  _Base::insert(__first, __last);
158	}
159
160      void
161      erase(iterator __position)
162      {
163	__glibcxx_check_erase(__position);
164	__position._M_invalidate();
165	_Base::erase(__position.base());
166      }
167
168      size_type
169      erase(const key_type& __x)
170      {
171	std::pair<iterator, iterator> __victims = this->equal_range(__x);
172	size_type __count = 0;
173	while (__victims.first != __victims.second)
174	{
175	  iterator __victim = __victims.first++;
176	  __victim._M_invalidate();
177	  _Base::erase(__victim.base());
178	  ++__count;
179	}
180	return __count;
181      }
182
183      void
184      erase(iterator __first, iterator __last)
185      {
186	// _GLIBCXX_RESOLVE_LIB_DEFECTS
187	// 151. can't currently clear() empty container
188	__glibcxx_check_erase_range(__first, __last);
189	while (__first != __last)
190	this->erase(__first++);
191      }
192
193      void
194      swap(multimap<_Key,_Tp,_Compare,_Allocator>& __x)
195      {
196	_Base::swap(__x);
197	this->_M_swap(__x);
198      }
199
200      void
201      clear()
202      { this->erase(begin(), end()); }
203
204      // observers:
205      using _Base::key_comp;
206      using _Base::value_comp;
207
208      // 23.3.1.3 multimap operations:
209      iterator
210      find(const key_type& __x)
211      { return iterator(_Base::find(__x), this); }
212
213      const_iterator
214      find(const key_type& __x) const
215      { return const_iterator(_Base::find(__x), this); }
216
217      using _Base::count;
218
219      iterator
220      lower_bound(const key_type& __x)
221      { return iterator(_Base::lower_bound(__x), this); }
222
223      const_iterator
224      lower_bound(const key_type& __x) const
225      { return const_iterator(_Base::lower_bound(__x), this); }
226
227      iterator
228      upper_bound(const key_type& __x)
229      { return iterator(_Base::upper_bound(__x), this); }
230
231      const_iterator
232      upper_bound(const key_type& __x) const
233      { return const_iterator(_Base::upper_bound(__x), this); }
234
235      std::pair<iterator,iterator>
236      equal_range(const key_type& __x)
237      {
238	typedef typename _Base::iterator _Base_iterator;
239	std::pair<_Base_iterator, _Base_iterator> __res =
240	_Base::equal_range(__x);
241	return std::make_pair(iterator(__res.first, this),
242			      iterator(__res.second, this));
243      }
244
245      std::pair<const_iterator,const_iterator>
246      equal_range(const key_type& __x) const
247      {
248	typedef typename _Base::const_iterator _Base_const_iterator;
249	std::pair<_Base_const_iterator, _Base_const_iterator> __res =
250	_Base::equal_range(__x);
251	return std::make_pair(const_iterator(__res.first, this),
252			      const_iterator(__res.second, this));
253      }
254
255      _Base&
256      _M_base() { return *this; }
257
258      const _Base&
259      _M_base() const { return *this; }
260
261    private:
262      void
263      _M_invalidate_all()
264      {
265	typedef typename _Base::const_iterator _Base_const_iterator;
266	typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
267	this->_M_invalidate_if(_Not_equal(_M_base().end()));
268      }
269    };
270
271  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
272    inline bool
273    operator==(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
274	       const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
275    { return __lhs._M_base() == __rhs._M_base(); }
276
277  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
278    inline bool
279    operator!=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
280	       const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
281    { return __lhs._M_base() != __rhs._M_base(); }
282
283  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
284    inline bool
285    operator<(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
286	      const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
287    { return __lhs._M_base() < __rhs._M_base(); }
288
289  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
290    inline bool
291    operator<=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
292	       const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
293    { return __lhs._M_base() <= __rhs._M_base(); }
294
295  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
296    inline bool
297    operator>=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
298	       const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
299    { return __lhs._M_base() >= __rhs._M_base(); }
300
301  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
302    inline bool
303    operator>(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
304	      const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
305    { return __lhs._M_base() > __rhs._M_base(); }
306
307  template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
308    inline void
309    swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
310	 multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
311    { __lhs.swap(__rhs); }
312} // namespace __gnu_debug_def
313
314#endif
315