File indexing completed on 2026-05-03 08:13:48
0001
0002
0003
0004
0005
0006
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
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>;
0110 using const_iterator = __iterator<true>;
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
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
0150
0151
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
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
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
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
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
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
0389
0390
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() ; });
0397 auto __clear_self_guard = std::__make_exception_guard([&]() noexcept { clear() ; });
0398 __containers_ = std::move(__other.__containers_);
0399 __compare_ = std::move(__other.__compare_);
0400 __clear_self_guard.__complete();
0401 return *this;
0402 }
0403
0404
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
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
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
0467 } else if (__prev_larger && !__next_smaller) {
0468
0469
0470
0471
0472
0473
0474
0475
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
0482
0483
0484
0485
0486
0487
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< 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< 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< 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() ; });
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() ; });
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() ; });
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
0605
0606
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
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
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() ; });
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() ; });
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
1007
1008 _LIBCPP_POP_MACROS
1009
1010 #endif