// Multiset implementation -*- C++ -*-

// Copyright (C) 2001-2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/*
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 *
 * Copyright (c) 1996
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

/** @file bits/stl_multiset.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{set}
 */

#ifndef _STL_MULTISET_H
#define _STL_MULTISET_H 1

#include <bits/concept_check.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER

  /**
   *  @brief A standard container made up of elements, which can be retrieved
   *  in logarithmic time.
   *
   *  @ingroup associative_containers
   *
   *
   *  @tparam _Key  Type of key objects.
   *  @tparam _Compare  Comparison function object type, defaults to less<_Key>.
   *  @tparam _Alloc  Allocator type, defaults to allocator<_Key>.
   *
   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
   *  <a href="tables.html#66">reversible container</a>, and an
   *  <a href="tables.html#69">associative container</a> (using equivalent
   *  keys).  For a @c multiset<Key> the key_type and value_type are Key.
   *
   *  Multisets support bidirectional iterators.
   *
   *  The private tree data is declared exactly the same way for set and
   *  multiset; the distinction is made entirely in how the tree functions are
   *  called (*_unique versus *_equal, same as the standard).
  */
  template <typename _Key, typename _Compare = std::less<_Key>,
	    typename _Alloc = std::allocator<_Key> >
    class multiset
    {
      // concept requirements
      typedef typename _Alloc::value_type                   _Alloc_value_type;
      __glibcxx_class_requires(_Key, _SGIAssignableConcept)
      __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
				_BinaryFunctionConcept)
      __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)	

    public:
      // typedefs:
      typedef _Key     key_type;
      typedef _Key     value_type;
      typedef _Compare key_compare;
      typedef _Compare value_compare;
      typedef _Alloc   allocator_type;

    private:
      /// This turns a red-black tree into a [multi]set.
      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
	rebind<_Key>::other _Key_alloc_type;

      typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
		       key_compare, _Key_alloc_type> _Rep_type;
      /// The actual tree structure.
      _Rep_type _M_t;

      typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;

    public:
      typedef typename _Alloc_traits::pointer		    pointer;
      typedef typename _Alloc_traits::const_pointer	    const_pointer;
      typedef typename _Alloc_traits::reference		    reference;
      typedef typename _Alloc_traits::const_reference	    const_reference;
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // DR 103. set::iterator is required to be modifiable,
      // but this allows modification of keys.
      typedef typename _Rep_type::const_iterator            iterator;
      typedef typename _Rep_type::const_iterator            const_iterator;
      typedef typename _Rep_type::const_reverse_iterator    reverse_iterator;
      typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
      typedef typename _Rep_type::size_type                 size_type;
      typedef typename _Rep_type::difference_type           difference_type;

      // allocation/deallocation
      /**
       *  @brief  Default constructor creates no elements.
       */
      multiset()
#if __cplusplus >= 201103L
      noexcept(is_nothrow_default_constructible<allocator_type>::value)
#endif
      : _M_t() { }

      /**
       *  @brief  Creates a %multiset with no elements.
       *  @param  __comp  Comparator to use.
       *  @param  __a  An allocator object.
       */
      explicit
      multiset(const _Compare& __comp,
	       const allocator_type& __a = allocator_type())
      : _M_t(__comp, _Key_alloc_type(__a)) { }

      /**
       *  @brief  Builds a %multiset from a range.
       *  @param  __first  An input iterator.
       *  @param  __last  An input iterator.
       *
       *  Create a %multiset consisting of copies of the elements from
       *  [first,last).  This is linear in N if the range is already sorted,
       *  and NlogN otherwise (where N is distance(__first,__last)).
       */
      template<typename _InputIterator>
        multiset(_InputIterator __first, _InputIterator __last)
	: _M_t()
        { _M_t._M_insert_equal(__first, __last); }

      /**
       *  @brief  Builds a %multiset from a range.
       *  @param  __first  An input iterator.
       *  @param  __last  An input iterator.
       *  @param  __comp  A comparison functor.
       *  @param  __a  An allocator object.
       *
       *  Create a %multiset consisting of copies of the elements from
       *  [__first,__last).  This is linear in N if the range is already sorted,
       *  and NlogN otherwise (where N is distance(__first,__last)).
       */
      template<typename _InputIterator>
        multiset(_InputIterator __first, _InputIterator __last,
		 const _Compare& __comp,
		 const allocator_type& __a = allocator_type())
	: _M_t(__comp, _Key_alloc_type(__a))
        { _M_t._M_insert_equal(__first, __last); }

      /**
       *  @brief  %Multiset copy constructor.
       *  @param  __x  A %multiset of identical element and allocator types.
       *
       *  The newly-created %multiset uses a copy of the allocation object used
       *  by @a __x.
       */
      multiset(const multiset& __x)
      : _M_t(__x._M_t) { }

