// <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/functexcept.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<const 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
