debug/multimap.h

Go to the documentation of this file.
00001 // Debugging multimap implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /** @file debug/multimap.h
00027  *  This file is a GNU debug extension to the Standard C++ Library.
00028  */
00029 
00030 #ifndef _GLIBCXX_DEBUG_MULTIMAP_H
00031 #define _GLIBCXX_DEBUG_MULTIMAP_H 1
00032 
00033 #include <debug/safe_sequence.h>
00034 #include <debug/safe_iterator.h>
00035 #include <utility>
00036 
00037 namespace std
00038 {
00039 namespace __debug
00040 {
00041   /// Class std::multimap with safety/checking/debug instrumentation.
00042   template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
00043        typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
00044     class multimap
00045     : public _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator>,
00046       public __gnu_debug::_Safe_sequence<multimap<_Key, _Tp,
00047                           _Compare, _Allocator> >
00048     {
00049       typedef _GLIBCXX_STD_D::multimap<_Key, _Tp, _Compare, _Allocator> _Base;
00050       typedef __gnu_debug::_Safe_sequence<multimap> _Safe_base;
00051 
00052     public:
00053       // types:
00054       typedef _Key                   key_type;
00055       typedef _Tp                    mapped_type;
00056       typedef std::pair<const _Key, _Tp>             value_type;
00057       typedef _Compare                               key_compare;
00058       typedef _Allocator                             allocator_type;
00059       typedef typename _Base::reference              reference;
00060       typedef typename _Base::const_reference        const_reference;
00061 
00062       typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, multimap>
00063                                                      iterator;
00064       typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
00065                                            multimap> const_iterator;
00066 
00067       typedef typename _Base::size_type              size_type;
00068       typedef typename _Base::difference_type        difference_type;
00069       typedef typename _Base::pointer                pointer;
00070       typedef typename _Base::const_pointer          const_pointer;
00071       typedef std::reverse_iterator<iterator>        reverse_iterator;
00072       typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
00073 
00074       using _Base::value_compare;
00075 
00076       // 23.3.1.1 construct/copy/destroy:
00077       explicit multimap(const _Compare& __comp = _Compare(),
00078             const _Allocator& __a = _Allocator())
00079       : _Base(__comp, __a) { }
00080 
00081       template<typename _InputIterator>
00082       multimap(_InputIterator __first, _InputIterator __last,
00083            const _Compare& __comp = _Compare(),
00084            const _Allocator& __a = _Allocator())
00085     : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
00086                                      __last)),
00087         __gnu_debug::__base(__last),
00088           __comp, __a) { }
00089 
00090       multimap(const multimap& __x)
00091       : _Base(__x), _Safe_base() { }
00092 
00093       multimap(const _Base& __x)
00094       : _Base(__x), _Safe_base() { }
00095 
00096 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00097       multimap(multimap&& __x)
00098       : _Base(std::move(__x)), _Safe_base()
00099       { this->_M_swap(__x); }
00100 
00101       multimap(initializer_list<value_type> __l,
00102            const _Compare& __c = _Compare(),
00103            const allocator_type& __a = allocator_type())
00104       : _Base(__l, __c, __a), _Safe_base() { }
00105 #endif
00106 
00107       ~multimap() { }
00108 
00109       multimap&
00110       operator=(const multimap& __x)
00111       {
00112     *static_cast<_Base*>(this) = __x;
00113     this->_M_invalidate_all();
00114     return *this;
00115       }
00116 
00117 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00118       multimap&
00119       operator=(multimap&& __x)
00120       {
00121     // NB: DR 1204.
00122     // NB: DR 675.
00123     clear();
00124     swap(__x);
00125     return *this;
00126       }
00127 
00128       multimap&
00129       operator=(initializer_list<value_type> __l)
00130       {
00131     this->clear();
00132     this->insert(__l);
00133     return *this;
00134       }
00135 #endif
00136 
00137       using _Base::get_allocator;
00138 
00139       // iterators:
00140       iterator
00141       begin()
00142       { return iterator(_Base::begin(), this); }
00143 
00144       const_iterator
00145       begin() const
00146       { return const_iterator(_Base::begin(), this); }
00147 
00148       iterator
00149       end()
00150       { return iterator(_Base::end(), this); }
00151 
00152       const_iterator
00153       end() const
00154       { return const_iterator(_Base::end(), this); }
00155 
00156       reverse_iterator
00157       rbegin()
00158       { return reverse_iterator(end()); }
00159 
00160       const_reverse_iterator
00161       rbegin() const
00162       { return const_reverse_iterator(end()); }
00163 
00164       reverse_iterator
00165       rend()
00166       { return reverse_iterator(begin()); }
00167 
00168       const_reverse_iterator
00169       rend() const
00170       { return const_reverse_iterator(begin()); }
00171 
00172 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00173       const_iterator
00174       cbegin() const
00175       { return const_iterator(_Base::begin(), this); }
00176 
00177       const_iterator
00178       cend() const
00179       { return const_iterator(_Base::end(), this); }
00180 
00181       const_reverse_iterator
00182       crbegin() const
00183       { return const_reverse_iterator(end()); }
00184 
00185       const_reverse_iterator
00186       crend() const
00187       { return const_reverse_iterator(begin()); }
00188 #endif
00189 
00190       // capacity:
00191       using _Base::empty;
00192       using _Base::size;
00193       using _Base::max_size;
00194 
00195       // modifiers:
00196       iterator
00197       insert(const value_type& __x)
00198       { return iterator(_Base::insert(__x), this); }
00199 
00200 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00201       void
00202       insert(std::initializer_list<value_type> __list)
00203       { _Base::insert(__list); }
00204 #endif
00205 
00206       iterator
00207       insert(iterator __position, const value_type& __x)
00208       {
00209     __glibcxx_check_insert(__position);
00210     return iterator(_Base::insert(__position.base(), __x), this);
00211       }
00212 
00213       template<typename _InputIterator>
00214         void
00215         insert(_InputIterator __first, _InputIterator __last)
00216         {
00217       __glibcxx_check_valid_range(__first, __last);
00218       _Base::insert(__gnu_debug::__base(__first),
00219             __gnu_debug::__base(__last));
00220     }
00221 
00222 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00223       iterator
00224       erase(iterator __position)
00225       {
00226     __glibcxx_check_erase(__position);
00227     __position._M_invalidate();
00228     return iterator(_Base::erase(__position.base()), this);
00229       }
00230 #else
00231       void
00232       erase(iterator __position)
00233       {
00234     __glibcxx_check_erase(__position);
00235     __position._M_invalidate();
00236     _Base::erase(__position.base());
00237       }
00238 #endif
00239 
00240       size_type
00241       erase(const key_type& __x)
00242       {
00243     std::pair<iterator, iterator> __victims = this->equal_range(__x);
00244     size_type __count = 0;
00245     while (__victims.first != __victims.second)
00246     {
00247       iterator __victim = __victims.first++;
00248       __victim._M_invalidate();
00249       _Base::erase(__victim.base());
00250       ++__count;
00251     }
00252     return __count;
00253       }
00254 
00255 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00256       iterator
00257       erase(iterator __first, iterator __last)
00258       {
00259     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00260     // 151. can't currently clear() empty container
00261     __glibcxx_check_erase_range(__first, __last);
00262     while (__first != __last)
00263       this->erase(__first++);
00264     return __last;
00265       }
00266 #else
00267       void
00268       erase(iterator __first, iterator __last)
00269       {
00270     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00271     // 151. can't currently clear() empty container
00272     __glibcxx_check_erase_range(__first, __last);
00273     while (__first != __last)
00274       this->erase(__first++);
00275       }
00276 #endif
00277 
00278       void
00279       swap(multimap& __x)
00280       {
00281     _Base::swap(__x);
00282     this->_M_swap(__x);
00283       }
00284 
00285       void
00286       clear()
00287       { this->erase(begin(), end()); }
00288 
00289       // observers:
00290       using _Base::key_comp;
00291       using _Base::value_comp;
00292 
00293       // 23.3.1.3 multimap operations:
00294       iterator
00295       find(const key_type& __x)
00296       { return iterator(_Base::find(__x), this); }
00297 
00298       const_iterator
00299       find(const key_type& __x) const
00300       { return const_iterator(_Base::find(__x), this); }
00301 
00302       using _Base::count;
00303 
00304       iterator
00305       lower_bound(const key_type& __x)
00306       { return iterator(_Base::lower_bound(__x), this); }
00307 
00308       const_iterator
00309       lower_bound(const key_type& __x) const
00310       { return const_iterator(_Base::lower_bound(__x), this); }
00311 
00312       iterator
00313       upper_bound(const key_type& __x)
00314       { return iterator(_Base::upper_bound(__x), this); }
00315 
00316       const_iterator
00317       upper_bound(const key_type& __x) const
00318       { return const_iterator(_Base::upper_bound(__x), this); }
00319 
00320       std::pair<iterator,iterator>
00321       equal_range(const key_type& __x)
00322       {
00323     typedef typename _Base::iterator _Base_iterator;
00324     std::pair<_Base_iterator, _Base_iterator> __res =
00325     _Base::equal_range(__x);
00326     return std::make_pair(iterator(__res.first, this),
00327                   iterator(__res.second, this));
00328       }
00329 
00330       std::pair<const_iterator,const_iterator>
00331       equal_range(const key_type& __x) const
00332       {
00333     typedef typename _Base::const_iterator _Base_const_iterator;
00334     std::pair<_Base_const_iterator, _Base_const_iterator> __res =
00335     _Base::equal_range(__x);
00336     return std::make_pair(const_iterator(__res.first, this),
00337                   const_iterator(__res.second, this));
00338       }
00339 
00340       _Base&
00341       _M_base() { return *this; }
00342 
00343       const _Base&
00344       _M_base() const { return *this; }
00345 
00346     private:
00347       void
00348       _M_invalidate_all()
00349       {
00350     typedef typename _Base::const_iterator _Base_const_iterator;
00351     typedef __gnu_debug::_Not_equal_to<_Base_const_iterator> _Not_equal;
00352     this->_M_invalidate_if(_Not_equal(_M_base().end()));
00353       }
00354     };
00355 
00356   template<typename _Key, typename _Tp,
00357        typename _Compare, typename _Allocator>
00358     inline bool
00359     operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00360            const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00361     { return __lhs._M_base() == __rhs._M_base(); }
00362 
00363   template<typename _Key, typename _Tp,
00364        typename _Compare, typename _Allocator>
00365     inline bool
00366     operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00367            const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00368     { return __lhs._M_base() != __rhs._M_base(); }
00369 
00370   template<typename _Key, typename _Tp,
00371        typename _Compare, typename _Allocator>
00372     inline bool
00373     operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00374           const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00375     { return __lhs._M_base() < __rhs._M_base(); }
00376 
00377   template<typename _Key, typename _Tp,
00378        typename _Compare, typename _Allocator>
00379     inline bool
00380     operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00381            const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00382     { return __lhs._M_base() <= __rhs._M_base(); }
00383 
00384   template<typename _Key, typename _Tp,
00385        typename _Compare, typename _Allocator>
00386     inline bool
00387     operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00388            const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00389     { return __lhs._M_base() >= __rhs._M_base(); }
00390 
00391   template<typename _Key, typename _Tp,
00392        typename _Compare, typename _Allocator>
00393     inline bool
00394     operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00395           const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00396     { return __lhs._M_base() > __rhs._M_base(); }
00397 
00398   template<typename _Key, typename _Tp,
00399        typename _Compare, typename _Allocator>
00400     inline void
00401     swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
00402      multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
00403     { __lhs.swap(__rhs); }
00404 
00405 } // namespace __debug
00406 } // namespace std
00407 
00408 #endif