#if __cplusplus >= 201103L
     /**
       *  @brief  %Multiset move constructor.
       *  @param  __x  A %multiset of identical element and allocator types.
       *
       *  The newly-created %multiset contains the exact contents of @a __x.
       *  The contents of @a __x are a valid, but unspecified %multiset.
       */
      multiset(multiset&& __x)
      noexcept(is_nothrow_copy_constructible<_Compare>::value)
      : _M_t(std::move(__x._M_t)) { }

      /**
       *  @brief  Builds a %multiset from an initializer_list.
       *  @param  __l  An initializer_list.
       *  @param  __comp  A comparison functor.
       *  @param  __a  An allocator object.
       *
       *  Create a %multiset consisting of copies of the elements from
       *  the list.  This is linear in N if the list is already sorted,
       *  and NlogN otherwise (where N is @a __l.size()).
       */
      multiset(initializer_list<value_type> __l,
	       const _Compare& __comp = _Compare(),
	       const allocator_type& __a = allocator_type())
      : _M_t(__comp, _Key_alloc_type(__a))
      { _M_t._M_insert_equal(__l.begin(), __l.end()); }

      /// Allocator-extended default constructor.
      explicit
      multiset(const allocator_type& __a)
      : _M_t(_Compare(), _Key_alloc_type(__a)) { }

      /// Allocator-extended copy constructor.
      multiset(const multiset& __m, const allocator_type& __a)
      : _M_t(__m._M_t, _Key_alloc_type(__a)) { }

      /// Allocator-extended move constructor.
      multiset(multiset&& __m, const allocator_type& __a)
      noexcept(is_nothrow_copy_constructible<_Compare>::value
	       && _Alloc_traits::_S_always_equal())
      : _M_t(std::move(__m._M_t), _Key_alloc_type(__a)) { }

      /// Allocator-extended initialier-list constructor.
      multiset(initializer_list<value_type> __l, const allocator_type& __a)
      : _M_t(_Compare(), _Key_alloc_type(__a))
      { _M_t._M_insert_equal(__l.begin(), __l.end()); }

      /// Allocator-extended range constructor.
      template<typename _InputIterator>
        multiset(_InputIterator __first, _InputIterator __last,
		 const allocator_type& __a)
	: _M_t(_Compare(), _Key_alloc_type(__a))
        { _M_t._M_insert_equal(__first, __last); }
#endif

      /**
       *  @brief  %Multiset assignment operator.
       *  @param  __x  A %multiset of identical element and allocator types.
       *
       *  All the elements of @a __x are copied, but unlike the copy
       *  constructor, the allocator object is not copied.
       */
      multiset&
      operator=(const multiset& __x)
      {
	_M_t = __x._M_t;
	return *this;
      }

