Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Debugging multimap implementation -*- C++ -*-
  2.  
  3. // Copyright (C) 2003-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file debug/multimap.h
  26.  *  This file is a GNU debug extension to the Standard C++ Library.
  27.  */
  28.  
  29. #ifndef _GLIBCXX_DEBUG_MULTIMAP_H
  30. #define _GLIBCXX_DEBUG_MULTIMAP_H 1
  31.  
  32. #include <debug/safe_sequence.h>
  33. #include <debug/safe_container.h>
  34. #include <debug/safe_iterator.h>
  35. #include <utility>
  36.  
  37. namespace std _GLIBCXX_VISIBILITY(default)
  38. {
  39. namespace __debug
  40. {
  41.   /// Class std::multimap 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 multimap
  45.       : public __gnu_debug::_Safe_container<
  46.         multimap<_Key, _Tp, _Compare, _Allocator>, _Allocator,
  47.         __gnu_debug::_Safe_node_sequence>,
  48.         public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>
  49.     {
  50.       typedef _GLIBCXX_STD_C::multimap<
  51.         _Key, _Tp, _Compare, _Allocator>                        _Base;
  52.       typedef __gnu_debug::_Safe_container<
  53.         multimap, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe;
  54.  
  55.       typedef typename _Base::const_iterator    _Base_const_iterator;
  56.       typedef typename _Base::iterator          _Base_iterator;
  57.       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
  58.  
  59.     public:
  60.       // types:
  61.       typedef _Key                                      key_type;
  62.       typedef _Tp                                       mapped_type;
  63.       typedef std::pair<const _Key, _Tp>                value_type;
  64.       typedef _Compare                                  key_compare;
  65.       typedef _Allocator                                allocator_type;
  66.       typedef typename _Base::reference                 reference;
  67.       typedef typename _Base::const_reference           const_reference;
  68.  
  69.       typedef __gnu_debug::_Safe_iterator<_Base_iterator, multimap>
  70.                                                         iterator;
  71.       typedef __gnu_debug::_Safe_iterator<_Base_const_iterator,
  72.                                           multimap>     const_iterator;
  73.  
  74.       typedef typename _Base::size_type                 size_type;
  75.       typedef typename _Base::difference_type           difference_type;
  76.       typedef typename _Base::pointer                   pointer;
  77.       typedef typename _Base::const_pointer             const_pointer;
  78.       typedef std::reverse_iterator<iterator>           reverse_iterator;
  79.       typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;
  80.  
  81.       // 23.3.1.1 construct/copy/destroy:
  82.  
  83. #if __cplusplus < 201103L
  84.       multimap() : _Base() { }
  85.  
  86.       multimap(const multimap& __x)
  87.       : _Base(__x) { }
  88.  
  89.       ~multimap() { }
  90. #else
  91.       multimap() = default;
  92.       multimap(const multimap&) = default;
  93.       multimap(multimap&&) = default;
  94.  
  95.       multimap(initializer_list<value_type> __l,
  96.                const _Compare& __c = _Compare(),
  97.                const allocator_type& __a = allocator_type())
  98.       : _Base(__l, __c, __a) { }
  99.  
  100.       explicit
  101.       multimap(const allocator_type& __a)
  102.       : _Base(__a) { }
  103.  
  104.       multimap(const multimap& __m, const allocator_type& __a)
  105.       : _Base(__m, __a) { }
  106.  
  107.       multimap(multimap&& __m, const allocator_type& __a)
  108.       : _Safe(std::move(__m._M_safe()), __a),
  109.         _Base(std::move(__m._M_base()), __a) { }
  110.  
  111.       multimap(initializer_list<value_type> __l, const allocator_type& __a)
  112.       : _Base(__l, __a) { }
  113.  
  114.       template<typename _InputIterator>
  115.         multimap(_InputIterator __first, _InputIterator __last,
  116.                  const allocator_type& __a)
  117.         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
  118.                                                                      __last)),
  119.                 __gnu_debug::__base(__last), __a) { }
  120.  
  121.       ~multimap() = default;
  122. #endif
  123.  
  124.       explicit multimap(const _Compare& __comp,
  125.                         const _Allocator& __a = _Allocator())
  126.       : _Base(__comp, __a) { }
  127.  
  128.       template<typename _InputIterator>
  129.       multimap(_InputIterator __first, _InputIterator __last,
  130.                const _Compare& __comp = _Compare(),
  131.                const _Allocator& __a = _Allocator())
  132.         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
  133.                                                                      __last)),
  134.                 __gnu_debug::__base(__last),
  135.               __comp, __a) { }
  136.  
  137.       multimap(const _Base& __x)
  138.       : _Base(__x) { }
  139.  
  140. #if __cplusplus < 201103L
  141.       multimap&
  142.       operator=(const multimap& __x)
  143.       {
  144.         this->_M_safe() = __x;
  145.         _M_base() = __x;
  146.         return *this;
  147.       }
  148. #else
  149.       multimap&
  150.       operator=(const multimap&) = default;
  151.  
  152.       multimap&
  153.       operator=(multimap&&) = default;
  154.  
  155.       multimap&
  156.       operator=(initializer_list<value_type> __l)
  157.       {
  158.         _M_base() = __l;
  159.         this->_M_invalidate_all();
  160.         return *this;
  161.       }
  162. #endif
  163.  
  164.       using _Base::get_allocator;
  165.  
  166.       // iterators:
  167.       iterator
  168.       begin() _GLIBCXX_NOEXCEPT
  169.       { return iterator(_Base::begin(), this); }
  170.  
  171.       const_iterator
  172.       begin() const _GLIBCXX_NOEXCEPT
  173.       { return const_iterator(_Base::begin(), this); }
  174.  
  175.       iterator
  176.       end() _GLIBCXX_NOEXCEPT
  177.       { return iterator(_Base::end(), this); }
  178.  
  179.       const_iterator
  180.       end() const _GLIBCXX_NOEXCEPT
  181.       { return const_iterator(_Base::end(), this); }
  182.  
  183.       reverse_iterator
  184.       rbegin() _GLIBCXX_NOEXCEPT
  185.       { return reverse_iterator(end()); }
  186.  
  187.       const_reverse_iterator
  188.       rbegin() const _GLIBCXX_NOEXCEPT
  189.       { return const_reverse_iterator(end()); }
  190.  
  191.       reverse_iterator
  192.       rend() _GLIBCXX_NOEXCEPT
  193.       { return reverse_iterator(begin()); }
  194.  
  195.       const_reverse_iterator
  196.       rend() const _GLIBCXX_NOEXCEPT
  197.       { return const_reverse_iterator(begin()); }
  198.  
  199. #if __cplusplus >= 201103L
  200.       const_iterator
  201.       cbegin() const noexcept
  202.       { return const_iterator(_Base::begin(), this); }
  203.  
  204.       const_iterator
  205.       cend() const noexcept
  206.       { return const_iterator(_Base::end(), this); }
  207.  
  208.       const_reverse_iterator
  209.       crbegin() const noexcept
  210.       { return const_reverse_iterator(end()); }
  211.  
  212.       const_reverse_iterator
  213.       crend() const noexcept
  214.       { return const_reverse_iterator(begin()); }
  215. #endif
  216.  
  217.       // capacity:
  218.       using _Base::empty;
  219.       using _Base::size;
  220.       using _Base::max_size;
  221.  
  222.       // modifiers:
  223. #if __cplusplus >= 201103L
  224.       template<typename... _Args>
  225.         iterator
  226.         emplace(_Args&&... __args)
  227.         {
  228.           return iterator(_Base::emplace(std::forward<_Args>(__args)...), this);
  229.         }
  230.  
  231.       template<typename... _Args>
  232.         iterator
  233.         emplace_hint(const_iterator __pos, _Args&&... __args)
  234.         {
  235.           __glibcxx_check_insert(__pos);
  236.           return iterator(_Base::emplace_hint(__pos.base(),
  237.                                               std::forward<_Args>(__args)...),
  238.                           this);
  239.         }
  240. #endif
  241.  
  242.       iterator
  243.       insert(const value_type& __x)
  244.       { return iterator(_Base::insert(__x), this); }
  245.  
  246. #if __cplusplus >= 201103L
  247.       template<typename _Pair, typename = typename
  248.                std::enable_if<std::is_constructible<value_type,
  249.                                                     _Pair&&>::value>::type>
  250.         iterator
  251.         insert(_Pair&& __x)
  252.         { return iterator(_Base::insert(std::forward<_Pair>(__x)), this); }
  253. #endif
  254.  
  255. #if __cplusplus >= 201103L
  256.       void
  257.       insert(std::initializer_list<value_type> __list)
  258.       { _Base::insert(__list); }
  259. #endif
  260.  
  261.       iterator
  262. #if __cplusplus >= 201103L
  263.       insert(const_iterator __position, const value_type& __x)
  264. #else
  265.       insert(iterator __position, const value_type& __x)
  266. #endif
  267.       {
  268.         __glibcxx_check_insert(__position);
  269.         return iterator(_Base::insert(__position.base(), __x), this);
  270.       }
  271.  
  272. #if __cplusplus >= 201103L
  273.       template<typename _Pair, typename = typename
  274.                std::enable_if<std::is_constructible<value_type,
  275.                                                     _Pair&&>::value>::type>
  276.         iterator
  277.         insert(const_iterator __position, _Pair&& __x)
  278.         {
  279.           __glibcxx_check_insert(__position);
  280.           return iterator(_Base::insert(__position.base(),
  281.                                         std::forward<_Pair>(__x)), this);
  282.         }
  283. #endif
  284.  
  285.       template<typename _InputIterator>
  286.         void
  287.         insert(_InputIterator __first, _InputIterator __last)
  288.         {
  289.           __glibcxx_check_valid_range(__first, __last);
  290.           _Base::insert(__gnu_debug::__base(__first),
  291.                         __gnu_debug::__base(__last));
  292.         }
  293.  
  294. #if __cplusplus >= 201103L
  295.       iterator
  296.       erase(const_iterator __position)
  297.       {
  298.         __glibcxx_check_erase(__position);
  299.         this->_M_invalidate_if(_Equal(__position.base()));
  300.         return iterator(_Base::erase(__position.base()), this);
  301.       }
  302.  
  303.       iterator
  304.       erase(iterator __position)
  305.       { return erase(const_iterator(__position)); }
  306. #else
  307.       void
  308.       erase(iterator __position)
  309.       {
  310.         __glibcxx_check_erase(__position);
  311.         this->_M_invalidate_if(_Equal(__position.base()));
  312.         _Base::erase(__position.base());
  313.       }
  314. #endif
  315.  
  316.       size_type
  317.       erase(const key_type& __x)
  318.       {
  319.         std::pair<_Base_iterator, _Base_iterator> __victims =
  320.           _Base::equal_range(__x);
  321.         size_type __count = 0;
  322.         _Base_iterator __victim = __victims.first;
  323.         while (__victim !=  __victims.second)
  324.           {
  325.             this->_M_invalidate_if(_Equal(__victim));
  326.             _Base::erase(__victim++);
  327.             ++__count;
  328.           }
  329.         return __count;
  330.       }
  331.  
  332. #if __cplusplus >= 201103L
  333.       iterator
  334.       erase(const_iterator __first, const_iterator __last)
  335.       {
  336.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  337.         // 151. can't currently clear() empty container
  338.         __glibcxx_check_erase_range(__first, __last);
  339.         for (_Base_const_iterator __victim = __first.base();
  340.              __victim != __last.base(); ++__victim)
  341.           {
  342.             _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
  343.                                   _M_message(__gnu_debug::__msg_valid_range)
  344.                                   ._M_iterator(__first, "first")
  345.                                   ._M_iterator(__last, "last"));
  346.             this->_M_invalidate_if(_Equal(__victim));
  347.           }
  348.         return iterator(_Base::erase(__first.base(), __last.base()), this);
  349.       }
  350. #else
  351.       void
  352.       erase(iterator __first, iterator __last)
  353.       {
  354.         // _GLIBCXX_RESOLVE_LIB_DEFECTS
  355.         // 151. can't currently clear() empty container
  356.         __glibcxx_check_erase_range(__first, __last);
  357.         for (_Base_iterator __victim = __first.base();
  358.              __victim != __last.base(); ++__victim)
  359.           {
  360.             _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
  361.                                   _M_message(__gnu_debug::__msg_valid_range)
  362.                                   ._M_iterator(__first, "first")
  363.                                   ._M_iterator(__last, "last"));
  364.             this->_M_invalidate_if(_Equal(__victim));
  365.           }
  366.         _Base::erase(__first.base(), __last.base());
  367.       }
  368. #endif
  369.  
  370.       void
  371.       swap(multimap& __x)
  372. #if __cplusplus >= 201103L
  373.         noexcept( noexcept(declval<_Base>().swap(__x)) )
  374. #endif
  375.       {
  376.         _Safe::_M_swap(__x);
  377.         _Base::swap(__x);
  378.       }
  379.  
  380.       void
  381.       clear() _GLIBCXX_NOEXCEPT
  382.       {
  383.         this->_M_invalidate_all();
  384.         _Base::clear();
  385.       }
  386.  
  387.       // observers:
  388.       using _Base::key_comp;
  389.       using _Base::value_comp;
  390.  
  391.       // 23.3.1.3 multimap operations:
  392.       iterator
  393.       find(const key_type& __x)
  394.       { return iterator(_Base::find(__x), this); }
  395.  
  396.       const_iterator
  397.       find(const key_type& __x) const
  398.       { return const_iterator(_Base::find(__x), this); }
  399.  
  400.       using _Base::count;
  401.  
  402.       iterator
  403.       lower_bound(const key_type& __x)
  404.       { return iterator(_Base::lower_bound(__x), this); }
  405.  
  406.       const_iterator
  407.       lower_bound(const key_type& __x) const
  408.       { return const_iterator(_Base::lower_bound(__x), this); }
  409.  
  410.       iterator
  411.       upper_bound(const key_type& __x)
  412.       { return iterator(_Base::upper_bound(__x), this); }
  413.  
  414.       const_iterator
  415.       upper_bound(const key_type& __x) const
  416.       { return const_iterator(_Base::upper_bound(__x), this); }
  417.  
  418.       std::pair<iterator,iterator>
  419.       equal_range(const key_type& __x)
  420.       {
  421.         std::pair<_Base_iterator, _Base_iterator> __res =
  422.         _Base::equal_range(__x);
  423.         return std::make_pair(iterator(__res.first, this),
  424.                               iterator(__res.second, this));
  425.       }
  426.  
  427.       std::pair<const_iterator,const_iterator>
  428.       equal_range(const key_type& __x) const
  429.       {
  430.         std::pair<_Base_const_iterator, _Base_const_iterator> __res =
  431.           _Base::equal_range(__x);
  432.         return std::make_pair(const_iterator(__res.first, this),
  433.                               const_iterator(__res.second, this));
  434.       }
  435.  
  436.       _Base&
  437.       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
  438.  
  439.       const _Base&
  440.       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
  441.     };
  442.  
  443.   template<typename _Key, typename _Tp,
  444.            typename _Compare, typename _Allocator>
  445.     inline bool
  446.     operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
  447.                const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
  448.     { return __lhs._M_base() == __rhs._M_base(); }
  449.  
  450.   template<typename _Key, typename _Tp,
  451.            typename _Compare, typename _Allocator>
  452.     inline bool
  453.     operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
  454.                const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
  455.     { return __lhs._M_base() != __rhs._M_base(); }
  456.  
  457.   template<typename _Key, typename _Tp,
  458.            typename _Compare, typename _Allocator>
  459.     inline bool
  460.     operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
  461.               const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
  462.     { return __lhs._M_base() < __rhs._M_base(); }
  463.  
  464.   template<typename _Key, typename _Tp,
  465.            typename _Compare, typename _Allocator>
  466.     inline bool
  467.     operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
  468.                const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
  469.     { return __lhs._M_base() <= __rhs._M_base(); }
  470.  
  471.   template<typename _Key, typename _Tp,
  472.            typename _Compare, typename _Allocator>
  473.     inline bool
  474.     operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
  475.                const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
  476.     { return __lhs._M_base() >= __rhs._M_base(); }
  477.  
  478.   template<typename _Key, typename _Tp,
  479.            typename _Compare, typename _Allocator>
  480.     inline bool
  481.     operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
  482.               const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
  483.     { return __lhs._M_base() > __rhs._M_base(); }
  484.  
  485.   template<typename _Key, typename _Tp,
  486.            typename _Compare, typename _Allocator>
  487.     inline void
  488.     swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
  489.          multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
  490.     { __lhs.swap(__rhs); }
  491.  
  492. } // namespace __debug
  493. } // namespace std
  494.  
  495. #endif
  496.