Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:48

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H
0011 #define _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H
0012 
0013 #include <__algorithm/lexicographical_compare_three_way.h>
0014 #include <__algorithm/min.h>
0015 #include <__algorithm/ranges_equal.h>
0016 #include <__algorithm/ranges_equal_range.h>
0017 #include <__algorithm/ranges_inplace_merge.h>
0018 #include <__algorithm/ranges_is_sorted.h>
0019 #include <__algorithm/ranges_lower_bound.h>
0020 #include <__algorithm/ranges_partition_point.h>
0021 #include <__algorithm/ranges_sort.h>
0022 #include <__algorithm/ranges_unique.h>
0023 #include <__algorithm/ranges_upper_bound.h>
0024 #include <__algorithm/remove_if.h>
0025 #include <__assert>
0026 #include <__compare/synth_three_way.h>
0027 #include <__concepts/convertible_to.h>
0028 #include <__concepts/swappable.h>
0029 #include <__config>
0030 #include <__cstddef/byte.h>
0031 #include <__cstddef/ptrdiff_t.h>
0032 #include <__flat_map/key_value_iterator.h>
0033 #include <__flat_map/sorted_equivalent.h>
0034 #include <__flat_map/utils.h>
0035 #include <__functional/invoke.h>
0036 #include <__functional/is_transparent.h>
0037 #include <__functional/operations.h>
0038 #include <__fwd/vector.h>
0039 #include <__iterator/concepts.h>
0040 #include <__iterator/distance.h>
0041 #include <__iterator/iterator_traits.h>
0042 #include <__iterator/ranges_iterator_traits.h>
0043 #include <__iterator/reverse_iterator.h>
0044 #include <__memory/allocator_traits.h>
0045 #include <__memory/uses_allocator.h>
0046 #include <__memory/uses_allocator_construction.h>
0047 #include <__ranges/access.h>
0048 #include <__ranges/concepts.h>
0049 #include <__ranges/container_compatible_range.h>
0050 #include <__ranges/drop_view.h>
0051 #include <__ranges/from_range.h>
0052 #include <__ranges/ref_view.h>
0053 #include <__ranges/size.h>
0054 #include <__ranges/subrange.h>
0055 #include <__ranges/zip_view.h>
0056 #include <__type_traits/conjunction.h>
0057 #include <__type_traits/container_traits.h>
0058 #include <__type_traits/invoke.h>
0059 #include <__type_traits/is_allocator.h>
0060 #include <__type_traits/is_nothrow_constructible.h>
0061 #include <__type_traits/is_same.h>
0062 #include <__type_traits/maybe_const.h>
0063 #include <__utility/exception_guard.h>
0064 #include <__utility/move.h>
0065 #include <__utility/pair.h>
0066 #include <__utility/scope_guard.h>
0067 #include <__vector/vector.h>
0068 #include <initializer_list>
0069 #include <stdexcept>
0070 
0071 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0072 #  pragma GCC system_header
0073 #endif
0074 
0075 _LIBCPP_PUSH_MACROS
0076 #include <__undef_macros>
0077 
0078 #if _LIBCPP_STD_VER >= 23
0079 
0080 _LIBCPP_BEGIN_NAMESPACE_STD
0081 
0082 template <class _Key,
0083           class _Tp,
0084           class _Compare         = less<_Key>,
0085           class _KeyContainer    = vector<_Key>,
0086           class _MappedContainer = vector<_Tp>>
0087 class flat_multimap {
0088   template <class, class, class, class, class>
0089   friend class flat_multimap;
0090 
0091   static_assert(is_same_v<_Key, typename _KeyContainer::value_type>);
0092   static_assert(is_same_v<_Tp, typename _MappedContainer::value_type>);
0093   static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
0094   static_assert(!is_same_v<_MappedContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
0095 
0096   template <bool _Const>
0097   using __iterator _LIBCPP_NODEBUG = __key_value_iterator<flat_multimap, _KeyContainer, _MappedContainer, _Const>;
0098 
0099 public:
0100   // types
0101   using key_type               = _Key;
0102   using mapped_type            = _Tp;
0103   using value_type             = pair<key_type, mapped_type>;
0104   using key_compare            = __type_identity_t<_Compare>;
0105   using reference              = pair<const key_type&, mapped_type&>;
0106   using const_reference        = pair<const key_type&, const mapped_type&>;
0107   using size_type              = size_t;
0108   using difference_type        = ptrdiff_t;
0109   using iterator               = __iterator<false>; // see [container.requirements]
0110   using const_iterator         = __iterator<true>;  // see [container.requirements]
0111   using reverse_iterator       = std::reverse_iterator<iterator>;
0112   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0113   using key_container_type     = _KeyContainer;
0114   using mapped_container_type  = _MappedContainer;
0115 
0116   class value_compare {
0117   private:
0118     _LIBCPP_NO_UNIQUE_ADDRESS key_compare __comp_;
0119     _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : __comp_(__c) {}
0120     friend flat_multimap;
0121 
0122   public:
0123     _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const {
0124       return __comp_(__x.first, __y.first);
0125     }
0126   };
0127 
0128   struct containers {
0129     key_container_type keys;
0130     mapped_container_type values;
0131   };
0132 
0133 private:
0134   template <class _Allocator>
0135   _LIBCPP_HIDE_FROM_ABI static constexpr bool __allocator_ctor_constraint =
0136       _And<uses_allocator<key_container_type, _Allocator>, uses_allocator<mapped_container_type, _Allocator>>::value;
0137 
0138   _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_compare_transparent = __is_transparent_v<_Compare>;
0139 
0140 public:
0141   // [flat.map.cons], construct/copy/destroy
0142   _LIBCPP_HIDE_FROM_ABI flat_multimap() noexcept(
0143       is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_MappedContainer> &&
0144       is_nothrow_default_constructible_v<_Compare>)
0145       : __containers_(), __compare_() {}
0146 
0147   _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap&) = default;
0148 
0149   // The copy/move constructors are not specified in the spec, which means they should be defaulted.
0150   // However, the move constructor can potentially leave a moved-from object in an inconsistent
0151   // state if an exception is thrown.
0152   _LIBCPP_HIDE_FROM_ABI flat_multimap(flat_multimap&& __other) noexcept(
0153       is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_MappedContainer> &&
0154       is_nothrow_move_constructible_v<_Compare>)
0155 #  if _LIBCPP_HAS_EXCEPTIONS
0156       try
0157 #  endif // _LIBCPP_HAS_EXCEPTIONS
0158       : __containers_(std::move(__other.__containers_)), __compare_(std::move(__other.__compare_)) {
0159     __other.clear();
0160 #  if _LIBCPP_HAS_EXCEPTIONS
0161   } catch (...) {
0162     __other.clear();
0163     // gcc does not like the `throw` keyword in a conditionally noexcept function
0164     if constexpr (!(is_nothrow_move_constructible_v<_KeyContainer> &&
0165                     is_nothrow_move_constructible_v<_MappedContainer> && is_nothrow_move_constructible_v<_Compare>)) {
0166       throw;
0167     }
0168 #  endif // _LIBCPP_HAS_EXCEPTIONS
0169   }
0170 
0171   template <class _Allocator>
0172     requires __allocator_ctor_constraint<_Allocator>
0173   _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap& __other, const _Allocator& __alloc)
0174       : flat_multimap(__ctor_uses_allocator_tag{},
0175                       __alloc,
0176                       __other.__containers_.keys,
0177                       __other.__containers_.values,
0178                       __other.__compare_) {}
0179 
0180   template <class _Allocator>
0181     requires __allocator_ctor_constraint<_Allocator>
0182   _LIBCPP_HIDE_FROM_ABI flat_multimap(flat_multimap&& __other, const _Allocator& __alloc)
0183 #  if _LIBCPP_HAS_EXCEPTIONS
0184       try
0185 #  endif // _LIBCPP_HAS_EXCEPTIONS
0186       : flat_multimap(__ctor_uses_allocator_tag{},
0187                       __alloc,
0188                       std::move(__other.__containers_.keys),
0189                       std::move(__other.__containers_.values),
0190                       std::move(__other.__compare_)) {
0191     __other.clear();
0192 #  if _LIBCPP_HAS_EXCEPTIONS
0193   } catch (...) {
0194     __other.clear();
0195     throw;
0196 #  endif // _LIBCPP_HAS_EXCEPTIONS
0197   }
0198 
0199   _LIBCPP_HIDE_FROM_ABI flat_multimap(
0200       key_container_type __key_cont, mapped_container_type __mapped_cont, const key_compare& __comp = key_compare())
0201       : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) {
0202     _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
0203                                      "flat_multimap keys and mapped containers have different size");
0204     __sort();
0205   }
0206 
0207   template <class _Allocator>
0208     requires __allocator_ctor_constraint<_Allocator>
0209   _LIBCPP_HIDE_FROM_ABI flat_multimap(
0210       const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const _Allocator& __alloc)
0211       : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) {
0212     _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
0213                                      "flat_multimap keys and mapped containers have different size");
0214     __sort();
0215   }
0216 
0217   template <class _Allocator>
0218     requires __allocator_ctor_constraint<_Allocator>
0219   _LIBCPP_HIDE_FROM_ABI
0220   flat_multimap(const key_container_type& __key_cont,
0221                 const mapped_container_type& __mapped_cont,
0222                 const key_compare& __comp,
0223                 const _Allocator& __alloc)
0224       : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) {
0225     _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
0226                                      "flat_multimap keys and mapped containers have different size");
0227     __sort();
0228   }
0229 
0230   _LIBCPP_HIDE_FROM_ABI
0231   flat_multimap(sorted_equivalent_t,
0232                 key_container_type __key_cont,
0233                 mapped_container_type __mapped_cont,
0234                 const key_compare& __comp = key_compare())
0235       : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) {
0236     _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
0237                                      "flat_multimap keys and mapped containers have different size");
0238     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted");
0239   }
0240 
0241   template <class _Allocator>
0242     requires __allocator_ctor_constraint<_Allocator>
0243   _LIBCPP_HIDE_FROM_ABI
0244   flat_multimap(sorted_equivalent_t,
0245                 const key_container_type& __key_cont,
0246                 const mapped_container_type& __mapped_cont,
0247                 const _Allocator& __alloc)
0248       : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) {
0249     _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
0250                                      "flat_multimap keys and mapped containers have different size");
0251     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted");
0252   }
0253 
0254   template <class _Allocator>
0255     requires __allocator_ctor_constraint<_Allocator>
0256   _LIBCPP_HIDE_FROM_ABI
0257   flat_multimap(sorted_equivalent_t,
0258                 const key_container_type& __key_cont,
0259                 const mapped_container_type& __mapped_cont,
0260                 const key_compare& __comp,
0261                 const _Allocator& __alloc)
0262       : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) {
0263     _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
0264                                      "flat_multimap keys and mapped containers have different size");
0265     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted");
0266   }
0267 
0268   _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const key_compare& __comp) : __containers_(), __compare_(__comp) {}
0269 
0270   template <class _Allocator>
0271     requires __allocator_ctor_constraint<_Allocator>
0272   _LIBCPP_HIDE_FROM_ABI flat_multimap(const key_compare& __comp, const _Allocator& __alloc)
0273       : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {}
0274 
0275   template <class _Allocator>
0276     requires __allocator_ctor_constraint<_Allocator>
0277   _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const _Allocator& __alloc)
0278       : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {}
0279 
0280   template <class _InputIterator>
0281     requires __has_input_iterator_category<_InputIterator>::value
0282   _LIBCPP_HIDE_FROM_ABI
0283   flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
0284       : __containers_(), __compare_(__comp) {
0285     insert(__first, __last);
0286   }
0287 
0288   template <class _InputIterator, class _Allocator>
0289     requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
0290   _LIBCPP_HIDE_FROM_ABI
0291   flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc)
0292       : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
0293     insert(__first, __last);
0294   }
0295 
0296   template <class _InputIterator, class _Allocator>
0297     requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
0298   _LIBCPP_HIDE_FROM_ABI flat_multimap(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
0299       : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {
0300     insert(__first, __last);
0301   }
0302 
0303   template <_ContainerCompatibleRange<value_type> _Range>
0304   _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t __fr, _Range&& __rg)
0305       : flat_multimap(__fr, std::forward<_Range>(__rg), key_compare()) {}
0306 
0307   template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
0308     requires __allocator_ctor_constraint<_Allocator>
0309   _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const _Allocator& __alloc)
0310       : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {
0311     insert_range(std::forward<_Range>(__rg));
0312   }
0313 
0314   template <_ContainerCompatibleRange<value_type> _Range>
0315   _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_multimap(__comp) {
0316     insert_range(std::forward<_Range>(__rg));
0317   }
0318 
0319   template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
0320     requires __allocator_ctor_constraint<_Allocator>
0321   _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc)
0322       : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
0323     insert_range(std::forward<_Range>(__rg));
0324   }
0325 
0326   template <class _InputIterator>
0327     requires __has_input_iterator_category<_InputIterator>::value
0328   _LIBCPP_HIDE_FROM_ABI flat_multimap(
0329       sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
0330       : __containers_(), __compare_(__comp) {
0331     insert(sorted_equivalent, __first, __last);
0332   }
0333   template <class _InputIterator, class _Allocator>
0334     requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
0335   _LIBCPP_HIDE_FROM_ABI
0336   flat_multimap(sorted_equivalent_t,
0337                 _InputIterator __first,
0338                 _InputIterator __last,
0339                 const key_compare& __comp,
0340                 const _Allocator& __alloc)
0341       : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
0342     insert(sorted_equivalent, __first, __last);
0343   }
0344 
0345   template <class _InputIterator, class _Allocator>
0346     requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
0347   _LIBCPP_HIDE_FROM_ABI
0348   flat_multimap(sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
0349       : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {
0350     insert(sorted_equivalent, __first, __last);
0351   }
0352 
0353   _LIBCPP_HIDE_FROM_ABI flat_multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
0354       : flat_multimap(__il.begin(), __il.end(), __comp) {}
0355 
0356   template <class _Allocator>
0357     requires __allocator_ctor_constraint<_Allocator>
0358   _LIBCPP_HIDE_FROM_ABI
0359   flat_multimap(initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
0360       : flat_multimap(__il.begin(), __il.end(), __comp, __alloc) {}
0361 
0362   template <class _Allocator>
0363     requires __allocator_ctor_constraint<_Allocator>
0364   _LIBCPP_HIDE_FROM_ABI flat_multimap(initializer_list<value_type> __il, const _Allocator& __alloc)
0365       : flat_multimap(__il.begin(), __il.end(), __alloc) {}
0366 
0367   _LIBCPP_HIDE_FROM_ABI
0368   flat_multimap(sorted_equivalent_t, initializer_list<value_type> __il, const key_compare& __comp = key_compare())
0369       : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __comp) {}
0370 
0371   template <class _Allocator>
0372     requires __allocator_ctor_constraint<_Allocator>
0373   _LIBCPP_HIDE_FROM_ABI flat_multimap(
0374       sorted_equivalent_t, initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
0375       : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __comp, __alloc) {}
0376 
0377   template <class _Allocator>
0378     requires __allocator_ctor_constraint<_Allocator>
0379   _LIBCPP_HIDE_FROM_ABI flat_multimap(sorted_equivalent_t, initializer_list<value_type> __il, const _Allocator& __alloc)
0380       : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __alloc) {}
0381 
0382   _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(initializer_list<value_type> __il) {
0383     clear();
0384     insert(__il);
0385     return *this;
0386   }
0387 
0388   // copy/move assignment are not specified in the spec (defaulted)
0389   // but move assignment can potentially leave moved from object in an inconsistent
0390   // state if an exception is thrown
0391   _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(const flat_multimap&) = default;
0392 
0393   _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(flat_multimap&& __other) noexcept(
0394       is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> &&
0395       is_nothrow_move_assignable_v<_Compare>) {
0396     auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; });
0397     auto __clear_self_guard  = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
0398     __containers_            = std::move(__other.__containers_);
0399     __compare_               = std::move(__other.__compare_);
0400     __clear_self_guard.__complete();
0401     return *this;
0402   }
0403 
0404   // iterators
0405   _LIBCPP_HIDE_FROM_ABI iterator begin() noexcept {
0406     return iterator(__containers_.keys.begin(), __containers_.values.begin());
0407   }
0408 
0409   _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept {
0410     return const_iterator(__containers_.keys.begin(), __containers_.values.begin());
0411   }
0412 
0413   _LIBCPP_HIDE_FROM_ABI iterator end() noexcept {
0414     return iterator(__containers_.keys.end(), __containers_.values.end());
0415   }
0416 
0417   _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept {
0418     return const_iterator(__containers_.keys.end(), __containers_.values.end());
0419   }
0420 
0421   _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
0422   _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
0423   _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
0424   _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
0425 
0426   _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return begin(); }
0427   _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return end(); }
0428   _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
0429   _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
0430 
0431   // [flat.map.capacity], capacity
0432   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __containers_.keys.empty(); }
0433 
0434   _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __containers_.keys.size(); }
0435 
0436   _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept {
0437     return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size());
0438   }
0439 
0440   // [flat.map.modifiers], modifiers
0441   template <class... _Args>
0442     requires is_constructible_v<pair<key_type, mapped_type>, _Args...> && is_move_constructible_v<key_type> &&
0443              is_move_constructible_v<mapped_type>
0444   _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {
0445     std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...);
0446     auto __key_it    = ranges::upper_bound(__containers_.keys, __pair.first, __compare_);
0447     auto __mapped_it = __corresponding_mapped_it(*this, __key_it);
0448 
0449     return __flat_map_utils::__emplace_exact_pos(
0450         *this, std::move(__key_it), std::move(__mapped_it), std::move(__pair.first), std::move(__pair.second));
0451   }
0452 
0453   template <class... _Args>
0454     requires is_constructible_v<pair<key_type, mapped_type>, _Args...>
0455   _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __hint, _Args&&... __args) {
0456     std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...);
0457 
0458     auto __prev_larger  = __hint != cbegin() && __compare_(__pair.first, (__hint - 1)->first);
0459     auto __next_smaller = __hint != cend() && __compare_(__hint->first, __pair.first);
0460 
0461     auto __hint_distance = __hint.__key_iter_ - __containers_.keys.cbegin();
0462     auto __key_iter      = __containers_.keys.begin() + __hint_distance;
0463     auto __mapped_iter   = __containers_.values.begin() + __hint_distance;
0464 
0465     if (!__prev_larger && !__next_smaller) [[likely]] {
0466       // hint correct, just use exact hint iterators
0467     } else if (__prev_larger && !__next_smaller) {
0468       // the hint position is more to the right than the key should have been.
0469       // we want to emplace the element to a position as right as possible
0470       // e.g. Insert new element "2" in the following range
0471       // 1, 1, 2, 2, 2, 3, 4, 6
0472       //                   ^
0473       //                   |
0474       //                  hint
0475       // We want to insert "2" after the last existing "2"
0476       __key_iter    = ranges::upper_bound(__containers_.keys.begin(), __key_iter, __pair.first, __compare_);
0477       __mapped_iter = __corresponding_mapped_it(*this, __key_iter);
0478     } else {
0479       _LIBCPP_ASSERT_INTERNAL(!__prev_larger && __next_smaller, "this means that the multimap is not sorted");
0480 
0481       // the hint position is more to the left than the key should have been.
0482       // we want to emplace the element to a position as left as possible
0483       //  1, 1, 2, 2, 2, 3, 4, 6
0484       //  ^
0485       //  |
0486       // hint
0487       // We want to insert "2" before the first existing "2"
0488       __key_iter    = ranges::lower_bound(__key_iter, __containers_.keys.end(), __pair.first, __compare_);
0489       __mapped_iter = __corresponding_mapped_it(*this, __key_iter);
0490     }
0491     return __flat_map_utils::__emplace_exact_pos(
0492         *this, __key_iter, __mapped_iter, std::move(__pair.first), std::move(__pair.second));
0493   }
0494 
0495   _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return emplace(__x); }
0496 
0497   _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __x) { return emplace(std::move(__x)); }
0498 
0499   _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, const value_type& __x) {
0500     return emplace_hint(__hint, __x);
0501   }
0502 
0503   _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, value_type&& __x) {
0504     return emplace_hint(__hint, std::move(__x));
0505   }
0506 
0507   template <class _PairLike>
0508     requires is_constructible_v<pair<key_type, mapped_type>, _PairLike>
0509   _LIBCPP_HIDE_FROM_ABI iterator insert(_PairLike&& __x) {
0510     return emplace(std::forward<_PairLike>(__x));
0511   }
0512 
0513   template <class _PairLike>
0514     requires is_constructible_v<pair<key_type, mapped_type>, _PairLike>
0515   _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, _PairLike&& __x) {
0516     return emplace_hint(__hint, std::forward<_PairLike>(__x));
0517   }
0518 
0519   template <class _InputIterator>
0520     requires __has_input_iterator_category<_InputIterator>::value
0521   _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) {
0522     if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
0523       __reserve(__last - __first);
0524     }
0525     __append_sort_merge</*WasSorted = */ false>(std::move(__first), std::move(__last));
0526   }
0527 
0528   template <class _InputIterator>
0529     requires __has_input_iterator_category<_InputIterator>::value
0530   _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, _InputIterator __first, _InputIterator __last) {
0531     if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
0532       __reserve(__last - __first);
0533     }
0534 
0535     __append_sort_merge</*WasSorted = */ true>(std::move(__first), std::move(__last));
0536   }
0537 
0538   template <_ContainerCompatibleRange<value_type> _Range>
0539   _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
0540     if constexpr (ranges::sized_range<_Range>) {
0541       __reserve(ranges::size(__range));
0542     }
0543 
0544     __append_sort_merge</*WasSorted = */ false>(ranges::begin(__range), ranges::end(__range));
0545   }
0546 
0547   _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
0548 
0549   _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, initializer_list<value_type> __il) {
0550     insert(sorted_equivalent, __il.begin(), __il.end());
0551   }
0552 
0553   _LIBCPP_HIDE_FROM_ABI containers extract() && {
0554     auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
0555     auto __ret   = std::move(__containers_);
0556     return __ret;
0557   }
0558 
0559   _LIBCPP_HIDE_FROM_ABI void replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) {
0560     _LIBCPP_ASSERT_VALID_INPUT_RANGE(
0561         __key_cont.size() == __mapped_cont.size(), "flat_multimap keys and mapped containers have different size");
0562 
0563     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__key_cont), "Key container is not sorted");
0564     auto __guard         = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
0565     __containers_.keys   = std::move(__key_cont);
0566     __containers_.values = std::move(__mapped_cont);
0567     __guard.__complete();
0568   }
0569 
0570   _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __position) {
0571     return __erase(__position.__key_iter_, __position.__mapped_iter_);
0572   }
0573 
0574   _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position) {
0575     return __erase(__position.__key_iter_, __position.__mapped_iter_);
0576   }
0577 
0578   _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __x) {
0579     auto [__first, __last] = equal_range(__x);
0580     auto __res             = __last - __first;
0581     erase(__first, __last);
0582     return __res;
0583   }
0584 
0585   template <class _Kp>
0586     requires(__is_compare_transparent && !is_convertible_v<_Kp &&, iterator> &&
0587              !is_convertible_v<_Kp &&, const_iterator>)
0588   _LIBCPP_HIDE_FROM_ABI size_type erase(_Kp&& __x) {
0589     auto [__first, __last] = equal_range(__x);
0590     auto __res             = __last - __first;
0591     erase(__first, __last);
0592     return __res;
0593   }
0594 
0595   _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) {
0596     auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
0597     auto __key_it     = __containers_.keys.erase(__first.__key_iter_, __last.__key_iter_);
0598     auto __mapped_it  = __containers_.values.erase(__first.__mapped_iter_, __last.__mapped_iter_);
0599     __on_failure.__complete();
0600     return iterator(std::move(__key_it), std::move(__mapped_it));
0601   }
0602 
0603   _LIBCPP_HIDE_FROM_ABI void swap(flat_multimap& __y) noexcept {
0604     // warning: The spec has unconditional noexcept, which means that
0605     // if any of the following functions throw an exception,
0606     // std::terminate will be called
0607     ranges::swap(__compare_, __y.__compare_);
0608     ranges::swap(__containers_.keys, __y.__containers_.keys);
0609     ranges::swap(__containers_.values, __y.__containers_.values);
0610   }
0611 
0612   _LIBCPP_HIDE_FROM_ABI void clear() noexcept {
0613     __containers_.keys.clear();
0614     __containers_.values.clear();
0615   }
0616 
0617   // observers
0618   _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __compare_; }
0619   _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__compare_); }
0620 
0621   _LIBCPP_HIDE_FROM_ABI const key_container_type& keys() const noexcept { return __containers_.keys; }
0622   _LIBCPP_HIDE_FROM_ABI const mapped_container_type& values() const noexcept { return __containers_.values; }
0623 
0624   // map operations
0625   _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __x) { return __find_impl(*this, __x); }
0626 
0627   _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __x) const { return __find_impl(*this, __x); }
0628 
0629   template <class _Kp>
0630     requires __is_compare_transparent
0631   _LIBCPP_HIDE_FROM_ABI iterator find(const _Kp& __x) {
0632     return __find_impl(*this, __x);
0633   }
0634 
0635   template <class _Kp>
0636     requires __is_compare_transparent
0637   _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Kp& __x) const {
0638     return __find_impl(*this, __x);
0639   }
0640 
0641   _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __x) const {
0642     auto [__first, __last] = equal_range(__x);
0643     return __last - __first;
0644   }
0645 
0646   template <class _Kp>
0647     requires __is_compare_transparent
0648   _LIBCPP_HIDE_FROM_ABI size_type count(const _Kp& __x) const {
0649     auto [__first, __last] = equal_range(__x);
0650     return __last - __first;
0651   }
0652 
0653   _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __x) const { return find(__x) != end(); }
0654 
0655   template <class _Kp>
0656     requires __is_compare_transparent
0657   _LIBCPP_HIDE_FROM_ABI bool contains(const _Kp& __x) const {
0658     return find(__x) != end();
0659   }
0660 
0661   _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __x) { return __lower_bound<iterator>(*this, __x); }
0662 
0663   _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __x) const {
0664     return __lower_bound<const_iterator>(*this, __x);
0665   }
0666 
0667   template <class _Kp>
0668     requires __is_compare_transparent
0669   _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Kp& __x) {
0670     return __lower_bound<iterator>(*this, __x);
0671   }
0672 
0673   template <class _Kp>
0674     requires __is_compare_transparent
0675   _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Kp& __x) const {
0676     return __lower_bound<const_iterator>(*this, __x);
0677   }
0678 
0679   _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __x) { return __upper_bound<iterator>(*this, __x); }
0680 
0681   _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __x) const {
0682     return __upper_bound<const_iterator>(*this, __x);
0683   }
0684 
0685   template <class _Kp>
0686     requires __is_compare_transparent
0687   _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Kp& __x) {
0688     return __upper_bound<iterator>(*this, __x);
0689   }
0690 
0691   template <class _Kp>
0692     requires __is_compare_transparent
0693   _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Kp& __x) const {
0694     return __upper_bound<const_iterator>(*this, __x);
0695   }
0696 
0697   _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __x) {
0698     return __equal_range_impl(*this, __x);
0699   }
0700 
0701   _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __x) const {
0702     return __equal_range_impl(*this, __x);
0703   }
0704 
0705   template <class _Kp>
0706     requires __is_compare_transparent
0707   _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _Kp& __x) {
0708     return __equal_range_impl(*this, __x);
0709   }
0710   template <class _Kp>
0711     requires __is_compare_transparent
0712   _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _Kp& __x) const {
0713     return __equal_range_impl(*this, __x);
0714   }
0715 
0716   friend _LIBCPP_HIDE_FROM_ABI bool operator==(const flat_multimap& __x, const flat_multimap& __y) {
0717     return ranges::equal(__x, __y);
0718   }
0719 
0720   friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_multimap& __x, const flat_multimap& __y) {
0721     return std::lexicographical_compare_three_way(
0722         __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
0723   }
0724 
0725   friend _LIBCPP_HIDE_FROM_ABI void swap(flat_multimap& __x, flat_multimap& __y) noexcept { __x.swap(__y); }
0726 
0727 private:
0728   struct __ctor_uses_allocator_tag {
0729     explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_tag() = default;
0730   };
0731   struct __ctor_uses_allocator_empty_tag {
0732     explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_empty_tag() = default;
0733   };
0734 
0735   template <class _Allocator, class _KeyCont, class _MappedCont, class... _CompArg>
0736     requires __allocator_ctor_constraint<_Allocator>
0737   _LIBCPP_HIDE_FROM_ABI
0738   flat_multimap(__ctor_uses_allocator_tag,
0739                 const _Allocator& __alloc,
0740                 _KeyCont&& __key_cont,
0741                 _MappedCont&& __mapped_cont,
0742                 _CompArg&&... __comp)
0743       : __containers_{.keys = std::make_obj_using_allocator<key_container_type>(
0744                           __alloc, std::forward<_KeyCont>(__key_cont)),
0745                       .values = std::make_obj_using_allocator<mapped_container_type>(
0746                           __alloc, std::forward<_MappedCont>(__mapped_cont))},
0747         __compare_(std::forward<_CompArg>(__comp)...) {}
0748 
0749   template <class _Allocator, class... _CompArg>
0750     requires __allocator_ctor_constraint<_Allocator>
0751   _LIBCPP_HIDE_FROM_ABI flat_multimap(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp)
0752       : __containers_{.keys   = std::make_obj_using_allocator<key_container_type>(__alloc),
0753                       .values = std::make_obj_using_allocator<mapped_container_type>(__alloc)},
0754         __compare_(std::forward<_CompArg>(__comp)...) {}
0755 
0756   _LIBCPP_HIDE_FROM_ABI bool __is_sorted(auto&& __key_container) const {
0757     return ranges::is_sorted(__key_container, __compare_);
0758   }
0759 
0760   _LIBCPP_HIDE_FROM_ABI void __sort() {
0761     auto __zv = ranges::views::zip(__containers_.keys, __containers_.values);
0762     ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); });
0763   }
0764 
0765   template <class _Self, class _KeyIter>
0766   _LIBCPP_HIDE_FROM_ABI static auto __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) {
0767     return __self.__containers_.values.begin() +
0768            static_cast<ranges::range_difference_t<mapped_container_type>>(
0769                ranges::distance(__self.__containers_.keys.begin(), __key_iter));
0770   }
0771 
0772   template <bool _WasSorted, class _InputIterator, class _Sentinel>
0773   _LIBCPP_HIDE_FROM_ABI void __append_sort_merge(_InputIterator __first, _Sentinel __last) {
0774     auto __on_failure     = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
0775     size_t __num_appended = __flat_map_utils::__append(*this, std::move(__first), std::move(__last));
0776     if (__num_appended != 0) {
0777       auto __zv                  = ranges::views::zip(__containers_.keys, __containers_.values);
0778       auto __append_start_offset = __containers_.keys.size() - __num_appended;
0779       auto __end                 = __zv.end();
0780       auto __compare_key         = [this](const auto& __p1, const auto& __p2) {
0781         return __compare_(std::get<0>(__p1), std::get<0>(__p2));
0782       };
0783       if constexpr (!_WasSorted) {
0784         ranges::sort(__zv.begin() + __append_start_offset, __end, __compare_key);
0785       } else {
0786         _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
0787             __is_sorted(__containers_.keys | ranges::views::drop(__append_start_offset)),
0788             "Key container is not sorted");
0789       }
0790       ranges::inplace_merge(__zv.begin(), __zv.begin() + __append_start_offset, __end, __compare_key);
0791     }
0792     __on_failure.__complete();
0793   }
0794 
0795   template <class _Self, class _Kp>
0796   _LIBCPP_HIDE_FROM_ABI static auto __find_impl(_Self&& __self, const _Kp& __key) {
0797     auto __it   = __self.lower_bound(__key);
0798     auto __last = __self.end();
0799     if (__it == __last || __self.__compare_(__key, __it->first)) {
0800       return __last;
0801     }
0802     return __it;
0803   }
0804 
0805   template <class _Self, class _Kp>
0806   _LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) {
0807     auto [__key_first, __key_last] = ranges::equal_range(__self.__containers_.keys, __key, __self.__compare_);
0808 
0809     using __iterator_type = ranges::iterator_t<decltype(__self)>;
0810     return std::make_pair(__iterator_type(__key_first, __corresponding_mapped_it(__self, __key_first)),
0811                           __iterator_type(__key_last, __corresponding_mapped_it(__self, __key_last)));
0812   }
0813 
0814   template <class _Res, class _Self, class _Kp>
0815   _LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) {
0816     auto __key_iter    = ranges::lower_bound(__self.__containers_.keys, __x, __self.__compare_);
0817     auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter);
0818     return _Res(std::move(__key_iter), std::move(__mapped_iter));
0819   }
0820 
0821   template <class _Res, class _Self, class _Kp>
0822   _LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) {
0823     auto __key_iter    = ranges::upper_bound(__self.__containers_.keys, __x, __self.__compare_);
0824     auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter);
0825     return _Res(std::move(__key_iter), std::move(__mapped_iter));
0826   }
0827 
0828   _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __size) {
0829     if constexpr (requires { __containers_.keys.reserve(__size); }) {
0830       __containers_.keys.reserve(__size);
0831     }
0832 
0833     if constexpr (requires { __containers_.values.reserve(__size); }) {
0834       __containers_.values.reserve(__size);
0835     }
0836   }
0837 
0838   template <class _KIter, class _MIter>
0839   _LIBCPP_HIDE_FROM_ABI iterator __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) {
0840     auto __on_failure  = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
0841     auto __key_iter    = __containers_.keys.erase(__key_iter_to_remove);
0842     auto __mapped_iter = __containers_.values.erase(__mapped_iter_to_remove);
0843     __on_failure.__complete();
0844     return iterator(std::move(__key_iter), std::move(__mapped_iter));
0845   }
0846 
0847   template <class _Key2, class _Tp2, class _Compare2, class _KeyContainer2, class _MappedContainer2, class _Predicate>
0848   friend typename flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type
0849   erase_if(flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate);
0850 
0851   friend __flat_map_utils;
0852 
0853   containers __containers_;
0854   _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_;
0855 
0856   struct __key_equiv {
0857     _LIBCPP_HIDE_FROM_ABI __key_equiv(key_compare __c) : __comp_(__c) {}
0858     _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const {
0859       return !__comp_(std::get<0>(__x), std::get<0>(__y)) && !__comp_(std::get<0>(__y), std::get<0>(__x));
0860     }
0861     key_compare __comp_;
0862   };
0863 };
0864 
0865 template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>>
0866   requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
0867            !__is_allocator<_MappedContainer>::value &&
0868            is_invocable_v<const _Compare&,
0869                           const typename _KeyContainer::value_type&,
0870                           const typename _KeyContainer::value_type&>)
0871 flat_multimap(_KeyContainer, _MappedContainer, _Compare = _Compare())
0872     -> flat_multimap<typename _KeyContainer::value_type,
0873                      typename _MappedContainer::value_type,
0874                      _Compare,
0875                      _KeyContainer,
0876                      _MappedContainer>;
0877 
0878 template <class _KeyContainer, class _MappedContainer, class _Allocator>
0879   requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
0880            !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value)
0881 flat_multimap(_KeyContainer, _MappedContainer, _Allocator)
0882     -> flat_multimap<typename _KeyContainer::value_type,
0883                      typename _MappedContainer::value_type,
0884                      less<typename _KeyContainer::value_type>,
0885                      _KeyContainer,
0886                      _MappedContainer>;
0887 
0888 template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator>
0889   requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
0890            !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> &&
0891            uses_allocator_v<_MappedContainer, _Allocator> &&
0892            is_invocable_v<const _Compare&,
0893                           const typename _KeyContainer::value_type&,
0894                           const typename _KeyContainer::value_type&>)
0895 flat_multimap(_KeyContainer, _MappedContainer, _Compare, _Allocator)
0896     -> flat_multimap<typename _KeyContainer::value_type,
0897                      typename _MappedContainer::value_type,
0898                      _Compare,
0899                      _KeyContainer,
0900                      _MappedContainer>;
0901 
0902 template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>>
0903   requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
0904            !__is_allocator<_MappedContainer>::value &&
0905            is_invocable_v<const _Compare&,
0906                           const typename _KeyContainer::value_type&,
0907                           const typename _KeyContainer::value_type&>)
0908 flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Compare = _Compare())
0909     -> flat_multimap<typename _KeyContainer::value_type,
0910                      typename _MappedContainer::value_type,
0911                      _Compare,
0912                      _KeyContainer,
0913                      _MappedContainer>;
0914 
0915 template <class _KeyContainer, class _MappedContainer, class _Allocator>
0916   requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> &&
0917            !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value)
0918 flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Allocator)
0919     -> flat_multimap<typename _KeyContainer::value_type,
0920                      typename _MappedContainer::value_type,
0921                      less<typename _KeyContainer::value_type>,
0922                      _KeyContainer,
0923                      _MappedContainer>;
0924 
0925 template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator>
0926   requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
0927            !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> &&
0928            uses_allocator_v<_MappedContainer, _Allocator> &&
0929            is_invocable_v<const _Compare&,
0930                           const typename _KeyContainer::value_type&,
0931                           const typename _KeyContainer::value_type&>)
0932 flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Compare, _Allocator)
0933     -> flat_multimap<typename _KeyContainer::value_type,
0934                      typename _MappedContainer::value_type,
0935                      _Compare,
0936                      _KeyContainer,
0937                      _MappedContainer>;
0938 
0939 template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>>
0940   requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
0941 flat_multimap(_InputIterator, _InputIterator, _Compare = _Compare())
0942     -> flat_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>;
0943 
0944 template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>>
0945   requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
0946 flat_multimap(sorted_equivalent_t, _InputIterator, _InputIterator, _Compare = _Compare())
0947     -> flat_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>;
0948 
0949 template <ranges::input_range _Range,
0950           class _Compare   = less<__range_key_type<_Range>>,
0951           class _Allocator = allocator<byte>,
0952           class            = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
0953 flat_multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_multimap<
0954     __range_key_type<_Range>,
0955     __range_mapped_type<_Range>,
0956     _Compare,
0957     vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
0958     vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
0959 
0960 template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>>
0961 flat_multimap(from_range_t, _Range&&, _Allocator) -> flat_multimap<
0962     __range_key_type<_Range>,
0963     __range_mapped_type<_Range>,
0964     less<__range_key_type<_Range>>,
0965     vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
0966     vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
0967 
0968 template <class _Key, class _Tp, class _Compare = less<_Key>>
0969   requires(!__is_allocator<_Compare>::value)
0970 flat_multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) -> flat_multimap<_Key, _Tp, _Compare>;
0971 
0972 template <class _Key, class _Tp, class _Compare = less<_Key>>
0973   requires(!__is_allocator<_Compare>::value)
0974 flat_multimap(sorted_equivalent_t, initializer_list<pair<_Key, _Tp>>, _Compare = _Compare())
0975     -> flat_multimap<_Key, _Tp, _Compare>;
0976 
0977 template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Allocator>
0978 struct uses_allocator<flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>, _Allocator>
0979     : bool_constant<uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator>> {};
0980 
0981 template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Predicate>
0982 _LIBCPP_HIDE_FROM_ABI typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type
0983 erase_if(flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_multimap, _Predicate __pred) {
0984   auto __zv     = ranges::views::zip(__flat_multimap.__containers_.keys, __flat_multimap.__containers_.values);
0985   auto __first  = __zv.begin();
0986   auto __last   = __zv.end();
0987   auto __guard  = std::__make_exception_guard([&] { __flat_multimap.clear(); });
0988   auto __it     = std::remove_if(__first, __last, [&](auto&& __zipped) -> bool {
0989     using _Ref = typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::const_reference;
0990     return __pred(_Ref(std::get<0>(__zipped), std::get<1>(__zipped)));
0991   });
0992   auto __res    = __last - __it;
0993   auto __offset = __it - __first;
0994 
0995   const auto __erase_container = [&](auto& __cont) { __cont.erase(__cont.begin() + __offset, __cont.end()); };
0996 
0997   __erase_container(__flat_multimap.__containers_.keys);
0998   __erase_container(__flat_multimap.__containers_.values);
0999 
1000   __guard.__complete();
1001   return __res;
1002 }
1003 
1004 _LIBCPP_END_NAMESPACE_STD
1005 
1006 #endif // _LIBCPP_STD_VER >= 23
1007 
1008 _LIBCPP_POP_MACROS
1009 
1010 #endif // _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H