#if __cplusplus >= 201103L
      /// Move assignment operator.
      multiset&
      operator=(multiset&&) = default;

      /**
       *  @brief  %Multiset list assignment operator.
       *  @param  __l  An initializer_list.
       *
       *  This function fills a %multiset with copies of the elements in the
       *  initializer list @a __l.
       *
       *  Note that the assignment completely changes the %multiset and
       *  that the resulting %multiset's size is the same as the number
       *  of elements assigned.  Old data may be lost.
       */
      multiset&
      operator=(initializer_list<value_type> __l)
      {
	_M_t._M_assign_equal(__l.begin(), __l.end());
	return *this;
      }
#endif

      // accessors:

      ///  Returns the comparison object.
      key_compare
      key_comp() const
      { return _M_t.key_comp(); }
      ///  Returns the comparison object.
      value_compare
      value_comp() const
      { return _M_t.key_comp(); }
      ///  Returns the memory allocation object.
      allocator_type
      get_allocator() const _GLIBCXX_NOEXCEPT
      { return allocator_type(_M_t.get_allocator()); }

      /**
       *  Returns a read-only (constant) iterator that points to the first
       *  element in the %multiset.  Iteration is done in ascending order
       *  according to the keys.
       */
      iterator
      begin() const _GLIBCXX_NOEXCEPT
      { return _M_t.begin(); }

      /**
       *  Returns a read-only (constant) iterator that points one past the last
       *  element in the %multiset.  Iteration is done in ascending order
       *  according to the keys.
       */
      iterator
      end() const _GLIBCXX_NOEXCEPT
      { return _M_t.end(); }

      /**
       *  Returns a read-only (constant) reverse iterator that points to the
       *  last element in the %multiset.  Iteration is done in descending order
       *  according to the keys.
       */
      reverse_iterator
      rbegin() const _GLIBCXX_NOEXCEPT
      { return _M_t.rbegin(); }

      /**
       *  Returns a read-only (constant) reverse iterator that points to the
       *  last element in the %multiset.  Iteration is done in descending order
       *  according to the keys.
       */
      reverse_iterator
      rend() const _GLIBCXX_NOEXCEPT
      { return _M_t.rend(); }

#if __cplusplus >= 201103L
      /**
       *  Returns a read-only (constant) iterator that points to the first
       *  element in the %multiset.  Iteration is done in ascending order
       *  according to the keys.
       */
      iterator
      cbegin() const noexcept
      { return _M_t.begin(); }

      /**
       *  Returns a read-only (constant) iterator that points one past the last
       *  element in the %multiset.  Iteration is done in ascending order
       *  according to the keys.
       */
      iterator
      cend() const noexcept
      { return _M_t.end(); }

      /**
       *  Returns a read-only (constant) reverse iterator that points to the
       *  last element in the %multiset.  Iteration is done in descending order
       *  according to the keys.
       */
      reverse_iterator
      crbegin() const noexcept
      { return _M_t.rbegin(); }

      /**
       *  Returns a read-only (constant) reverse iterator that points to the
       *  last element in the %multiset.  Iteration is done in descending order
       *  according to the keys.
       */
      reverse_iterator
      crend() const noexcept
      { return _M_t.rend(); }
#endif

      ///  Returns true if the %set is empty.
      bool
      empty() const _GLIBCXX_NOEXCEPT
      { return _M_t.empty(); }

      ///  Returns the size of the %set.
      size_type
      size() const _GLIBCXX_NOEXCEPT
      { return _M_t.size(); }

      ///  Returns the maximum size of the %set.
      size_type
      max_size() const _GLIBCXX_NOEXCEPT
      { return _M_t.max_size(); }

      /**
       *  @brief  Swaps data with another %multiset.
       *  @param  __x  A %multiset of the same element and allocator types.
       *
       *  This exchanges the elements between two multisets in constant time.
       *  (It is only swapping a pointer, an integer, and an instance of the @c
       *  Compare type (which itself is often stateless and empty), so it should
       *  be quite fast.)
       *  Note that the global std::swap() function is specialized such that
       *  std::swap(s1,s2) will feed to this function.
       */
      void
      swap(multiset& __x)
      _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value)
      { _M_t.swap(__x._M_t); }

      // insert/erase
