// <flat_map> -*- 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_map
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_FLAT_MAP
#define _GLIBCXX_FLAT_MAP 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#define __glibcxx_want_flat_map
#include <bits/version.h>

#ifdef __cpp_lib_flat_map // >= C++23

#include <compare>
#include <initializer_list>

#include <exception>
#include <functional> // not_fn
#include <optional>
#include <ranges> // views::zip
#include <type_traits>
#include <vector>
#include <bits/stdexcept_throw.h>
#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
#include <bits/ranges_algo.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<typename _Key, typename _Tp, typename _Compare,
	   typename _KeyContainer, typename _MappedContainer>
    class flat_map;

  template<typename _Key, typename _Tp, typename _Compare,
	   typename _KeyContainer, typename _MappedContainer>
    class flat_multimap;

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

      static_assert(is_nothrow_swappable_v<_KeyContainer>);
      static_assert(is_nothrow_swappable_v<_MappedContainer>);

      using _Derived = __conditional_t<_Multi,
				       flat_multimap<_Key, _Tp, _Compare,
						     _KeyContainer, _MappedContainer>,
				       flat_map<_Key, _Tp, _Compare,
						_KeyContainer, _MappedContainer>>;
      using __sorted_t = __conditional_t<_Multi, sorted_equivalent_t, sorted_unique_t>;

    public:
      template<bool _Const> struct _Iterator;

      using key_type                = _Key;
      using mapped_type             = _Tp;
      using value_type              = pair<key_type, mapped_type>;
      using key_compare             = _Compare;
      using reference               = pair<const key_type&, mapped_type&>;
      using const_reference         = pair<const key_type&, const mapped_type&>;
      using size_type               = size_t;
      using difference_type         = ptrdiff_t;
      using iterator                = _Iterator<false>;
      using const_iterator          = _Iterator<true>;
      using reverse_iterator        = std::reverse_iterator<iterator>;
      using const_reverse_iterator  = std::reverse_iterator<const_iterator>;
      using key_container_type      = _KeyContainer;
      using mapped_container_type   = _MappedContainer;

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

    public:
      class value_compare
      {
	[[no_unique_address]] key_compare _M_comp;
	value_compare(key_compare __c) : _M_comp(__c) { }

      public:
	bool
	operator()(const_reference __x, const_reference __y) const
	{ return _M_comp(__x.first, __y.first); }

	friend _Flat_map_impl;
      };

      struct containers
      {
	key_container_type keys;
	mapped_container_type values;
      };

    private:
      struct _ClearGuard
      {
	containers* _M_cont;

	_ClearGuard(containers& __cont)
	: _M_cont(std::__addressof(__cont))
	{ }

	~_ClearGuard()
	{
	  if (_M_cont)
	    {
	      _M_cont->keys.clear();
	      _M_cont->values.clear();
	    }
	}

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

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

    public:
      // constructors
      _Flat_map_impl() : _Flat_map_impl(key_compare()) { }

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

      _Flat_map_impl(key_container_type __key_cont,
		     mapped_container_type __mapped_cont,
		     const key_compare& __comp = key_compare())
      : _M_cont(std::move(__key_cont), std::move(__mapped_cont)), _M_comp(__comp)
      {
	__glibcxx_assert(_M_cont.keys.size() == _M_cont.values.size());
	_M_sort_uniq();
      }

      _Flat_map_impl(__sorted_t,
		     key_container_type __key_cont,
		     mapped_container_type __mapped_cont,
		     const key_compare& __comp = key_compare())
      : _M_cont(std::move(__key_cont), std::move(__mapped_cont)), _M_comp(__comp)
      {
	__glibcxx_assert(_M_cont.keys.size() == _M_cont.values.size());
	_GLIBCXX_DEBUG_ASSERT(ranges::is_sorted(_M_cont.keys, _M_comp));
      }

      template<__has_input_iter_cat _InputIterator>
	_Flat_map_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>
	_Flat_map_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>
	_Flat_map_impl(from_range_t, _Rg&& __rg)
	: _Flat_map_impl(from_range, std::forward<_Rg>(__rg), key_compare())
	{ }

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

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

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

      // constructors with allocators

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	explicit
	_Flat_map_impl(const _Alloc& __a)
	: _Flat_map_impl(key_compare(), __a)
	{ }

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(const key_compare& __comp, const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<key_container_type>(__a),
		  std::make_obj_using_allocator<mapped_container_type>(__a)),
	  _M_comp(__comp)
	{ }

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(const key_container_type& __key_cont,
		       const mapped_container_type& __mapped_cont,
		       const _Alloc& __a)
	: _Flat_map_impl(__key_cont, __mapped_cont, key_compare(), __a)
	{ }

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(const key_container_type& __key_cont,
		       const mapped_container_type& __mapped_cont,
		       const key_compare& __comp,
		       const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<key_container_type>(__a, __key_cont),
		  std::make_obj_using_allocator<mapped_container_type>(__a, __mapped_cont)),
	  _M_comp(__comp)
	{
	  __glibcxx_assert(_M_cont.keys.size() == _M_cont.values.size());
	  _M_sort_uniq();
	}

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(__sorted_t __s,
		       const key_container_type& __key_cont,
		       const mapped_container_type& __mapped_cont,
		       const _Alloc& __a)
	: _Flat_map_impl(__s, __key_cont, __mapped_cont, key_compare(), __a)
	{ }

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(__sorted_t,
		       const key_container_type& __key_cont,
		       const mapped_container_type& __mapped_cont,
		       const key_compare& __comp,
		       const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<key_container_type>(__a, __key_cont),
		  std::make_obj_using_allocator<mapped_container_type>(__a, __mapped_cont)),
	  _M_comp(__comp)
	{
	  __glibcxx_assert(_M_cont.keys.size() == _M_cont.values.size());
	_GLIBCXX_DEBUG_ASSERT(ranges::is_sorted(_M_cont.keys, _M_comp));
	}

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(const _Derived& __x, const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<key_container_type>(__a, __x._M_cont.keys),
		  std::make_obj_using_allocator<mapped_container_type>(__a, __x._M_cont.values)),
	  _M_comp(__x._M_comp)
	{ }

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(_Derived&& __x, const _Alloc& __a)
	: _M_cont(std::make_obj_using_allocator<key_container_type>
		  (__a, std::move(__x._M_cont.keys)),
		  std::make_obj_using_allocator<mapped_container_type>
		  (__a, std::move(__x._M_cont.values))),
	  _M_comp(__x._M_comp)
	{ }

      template<__has_input_iter_cat _InputIterator,
	       __allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(_InputIterator __first, _InputIterator __last,
		       const _Alloc& __a)
	: _Flat_map_impl(std::move(__first), std::move(__last), key_compare(), __a)
	{ }

      template<__has_input_iter_cat _InputIterator,
	       __allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(_InputIterator __first, _InputIterator __last,
		       const key_compare& __comp,
		       const _Alloc& __a)
	: _Flat_map_impl(__comp, __a)
	{ insert(__first, __last); }

      template<__has_input_iter_cat _InputIterator,
	       __allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(__sorted_t __s,
		       _InputIterator __first, _InputIterator __last,
		       const _Alloc& __a)
	: _Flat_map_impl(__s, std::move(__first), std::move(__last), key_compare(), __a)
	{ }

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

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

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

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(initializer_list<value_type> __il,
		       const _Alloc& __a)
	: _Flat_map_impl(__il, key_compare(), __a)
	{ }

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(initializer_list<value_type> __il,
		       const key_compare& __comp,
		       const _Alloc& __a)
	: _Flat_map_impl(__il.begin(), __il.end(), __comp, __a)
	{ }

      template<__allocator_for<key_container_type, mapped_container_type> _Alloc>
	_Flat_map_impl(__sorted_t __s,
		       initializer_list<value_type> __il,
		       const _Alloc& __a)
	: _Flat_map_impl(__s, __il.begin(), __il.end(), key_compare(), __a)
	{ }

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

      _Derived&
      operator=(initializer_list<value_type> __il)
      {
	clear();
	insert(__il);
	return static_cast<_Derived&>(*this);
      }

      // iterators
      iterator
      begin() noexcept
      { return {this, _M_cont.keys.cbegin()}; }

      const_iterator
      begin() const noexcept
      { return {this, _M_cont.keys.cbegin()}; }

      iterator
      end() noexcept
      { return {this, _M_cont.keys.cend()}; }

      const_iterator
      end() const noexcept
      { return {this, _M_cont.keys.cend()}; }

      reverse_iterator
      rbegin() noexcept
      { return reverse_iterator(end()); }

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

      reverse_iterator
      rend() noexcept
      { return reverse_iterator(begin()); }

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

      const_iterator
      cbegin() const noexcept
      { return {this, _M_cont.keys.cbegin()}; }

      const_iterator
      cend() const noexcept
      { return {this, _M_cont.keys.cend()}; }

      const_reverse_iterator
      crbegin() const noexcept
      { return const_reverse_iterator(cend()); }

      const_reverse_iterator
      crend() const noexcept
      { return const_reverse_iterator(cbegin()); }

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

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

      size_type
      max_size() const noexcept
      { return std::min<size_type>(keys().max_size(), values().max_size()); }

      // element access
      // operator[] and at defined directly in class flat_map only.

      // modifiers
      template<typename _Key2, typename... _Args>
	pair<iterator, bool>
	_M_try_emplace(optional<const_iterator> __hint, _Key2&& __k, _Args&&... __args)
	{
	  // TODO: Simplify and audit the hint handling.
	  typename key_container_type::iterator __key_it;
	  typename mapped_container_type::iterator __value_it;
	  int __r = -1, __s = -1;
	  if (__hint.has_value()
	      && (__hint == cbegin()
		  || (__r = !_M_comp(__k, (*__hint)[-1].first))) // k >= hint[-1]
	      && (__hint == cend()
		  || (__s = !_M_comp((*__hint)[0].first, __k)))) // k <= hint[0]
	    {
	      __key_it = _M_cont.keys.begin() + __hint->_M_index;
	      if constexpr (!_Multi)
		if (__r == 1 && !_M_comp(__key_it[-1], __k)) // k == hint[-1]
		  return {iterator{this, __key_it - 1}, false};
	    }
	  else
	    {
	      auto __first = _M_cont.keys.begin();
	      auto __last = _M_cont.keys.end();
	      if (__r == 1) // k >= hint[-1]
		__first += __hint->_M_index;
	      else if (__r == 0) // k < __hint[-1]
		__last = __first + __hint->_M_index;
	      if constexpr (_Multi)
		{
		  if (__s == 0) // hint[0] < k
		    // Insert before the leftmost equivalent key.
		    __key_it = std::lower_bound(__first, __last, __k, _M_comp);
		  else
		    // Insert after the rightmost equivalent key.
		    __key_it = std::upper_bound(std::make_reverse_iterator(__last),
						std::make_reverse_iterator(__first),
						__k, std::not_fn(_M_comp)).base();
		}
	      else
		__key_it = std::lower_bound(__first, __last, __k, _M_comp);
	    }

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

	  auto __guard = _M_make_clear_guard();
	  __key_it = _M_cont.keys.insert(__key_it, std::move(__k));
	  __value_it = _M_cont.values.begin() + (__key_it - _M_cont.keys.begin());
	  _M_cont.values.emplace(__value_it, std::forward<_Args>(__args)...);
	  __guard._M_disable();
	  return {iterator{this, __key_it}, true};
	}

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

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

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

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

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

      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>
	__emplace_result_t
	insert(_Arg&& __x)
	{ return emplace(std::forward<_Arg>(__x)); }

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

    private:
      template<typename _Iter, typename _Sent>
	void
	_M_insert(_Iter __first, _Sent __last)
	{
	  // FIXME: This implementation fails its complexity requirements.
	  // We can't idiomatically implement an efficient version (as in the
	  // disabled code) until ranges::inplace_merge is fixed to dispatch
	  // on iterator concept instead of iterator category.
#if 0
	  auto __guard = _M_make_clear_guard();
	  auto __n = size();
	  for (; __first != __last; ++__first)
	    {
	      value_type __value = *__first;
	      _M_cont.keys.emplace_back(std::move(__value.first));
	      _M_cont.values.emplace_back(std::move(__value.second));
	    }
	  auto __zv = views::zip(_M_cont.keys, _M_cont.values);
	  ranges::sort(__zv.begin() + __n, __zv.end(), value_comp());
	  ranges::inplace_merge(__zv.begin(), __zv.begin() + __n, __zv.end(), value_comp());
	  if constexpr (!_Multi)
	    _M_unique();
	  __guard._M_cont = nullptr;
#else
	  auto __guard = _M_make_clear_guard();
	  for (; __first != __last; ++__first)
	    {
	      value_type __value = *__first;
	      _M_cont.keys.emplace_back(std::move(__value.first));
	      _M_cont.values.emplace_back(std::move(__value.second));
	    }
	  _M_sort_uniq();
	  __guard._M_disable();
#endif
	}

    public:
      template<__has_input_iter_cat _InputIterator>
	void
	insert(_InputIterator __first, _InputIterator __last)
	{ _M_insert(std::move(__first), std::move(__last)); }

      template<__has_input_iter_cat _InputIterator>
	void
	insert(__sorted_t, _InputIterator __first, _InputIterator __last)
	{
	  // FIXME: This implementation fails its complexity requirements; see above.
	  insert(std::move(__first), std::move(__last));
	}

      template<__detail::__container_compatible_range<value_type> _Rg>
	void
	insert_range(_Rg&& __rg)
	{ _M_insert(ranges::begin(__rg), ranges::end(__rg)); }

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

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

      containers
      extract() &&
      {
	auto __guard = _M_make_clear_guard();
	return {std::move(_M_cont.keys), std::move(_M_cont.values)};
      }

      void
      replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont)
      {
	__glibcxx_assert(__key_cont.size() == __mapped_cont.size());
	_GLIBCXX_DEBUG_ASSERT(ranges::is_sorted(__key_cont, _M_comp));
	auto __guard = _M_make_clear_guard();
	_M_cont.keys = std::move(__key_cont);
	_M_cont.values = std::move(__mapped_cont);
	__guard._M_disable();
      }

      // try_emplace and insert_or_assign defined directly in class flat_map only.

      iterator
      erase(iterator __position)
      { return erase(static_cast<const_iterator>(__position)); }

      iterator
      erase(const_iterator __position)
      {
	auto __guard = _M_make_clear_guard();
	auto __idx = __position._M_index;
	auto __it = _M_cont.keys.erase(_M_cont.keys.begin() + __idx);
	_M_cont.values.erase(_M_cont.values.begin() + __idx);
	__guard._M_disable();
	return iterator{this, __it};
      }

      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>)
	size_type
	erase(_Key2&& __x)
	{
	  auto [__first, __last] = equal_range(std::forward<_Key2>(__x));
	  auto __n = __last - __first;
	  erase(__first, __last);
	  return __n;
	}

      iterator
      erase(const_iterator __first, const_iterator __last)
      {
	auto __guard = _M_make_clear_guard();
	auto __it = _M_cont.keys.erase(_M_cont.keys.begin() + __first._M_index,
				       _M_cont.keys.begin() + __last._M_index);
	_M_cont.values.erase(_M_cont.values.begin() + __first._M_index,
			     _M_cont.values.begin() + __last._M_index);
	__guard._M_disable();
	return iterator{this, __it};
      }

      void
      swap(_Derived& __y) noexcept
      {
	ranges::swap(_M_comp, __y._M_comp);
	ranges::swap(_M_cont.keys, __y._M_cont.keys);
	ranges::swap(_M_cont.values, __y._M_cont.values);
      }

      void
      clear() noexcept
      {
	_M_cont.keys.clear();
	_M_cont.values.clear();
      }

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

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

      [[nodiscard]]
      const key_container_type&
      keys() const noexcept
      { return _M_cont.keys; }

      [[nodiscard]]
      const mapped_container_type&
      values() const noexcept
      { return _M_cont.values; }

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

      [[nodiscard]]
      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]]
	iterator
	find(const _Key2& __x)
	{
	  auto __it = lower_bound(__x);
	  if (__it != end() && !_M_comp(__x, __it->first))
	    return __it;
	  else
	    return end();
	}

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

      [[nodiscard]]
      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]]
	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]]
      bool
      contains(const key_type& __x) const
      { return contains<key_type>(__x); }

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

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

      [[nodiscard]]
      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]]
	iterator
	lower_bound(const _Key2& __x)
	{
	  auto __it = std::lower_bound(_M_cont.keys.begin(), _M_cont.keys.end(),
				       __x, _M_comp);
	  return {this, __it};
	}

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	const_iterator
	lower_bound(const _Key2& __x) const
	{
	  auto __it = std::lower_bound(_M_cont.keys.begin(), _M_cont.keys.end(),
				       __x, _M_comp);
	  return {this, __it};
	}

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

      [[nodiscard]]
      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]]
	iterator
	upper_bound(const _Key2& __x)
	{
	  auto __it = std::upper_bound(_M_cont.keys.begin(), _M_cont.keys.end(),
				       __x, _M_comp);
	  return {this, __it};
	}

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	const_iterator
	upper_bound(const _Key2& __x) const
	{
	  auto __it = std::upper_bound(_M_cont.keys.begin(), _M_cont.keys.end(),
				       __x, _M_comp);
	  return {this, __it};
	}

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

      [[nodiscard]]
      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]]
	pair<iterator, iterator>
	equal_range(const _Key2& __x)
	{
	  auto [__first, __last] = std::equal_range(_M_cont.keys.begin(),
						    _M_cont.keys.end(),
						    __x, _M_comp);
	  return {{this, __first}, {this, __last}};
	}

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	[[nodiscard]]
	pair<const_iterator, const_iterator>
	equal_range(const _Key2& __x) const
	{
	  auto [__first, __last] = std::equal_range(_M_cont.keys.begin(),
						    _M_cont.keys.end(),
						    __x, _M_comp);
	  return {{this, __first}, {this, __last}};
	}

      [[nodiscard]]
      friend bool
      operator==(const _Derived& __x, const _Derived& __y)
      {
	return __x._M_cont.keys == __y._M_cont.keys
	  && __x._M_cont.values == __y._M_cont.values;
      }

      template<typename _Up = value_type>
	[[nodiscard]]
	friend __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 void
      swap(_Derived& __x, _Derived& __y) noexcept
      { return __x.swap(__y); }

      template<typename _Predicate>
	size_type
	_M_erase_if(_Predicate __pred)
	{
	  auto __guard = _M_make_clear_guard();
	  auto __zv = views::zip(_M_cont.keys, _M_cont.values);
	  auto __sr = ranges::remove_if(__zv, __pred,
					[](const auto& __e) {
					  return const_reference(__e);
					});
	  auto __erased = __sr.size();
	  erase(end() - __erased, end());
	  __guard._M_disable();
	  return __erased;
	}

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

      void
      _M_sort_uniq()
      {
	auto __zv = views::zip(_M_cont.keys, _M_cont.values);
	ranges::sort(__zv, value_comp());
	if constexpr (!_Multi)
	  _M_unique();
      }

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

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

	  [[no_unique_address]] key_compare _M_comp;
	};

	auto __zv = views::zip(_M_cont.keys, _M_cont.values);
	auto __it = ranges::unique(__zv, __key_equiv(_M_comp)).begin();
	auto __n = __it - __zv.begin();
	_M_cont.keys.erase(_M_cont.keys.begin() + __n, _M_cont.keys.end());
	_M_cont.values.erase(_M_cont.values.begin() + __n, _M_cont.values.end());
      }
    };

  template<typename _Key, typename _Tp, typename _Compare,
	   typename _KeyContainer, typename _MappedContainer, bool _Multi>
  template<bool _Const>
    class _Flat_map_impl<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer, _Multi>::_Iterator
    {
      using __size_type = typename _Flat_map_impl::size_type;

    public:
      using iterator_category = input_iterator_tag;
      using iterator_concept  = random_access_iterator_tag;
      using value_type        = pair<key_type, mapped_type>;
      using reference         = pair<const key_type&,
				     ranges::__maybe_const_t<_Const, mapped_type>&>;
      using difference_type   = ptrdiff_t;

      _Iterator() = default;

      _Iterator(_Iterator<!_Const> __it) requires _Const
      : _M_cont(__it._M_cont), _M_index(__it._M_index)
      { }

      reference
      operator*() const noexcept
      {
	__glibcxx_assert(_M_index < _M_cont->keys.size());
	return {_M_cont->keys[_M_index], _M_cont->values[_M_index]};
      }

      struct pointer
      {
	reference __p;

	const reference*
	operator->() const noexcept
	{ return std::__addressof(__p); }
      };

      pointer
      operator->() const
      { return pointer{operator*()}; }

      reference
      operator[](difference_type __n) const noexcept
      { return *(*this + __n); }

      _Iterator&
      operator++() noexcept
      {
	++_M_index;
	return *this;
      }

      _Iterator&
      operator--() noexcept
      {
	--_M_index;
	return *this;
      }

      _Iterator
      operator++(int) noexcept
      {
	auto __tmp = *this;
	++*this;
	return __tmp;
      }

      _Iterator
      operator--(int) noexcept
      {
	auto __tmp = *this;
	--*this;
	return __tmp;
      }

      _Iterator&
      operator+=(difference_type __n) noexcept
      {
	_M_index += __n;
	return *this;
      }

      _Iterator&
      operator-=(difference_type __n) noexcept
      {
	_M_index -= __n;
	return *this;
      }

    private:
      friend _Flat_map_impl;
      friend _Iterator<!_Const>;

      _Iterator(_Flat_map_impl* __fm, typename key_container_type::const_iterator __it)
      requires (!_Const)
      : _M_cont(std::__addressof(__fm->_M_cont)), _M_index(__it - __fm->keys().cbegin())
      { }

      _Iterator(const _Flat_map_impl* __fm, typename key_container_type::const_iterator __it)
      requires _Const
      : _M_cont(std::__addressof(__fm->_M_cont)), _M_index(__it - __fm->keys().cbegin())
      { }

      friend _Iterator
      operator+(_Iterator __it, difference_type __n) noexcept
      {
	__it += __n;
	return __it;
      }

      friend _Iterator
      operator+(difference_type __n, _Iterator __it) noexcept
      {
	__it += __n;
	return __it;
      }

      friend _Iterator
      operator-(_Iterator __it, difference_type __n) noexcept
      {
	__it -= __n;
	return __it;
      }

      friend difference_type
      operator-(const _Iterator& __x, const _Iterator& __y) noexcept
      {
	__glibcxx_assert(__x._M_cont == __y._M_cont);
	return __x._M_index - __y._M_index;
      }

      friend bool
      operator==(const _Iterator& __x, const _Iterator& __y) noexcept
      {
	__glibcxx_assert(__x._M_cont == __y._M_cont);
	__glibcxx_assert((__x._M_index == size_t(-1)) == (__y._M_index == size_t(-1)));
	return __x._M_index == __y._M_index;
      }

      friend strong_ordering
      operator<=>(const _Iterator& __x, const _Iterator& __y)
      {
	__glibcxx_assert(__x._M_cont == __y._M_cont);
	__glibcxx_assert((__x._M_index == size_t(-1)) == (__y._M_index == size_t(-1)));
	return __x._M_index <=> __y._M_index;
      }

      ranges::__maybe_const_t<_Const, containers>* _M_cont = nullptr;
      __size_type _M_index = -1;
    };

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

    public:
      // types
      using typename _Impl::key_type;
      using typename _Impl::mapped_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::key_container_type;
      using typename _Impl::mapped_container_type;
      using typename _Impl::value_compare;
      using typename _Impl::containers;

      // constructors
      using _Impl::_Impl;

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

      // element access
      mapped_type&
      operator[](const key_type& __x)
      { return try_emplace(__x).first->second; }

      mapped_type&
      operator[](key_type&& __x)
      { return try_emplace(std::move(__x)).first->second; }

      template<typename _Key2>
	requires __transparent_comparator<_Compare>
	mapped_type&
	operator[](_Key2&& __x)
	{ return try_emplace(std::forward<_Key2>(__x)).first->second; }

      mapped_type&
      at(const key_type& __x)
      { return at<key_type>(__x); }

      const mapped_type&
      at(const key_type& __x) const
      { return at<key_type>(__x); }

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	mapped_type&
	at(const _Key2& __x)
	{
	  auto __it = this->find(__x);
	  if (__it == this->end())
	    __throw_out_of_range("flat_map::at");
	  return __it->second;
	}

      template<typename _Key2>
	requires same_as<_Key2, _Key> || __transparent_comparator<_Compare>
	const mapped_type&
	at(const _Key2& __x) const
	{
	  auto __it = this->find(__x);
	  if (__it == this->end())
	    __throw_out_of_range("flat_map::at");
	  return __it->second;
	}

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

      template<typename... _Args>
	requires is_constructible_v<mapped_type, _Args...>
	pair<iterator, bool>
	try_emplace(const key_type& __k, _Args&&... __args)
	{ return _Impl::_M_try_emplace(nullopt, __k, std::forward<_Args>(__args)...); }

      template<typename... _Args>
	requires is_constructible_v<mapped_type, _Args...>
	pair<iterator, bool>
	try_emplace(key_type&& __k, _Args&&... __args)
	{
	  return _Impl::_M_try_emplace(nullopt, std::move(__k),
				       std::forward<_Args>(__args)...);
	}

      template<typename _Key2, typename... _Args>
	requires __transparent_comparator<_Compare>
	  && is_constructible_v<key_type, _Key2>
	  && is_constructible_v<mapped_type, _Args...>
	  && (!is_convertible_v<_Key2&&, const_iterator>)
	  && (!is_convertible_v<_Key2&&, iterator>)
	pair<iterator, bool>
	try_emplace(_Key2&& __k, _Args&&... __args)
	{
	  return _Impl::_M_try_emplace(nullopt, std::forward<_Key2>(__k),
				       std::forward<_Args>(__args)...);
	}

      template<typename... _Args>
	requires is_constructible_v<mapped_type, _Args...>
	iterator
	try_emplace(const_iterator __hint, const key_type& __k, _Args&&... __args)
	{ return _Impl::_M_try_emplace(__hint, __k, std::forward<_Args>(__args)...).first; }

      template<typename... _Args>
	requires is_constructible_v<mapped_type, _Args...>
	iterator
	try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args)
	{
	  return _Impl::_M_try_emplace(__hint, std::move(__k),
				       std::forward<_Args>(__args)...).first;
	}

      template<typename _Key2, typename... _Args>
	requires __transparent_comparator<_Compare>
	  && is_constructible_v<key_type, _Key2>
	  && is_constructible_v<mapped_type, _Args...>
	iterator
	try_emplace(const_iterator __hint, _Key2&& __k, _Args&&... __args)
	{
	  return _Impl::_M_try_emplace(__hint, std::forward<_Key2>(__k),
				       std::forward<_Args>(__args)...).first;
	}

      template<typename _Mapped>
	requires is_assignable_v<mapped_type&, _Mapped>
	  && is_constructible_v<mapped_type, _Mapped>
	pair<iterator, bool>
	insert_or_assign(const key_type& __k, _Mapped&& __obj)
	{ return insert_or_assign<const key_type&, _Mapped>(__k, std::forward<_Mapped>(__obj)); }

      template<typename _Mapped>
	requires is_assignable_v<mapped_type&, _Mapped>
	  && is_constructible_v<mapped_type, _Mapped>
	pair<iterator, bool>
	insert_or_assign(key_type&& __k, _Mapped&& __obj)
	{
	  return insert_or_assign<key_type, _Mapped>(std::move(__k),
						     std::forward<_Mapped>(__obj));
	}

      template<typename _Key2, typename _Mapped>
	requires (same_as<remove_cvref_t<_Key2>, _Key> || __transparent_comparator<_Compare>)
	  && is_constructible_v<key_type, _Key2>
	  && is_assignable_v<mapped_type&, _Mapped>
	  && is_constructible_v<mapped_type, _Mapped>
	pair<iterator, bool>
	insert_or_assign(_Key2&& __k, _Mapped&& __obj)
	{
	  auto __r = _Impl::_M_try_emplace(nullopt, std::forward<_Key2>(__k),
					   std::forward<_Mapped>(__obj));
	  if (!__r.second)
	    __r.first->second = std::forward<_Mapped>(__obj);
	  return __r;
	}

      template<typename _Mapped>
	requires is_assignable_v<mapped_type&, _Mapped>
	  && is_constructible_v<mapped_type, _Mapped>
	iterator
	insert_or_assign(const_iterator __hint, const key_type& __k, _Mapped&& __obj)
	{
	  return insert_or_assign<const key_type&, _Mapped>(__hint, __k,
							    std::forward<_Mapped>(__obj));
	}

      template<typename _Mapped>
	requires is_assignable_v<mapped_type&, _Mapped>
	  && is_constructible_v<mapped_type, _Mapped>
	iterator
	insert_or_assign(const_iterator __hint, key_type&& __k, _Mapped&& __obj)
	{
	  return insert_or_assign<key_type, _Mapped>(__hint, std::move(__k),
						     std::forward<_Mapped>(__obj));
	}

      template<typename _Key2, typename _Mapped>
	requires (same_as<remove_cvref_t<_Key2>, _Key> || __transparent_comparator<_Compare>)
	  && is_constructible_v<key_type, _Key2>
	  && is_assignable_v<mapped_type&, _Mapped>
	  && is_constructible_v<mapped_type, _Mapped>
	iterator
	insert_or_assign(const_iterator __hint, _Key2&& __k, _Mapped&& __obj)
	{
	  auto __r = _Impl::_M_try_emplace(__hint, std::forward<_Key2>(__k),
					   std::forward<_Mapped>(__obj));
	  if (!__r.second)
	    __r.first->second = std::forward<_Mapped>(__obj);
	  return __r.first;
	}

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

      // map 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, typename _MappedContainer,
	   __not_allocator_like _Compare = less<typename _KeyContainer::value_type>>
    flat_map(_KeyContainer, _MappedContainer, _Compare = _Compare())
    -> flat_map<typename _KeyContainer::value_type, typename _MappedContainer::value_type,
		_Compare, _KeyContainer, _MappedContainer>;

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

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

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

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

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

  template<__has_input_iter_cat _InputIterator,
	   __not_allocator_like _Compare = less<__iter_key_t<_InputIterator>>>
    flat_map(_InputIterator, _InputIterator, _Compare = _Compare())
    -> flat_map<__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_map(sorted_unique_t, _InputIterator, _InputIterator, _Compare = _Compare())
    -> flat_map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Compare>;

  template<ranges::input_range _Rg,
	   __not_allocator_like _Compare = less<__detail::__range_key_type<_Rg>>,
	   __allocator_like _Alloc = allocator<byte>>
    flat_map(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc())
    -> flat_map<__detail::__range_key_type<_Rg>, __detail::__range_mapped_type<_Rg>,
		_Compare,
		vector<__detail::__range_key_type<_Rg>,
		       __alloc_rebind<_Alloc, __detail::__range_key_type<_Rg>>>,
		vector<__detail::__range_mapped_type<_Rg>,
		       __alloc_rebind<_Alloc, __detail::__range_mapped_type<_Rg>>>>;

  template<ranges::input_range _Rg, __allocator_like _Alloc>
    flat_map(from_range_t, _Rg&&, _Alloc)
    -> flat_map<__detail::__range_key_type<_Rg>, __detail::__range_mapped_type<_Rg>,
		less<__detail::__range_key_type<_Rg>>,
		vector<__detail::__range_key_type<_Rg>,
		       __alloc_rebind<_Alloc, __detail::__range_key_type<_Rg>>>,
		vector<__detail::__range_mapped_type<_Rg>,
		       __alloc_rebind<_Alloc, __detail::__range_mapped_type<_Rg>>>>;

  template<typename _Key, typename _Tp, __not_allocator_like _Compare = less<_Key>>
    flat_map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare())
    -> flat_map<_Key, _Tp, _Compare>;

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

  template<typename _Key, typename _Tp, typename _Compare,
	   typename _KeyContainer, typename _MappedContainer, typename _Alloc>
    struct uses_allocator<flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>, _Alloc>
    : bool_constant<uses_allocator_v<_KeyContainer, _Alloc>
		    && uses_allocator_v<_MappedContainer, _Alloc>>
    { };

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

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

    public:
      // types
      using typename _Impl::key_type;
      using typename _Impl::mapped_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::key_container_type;
      using typename _Impl::mapped_container_type;
      using typename _Impl::value_compare;
      using typename _Impl::containers;

      // constructors
      using _Impl::_Impl;

      // 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;
      using _Impl::keys;
      using _Impl::values;

      // map 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, typename _MappedContainer,
	   __not_allocator_like _Compare = less<typename _KeyContainer::value_type>>
    flat_multimap(_KeyContainer, _MappedContainer, _Compare = _Compare())
    -> flat_multimap<typename _KeyContainer::value_type, typename _MappedContainer::value_type,
		     _Compare, _KeyContainer, _MappedContainer>;

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

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

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

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

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

  template<__has_input_iter_cat _InputIterator,
	   __not_allocator_like _Compare = less<__iter_key_t<_InputIterator>>>
    flat_multimap(_InputIterator, _InputIterator, _Compare = _Compare())
    -> flat_multimap<__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_multimap(sorted_equivalent_t, _InputIterator, _InputIterator, _Compare = _Compare())
    -> flat_multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Compare>;

  template<ranges::input_range _Rg,
	   __not_allocator_like _Compare = less<__detail::__range_key_type<_Rg>>,
	   __allocator_like _Alloc = allocator<byte>>
    flat_multimap(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc())
    -> flat_multimap<__detail::__range_key_type<_Rg>, __detail::__range_mapped_type<_Rg>,
		     _Compare,
		     vector<__detail::__range_key_type<_Rg>,
			    __alloc_rebind<_Alloc, __detail::__range_key_type<_Rg>>>,
		     vector<__detail::__range_mapped_type<_Rg>,
			    __alloc_rebind<_Alloc, __detail::__range_mapped_type<_Rg>>>>;

  template<ranges::input_range _Rg, __allocator_like _Alloc>
    flat_multimap(from_range_t, _Rg&&, _Alloc)
    -> flat_multimap<__detail::__range_key_type<_Rg>, __detail::__range_mapped_type<_Rg>,
		     less<__detail::__range_key_type<_Rg>>,
		     vector<__detail::__range_key_type<_Rg>,
			    __alloc_rebind<_Alloc, __detail::__range_key_type<_Rg>>>,
		     vector<__detail::__range_mapped_type<_Rg>,
			    __alloc_rebind<_Alloc, __detail::__range_mapped_type<_Rg>>>>;

  template<typename _Key, typename _Tp, __not_allocator_like _Compare = less<_Key>>
    flat_multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare())
    -> flat_multimap<_Key, _Tp, _Compare>;

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

  template<typename _Key, typename _Tp, typename _Compare,
	   typename _KeyContainer, typename _MappedContainer, typename _Alloc>
    struct uses_allocator<flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>,
			  _Alloc>
    : bool_constant<uses_allocator_v<_KeyContainer, _Alloc>
		    && uses_allocator_v<_MappedContainer, _Alloc>>
    { };

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

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __cpp_lib_flat_map
#endif // _GLIBCXX_FLAT_MAP
