// <flat_set> -*- C++ -*-

// Copyright The GNU Toolchain Authors.
//
// 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/>.

/** @file include/flat_set
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_FLAT_SET
#define _GLIBCXX_FLAT_SET 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#define __glibcxx_want_constexpr_flat_set
#define __glibcxx_want_flat_set
#include <bits/version.h>

#ifdef __cpp_lib_flat_set // >= C++23

#include <compare>
#include <initializer_list>

#include <exception>
#include <functional> // not_fn
#include <optional>
#include <type_traits>
#include <vector>
#include <bits/stl_algo.h>
#include <bits/stl_function.h>  // less
#include <bits/stl_pair.h>
#include <bits/uses_allocator_args.h> // make_obj_using_allocator
#ifdef _GLIBCXX_DEBUG
# include <bits/ranges_algo.h> // ranges::is_sorted
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<typename _Key, typename _Compare,
	   typename _KeyContainer>
    class flat_set;

  template<typename _Key, typename _Compare,
	   typename _KeyContainer>
    class flat_multiset;

  template<typename _Key, typename _Compare, typename _KeyContainer, bool _Multi>
    class _Flat_set_impl
    {
      static_assert(is_same_v<_Key, typename _KeyContainer::value_type>);

      using _Derived = __conditional_t<_Multi,
				       flat_multiset<_Key, _Compare, _KeyContainer>,
				       flat_set<_Key, _Compare, _KeyContainer>>;
      using __sorted_t = __conditional_t<_Multi, sorted_equivalent_t, sorted_unique_t>;

    public:
      using key_type                = _Key;
      using value_type              = _Key;
      using key_compare             = _Compare;
      using value_compare           = _Compare;
      using reference               = value_type&;
      using const_reference         = const value_type&;
      using size_type               = typename _KeyContainer::size_type;
      using difference_type         = typename _KeyContainer::difference_type;
      using iterator                = typename _KeyContainer::const_iterator;
      using const_iterator          = typename _KeyContainer::const_iterator;
      using reverse_iterator        = std::reverse_iterator<iterator>;
      using const_reverse_iterator  = std::reverse_iterator<const_iterator>;
      using container_type          = _KeyContainer;

    private:
      using __emplace_result_t = __conditional_t<_Multi, iterator, pair<iterator, bool>>;

      struct _ClearGuard
      {
	container_type* _M_cont;

	_GLIBCXX26_CONSTEXPR
	_ClearGuard(container_type& __cont)
	: _M_cont(std::__addressof(__cont))
	{ }

	_GLIBCXX26_CONSTEXPR
	~_ClearGuard()
	{
	  if (_M_cont)
	    _M_cont->clear();
	}

	_GLIBCXX26_CONSTEXPR
	void
	_M_disable()
	{ _M_cont = nullptr; }
      };

      _GLIBCXX26_CONSTEXPR
      _ClearGuard
      _M_make_clear_guard()
      { return _ClearGuard{this->_M_cont}; }

    public:
      // constructors
      _GLIBCXX26_CONSTEXPR
      _Flat_set_impl() : _Flat_set_impl(key_compare()) { }

      _GLIBCXX26_CONSTEXPR
      explicit
      _Flat_set_impl(const key_compare& __comp)
      : _M_cont(), _M_comp(__comp)
      { }

      _GLIBCXX26_CONSTEXPR
      _Flat_set_impl(container_type __cont, const key_compare& __comp = key_compare())
      : _M_cont(std::move(__cont)), _M_comp(__comp)
      { _M_sort_uniq(); }

      _GLIBCXX26_CONSTEXPR
      _Flat_set_impl(__sorted_t,
		     container_type __cont, const key_compare& __comp = key_compare())
      : _M_cont(std::move(__cont)), _M_comp(__comp)
      { _GLIBCXX_DEBUG_ASSERT(ranges::is_sorted(_M_cont, _M_comp)); }

      template<__has_input_iter_cat _InputIterator>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(_InputIterator __first, _InputIterator __last,
		       const key_compare& __comp = key_compare())
	: _M_cont(), _M_comp(__comp)
	{ insert(__first, __last); }

      template<__has_input_iter_cat _InputIterator>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(__sorted_t __s,
		       _InputIterator __first, _InputIterator __last,
		       const key_compare& __comp = key_compare())
	: _M_cont(), _M_comp(__comp)
	{ insert(__s, __first, __last); }

      template<__detail::__container_compatible_range<value_type> _Rg>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(from_range_t, _Rg&& __rg)
	: _Flat_set_impl(from_range, std::forward<_Rg>(__rg), key_compare())
	{ }

      template<__detail::__container_compatible_range<value_type> _Rg>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(from_range_t, _Rg&& __rg, const key_compare& __comp)
	: _Flat_set_impl(__comp)
	{ insert_range(std::forward<_Rg>(__rg)); }

      _GLIBCXX26_CONSTEXPR
      _Flat_set_impl(initializer_list<value_type> __il,
		     const key_compare& __comp = key_compare())
      : _Flat_set_impl(__il.begin(), __il.end(), __comp)
      { }

      _GLIBCXX26_CONSTEXPR
      _Flat_set_impl(__sorted_t __s,
		     initializer_list<value_type> __il,
		     const key_compare& __comp = key_compare())
      : _Flat_set_impl(__s, __il.begin(), __il.end(), __comp)
      { }

      // constructors with allocators

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	explicit
	_Flat_set_impl(const _Alloc& __a)
	: _Flat_set_impl(key_compare(), __a)
	{ }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(const key_compare& __comp, const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<container_type>(__a)),
	  _M_comp(__comp)
	{ }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(const container_type& __cont, const _Alloc& __a)
	: _Flat_set_impl(__cont, key_compare(), __a)
	{ }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(const container_type& __cont, const key_compare& __comp,
		       const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<container_type>(__a, __cont)),
	  _M_comp(__comp)
	{ _M_sort_uniq(); }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(__sorted_t __s, const container_type& __cont, const _Alloc& __a)
	: _Flat_set_impl(__s, __cont, key_compare(), __a)
	{ }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(__sorted_t, const container_type& __cont, const key_compare& __comp,
		       const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<container_type>(__a, __cont)),
	  _M_comp(__comp)
	{ _GLIBCXX_DEBUG_ASSERT(ranges::is_sorted(_M_cont, _M_comp)); }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(const _Derived& __x, const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<container_type>(__a, __x._M_cont)),
	  _M_comp(__x._M_comp)
	{ }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(_Derived&& __x, const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<container_type>(__a, std::move(__x._M_cont))),
	  _M_comp(__x._M_comp)
	{ }

      template<__has_input_iter_cat _InputIterator, __allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(_InputIterator __first, _InputIterator __last,
		       const _Alloc& __a)
	: _Flat_set_impl(std::move(__first), std::move(__last), key_compare(), __a)
	{ }

      template<__has_input_iter_cat _InputIterator, __allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(_InputIterator __first, _InputIterator __last,
		       const key_compare& __comp,
		       const _Alloc& __a)
	: _Flat_set_impl(__comp, __a)
	{ insert(__first, __last); }

      template<__has_input_iter_cat _InputIterator, __allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(__sorted_t __s,
		       _InputIterator __first, _InputIterator __last,
		       const _Alloc& __a)
	: _Flat_set_impl(__s, std::move(__first), std::move(__last), key_compare(), __a)
	{ }

      template<__has_input_iter_cat _InputIterator, __allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(__sorted_t __s,
		       _InputIterator __first, _InputIterator __last,
		       const key_compare& __comp,
		       const _Alloc& __a)
	: _Flat_set_impl(__comp, __a)
	{ insert(__s, __first, __last); }

      template<__detail::__container_compatible_range<value_type> _Rg,
	       __allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(from_range_t, _Rg&& __rg,
		       const _Alloc& __a)
	: _Flat_set_impl(from_range, std::forward<_Rg>(__rg), key_compare(), __a)
	{ }

      template<__detail::__container_compatible_range<value_type> _Rg,
	       __allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(from_range_t, _Rg&& __rg,
		       const key_compare& __comp,
		       const _Alloc& __a)
	: _Flat_set_impl(__comp, __a)
	{ insert_range(std::forward<_Rg>(__rg)); }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(initializer_list<value_type> __il,
		       const _Alloc& __a)
	: _Flat_set_impl(__il, key_compare(), __a)
	{ }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(initializer_list<value_type> __il,
		       const key_compare& __comp,
		       const _Alloc& __a)
	: _Flat_set_impl(__il.begin(), __il.end(), __comp, __a)
	{ }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(__sorted_t __s,
		       initializer_list<value_type> __il,
		       const _Alloc& __a)
	: _Flat_set_impl(__s, __il.begin(), __il.end(), key_compare(), __a)
	{ }

      template<__allocator_for<container_type> _Alloc>
	_GLIBCXX26_CONSTEXPR
	_Flat_set_impl(__sorted_t __s,
		       initializer_list<value_type> __il,
		       const key_compare& __comp,
		       const _Alloc& __a)
	: _Flat_set_impl(__s, __il.begin(), __il.end(), __comp, __a)
	{ }

      _Flat_set_impl(const _Flat_set_impl&) = default;
      _Flat_set_impl& operator=(const _Flat_set_impl&) = default;

      _GLIBCXX26_CONSTEXPR
      _Flat_set_impl(_Flat_set_impl&& __other)
      noexcept(is_nothrow_move_constructible_v<container_type>
	       && is_nothrow_move_constructible_v<key_compare>)
#if __cpp_exceptions
      try
#endif
      : _M_cont(std::move(__other._M_cont)), _M_comp(std::move(__other._M_comp))
      { __other.clear(); }
#if __cpp_exceptions
      catch (...)
      { __other.clear(); }
#endif

      _GLIBCXX26_CONSTEXPR
      _Flat_set_impl&
      operator=(_Flat_set_impl&& __other)
      noexcept(is_nothrow_move_assignable_v<container_type>
	       && is_nothrow_move_assignable_v<key_compare>)
      {
	auto __guard = _M_make_clear_guard();
	auto __guard_other = _ClearGuard{__other._M_cont};
	_M_cont = std::move(__other._M_cont);
	_M_comp = std::move(__other._M_comp);
	__guard._M_disable();
	// __guard_other._M_disable is deliberately not called.
	return *this;
      }

      _GLIBCXX26_CONSTEXPR
      _Derived&
      operator=(initializer_list<value_type> __il)
      {
	auto __guard = _M_make_clear_guard();
	_M_cont = __il;
	_M_sort_uniq();
	__guard._M_disable();
	return static_cast<_Derived&>(*this);
      }

      // iterators
      _GLIBCXX26_CONSTEXPR
      const_iterator
      begin() const noexcept
      { return _M_cont.begin(); }

      _GLIBCXX26_CONSTEXPR
      const_iterator
      end() const noexcept
      { return _M_cont.end(); }

      _GLIBCXX26_CONSTEXPR
      const_reverse_iterator
      rbegin() const noexcept
      { return const_reverse_iterator(end()); }

      _GLIBCXX26_CONSTEXPR
      const_reverse_iterator
      rend() const noexcept
      { return const_reverse_iterator(begin()); }

      _GLIBCXX26_CONSTEXPR
      const_iterator
      cbegin() const noexcept
      { return begin(); }

      _GLIBCXX26_CONSTEXPR
      const_iterator
      cend() const noexcept
      { return end(); }

      _GLIBCXX26_CONSTEXPR
      const_reverse_iterator
      crbegin() const noexcept
      { return rbegin(); }

      _GLIBCXX26_CONSTEXPR
      const_reverse_iterator
      crend() const noexcept
      { return rend(); }

      // capacity
      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      bool
      empty() const noexcept
      { return _M_cont.empty(); }

      _GLIBCXX26_CONSTEXPR
      size_type
      size() const noexcept
      { return _M_cont.size(); }

      _GLIBCXX26_CONSTEXPR
      size_type
      max_size() const noexcept
      { return _M_cont.max_size(); }

      // modifiers
      template<typename _Arg, typename... _Args>
	_GLIBCXX26_CONSTEXPR
	pair<iterator, bool>
	_M_try_emplace(optional<const_iterator> __hint, _Arg&& __arg, _Args&&... __args)
	{
	  // TODO: Simplify and audit the hint handling.
	  auto&& __k = [&] -> decltype(auto) {
	    if constexpr (sizeof...(_Args) == 0
			  && same_as<remove_cvref_t<_Arg>, value_type>)
	      return std::forward<_Arg>(__arg);
	    else
	      return value_type(std::forward<_Arg>(__arg),
				std::forward<_Args>(__args)...);
	  }();
	  typename container_type::iterator __it;
	  int __r = -1, __s = -1;
	  if (__hint.has_value()
	      && (__hint == cbegin()
		  || (__r = !_M_comp(__k, (*__hint)[-1]))) // k >= hint[-1]
	      && (__hint == cend()
		  || (__s = !_M_comp((*__hint)[0], __k)))) // k <= hint[0]
	    {
	      __it = _M_cont.begin() + (*__hint - begin());
	      if constexpr (!_Multi)
		if (__r == 1 && !_M_comp(__it[-1], __k)) // k == hint[-1]
		  return {__it - 1, false};
	    }
	  else
	    {
	      auto __first = _M_cont.begin();
	      auto __last = _M_cont.end();
	      if (__r == 1) // k >= hint[-1]
		__first += *__hint - _M_cont.begin();
	      else if (__r == 0) // k < __hint[-1]
		__last = __first + (*__hint - _M_cont.begin());
	      if constexpr (_Multi)
		{
		  if (__s == 0) // hint[0] < k
		    // Insert before the leftmost equivalent key.
		    __it = std::lower_bound(__first, __last, __k, _M_comp);
		  else
		    // Insert after the rightmost equivalent key.
		    __it = std::upper_bound(std::make_reverse_iterator(__last),
					    std::make_reverse_iterator(__first),
					    __k, std::not_fn(_M_comp)).base();
		}
	      else
		__it = std::lower_bound(__first, __last, __k, _M_comp);
	    }

	  if constexpr (!_Multi)
	    if (__it != _M_cont.end() && !_M_comp(__k, __it[0]))
	      return {__it, false};

	  auto __guard = _M_make_clear_guard();
	  __it = _M_cont.insert(__it, std::forward<decltype(__k)>(__k));
	  __guard._M_disable();
	  return {__it, true};
	}

      template<typename... _Args>
	_GLIBCXX26_CONSTEXPR
	pair<iterator, bool>
	_M_try_emplace(optional<const_iterator> __hint)
	{ return _M_try_emplace(__hint, value_type()); }

      template<typename... _Args>
	requires is_constructible_v<value_type, _Args...>
	_GLIBCXX26_CONSTEXPR
	__emplace_result_t
	emplace(_Args&&... __args)
	{
	  auto __r = _M_try_emplace(nullopt, std::forward<_Args>(__args)...);
	  if constexpr (_Multi)
	    return __r.first;
	  else
	    return __r;
	}

      template<typename... _Args>
	_GLIBCXX26_CONSTEXPR
	iterator
	emplace_hint(const_iterator __position, _Args&&... __args)
	{ return _M_try_emplace(__position, std::forward<_Args>(__args)...).first; }

      _GLIBCXX26_CONSTEXPR
      __emplace_result_t
      insert(const value_type& __x)
      { return emplace(__x); }

      _GLIBCXX26_CONSTEXPR
      __emplace_result_t
      insert(value_type&& __x)
      { return emplace(std::move(__x)); }

      _GLIBCXX26_CONSTEXPR
      iterator
      insert(const_iterator __position, const value_type& __x)
      { return emplace_hint(__position, __x); }

      _GLIBCXX26_CONSTEXPR
      iterator
      insert(const_iterator __position, value_type&& __x)
      { return emplace_hint(__position, std::move(__x)); }

      template<typename _Arg>
	requires is_constructible_v<value_type, _Arg>
	_GLIBCXX26_CONSTEXPR
	__emplace_result_t
	insert(_Arg&& __x)
	{ return emplace(std::forward<_Arg>(__x)); }

      template<typename _Arg>
	requires is_constructible_v<value_type, _Arg>
	_GLIBCXX26_CONSTEXPR
	iterator
	insert(const_iterator __position, _Arg&& __x)
	{ return emplace_hint(__position, std::forward<_Arg>(__x)); }

      template<__has_input_iter_cat _InputIterator>
	_GLIBCXX26_CONSTEXPR
	void
	insert(_InputIterator __first, _InputIterator __last)
	{
	  auto __guard = _M_make_clear_guard();
	  auto __it = _M_cont.insert(_M_cont.end(), __first, __last);
	  std::sort(__it, _M_cont.end(), _M_comp);
	  std::inplace_merge(_M_cont.begin(), __it, _M_cont.end(), _M_comp);
	  if constexpr (!_Multi)
	    _M_unique();
	  __guard._M_disable();
	}

      template<__has_input_iter_cat _InputIterator>
	_GLIBCXX26_CONSTEXPR
	void
	insert(__sorted_t, _InputIterator __first, _InputIterator __last)
	{
	  auto __guard = _M_make_clear_guard();
	  auto __it = _M_cont.insert(_M_cont.end(), __first, __last);
	  std::inplace_merge(_M_cont.begin(), __it, _M_cont.end(), _M_comp);
	  if constexpr (!_Multi)
	    _M_unique();
	  __guard._M_disable();
	}

      template<typename _Rg>
	_GLIBCXX26_CONSTEXPR
	void
	_M_insert_range(_Rg&& __rg, bool __is_sorted = false)
	{
	  auto __guard = _M_make_clear_guard();
	  typename container_type::iterator __it;
	  if constexpr (requires { _M_cont.insert_range(_M_cont.end(), __rg); })
	    __it = _M_cont.insert_range(_M_cont.end(), __rg);
	  else if constexpr (ranges::common_range<_Rg>
			     && __has_input_iter_cat<ranges::iterator_t<_Rg>>)
	    __it = _M_cont.insert(_M_cont.end(), ranges::begin(__rg), ranges::end(__rg));
	  else
	    {
	      size_type __n = size();
	      auto __first = ranges::begin(__rg);
	      auto __last = ranges::end(__rg);
	      for (; __first != __last; ++__first)
		_M_cont.emplace_back(*__first);
	      __it = _M_cont.begin() + __n;
	    }
	  if (__is_sorted)
	    _GLIBCXX_DEBUG_ASSERT(ranges::is_sorted(__it, _M_cont.end(), _M_comp));
	  else
	    std::sort(__it, _M_cont.end(), _M_comp);
	  std::inplace_merge(_M_cont.begin(), __it, _M_cont.end(), _M_comp);
	  if constexpr (!_Multi)
	    _M_unique();
	  __guard._M_disable();
	}

    template<__detail::__container_compatible_range<value_type> _Rg>
      _GLIBCXX26_CONSTEXPR
      void
      insert_range(_Rg&& __rg)
      { _M_insert_range(std::forward<_Rg>(__rg)); }

    template<__detail::__container_compatible_range<value_type> _Rg>
      _GLIBCXX26_CONSTEXPR
      void
      insert_range(__sorted_t, _Rg&& __rg)
      { _M_insert_range(std::forward<_Rg>(__rg), true); }

      _GLIBCXX26_CONSTEXPR
      void
      insert(initializer_list<value_type> __il)
      { insert(__il.begin(), __il.end()); }

      _GLIBCXX26_CONSTEXPR
      void
      insert(__sorted_t __s, initializer_list<value_type> __il)
      { insert(__s, __il.begin(), __il.end()); }

      _GLIBCXX26_CONSTEXPR
      container_type
      extract() &&
      {
	auto __guard = _M_make_clear_guard();
	return std::move(_M_cont);
      }

      _GLIBCXX26_CONSTEXPR
      void
      replace(container_type&& __cont)
      {
	_GLIBCXX_DEBUG_ASSERT(ranges::is_sorted(__cont, _M_comp));
	auto __guard = _M_make_clear_guard();
	_M_cont = std::move(__cont);
	__guard._M_disable();
      }

      _GLIBCXX26_CONSTEXPR
      iterator
      erase(const_iterator __position)
      { return _M_cont.erase(__position); }

      _GLIBCXX26_CONSTEXPR
      size_type
      erase(const key_type& __x)
      { return erase<const key_type&>(__x); }

      template<typename _Key2>
	requires same_as<remove_cvref_t<_Key2>, _Key>
	  || (__transparent_comparator<_Compare>
	      && !is_convertible_v<_Key2, iterator>
	      && !is_convertible_v<_Key2, const_iterator>)
	_GLIBCXX26_CONSTEXPR
	size_type
	erase(_Key2&& __x)
	{
	  auto [__first, __last] = equal_range(std::forward<_Key2>(__x));
	  auto __n = __last - __first;
	  erase(__first, __last);
	  return __n;
	}

      _GLIBCXX26_CONSTEXPR
      iterator
      erase(const_iterator __first, const_iterator __last)
      { return _M_cont.erase(__first, __last); }

      _GLIBCXX26_CONSTEXPR
      void
      swap(_Derived& __y)
      noexcept(is_nothrow_swappable_v<container_type>
	       && is_nothrow_swappable_v<key_compare>)
      {
	auto __guard = _M_make_clear_guard();
	auto __guard_y = _ClearGuard{__y._M_cont};
	ranges::swap(_M_cont, __y._M_cont);
	ranges::swap(_M_comp, __y._M_comp);
	__guard._M_disable();
	__guard_y._M_disable();
      }

      _GLIBCXX26_CONSTEXPR
      void
      clear() noexcept
      { _M_cont.clear(); }

      // observers
      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      key_compare
      key_comp() const
      { return _M_comp; }

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      value_compare
      value_comp() const
      { return _M_comp; }

      // set operations
      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      iterator
      find(const key_type& __x)
      { return find<key_type>(__x); }

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      const_iterator
      find(const key_type& __x) const
      { return find<key_type>(__x); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	iterator
	find(const _Key2& __x)
	{
	  auto __it = lower_bound(__x);
	  if (__it != end() && !_M_comp(__x, *__it))
	    return __it;
	  else
	    return end();
	}

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	const_iterator
	find(const _Key2& __x) const
	{
	  auto __it = lower_bound(__x);
	  if (__it != cend() && !_M_comp(__x, *__it))
	    return __it;
	  else
	    return cend();
	}

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      size_type
      count(const key_type& __x) const
      { return count<key_type>(__x); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	size_type
	count(const _Key2& __x) const
	{
	  if constexpr (!_Multi)
	    return contains<_Key2>(__x);
	  else
	    {
	      auto [__first, __last] = equal_range(__x);
	      return __last - __first;
	    }
	}

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      bool
      contains(const key_type& __x) const
      { return contains<key_type>(__x); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	bool
	contains(const _Key2& __x) const
	{ return find(__x) != cend(); }

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      iterator
      lower_bound(const key_type& __x)
      { return lower_bound<key_type>(__x); }

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      const_iterator
      lower_bound(const key_type& __x) const
      { return lower_bound<key_type>(__x); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	iterator
	lower_bound(const _Key2& __x)
	{ return std::lower_bound(begin(), end(), __x, _M_comp); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	const_iterator
	lower_bound(const _Key2& __x) const
	{ return std::lower_bound(begin(), end(), __x, _M_comp); }

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      iterator
      upper_bound(const key_type& __x)
      { return upper_bound<key_type>(__x); }

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      const_iterator
      upper_bound(const key_type& __x) const
      { return upper_bound<key_type>(__x); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	iterator
	upper_bound(const _Key2& __x)
	{ return std::upper_bound(begin(), end(), __x, _M_comp); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	const_iterator
	upper_bound(const _Key2& __x) const
	{ return std::upper_bound(begin(), end(), __x, _M_comp); }

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      pair<iterator, iterator>
      equal_range(const key_type& __x)
      { return equal_range<key_type>(__x); }

      [[nodiscard]]
      _GLIBCXX26_CONSTEXPR
      pair<const_iterator, const_iterator>
      equal_range(const key_type& __x) const
      { return equal_range<key_type>(__x); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	pair<iterator, iterator>
	equal_range(const _Key2& __x)
	{ return std::equal_range(begin(), end(), __x, _M_comp); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	_GLIBCXX26_CONSTEXPR
	pair<const_iterator, const_iterator>
	equal_range(const _Key2& __x) const
	{ return std::equal_range(begin(), end(), __x, _M_comp); }

      [[nodiscard]]
      friend _GLIBCXX26_CONSTEXPR bool
      operator==(const _Derived& __x, const _Derived& __y)
      { return std::equal(__x.begin(), __x.end(), __y.begin(), __y.end()); }

      template<typename _Up = value_type>
	[[nodiscard]]
	friend _GLIBCXX26_CONSTEXPR __detail::__synth3way_t<_Up>
	operator<=>(const _Derived& __x, const _Derived& __y)
	{
	  return std::lexicographical_compare_three_way(__x.begin(), __x.end(),
							__y.begin(), __y.end(),
							__detail::__synth3way);
	}

      friend _GLIBCXX26_CONSTEXPR void
      swap(_Derived& __x, _Derived& __y) noexcept(noexcept(__x.swap(__y)))
      { return __x.swap(__y); }

      template<typename _Predicate>
	_GLIBCXX26_CONSTEXPR
	size_type
	_M_erase_if(_Predicate __pred)
	{
	  auto __guard = _M_make_clear_guard();
	  auto __first = _M_cont.begin();
	  auto __last = _M_cont.end();
	  __first = std::remove_if(__first, __last, __pred);
	  auto __n = __last - __first;
	  erase(__first, __last);
	  __guard._M_disable();
	  return __n;
	}

    private:
      container_type _M_cont;
      [[no_unique_address]] _Compare _M_comp;

      _GLIBCXX26_CONSTEXPR
      void
      _M_sort_uniq()
      {
	std::sort(_M_cont.begin(), _M_cont.end(), _M_comp);
	if constexpr (!_Multi)
	  _M_unique();
      }

      _GLIBCXX26_CONSTEXPR
      void
      _M_unique() requires (!_Multi)
      {
	struct __key_equiv
	{
	  _GLIBCXX26_CONSTEXPR
	  __key_equiv(key_compare __c) : _M_comp(__c) { }

	  _GLIBCXX26_CONSTEXPR
	  bool
	  operator()(const_reference __x, const_reference __y) const
	  { return !_M_comp(__x, __y) && !_M_comp(__y, __x); }

	  [[no_unique_address]] key_compare _M_comp;
	};

	auto __first = _M_cont.begin();
	auto __last = _M_cont.end();
	__first = std::unique(__first, __last, __key_equiv(_M_comp));
	_M_cont.erase(__first, __last);
      }
    };

  /* Class template flat_set - container adaptor
   *
   * @ingroup
   */
  template<typename _Key, typename _Compare = less<_Key>,
	   typename _KeyContainer = vector<_Key>>
    class flat_set
    : private _Flat_set_impl<_Key, _Compare, _KeyContainer, false>
    {
      using _Impl = _Flat_set_impl<_Key, _Compare, _KeyContainer, false>;
      friend _Impl;

    public:
      // types
      using typename _Impl::key_type;
      using typename _Impl::value_type;
      using typename _Impl::key_compare;
      using typename _Impl::reference;
      using typename _Impl::const_reference;
      using typename _Impl::size_type;
      using typename _Impl::difference_type;
      using typename _Impl::iterator;
      using typename _Impl::const_iterator;
      using typename _Impl::reverse_iterator;
      using typename _Impl::const_reverse_iterator;
      using typename _Impl::container_type;
      using typename _Impl::value_compare;

      // constructors
      using _Impl::_Impl;

      // operator=(initializer_list<value_type>)
      // Although this also brings in the base move/copy assignment operators,
      // they will be hidden by our synthesized ones.
      using _Impl::operator=;

      // iterators
      using _Impl::begin;
      using _Impl::end;
      using _Impl::rbegin;
      using _Impl::rend;

      using _Impl::cbegin;
      using _Impl::cend;
      using _Impl::crbegin;
      using _Impl::crend;

      // capacity
      using _Impl::empty;
      using _Impl::size;
      using _Impl::max_size;

      // modifiers
      using _Impl::emplace;
      using _Impl::emplace_hint;
      using _Impl::insert;
      using _Impl::insert_range;
      using _Impl::extract;
      using _Impl::replace;
      using _Impl::erase;
      using _Impl::swap;
      using _Impl::clear;

      // observers
      using _Impl::key_comp;
      using _Impl::value_comp;

      // set operations
      using _Impl::find;
      using _Impl::count;
      using _Impl::contains;
      using _Impl::lower_bound;
      using _Impl::upper_bound;
      using _Impl::equal_range;

      using _Impl::_M_erase_if;
    };

  template<typename _KeyContainer,
	   __not_allocator_like _Compare = less<typename _KeyContainer::value_type>>
    flat_set(_KeyContainer, _Compare = _Compare())
    -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;

  template<typename _KeyContainer, __allocator_for<_KeyContainer> _Alloc>
    flat_set(_KeyContainer, _Alloc)
    -> flat_set<typename _KeyContainer::value_type,
		less<typename _KeyContainer::value_type>, _KeyContainer>;

  template<typename _KeyContainer, __not_allocator_like _Compare,
	   __allocator_for<_KeyContainer> _Alloc>
    flat_set(_KeyContainer, _Compare, _Alloc)
    -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;

  template<typename _KeyContainer,
	   __not_allocator_like _Compare = less<typename _KeyContainer::value_type>>
    flat_set(sorted_unique_t, _KeyContainer, _Compare = _Compare())
    -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;

  template<typename _KeyContainer, __allocator_for<_KeyContainer> _Alloc>
    flat_set(sorted_unique_t, _KeyContainer, _Alloc)
    -> flat_set<typename _KeyContainer::value_type,
		less<typename _KeyContainer::value_type>, _KeyContainer>;

  template<typename _KeyContainer, __not_allocator_like _Compare,
	   __allocator_for<_KeyContainer> _Alloc>
    flat_set(sorted_unique_t, _KeyContainer, _Compare, _Alloc)
    -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;

  template<__has_input_iter_cat _InputIterator,
	   __not_allocator_like _Compare = less<__iter_key_t<_InputIterator>>>
    flat_set(_InputIterator, _InputIterator, _Compare = _Compare())
    -> flat_set<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Compare>;

  template<__has_input_iter_cat _InputIterator,
	   __not_allocator_like _Compare = less<__iter_key_t<_InputIterator>>>
    flat_set(sorted_unique_t, _InputIterator, _InputIterator, _Compare = _Compare())
    -> flat_set<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Compare>;

  template<ranges::input_range _Rg,
	   __not_allocator_like _Compare = less<ranges::range_value_t<_Rg>>,
	   __allocator_like _Alloc = allocator<ranges::range_value_t<_Rg>>>
    flat_set(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc())
    -> flat_set<ranges::range_value_t<_Rg>, _Compare,
		vector<ranges::range_value_t<_Rg>,
		       __alloc_rebind<_Alloc, ranges::range_value_t<_Rg>>>>;

  template<ranges::input_range _Rg, __allocator_like _Alloc>
    flat_set(from_range_t, _Rg&&, _Alloc)
    -> flat_set<ranges::range_value_t<_Rg>, less<ranges::range_value_t<_Rg>>,
		vector<ranges::range_value_t<_Rg>,
		       __alloc_rebind<_Alloc, ranges::range_value_t<_Rg>>>>;

  template<typename _Key, __not_allocator_like _Compare = less<_Key>>
    flat_set(initializer_list<_Key>, _Compare = _Compare())
    -> flat_set<_Key, _Compare>;

  template<typename _Key, __not_allocator_like _Compare = less<_Key>>
    flat_set(sorted_unique_t, initializer_list<_Key>, _Compare = _Compare())
    -> flat_set<_Key, _Compare>;

  template<typename _Key, typename _Compare,
	   typename _KeyContainer, typename _Alloc>
    struct uses_allocator<flat_set<_Key, _Compare, _KeyContainer>, _Alloc>
    : bool_constant<uses_allocator_v<_KeyContainer, _Alloc>>
    { };

  template<typename _Key, typename _Compare, typename _KeyContainer,
	   typename _Predicate>
    _GLIBCXX26_CONSTEXPR
    typename flat_set<_Key, _Compare, _KeyContainer>::size_type
    erase_if(flat_set<_Key, _Compare, _KeyContainer>& __c, _Predicate __pred)
    { return __c._M_erase_if(std::move(__pred)); }

  /* Class template flat_multiset - container adaptor
   *
   * @ingroup
   */
  template<typename _Key, typename _Compare = less<_Key>,
	   typename _KeyContainer = vector<_Key>>
    class flat_multiset
    : private _Flat_set_impl<_Key, _Compare, _KeyContainer, true>
    {
      using _Impl = _Flat_set_impl<_Key, _Compare, _KeyContainer, true>;
      friend _Impl;

    public:
      // types
      using typename _Impl::key_type;
      using typename _Impl::value_type;
      using typename _Impl::key_compare;
      using typename _Impl::reference;
      using typename _Impl::const_reference;
      using typename _Impl::size_type;
      using typename _Impl::difference_type;
      using typename _Impl::iterator;
      using typename _Impl::const_iterator;
      using typename _Impl::reverse_iterator;
      using typename _Impl::const_reverse_iterator;
      using typename _Impl::container_type;
      using typename _Impl::value_compare;

      // constructors
      using _Impl::_Impl;

      // operator=(initializer_list<value_type>)
      // Although this also brings in the base move/copy assignment operators,
      // they will be hidden by our synthesized ones.
      using _Impl::operator=;

      // iterators
      using _Impl::begin;
      using _Impl::end;
      using _Impl::rbegin;
      using _Impl::rend;

      using _Impl::cbegin;
      using _Impl::cend;
      using _Impl::crbegin;
      using _Impl::crend;

      // capacity
      using _Impl::empty;
      using _Impl::size;
      using _Impl::max_size;

      // modifiers
      using _Impl::emplace;
      using _Impl::emplace_hint;
      using _Impl::insert;
      using _Impl::insert_range;
      using _Impl::extract;
      using _Impl::replace;
      using _Impl::erase;
      using _Impl::swap;
      using _Impl::clear;

      // observers
      using _Impl::key_comp;
      using _Impl::value_comp;

      // set operations
      using _Impl::find;
      using _Impl::count;
      using _Impl::contains;
      using _Impl::lower_bound;
      using _Impl::upper_bound;
      using _Impl::equal_range;

      using _Impl::_M_erase_if;
    };

  template<typename _KeyContainer,
	   __not_allocator_like _Compare = less<typename _KeyContainer::value_type>>
    flat_multiset(_KeyContainer, _Compare = _Compare())
    -> flat_multiset<typename _KeyContainer::value_type, _Compare, _KeyContainer>;

  template<typename _KeyContainer, __allocator_for<_KeyContainer> _Alloc>
    flat_multiset(_KeyContainer, _Alloc)
    -> flat_multiset<typename _KeyContainer::value_type,
		     less<typename _KeyContainer::value_type>, _KeyContainer>;

  template<typename _KeyContainer, __not_allocator_like _Compare,
	   __allocator_for<_KeyContainer> _Alloc>
    flat_multiset(_KeyContainer, _Compare, _Alloc)
    -> flat_multiset<typename _KeyContainer::value_type, _Compare, _KeyContainer>;

  template<typename _KeyContainer,
	   __not_allocator_like _Compare = less<typename _KeyContainer::value_type>>
    flat_multiset(sorted_equivalent_t, _KeyContainer, _Compare = _Compare())
    -> flat_multiset<typename _KeyContainer::value_type, _Compare, _KeyContainer>;

  template<typename _KeyContainer, __allocator_for<_KeyContainer> _Alloc>
    flat_multiset(sorted_equivalent_t, _KeyContainer, _Alloc)
    -> flat_multiset<typename _KeyContainer::value_type,
		     less<typename _KeyContainer::value_type>, _KeyContainer>;

  template<typename _KeyContainer, __not_allocator_like _Compare,
	   __allocator_for<_KeyContainer> _Alloc>
    flat_multiset(sorted_equivalent_t, _KeyContainer, _Compare, _Alloc)
    -> flat_multiset<typename _KeyContainer::value_type, _Compare, _KeyContainer>;

  template<__has_input_iter_cat _InputIterator,
	   __not_allocator_like _Compare = less<__iter_key_t<_InputIterator>>>
    flat_multiset(_InputIterator, _InputIterator, _Compare = _Compare())
    -> flat_multiset<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Compare>;

  template<__has_input_iter_cat _InputIterator,
	   __not_allocator_like _Compare = less<__iter_key_t<_InputIterator>>>
    flat_multiset(sorted_equivalent_t, _InputIterator, _InputIterator, _Compare = _Compare())
    -> flat_multiset<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Compare>;

  template<ranges::input_range _Rg,
	   __not_allocator_like _Compare = less<ranges::range_value_t<_Rg>>,
	   __allocator_like _Alloc = allocator<ranges::range_value_t<_Rg>>>
    flat_multiset(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc())
    -> flat_multiset<ranges::range_value_t<_Rg>, _Compare,
		     vector<ranges::range_value_t<_Rg>,
			    __alloc_rebind<_Alloc, ranges::range_value_t<_Rg>>>>;

  template<ranges::input_range _Rg, __allocator_like _Alloc>
    flat_multiset(from_range_t, _Rg&&, _Alloc)
    -> flat_multiset<ranges::range_value_t<_Rg>, less<ranges::range_value_t<_Rg>>,
		     vector<ranges::range_value_t<_Rg>,
			    __alloc_rebind<_Alloc, ranges::range_value_t<_Rg>>>>;

  template<typename _Key, __not_allocator_like _Compare = less<_Key>>
    flat_multiset(initializer_list<_Key>, _Compare = _Compare())
    -> flat_multiset<_Key, _Compare>;

  template<typename _Key, __not_allocator_like _Compare = less<_Key>>
    flat_multiset(sorted_equivalent_t, initializer_list<_Key>, _Compare = _Compare())
    -> flat_multiset<_Key, _Compare>;

  template<typename _Key, typename _Compare,
	   typename _KeyContainer, typename _Alloc>
    struct uses_allocator<flat_multiset<_Key, _Compare, _KeyContainer>, _Alloc>
    : bool_constant<uses_allocator_v<_KeyContainer, _Alloc>>
    { };

  template<typename _Key, typename _Compare, typename _KeyContainer,
	   typename _Predicate>
    _GLIBCXX26_CONSTEXPR
    typename flat_multiset<_Key, _Compare, _KeyContainer>::size_type
    erase_if(flat_multiset<_Key, _Compare, _KeyContainer>& __c, _Predicate __pred)
    { return __c._M_erase_if(std::move(__pred)); }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __cpp_lib_flat_set
#endif // _GLIBCXX_FLAT_SET