#if __cplusplus >= 201103L
      /**
       *  @brief Builds and inserts an element into the %multiset.
       *  @param  __args  Arguments used to generate the element instance to be
       *                 inserted.
       *  @return An iterator that points to the inserted element.
       *
       *  This function inserts an element into the %multiset.  Contrary
       *  to a std::set the %multiset does not rely on unique keys and thus
       *  multiple copies of the same element can be inserted.
       *
       *  Insertion requires logarithmic time.
       */
      template<typename... _Args>
	iterator
	emplace(_Args&&... __args)
	{ return _M_t._M_emplace_equal(std::forward<_Args>(__args)...); }

      /**
       *  @brief Builds and inserts an element into the %multiset.
       *  @param  __pos  An iterator that serves as a hint as to where the
       *                element should be inserted.
       *  @param  __args  Arguments used to generate the element instance to be
       *                 inserted.
       *  @return An iterator that points to the inserted element.
       *
       *  This function inserts an element into the %multiset.  Contrary
       *  to a std::set the %multiset does not rely on unique keys and thus
       *  multiple copies of the same element can be inserted.
       *
       *  Note that the first parameter is only a hint and can potentially
       *  improve the performance of the insertion process.  A bad hint would
       *  cause no gains in efficiency.
       *
       *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
       *  for more on @a hinting.
       *
       *  Insertion requires logarithmic time (if the hint is not taken).
       */
      template<typename... _Args>
	iterator
	emplace_hint(const_iterator __pos, _Args&&... __args)
	{
	  return _M_t._M_emplace_hint_equal(__pos,
					    std::forward<_Args>(__args)...);
	}
#endif

      /**
       *  @brief Inserts an element into the %multiset.
       *  @param  __x  Element to be inserted.
       *  @return An iterator that points to the inserted element.
       *
       *  This function inserts an element into the %multiset.  Contrary
       *  to a std::set the %multiset does not rely on unique keys and thus
       *  multiple copies of the same element can be inserted.
       *
       *  Insertion requires logarithmic time.
       */
      iterator
      insert(const value_type& __x)
      { return _M_t._M_insert_equal(__x); }

#if __cplusplus >= 201103L
      iterator
      insert(value_type&& __x)
      { return _M_t._M_insert_equal(std::move(__x)); }
#endif

      /**
       *  @brief Inserts an element into the %multiset.
       *  @param  __position  An iterator that serves as a hint as to where the
       *                    element should be inserted.
       *  @param  __x  Element to be inserted.
       *  @return An iterator that points to the inserted element.
       *
       *  This function inserts an element into the %multiset.  Contrary
       *  to a std::set the %multiset does not rely on unique keys and thus
       *  multiple copies of the same element can be inserted.
       *
       *  Note that the first parameter is only a hint and can potentially
       *  improve the performance of the insertion process.  A bad hint would
       *  cause no gains in efficiency.
       *
       *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
       *  for more on @a hinting.
       *
       *  Insertion requires logarithmic time (if the hint is not taken).
       */
      iterator
      insert(const_iterator __position, const value_type& __x)
      { return _M_t._M_insert_equal_(__position, __x); }

#if __cplusplus >= 201103L
      iterator
      insert(const_iterator __position, value_type&& __x)
      { return _M_t._M_insert_equal_(__position, std::move(__x)); }
#endif

      /**
       *  @brief A template function that tries to insert a range of elements.
       *  @param  __first  Iterator pointing to the start of the range to be
       *                   inserted.
       *  @param  __last  Iterator pointing to the end of the range.
       *
       *  Complexity similar to that of the range constructor.
       */
      template<typename _InputIterator>
        void
        insert(_InputIterator __first, _InputIterator __last)
        { _M_t._M_insert_equal(__first, __last); }

