// <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};
	}

      _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
