00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #ifndef _GLIBCXX_DEBUG_MULTIMAP_H
00032 #define _GLIBCXX_DEBUG_MULTIMAP_H 1
00033 
00034 #include <debug/safe_sequence.h>
00035 #include <debug/safe_iterator.h>
00036 #include <utility>
00037 
00038 namespace __gnu_debug_def
00039 {
00040   template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
00041        typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
00042     class multimap
00043     : public _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator>,
00044     public __gnu_debug::_Safe_sequence<multimap<_Key,_Tp,_Compare,_Allocator> >
00045     {
00046       typedef _GLIBCXX_STD::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
00047       typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base;
00048 
00049     public:
00050       
00051       typedef _Key                   key_type;
00052       typedef _Tp                    mapped_type;
00053       typedef std::pair<const _Key, _Tp>             value_type;
00054       typedef _Compare                               key_compare;
00055       typedef _Allocator                             allocator_type;
00056       typedef typename _Base::reference              reference;
00057       typedef typename _Base::const_reference        const_reference;
00058 
00059       typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multimap>
00060                                                      iterator;
00061       typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
00062                                            multimap> const_iterator;
00063 
00064       typedef typename _Base::size_type              size_type;
00065       typedef typename _Base::difference_type        difference_type;
00066       typedef typename _Base::pointer                pointer;
00067       typedef typename _Base::const_pointer          const_pointer;
00068       typedef std::reverse_iterator<iterator>        reverse_iterator;
00069       typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
00070 
00071       using _Base::value_compare;
00072 
00073       
00074       explicit multimap(const _Compare& __comp = _Compare(),
00075             const _Allocator& __a = _Allocator())
00076       : _Base(__comp, __a) { }
00077 
00078       template<typename _InputIterator>
00079       multimap(_InputIterator __first, _InputIterator __last,
00080            const _Compare& __comp = _Compare(),
00081            const _Allocator& __a = _Allocator())
00082       : _Base(__gnu_debug::__check_valid_range(__first, __last), __last,
00083           __comp, __a) { }
00084 
00085       multimap(const multimap<_Key,_Tp,_Compare,_Allocator>& __x)
00086       : _Base(__x), _Safe_base() { }
00087 
00088       multimap(const _Base& __x) : _Base(__x), _Safe_base() { }
00089 
00090       ~multimap() { }
00091 
00092       multimap<_Key,_Tp,_Compare,_Allocator>&
00093       operator=(const multimap<_Key,_Tp,_Compare,_Allocator>& __x)
00094       {
00095     *static_cast<_Base*>(this) = __x;
00096     this->_M_invalidate_all();
00097     return *this;
00098       }
00099 
00100       using _Base::get_allocator;
00101 
00102       
00103       iterator
00104       begin()
00105       { return iterator(_Base::begin(), this); }
00106 
00107       const_iterator
00108       begin() const
00109       { return const_iterator(_Base::begin(), this); }
00110 
00111       iterator
00112       end()
00113       { return iterator(_Base::end(), this); }
00114 
00115       const_iterator
00116       end() const
00117       { return const_iterator(_Base::end(), this); }
00118 
00119       reverse_iterator
00120       rbegin()
00121       { return reverse_iterator(end()); }
00122 
00123       const_reverse_iterator
00124       rbegin() const
00125       { return const_reverse_iterator(end()); }
00126 
00127       reverse_iterator
00128       rend()
00129       { return reverse_iterator(begin()); }
00130 
00131       const_reverse_iterator
00132       rend() const
00133       { return const_reverse_iterator(begin()); }
00134 
00135       
00136       using _Base::empty;
00137       using _Base::size;
00138       using _Base::max_size;
00139 
00140       
00141       iterator
00142       insert(const value_type& __x)
00143       { return iterator(_Base::insert(__x), this); }
00144 
00145       iterator
00146       insert(iterator __position, const value_type& __x)
00147       {
00148     __glibcxx_check_insert(__position);
00149     return iterator(_Base::insert(__position.base(), __x), this);
00150       }
00151 
00152       template<typename _InputIterator>
00153         void
00154         insert(_InputIterator __first, _InputIterator __last)
00155         {
00156       __glibcxx_check_valid_range(__first, __last);
00157       _Base::insert(__first, __last);
00158     }
00159 
00160       void
00161       erase(iterator __position)
00162       {
00163     __glibcxx_check_erase(__position);
00164     __position._M_invalidate();
00165     _Base::erase(__position.base());
00166       }
00167 
00168       size_type
00169       erase(const key_type& __x)
00170       {
00171     std::pair<iterator, iterator> __victims = this->equal_range(__x);
00172     size_type __count = 0;
00173     while (__victims.first != __victims.second)
00174     {
00175       iterator __victim = __victims.first++;
00176       __victim._M_invalidate();
00177       _Base::erase(__victim.base());
00178       ++__count;
00179     }
00180     return __count;
00181       }
00182 
00183       void
00184       erase(iterator __first, iterator __last)
00185       {
00186     
00187     
00188     __glibcxx_check_erase_range(__first, __last);
00189     while (__first != __last)
00190     this->erase(__first++);
00191       }
00192 
00193       void
00194       swap(multimap<_Key,_Tp,_Compare,_Allocator>& __x)
00195       {
00196     _Base::swap(__x);
00197     this->_M_swap(__x);
00198       }
00199 
00200       void
00201       clear()
00202       { this->erase(begin(), end()); }
00203 
00204       
00205       using _Base::key_comp;
00206       using _Base::value_comp;
00207 
00208       
00209       iterator
00210       find(const key_type& __x)
00211       { return iterator(_Base::find(__x), this); }
00212 
00213       const_iterator
00214       find(const key_type& __x) const
00215       { return const_iterator(_Base::find(__x), this); }
00216 
00217       using _Base::count;
00218 
00219       iterator
00220       lower_bound(const key_type& __x)
00221       { return iterator(_Base::lower_bound(__x), this); }
00222 
00223       const_iterator
00224       lower_bound(const key_type& __x) const
00225       { return const_iterator(_Base::lower_bound(__x), this); }
00226 
00227       iterator
00228       upper_bound(const key_type& __x)
00229       { return iterator(_Base::upper_bound(__x), this); }
00230 
00231       const_iterator
00232       upper_bound(const key_type& __x) const
00233       { return const_iterator(_Base::upper_bound(__x), this); }
00234 
00235       std::pair<iterator,iterator>
00236       equal_range(const key_type& __x)
00237       {
00238     typedef typename _Base::iterator _Base_iterator;
00239     std::pair<_Base_iterator, _Base_iterator> __res =
00240     _Base::equal_range(__x);
00241     return std::make_pair(iterator(__res.first, this),
00242                   iterator(__res.second, this));
00243       }
00244 
00245       std::pair<const_iterator,const_iterator>
00246       equal_range(const key_type& __x) const
00247       {
00248     typedef typename _Base::const_iterator _Base_const_iterator;
00249     std::pair<_Base_const_iterator, _Base_const_iterator> __res =
00250     _Base::equal_range(__x);
00251     return std::make_pair(const_iterator(__res.first, this),
00252                   const_iterator(__res.second, this));
00253       }
00254 
00255       _Base&
00256       _M_base() { return *this; }
00257 
00258       const _Base&
00259       _M_base() const { return *this; }
00260 
00261     private:
00262       void
00263       _M_invalidate_all()
00264       {
00265     typedef typename _Base::const_iterator _Base_const_iterator;
00266     typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
00267     this->_M_invalidate_if(_Not_equal(_M_base().end()));
00268       }
00269     };
00270 
00271   template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
00272     inline bool
00273     operator==(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
00274            const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
00275     { return __lhs._M_base() == __rhs._M_base(); }
00276 
00277   template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
00278     inline bool
00279     operator!=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
00280            const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
00281     { return __lhs._M_base() != __rhs._M_base(); }
00282 
00283   template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
00284     inline bool
00285     operator<(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
00286           const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
00287     { return __lhs._M_base() < __rhs._M_base(); }
00288 
00289   template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
00290     inline bool
00291     operator<=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
00292            const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
00293     { return __lhs._M_base() <= __rhs._M_base(); }
00294 
00295   template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
00296     inline bool
00297     operator>=(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
00298            const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
00299     { return __lhs._M_base() >= __rhs._M_base(); }
00300 
00301   template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
00302     inline bool
00303     operator>(const multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
00304           const multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
00305     { return __lhs._M_base() > __rhs._M_base(); }
00306 
00307   template<typename _Key,typename _Tp,typename _Compare,typename _Allocator>
00308     inline void
00309     swap(multimap<_Key,_Tp,_Compare,_Allocator>& __lhs,
00310      multimap<_Key,_Tp,_Compare,_Allocator>& __rhs)
00311     { __lhs.swap(__rhs); }
00312 } 
00313 
00314 #endif