#if __cplusplus >= 201103L
      /**
       *  @brief Attempts to insert a list of elements into the %multiset.
       *  @param  __l  A std::initializer_list<value_type> of elements
       *               to be inserted.
       *
       *  Complexity similar to that of the range constructor.
       */
      void
      insert(initializer_list<value_type> __l)
      { this->insert(__l.begin(), __l.end()); }
#endif

#if __cplusplus >= 201103L
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // DR 130. Associative erase should return an iterator.
      /**
       *  @brief Erases an element from a %multiset.
       *  @param  __position  An iterator pointing to the element to be erased.
       *  @return An iterator pointing to the element immediately following
       *          @a position prior to the element being erased. If no such 
       *          element exists, end() is returned.
       *
       *  This function erases an element, pointed to by the given iterator,
       *  from a %multiset.  Note that this function only erases the element,
       *  and that if the element is itself a pointer, the pointed-to memory is
       *  not touched in any way.  Managing the pointer is the user's
       *  responsibility.
       */
      _GLIBCXX_ABI_TAG_CXX11
      iterator
      erase(const_iterator __position)
      { return _M_t.erase(__position); }
#else
      /**
       *  @brief Erases an element from a %multiset.
       *  @param  __position  An iterator pointing to the element to be erased.
       *
       *  This function erases an element, pointed to by the given iterator,
       *  from a %multiset.  Note that this function only erases the element,
       *  and that if the element is itself a pointer, the pointed-to memory is
       *  not touched in any way.  Managing the pointer is the user's
       *  responsibility.
       */
      void
      erase(iterator __position)
      { _M_t.erase(__position); }
#endif

      /**
       *  @brief Erases elements according to the provided key.
       *  @param  __x  Key of element to be erased.
       *  @return  The number of elements erased.
       *
       *  This function erases all elements located by the given key from a
       *  %multiset.
       *  Note that this function only erases the element, and that if
       *  the element is itself a pointer, the pointed-to memory is not touched
       *  in any way.  Managing the pointer is the user's responsibility.
       */
      size_type
      erase(const key_type& __x)
      { return _M_t.erase(__x); }

#if __cplusplus >= 201103L
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // DR 130. Associative erase should return an iterator.
      /**
       *  @brief Erases a [first,last) range of elements from a %multiset.
       *  @param  __first  Iterator pointing to the start of the range to be
       *                   erased.
       *  @param __last Iterator pointing to the end of the range to
       *                be erased.
       *  @return The iterator @a last.
       *
       *  This function erases a sequence of elements from a %multiset.
       *  Note that this function only erases the elements, and that if
       *  the elements themselves are pointers, the pointed-to memory is not
       *  touched in any way.  Managing the pointer is the user's
       *  responsibility.
       */
      _GLIBCXX_ABI_TAG_CXX11
      iterator
      erase(const_iterator __first, const_iterator __last)
      { return _M_t.erase(__first, __last); }
#else
      /**
       *  @brief Erases a [first,last) range of elements from a %multiset.
       *  @param  first  Iterator pointing to the start of the range to be
       *                 erased.
       *  @param  last  Iterator pointing to the end of the range to be erased.
       *
       *  This function erases a sequence of elements from a %multiset.
       *  Note that this function only erases the elements, and that if
       *  the elements themselves are pointers, the pointed-to memory is not
       *  touched in any way.  Managing the pointer is the user's
       *  responsibility.
       */
      void
      erase(iterator __first, iterator __last)
      { _M_t.erase(__first, __last); }
#endif

      /**
       *  Erases all elements in a %multiset.  Note that this function only
       *  erases the elements, and that if the elements themselves are pointers,
       *  the pointed-to memory is not touched in any way.  Managing the pointer
       *  is the user's responsibility.
       */
      void
      clear() _GLIBCXX_NOEXCEPT
      { _M_t.clear(); }

      // multiset operations:

      //@{
      /**
       *  @brief Finds the number of elements with given key.
       *  @param  __x  Key of elements to be located.
       *  @return Number of elements with specified key.
       */
      size_type
      count(const key_type& __x) const
      { return _M_t.count(__x); }

#if __cplusplus > 201103L
      template<typename _Kt>
	auto
	count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x))
	{ return _M_t._M_count_tr(__x); }
#endif
      //@}

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 214.  set::find() missing const overload
      //@{
      /**
       *  @brief Tries to locate an element in a %set.
       *  @param  __x  Element to be located.
       *  @return  Iterator pointing to sought-after element, or end() if not
       *           found.
       *
       *  This function takes a key and tries to locate the element with which
       *  the key matches.  If successful the function returns an iterator
       *  pointing to the sought after element.  If unsuccessful it returns the
       *  past-the-end ( @c end() ) iterator.
       */
      iterator
      find(const key_type& __x)
      { return _M_t.find(__x); }

      const_iterator
      find(const key_type& __x) const
      { return _M_t.find(__x); }

#if __cplusplus > 201103L
      template<typename _Kt>
	auto
	find(const _Kt& __x)
	-> decltype(iterator{_M_t._M_find_tr(__x)})
	{ return iterator{_M_t._M_find_tr(__x)}; }

      template<typename _Kt>
	auto
	find(const _Kt& __x) const
	-> decltype(const_iterator{_M_t._M_find_tr(__x)})
	{ return const_iterator{_M_t._M_find_tr(__x)}; }
#endif
      //@}

      //@{
      /**
       *  @brief Finds the beginning of a subsequence matching given key.
       *  @param  __x  Key to be located.
       *  @return  Iterator pointing to first element equal to or greater
       *           than key, or end().
       *
       *  This function returns the first element of a subsequence of elements
       *  that matches the given key.  If unsuccessful it returns an iterator
       *  pointing to the first element that has a greater value than given key
       *  or end() if no such element exists.
       */
      iterator
      lower_bound(const key_type& __x)
      { return _M_t.lower_bound(__x); }

      const_iterator
      lower_bound(const key_type& __x) const
      { return _M_t.lower_bound(__x); }

#if __cplusplus > 201103L
      template<typename _Kt>
	auto
	lower_bound(const _Kt& __x)
	-> decltype(_M_t._M_lower_bound_tr(__x))
	{ return _M_t._M_lower_bound_tr(__x); }

      template<typename _Kt>
	auto
	lower_bound(const _Kt& __x) const
	-> decltype(_M_t._M_lower_bound_tr(__x))
	{ return _M_t._M_lower_bound_tr(__x); }
#endif
      //@}

      //@{
      /**
       *  @brief Finds the end of a subsequence matching given key.
       *  @param  __x  Key to be located.
       *  @return Iterator pointing to the first element
       *          greater than key, or end().
       */
      iterator
      upper_bound(const key_type& __x)
      { return _M_t.upper_bound(__x); }

      const_iterator
      upper_bound(const key_type& __x) const
      { return _M_t.upper_bound(__x); }

#if __cplusplus > 201103L
      template<typename _Kt>
	auto
	upper_bound(const _Kt& __x)
	-> decltype(_M_t._M_upper_bound_tr(__x))
	{ return _M_t._M_upper_bound_tr(__x); }

      template<typename _Kt>
	auto
	upper_bound(const _Kt& __x) const
	-> decltype(_M_t._M_upper_bound_tr(__x))
	{ return _M_t._M_upper_bound_tr(__x); }
#endif
      //@}

      //@{
      /**
       *  @brief Finds a subsequence matching given key.
       *  @param  __x  Key to be located.
       *  @return  Pair of iterators that possibly points to the subsequence
       *           matching given key.
       *
       *  This function is equivalent to
       *  @code
       *    std::make_pair(c.lower_bound(val),
       *                   c.upper_bound(val))
       *  @endcode
       *  (but is faster than making the calls separately).
       *
       *  This function probably only makes sense for multisets.
       */
      std::pair<iterator, iterator>
      equal_range(const key_type& __x)
      { return _M_t.equal_range(__x); }

      std::pair<const_iterator, const_iterator>
      equal_range(const key_type& __x) const
      { return _M_t.equal_range(__x); }

#if __cplusplus > 201103L
      template<typename _Kt>
	auto
	equal_range(const _Kt& __x)
	-> decltype(_M_t._M_equal_range_tr(__x))
	{ return _M_t._M_equal_range_tr(__x); }

      template<typename _Kt>
	auto
	equal_range(const _Kt& __x) const
	-> decltype(_M_t._M_equal_range_tr(__x))
	{ return _M_t._M_equal_range_tr(__x); }
#endif
      //@}

      template<typename _K1, typename _C1, typename _A1>
        friend bool
        operator==(const multiset<_K1, _C1, _A1>&,
		   const multiset<_K1, _C1, _A1>&);

      template<typename _K1, typename _C1, typename _A1>
        friend bool
        operator< (const multiset<_K1, _C1, _A1>&,
		   const multiset<_K1, _C1, _A1>&);
    };

  /**
   *  @brief  Multiset equality comparison.
   *  @param  __x  A %multiset.
   *  @param  __y  A %multiset of the same type as @a __x.
   *  @return  True iff the size and elements of the multisets are equal.
   *
   *  This is an equivalence relation.  It is linear in the size of the
   *  multisets.
   *  Multisets are considered equivalent if their sizes are equal, and if
   *  corresponding elements compare equal.
  */
  template<typename _Key, typename _Compare, typename _Alloc>
    inline bool
    operator==(const multiset<_Key, _Compare, _Alloc>& __x,
	       const multiset<_Key, _Compare, _Alloc>& __y)
    { return __x._M_t == __y._M_t; }

  /**
   *  @brief  Multiset ordering relation.
   *  @param  __x  A %multiset.
   *  @param  __y  A %multiset of the same type as @a __x.
   *  @return  True iff @a __x is lexicographically less than @a __y.
   *
   *  This is a total ordering relation.  It is linear in the size of the
   *  sets.  The elements must be comparable with @c <.
   *
   *  See std::lexicographical_compare() for how the determination is made.
  */
  template<typename _Key, typename _Compare, typename _Alloc>
    inline bool
    operator<(const multiset<_Key, _Compare, _Alloc>& __x,
	      const multiset<_Key, _Compare, _Alloc>& __y)
    { return __x._M_t < __y._M_t; }

  ///  Returns !(x == y).
  template<typename _Key, typename _Compare, typename _Alloc>
    inline bool
    operator!=(const multiset<_Key, _Compare, _Alloc>& __x,
	       const multiset<_Key, _Compare, _Alloc>& __y)
    { return !(__x == __y); }

  ///  Returns y < x.
  template<typename _Key, typename _Compare, typename _Alloc>
    inline bool
    operator>(const multiset<_Key,_Compare,_Alloc>& __x,
	      const multiset<_Key,_Compare,_Alloc>& __y)
    { return __y < __x; }

  ///  Returns !(y < x)
  template<typename _Key, typename _Compare, typename _Alloc>
    inline bool
    operator<=(const multiset<_Key, _Compare, _Alloc>& __x,
	       const multiset<_Key, _Compare, _Alloc>& __y)
    { return !(__y < __x); }

  ///  Returns !(x < y)
  template<typename _Key, typename _Compare, typename _Alloc>
    inline bool
    operator>=(const multiset<_Key, _Compare, _Alloc>& __x,
	       const multiset<_Key, _Compare, _Alloc>& __y)
    { return !(__x < __y); }

  /// See std::multiset::swap().
  template<typename _Key, typename _Compare, typename _Alloc>
    inline void
    swap(multiset<_Key, _Compare, _Alloc>& __x,
	 multiset<_Key, _Compare, _Alloc>& __y)
    _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
    { __x.swap(__y); }

_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std

#endif /* _STL_MULTISET_H */
