1*700637cbSDimitry Andric // -*- C++ -*- 2*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 3*700637cbSDimitry Andric // 4*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*700637cbSDimitry Andric // 8*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 9*700637cbSDimitry Andric 10*700637cbSDimitry Andric #ifndef _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H 11*700637cbSDimitry Andric #define _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H 12*700637cbSDimitry Andric 13*700637cbSDimitry Andric #include <__algorithm/equal_range.h> 14*700637cbSDimitry Andric #include <__algorithm/lexicographical_compare_three_way.h> 15*700637cbSDimitry Andric #include <__algorithm/lower_bound.h> 16*700637cbSDimitry Andric #include <__algorithm/min.h> 17*700637cbSDimitry Andric #include <__algorithm/ranges_equal.h> 18*700637cbSDimitry Andric #include <__algorithm/ranges_inplace_merge.h> 19*700637cbSDimitry Andric #include <__algorithm/ranges_is_sorted.h> 20*700637cbSDimitry Andric #include <__algorithm/ranges_sort.h> 21*700637cbSDimitry Andric #include <__algorithm/remove_if.h> 22*700637cbSDimitry Andric #include <__algorithm/upper_bound.h> 23*700637cbSDimitry Andric #include <__assert> 24*700637cbSDimitry Andric #include <__compare/synth_three_way.h> 25*700637cbSDimitry Andric #include <__concepts/convertible_to.h> 26*700637cbSDimitry Andric #include <__concepts/swappable.h> 27*700637cbSDimitry Andric #include <__config> 28*700637cbSDimitry Andric #include <__cstddef/byte.h> 29*700637cbSDimitry Andric #include <__cstddef/ptrdiff_t.h> 30*700637cbSDimitry Andric #include <__flat_map/key_value_iterator.h> 31*700637cbSDimitry Andric #include <__flat_map/sorted_equivalent.h> 32*700637cbSDimitry Andric #include <__flat_map/utils.h> 33*700637cbSDimitry Andric #include <__functional/invoke.h> 34*700637cbSDimitry Andric #include <__functional/is_transparent.h> 35*700637cbSDimitry Andric #include <__functional/operations.h> 36*700637cbSDimitry Andric #include <__fwd/vector.h> 37*700637cbSDimitry Andric #include <__iterator/concepts.h> 38*700637cbSDimitry Andric #include <__iterator/distance.h> 39*700637cbSDimitry Andric #include <__iterator/iterator_traits.h> 40*700637cbSDimitry Andric #include <__iterator/ranges_iterator_traits.h> 41*700637cbSDimitry Andric #include <__iterator/reverse_iterator.h> 42*700637cbSDimitry Andric #include <__memory/allocator_traits.h> 43*700637cbSDimitry Andric #include <__memory/uses_allocator.h> 44*700637cbSDimitry Andric #include <__memory/uses_allocator_construction.h> 45*700637cbSDimitry Andric #include <__ranges/access.h> 46*700637cbSDimitry Andric #include <__ranges/concepts.h> 47*700637cbSDimitry Andric #include <__ranges/container_compatible_range.h> 48*700637cbSDimitry Andric #include <__ranges/drop_view.h> 49*700637cbSDimitry Andric #include <__ranges/from_range.h> 50*700637cbSDimitry Andric #include <__ranges/ref_view.h> 51*700637cbSDimitry Andric #include <__ranges/size.h> 52*700637cbSDimitry Andric #include <__ranges/subrange.h> 53*700637cbSDimitry Andric #include <__ranges/zip_view.h> 54*700637cbSDimitry Andric #include <__type_traits/conjunction.h> 55*700637cbSDimitry Andric #include <__type_traits/container_traits.h> 56*700637cbSDimitry Andric #include <__type_traits/invoke.h> 57*700637cbSDimitry Andric #include <__type_traits/is_allocator.h> 58*700637cbSDimitry Andric #include <__type_traits/is_nothrow_constructible.h> 59*700637cbSDimitry Andric #include <__type_traits/is_same.h> 60*700637cbSDimitry Andric #include <__type_traits/maybe_const.h> 61*700637cbSDimitry Andric #include <__utility/exception_guard.h> 62*700637cbSDimitry Andric #include <__utility/move.h> 63*700637cbSDimitry Andric #include <__utility/pair.h> 64*700637cbSDimitry Andric #include <__utility/scope_guard.h> 65*700637cbSDimitry Andric #include <__vector/vector.h> 66*700637cbSDimitry Andric #include <initializer_list> 67*700637cbSDimitry Andric #include <stdexcept> 68*700637cbSDimitry Andric 69*700637cbSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 70*700637cbSDimitry Andric # pragma GCC system_header 71*700637cbSDimitry Andric #endif 72*700637cbSDimitry Andric 73*700637cbSDimitry Andric _LIBCPP_PUSH_MACROS 74*700637cbSDimitry Andric #include <__undef_macros> 75*700637cbSDimitry Andric 76*700637cbSDimitry Andric #if _LIBCPP_STD_VER >= 23 77*700637cbSDimitry Andric 78*700637cbSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 79*700637cbSDimitry Andric 80*700637cbSDimitry Andric template <class _Key, 81*700637cbSDimitry Andric class _Tp, 82*700637cbSDimitry Andric class _Compare = less<_Key>, 83*700637cbSDimitry Andric class _KeyContainer = vector<_Key>, 84*700637cbSDimitry Andric class _MappedContainer = vector<_Tp>> 85*700637cbSDimitry Andric class flat_multimap { 86*700637cbSDimitry Andric template <class, class, class, class, class> 87*700637cbSDimitry Andric friend class flat_multimap; 88*700637cbSDimitry Andric 89*700637cbSDimitry Andric static_assert(is_same_v<_Key, typename _KeyContainer::value_type>); 90*700637cbSDimitry Andric static_assert(is_same_v<_Tp, typename _MappedContainer::value_type>); 91*700637cbSDimitry Andric static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container"); 92*700637cbSDimitry Andric static_assert(!is_same_v<_MappedContainer, std::vector<bool>>, "vector<bool> is not a sequence container"); 93*700637cbSDimitry Andric 94*700637cbSDimitry Andric template <bool _Const> 95*700637cbSDimitry Andric using __iterator _LIBCPP_NODEBUG = __key_value_iterator<flat_multimap, _KeyContainer, _MappedContainer, _Const>; 96*700637cbSDimitry Andric 97*700637cbSDimitry Andric public: 98*700637cbSDimitry Andric // types 99*700637cbSDimitry Andric using key_type = _Key; 100*700637cbSDimitry Andric using mapped_type = _Tp; 101*700637cbSDimitry Andric using value_type = pair<key_type, mapped_type>; 102*700637cbSDimitry Andric using key_compare = __type_identity_t<_Compare>; 103*700637cbSDimitry Andric using reference = pair<const key_type&, mapped_type&>; 104*700637cbSDimitry Andric using const_reference = pair<const key_type&, const mapped_type&>; 105*700637cbSDimitry Andric using size_type = size_t; 106*700637cbSDimitry Andric using difference_type = ptrdiff_t; 107*700637cbSDimitry Andric using iterator = __iterator<false>; // see [container.requirements] 108*700637cbSDimitry Andric using const_iterator = __iterator<true>; // see [container.requirements] 109*700637cbSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 110*700637cbSDimitry Andric using const_reverse_iterator = std::reverse_iterator<const_iterator>; 111*700637cbSDimitry Andric using key_container_type = _KeyContainer; 112*700637cbSDimitry Andric using mapped_container_type = _MappedContainer; 113*700637cbSDimitry Andric 114*700637cbSDimitry Andric class value_compare { 115*700637cbSDimitry Andric private: 116*700637cbSDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS key_compare __comp_; value_compare(key_compare __c)117*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : __comp_(__c) {} 118*700637cbSDimitry Andric friend flat_multimap; 119*700637cbSDimitry Andric 120*700637cbSDimitry Andric public: operator()121*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const { 122*700637cbSDimitry Andric return __comp_(__x.first, __y.first); 123*700637cbSDimitry Andric } 124*700637cbSDimitry Andric }; 125*700637cbSDimitry Andric 126*700637cbSDimitry Andric struct containers { 127*700637cbSDimitry Andric key_container_type keys; 128*700637cbSDimitry Andric mapped_container_type values; 129*700637cbSDimitry Andric }; 130*700637cbSDimitry Andric 131*700637cbSDimitry Andric private: 132*700637cbSDimitry Andric template <class _Allocator> 133*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool __allocator_ctor_constraint = 134*700637cbSDimitry Andric _And<uses_allocator<key_container_type, _Allocator>, uses_allocator<mapped_container_type, _Allocator>>::value; 135*700637cbSDimitry Andric 136*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_compare_transparent = __is_transparent_v<_Compare>; 137*700637cbSDimitry Andric 138*700637cbSDimitry Andric public: 139*700637cbSDimitry Andric // [flat.map.cons], construct/copy/destroy flat_multimap()140*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap() noexcept( 141*700637cbSDimitry Andric is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_MappedContainer> && 142*700637cbSDimitry Andric is_nothrow_default_constructible_v<_Compare>) 143*700637cbSDimitry Andric : __containers_(), __compare_() {} 144*700637cbSDimitry Andric 145*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap&) = default; 146*700637cbSDimitry Andric 147*700637cbSDimitry Andric // The copy/move constructors are not specified in the spec, which means they should be defaulted. 148*700637cbSDimitry Andric // However, the move constructor can potentially leave a moved-from object in an inconsistent 149*700637cbSDimitry Andric // state if an exception is thrown. flat_multimap(flat_multimap && __other)150*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(flat_multimap&& __other) noexcept( 151*700637cbSDimitry Andric is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_MappedContainer> && 152*700637cbSDimitry Andric is_nothrow_move_constructible_v<_Compare>) 153*700637cbSDimitry Andric # if _LIBCPP_HAS_EXCEPTIONS 154*700637cbSDimitry Andric try 155*700637cbSDimitry Andric # endif // _LIBCPP_HAS_EXCEPTIONS 156*700637cbSDimitry Andric : __containers_(std::move(__other.__containers_)), __compare_(std::move(__other.__compare_)) { 157*700637cbSDimitry Andric __other.clear(); 158*700637cbSDimitry Andric # if _LIBCPP_HAS_EXCEPTIONS 159*700637cbSDimitry Andric } catch (...) { 160*700637cbSDimitry Andric __other.clear(); 161*700637cbSDimitry Andric // gcc does not like the `throw` keyword in a conditionally noexcept function 162*700637cbSDimitry Andric if constexpr (!(is_nothrow_move_constructible_v<_KeyContainer> && 163*700637cbSDimitry Andric is_nothrow_move_constructible_v<_MappedContainer> && is_nothrow_move_constructible_v<_Compare>)) { 164*700637cbSDimitry Andric throw; 165*700637cbSDimitry Andric } 166*700637cbSDimitry Andric # endif // _LIBCPP_HAS_EXCEPTIONS 167*700637cbSDimitry Andric } 168*700637cbSDimitry Andric 169*700637cbSDimitry Andric template <class _Allocator> 170*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(const flat_multimap & __other,const _Allocator & __alloc)171*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap& __other, const _Allocator& __alloc) 172*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_tag{}, 173*700637cbSDimitry Andric __alloc, 174*700637cbSDimitry Andric __other.__containers_.keys, 175*700637cbSDimitry Andric __other.__containers_.values, 176*700637cbSDimitry Andric __other.__compare_) {} 177*700637cbSDimitry Andric 178*700637cbSDimitry Andric template <class _Allocator> 179*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(flat_multimap && __other,const _Allocator & __alloc)180*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(flat_multimap&& __other, const _Allocator& __alloc) 181*700637cbSDimitry Andric # if _LIBCPP_HAS_EXCEPTIONS 182*700637cbSDimitry Andric try 183*700637cbSDimitry Andric # endif // _LIBCPP_HAS_EXCEPTIONS 184*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_tag{}, 185*700637cbSDimitry Andric __alloc, 186*700637cbSDimitry Andric std::move(__other.__containers_.keys), 187*700637cbSDimitry Andric std::move(__other.__containers_.values), 188*700637cbSDimitry Andric std::move(__other.__compare_)) { 189*700637cbSDimitry Andric __other.clear(); 190*700637cbSDimitry Andric # if _LIBCPP_HAS_EXCEPTIONS catch(...)191*700637cbSDimitry Andric } catch (...) { 192*700637cbSDimitry Andric __other.clear(); 193*700637cbSDimitry Andric throw; 194*700637cbSDimitry Andric # endif // _LIBCPP_HAS_EXCEPTIONS 195*700637cbSDimitry Andric } 196*700637cbSDimitry Andric 197*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap( 198*700637cbSDimitry Andric key_container_type __key_cont, mapped_container_type __mapped_cont, const key_compare& __comp = key_compare()) 199*700637cbSDimitry Andric : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) { 200*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 201*700637cbSDimitry Andric "flat_multimap keys and mapped containers have different size"); 202*700637cbSDimitry Andric __sort(); 203*700637cbSDimitry Andric } 204*700637cbSDimitry Andric 205*700637cbSDimitry Andric template <class _Allocator> 206*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(const key_container_type & __key_cont,const mapped_container_type & __mapped_cont,const _Allocator & __alloc)207*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap( 208*700637cbSDimitry Andric const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const _Allocator& __alloc) 209*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { 210*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 211*700637cbSDimitry Andric "flat_multimap keys and mapped containers have different size"); 212*700637cbSDimitry Andric __sort(); 213*700637cbSDimitry Andric } 214*700637cbSDimitry Andric 215*700637cbSDimitry Andric template <class _Allocator> 216*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 217*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(const key_container_type & __key_cont,const mapped_container_type & __mapped_cont,const key_compare & __comp,const _Allocator & __alloc)218*700637cbSDimitry Andric flat_multimap(const key_container_type& __key_cont, 219*700637cbSDimitry Andric const mapped_container_type& __mapped_cont, 220*700637cbSDimitry Andric const key_compare& __comp, 221*700637cbSDimitry Andric const _Allocator& __alloc) 222*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) { 223*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 224*700637cbSDimitry Andric "flat_multimap keys and mapped containers have different size"); 225*700637cbSDimitry Andric __sort(); 226*700637cbSDimitry Andric } 227*700637cbSDimitry Andric 228*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI 229*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, 230*700637cbSDimitry Andric key_container_type __key_cont, 231*700637cbSDimitry Andric mapped_container_type __mapped_cont, 232*700637cbSDimitry Andric const key_compare& __comp = key_compare()) 233*700637cbSDimitry Andric : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) { 234*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 235*700637cbSDimitry Andric "flat_multimap keys and mapped containers have different size"); 236*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted"); 237*700637cbSDimitry Andric } 238*700637cbSDimitry Andric 239*700637cbSDimitry Andric template <class _Allocator> 240*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 241*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(sorted_equivalent_t,const key_container_type & __key_cont,const mapped_container_type & __mapped_cont,const _Allocator & __alloc)242*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, 243*700637cbSDimitry Andric const key_container_type& __key_cont, 244*700637cbSDimitry Andric const mapped_container_type& __mapped_cont, 245*700637cbSDimitry Andric const _Allocator& __alloc) 246*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { 247*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 248*700637cbSDimitry Andric "flat_multimap keys and mapped containers have different size"); 249*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted"); 250*700637cbSDimitry Andric } 251*700637cbSDimitry Andric 252*700637cbSDimitry Andric template <class _Allocator> 253*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 254*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(sorted_equivalent_t,const key_container_type & __key_cont,const mapped_container_type & __mapped_cont,const key_compare & __comp,const _Allocator & __alloc)255*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, 256*700637cbSDimitry Andric const key_container_type& __key_cont, 257*700637cbSDimitry Andric const mapped_container_type& __mapped_cont, 258*700637cbSDimitry Andric const key_compare& __comp, 259*700637cbSDimitry Andric const _Allocator& __alloc) 260*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) { 261*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 262*700637cbSDimitry Andric "flat_multimap keys and mapped containers have different size"); 263*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted"); 264*700637cbSDimitry Andric } 265*700637cbSDimitry Andric flat_multimap(const key_compare & __comp)266*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const key_compare& __comp) : __containers_(), __compare_(__comp) {} 267*700637cbSDimitry Andric 268*700637cbSDimitry Andric template <class _Allocator> 269*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(const key_compare & __comp,const _Allocator & __alloc)270*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(const key_compare& __comp, const _Allocator& __alloc) 271*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {} 272*700637cbSDimitry Andric 273*700637cbSDimitry Andric template <class _Allocator> 274*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(const _Allocator & __alloc)275*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const _Allocator& __alloc) 276*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {} 277*700637cbSDimitry Andric 278*700637cbSDimitry Andric template <class _InputIterator> 279*700637cbSDimitry Andric requires __has_input_iterator_category<_InputIterator>::value 280*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI 281*700637cbSDimitry Andric flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) __containers_()282*700637cbSDimitry Andric : __containers_(), __compare_(__comp) { 283*700637cbSDimitry Andric insert(__first, __last); 284*700637cbSDimitry Andric } 285*700637cbSDimitry Andric 286*700637cbSDimitry Andric template <class _InputIterator, class _Allocator> requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)287*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 288*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI 289*700637cbSDimitry Andric flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc) 290*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { 291*700637cbSDimitry Andric insert(__first, __last); 292*700637cbSDimitry Andric } 293*700637cbSDimitry Andric 294*700637cbSDimitry Andric template <class _InputIterator, class _Allocator> requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)295*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 296*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) 297*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) { 298*700637cbSDimitry Andric insert(__first, __last); 299*700637cbSDimitry Andric } 300*700637cbSDimitry Andric 301*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range> flat_multimap(from_range_t __fr,_Range && __rg)302*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t __fr, _Range&& __rg) 303*700637cbSDimitry Andric : flat_multimap(__fr, std::forward<_Range>(__rg), key_compare()) {} 304*700637cbSDimitry Andric 305*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range, class _Allocator> 306*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(from_range_t,_Range && __rg,const _Allocator & __alloc)307*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const _Allocator& __alloc) 308*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) { 309*700637cbSDimitry Andric insert_range(std::forward<_Range>(__rg)); 310*700637cbSDimitry Andric } 311*700637cbSDimitry Andric 312*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range> flat_multimap(from_range_t,_Range && __rg,const key_compare & __comp)313*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_multimap(__comp) { 314*700637cbSDimitry Andric insert_range(std::forward<_Range>(__rg)); 315*700637cbSDimitry Andric } 316*700637cbSDimitry Andric 317*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range, class _Allocator> 318*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(from_range_t,_Range && __rg,const key_compare & __comp,const _Allocator & __alloc)319*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) 320*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { 321*700637cbSDimitry Andric insert_range(std::forward<_Range>(__rg)); 322*700637cbSDimitry Andric } 323*700637cbSDimitry Andric 324*700637cbSDimitry Andric template <class _InputIterator> 325*700637cbSDimitry Andric requires __has_input_iterator_category<_InputIterator>::value 326*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap( 327*700637cbSDimitry Andric sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) __containers_()328*700637cbSDimitry Andric : __containers_(), __compare_(__comp) { 329*700637cbSDimitry Andric insert(sorted_equivalent, __first, __last); 330*700637cbSDimitry Andric } 331*700637cbSDimitry Andric template <class _InputIterator, class _Allocator> requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)332*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 333*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI 334*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, 335*700637cbSDimitry Andric _InputIterator __first, 336*700637cbSDimitry Andric _InputIterator __last, 337*700637cbSDimitry Andric const key_compare& __comp, 338*700637cbSDimitry Andric const _Allocator& __alloc) 339*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { 340*700637cbSDimitry Andric insert(sorted_equivalent, __first, __last); 341*700637cbSDimitry Andric } 342*700637cbSDimitry Andric 343*700637cbSDimitry Andric template <class _InputIterator, class _Allocator> requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)344*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 345*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI 346*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc) 347*700637cbSDimitry Andric : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) { 348*700637cbSDimitry Andric insert(sorted_equivalent, __first, __last); 349*700637cbSDimitry Andric } 350*700637cbSDimitry Andric 351*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare()) 352*700637cbSDimitry Andric : flat_multimap(__il.begin(), __il.end(), __comp) {} 353*700637cbSDimitry Andric 354*700637cbSDimitry Andric template <class _Allocator> 355*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 356*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(initializer_list<value_type> __il,const key_compare & __comp,const _Allocator & __alloc)357*700637cbSDimitry Andric flat_multimap(initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc) 358*700637cbSDimitry Andric : flat_multimap(__il.begin(), __il.end(), __comp, __alloc) {} 359*700637cbSDimitry Andric 360*700637cbSDimitry Andric template <class _Allocator> 361*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(initializer_list<value_type> __il,const _Allocator & __alloc)362*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(initializer_list<value_type> __il, const _Allocator& __alloc) 363*700637cbSDimitry Andric : flat_multimap(__il.begin(), __il.end(), __alloc) {} 364*700637cbSDimitry Andric 365*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI 366*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, initializer_list<value_type> __il, const key_compare& __comp = key_compare()) 367*700637cbSDimitry Andric : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __comp) {} 368*700637cbSDimitry Andric 369*700637cbSDimitry Andric template <class _Allocator> 370*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(sorted_equivalent_t,initializer_list<value_type> __il,const key_compare & __comp,const _Allocator & __alloc)371*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap( 372*700637cbSDimitry Andric sorted_equivalent_t, initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc) 373*700637cbSDimitry Andric : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __comp, __alloc) {} 374*700637cbSDimitry Andric 375*700637cbSDimitry Andric template <class _Allocator> 376*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(sorted_equivalent_t,initializer_list<value_type> __il,const _Allocator & __alloc)377*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(sorted_equivalent_t, initializer_list<value_type> __il, const _Allocator& __alloc) 378*700637cbSDimitry Andric : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __alloc) {} 379*700637cbSDimitry Andric 380*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(initializer_list<value_type> __il) { 381*700637cbSDimitry Andric clear(); 382*700637cbSDimitry Andric insert(__il); 383*700637cbSDimitry Andric return *this; 384*700637cbSDimitry Andric } 385*700637cbSDimitry Andric 386*700637cbSDimitry Andric // copy/move assignment are not specified in the spec (defaulted) 387*700637cbSDimitry Andric // but move assignment can potentially leave moved from object in an inconsistent 388*700637cbSDimitry Andric // state if an exception is thrown 389*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(const flat_multimap&) = default; 390*700637cbSDimitry Andric noexcept(is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> && is_nothrow_move_assignable_v<_Compare>)391*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(flat_multimap&& __other) noexcept( 392*700637cbSDimitry Andric is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> && 393*700637cbSDimitry Andric is_nothrow_move_assignable_v<_Compare>) { 394*700637cbSDimitry Andric auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; }); 395*700637cbSDimitry Andric auto __clear_self_guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 396*700637cbSDimitry Andric __containers_ = std::move(__other.__containers_); 397*700637cbSDimitry Andric __compare_ = std::move(__other.__compare_); 398*700637cbSDimitry Andric __clear_self_guard.__complete(); 399*700637cbSDimitry Andric return *this; 400*700637cbSDimitry Andric } 401*700637cbSDimitry Andric 402*700637cbSDimitry Andric // iterators begin()403*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator begin() noexcept { 404*700637cbSDimitry Andric return iterator(__containers_.keys.begin(), __containers_.values.begin()); 405*700637cbSDimitry Andric } 406*700637cbSDimitry Andric begin()407*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { 408*700637cbSDimitry Andric return const_iterator(__containers_.keys.begin(), __containers_.values.begin()); 409*700637cbSDimitry Andric } 410*700637cbSDimitry Andric end()411*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator end() noexcept { 412*700637cbSDimitry Andric return iterator(__containers_.keys.end(), __containers_.values.end()); 413*700637cbSDimitry Andric } 414*700637cbSDimitry Andric end()415*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { 416*700637cbSDimitry Andric return const_iterator(__containers_.keys.end(), __containers_.values.end()); 417*700637cbSDimitry Andric } 418*700637cbSDimitry Andric rbegin()419*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } rbegin()420*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } rend()421*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() noexcept { return reverse_iterator(begin()); } rend()422*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } 423*700637cbSDimitry Andric cbegin()424*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return begin(); } cend()425*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return end(); } crbegin()426*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } crend()427*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } 428*700637cbSDimitry Andric 429*700637cbSDimitry Andric // [flat.map.capacity], capacity empty()430*700637cbSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __containers_.keys.empty(); } 431*700637cbSDimitry Andric size()432*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __containers_.keys.size(); } 433*700637cbSDimitry Andric max_size()434*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept { 435*700637cbSDimitry Andric return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size()); 436*700637cbSDimitry Andric } 437*700637cbSDimitry Andric 438*700637cbSDimitry Andric // [flat.map.modifiers], modifiers 439*700637cbSDimitry Andric template <class... _Args> 440*700637cbSDimitry Andric requires is_constructible_v<pair<key_type, mapped_type>, _Args...> && is_move_constructible_v<key_type> && 441*700637cbSDimitry Andric is_move_constructible_v<mapped_type> emplace(_Args &&...__args)442*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) { 443*700637cbSDimitry Andric std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...); 444*700637cbSDimitry Andric auto __key_it = std::upper_bound(__containers_.keys.begin(), __containers_.keys.end(), __pair.first, __compare_); 445*700637cbSDimitry Andric auto __mapped_it = __corresponding_mapped_it(*this, __key_it); 446*700637cbSDimitry Andric 447*700637cbSDimitry Andric return __flat_map_utils::__emplace_exact_pos( 448*700637cbSDimitry Andric *this, std::move(__key_it), std::move(__mapped_it), std::move(__pair.first), std::move(__pair.second)); 449*700637cbSDimitry Andric } 450*700637cbSDimitry Andric 451*700637cbSDimitry Andric template <class... _Args> 452*700637cbSDimitry Andric requires is_constructible_v<pair<key_type, mapped_type>, _Args...> emplace_hint(const_iterator __hint,_Args &&...__args)453*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __hint, _Args&&... __args) { 454*700637cbSDimitry Andric std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...); 455*700637cbSDimitry Andric 456*700637cbSDimitry Andric auto __prev_larger = __hint != cbegin() && __compare_(__pair.first, (__hint - 1)->first); 457*700637cbSDimitry Andric auto __next_smaller = __hint != cend() && __compare_(__hint->first, __pair.first); 458*700637cbSDimitry Andric 459*700637cbSDimitry Andric auto __hint_distance = __hint.__key_iter_ - __containers_.keys.cbegin(); 460*700637cbSDimitry Andric auto __key_iter = __containers_.keys.begin() + __hint_distance; 461*700637cbSDimitry Andric auto __mapped_iter = __containers_.values.begin() + __hint_distance; 462*700637cbSDimitry Andric 463*700637cbSDimitry Andric if (!__prev_larger && !__next_smaller) [[likely]] { 464*700637cbSDimitry Andric // hint correct, just use exact hint iterators 465*700637cbSDimitry Andric } else if (__prev_larger && !__next_smaller) { 466*700637cbSDimitry Andric // the hint position is more to the right than the key should have been. 467*700637cbSDimitry Andric // we want to emplace the element to a position as right as possible 468*700637cbSDimitry Andric // e.g. Insert new element "2" in the following range 469*700637cbSDimitry Andric // 1, 1, 2, 2, 2, 3, 4, 6 470*700637cbSDimitry Andric // ^ 471*700637cbSDimitry Andric // | 472*700637cbSDimitry Andric // hint 473*700637cbSDimitry Andric // We want to insert "2" after the last existing "2" 474*700637cbSDimitry Andric __key_iter = std::upper_bound(__containers_.keys.begin(), __key_iter, __pair.first, __compare_); 475*700637cbSDimitry Andric __mapped_iter = __corresponding_mapped_it(*this, __key_iter); 476*700637cbSDimitry Andric } else { 477*700637cbSDimitry Andric _LIBCPP_ASSERT_INTERNAL(!__prev_larger && __next_smaller, "this means that the multimap is not sorted"); 478*700637cbSDimitry Andric 479*700637cbSDimitry Andric // the hint position is more to the left than the key should have been. 480*700637cbSDimitry Andric // we want to emplace the element to a position as left as possible 481*700637cbSDimitry Andric // 1, 1, 2, 2, 2, 3, 4, 6 482*700637cbSDimitry Andric // ^ 483*700637cbSDimitry Andric // | 484*700637cbSDimitry Andric // hint 485*700637cbSDimitry Andric // We want to insert "2" before the first existing "2" 486*700637cbSDimitry Andric __key_iter = std::lower_bound(__key_iter, __containers_.keys.end(), __pair.first, __compare_); 487*700637cbSDimitry Andric __mapped_iter = __corresponding_mapped_it(*this, __key_iter); 488*700637cbSDimitry Andric } 489*700637cbSDimitry Andric return __flat_map_utils::__emplace_exact_pos( 490*700637cbSDimitry Andric *this, __key_iter, __mapped_iter, std::move(__pair.first), std::move(__pair.second)); 491*700637cbSDimitry Andric } 492*700637cbSDimitry Andric insert(const value_type & __x)493*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return emplace(__x); } 494*700637cbSDimitry Andric insert(value_type && __x)495*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __x) { return emplace(std::move(__x)); } 496*700637cbSDimitry Andric insert(const_iterator __hint,const value_type & __x)497*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, const value_type& __x) { 498*700637cbSDimitry Andric return emplace_hint(__hint, __x); 499*700637cbSDimitry Andric } 500*700637cbSDimitry Andric insert(const_iterator __hint,value_type && __x)501*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, value_type&& __x) { 502*700637cbSDimitry Andric return emplace_hint(__hint, std::move(__x)); 503*700637cbSDimitry Andric } 504*700637cbSDimitry Andric 505*700637cbSDimitry Andric template <class _PairLike> 506*700637cbSDimitry Andric requires is_constructible_v<pair<key_type, mapped_type>, _PairLike> insert(_PairLike && __x)507*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(_PairLike&& __x) { 508*700637cbSDimitry Andric return emplace(std::forward<_PairLike>(__x)); 509*700637cbSDimitry Andric } 510*700637cbSDimitry Andric 511*700637cbSDimitry Andric template <class _PairLike> 512*700637cbSDimitry Andric requires is_constructible_v<pair<key_type, mapped_type>, _PairLike> insert(const_iterator __hint,_PairLike && __x)513*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, _PairLike&& __x) { 514*700637cbSDimitry Andric return emplace_hint(__hint, std::forward<_PairLike>(__x)); 515*700637cbSDimitry Andric } 516*700637cbSDimitry Andric 517*700637cbSDimitry Andric template <class _InputIterator> 518*700637cbSDimitry Andric requires __has_input_iterator_category<_InputIterator>::value insert(_InputIterator __first,_InputIterator __last)519*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) { 520*700637cbSDimitry Andric if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { 521*700637cbSDimitry Andric __reserve(__last - __first); 522*700637cbSDimitry Andric } 523*700637cbSDimitry Andric __append_sort_merge</*WasSorted = */ false>(std::move(__first), std::move(__last)); 524*700637cbSDimitry Andric } 525*700637cbSDimitry Andric 526*700637cbSDimitry Andric template <class _InputIterator> 527*700637cbSDimitry Andric requires __has_input_iterator_category<_InputIterator>::value insert(sorted_equivalent_t,_InputIterator __first,_InputIterator __last)528*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, _InputIterator __first, _InputIterator __last) { 529*700637cbSDimitry Andric if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { 530*700637cbSDimitry Andric __reserve(__last - __first); 531*700637cbSDimitry Andric } 532*700637cbSDimitry Andric 533*700637cbSDimitry Andric __append_sort_merge</*WasSorted = */ true>(std::move(__first), std::move(__last)); 534*700637cbSDimitry Andric } 535*700637cbSDimitry Andric 536*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range> insert_range(_Range && __range)537*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) { 538*700637cbSDimitry Andric if constexpr (ranges::sized_range<_Range>) { 539*700637cbSDimitry Andric __reserve(ranges::size(__range)); 540*700637cbSDimitry Andric } 541*700637cbSDimitry Andric 542*700637cbSDimitry Andric __append_sort_merge</*WasSorted = */ false>(ranges::begin(__range), ranges::end(__range)); 543*700637cbSDimitry Andric } 544*700637cbSDimitry Andric insert(initializer_list<value_type> __il)545*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); } 546*700637cbSDimitry Andric insert(sorted_equivalent_t,initializer_list<value_type> __il)547*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, initializer_list<value_type> __il) { 548*700637cbSDimitry Andric insert(sorted_equivalent, __il.begin(), __il.end()); 549*700637cbSDimitry Andric } 550*700637cbSDimitry Andric extract()551*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI containers extract() && { 552*700637cbSDimitry Andric auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; }); 553*700637cbSDimitry Andric auto __ret = std::move(__containers_); 554*700637cbSDimitry Andric return __ret; 555*700637cbSDimitry Andric } 556*700637cbSDimitry Andric replace(key_container_type && __key_cont,mapped_container_type && __mapped_cont)557*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) { 558*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE( 559*700637cbSDimitry Andric __key_cont.size() == __mapped_cont.size(), "flat_multimap keys and mapped containers have different size"); 560*700637cbSDimitry Andric 561*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__key_cont), "Key container is not sorted"); 562*700637cbSDimitry Andric auto __guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 563*700637cbSDimitry Andric __containers_.keys = std::move(__key_cont); 564*700637cbSDimitry Andric __containers_.values = std::move(__mapped_cont); 565*700637cbSDimitry Andric __guard.__complete(); 566*700637cbSDimitry Andric } 567*700637cbSDimitry Andric erase(iterator __position)568*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __position) { 569*700637cbSDimitry Andric return __erase(__position.__key_iter_, __position.__mapped_iter_); 570*700637cbSDimitry Andric } 571*700637cbSDimitry Andric erase(const_iterator __position)572*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position) { 573*700637cbSDimitry Andric return __erase(__position.__key_iter_, __position.__mapped_iter_); 574*700637cbSDimitry Andric } 575*700637cbSDimitry Andric erase(const key_type & __x)576*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __x) { 577*700637cbSDimitry Andric auto [__first, __last] = equal_range(__x); 578*700637cbSDimitry Andric auto __res = __last - __first; 579*700637cbSDimitry Andric erase(__first, __last); 580*700637cbSDimitry Andric return __res; 581*700637cbSDimitry Andric } 582*700637cbSDimitry Andric 583*700637cbSDimitry Andric template <class _Kp> 584*700637cbSDimitry Andric requires(__is_compare_transparent && !is_convertible_v<_Kp &&, iterator> && 585*700637cbSDimitry Andric !is_convertible_v<_Kp &&, const_iterator>) erase(_Kp && __x)586*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type erase(_Kp&& __x) { 587*700637cbSDimitry Andric auto [__first, __last] = equal_range(__x); 588*700637cbSDimitry Andric auto __res = __last - __first; 589*700637cbSDimitry Andric erase(__first, __last); 590*700637cbSDimitry Andric return __res; 591*700637cbSDimitry Andric } 592*700637cbSDimitry Andric erase(const_iterator __first,const_iterator __last)593*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) { 594*700637cbSDimitry Andric auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 595*700637cbSDimitry Andric auto __key_it = __containers_.keys.erase(__first.__key_iter_, __last.__key_iter_); 596*700637cbSDimitry Andric auto __mapped_it = __containers_.values.erase(__first.__mapped_iter_, __last.__mapped_iter_); 597*700637cbSDimitry Andric __on_failure.__complete(); 598*700637cbSDimitry Andric return iterator(std::move(__key_it), std::move(__mapped_it)); 599*700637cbSDimitry Andric } 600*700637cbSDimitry Andric swap(flat_multimap & __y)601*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void swap(flat_multimap& __y) noexcept { 602*700637cbSDimitry Andric // warning: The spec has unconditional noexcept, which means that 603*700637cbSDimitry Andric // if any of the following functions throw an exception, 604*700637cbSDimitry Andric // std::terminate will be called 605*700637cbSDimitry Andric ranges::swap(__compare_, __y.__compare_); 606*700637cbSDimitry Andric ranges::swap(__containers_.keys, __y.__containers_.keys); 607*700637cbSDimitry Andric ranges::swap(__containers_.values, __y.__containers_.values); 608*700637cbSDimitry Andric } 609*700637cbSDimitry Andric clear()610*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void clear() noexcept { 611*700637cbSDimitry Andric __containers_.keys.clear(); 612*700637cbSDimitry Andric __containers_.values.clear(); 613*700637cbSDimitry Andric } 614*700637cbSDimitry Andric 615*700637cbSDimitry Andric // observers key_comp()616*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __compare_; } value_comp()617*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__compare_); } 618*700637cbSDimitry Andric keys()619*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const key_container_type& keys() const noexcept { return __containers_.keys; } values()620*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const mapped_container_type& values() const noexcept { return __containers_.values; } 621*700637cbSDimitry Andric 622*700637cbSDimitry Andric // map operations find(const key_type & __x)623*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __x) { return __find_impl(*this, __x); } 624*700637cbSDimitry Andric find(const key_type & __x)625*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __x) const { return __find_impl(*this, __x); } 626*700637cbSDimitry Andric 627*700637cbSDimitry Andric template <class _Kp> 628*700637cbSDimitry Andric requires __is_compare_transparent find(const _Kp & __x)629*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator find(const _Kp& __x) { 630*700637cbSDimitry Andric return __find_impl(*this, __x); 631*700637cbSDimitry Andric } 632*700637cbSDimitry Andric 633*700637cbSDimitry Andric template <class _Kp> 634*700637cbSDimitry Andric requires __is_compare_transparent find(const _Kp & __x)635*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Kp& __x) const { 636*700637cbSDimitry Andric return __find_impl(*this, __x); 637*700637cbSDimitry Andric } 638*700637cbSDimitry Andric count(const key_type & __x)639*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __x) const { 640*700637cbSDimitry Andric auto [__first, __last] = equal_range(__x); 641*700637cbSDimitry Andric return __last - __first; 642*700637cbSDimitry Andric } 643*700637cbSDimitry Andric 644*700637cbSDimitry Andric template <class _Kp> 645*700637cbSDimitry Andric requires __is_compare_transparent count(const _Kp & __x)646*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type count(const _Kp& __x) const { 647*700637cbSDimitry Andric auto [__first, __last] = equal_range(__x); 648*700637cbSDimitry Andric return __last - __first; 649*700637cbSDimitry Andric } 650*700637cbSDimitry Andric contains(const key_type & __x)651*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __x) const { return find(__x) != end(); } 652*700637cbSDimitry Andric 653*700637cbSDimitry Andric template <class _Kp> 654*700637cbSDimitry Andric requires __is_compare_transparent contains(const _Kp & __x)655*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool contains(const _Kp& __x) const { 656*700637cbSDimitry Andric return find(__x) != end(); 657*700637cbSDimitry Andric } 658*700637cbSDimitry Andric lower_bound(const key_type & __x)659*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __x) { return __lower_bound<iterator>(*this, __x); } 660*700637cbSDimitry Andric lower_bound(const key_type & __x)661*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __x) const { 662*700637cbSDimitry Andric return __lower_bound<const_iterator>(*this, __x); 663*700637cbSDimitry Andric } 664*700637cbSDimitry Andric 665*700637cbSDimitry Andric template <class _Kp> 666*700637cbSDimitry Andric requires __is_compare_transparent lower_bound(const _Kp & __x)667*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Kp& __x) { 668*700637cbSDimitry Andric return __lower_bound<iterator>(*this, __x); 669*700637cbSDimitry Andric } 670*700637cbSDimitry Andric 671*700637cbSDimitry Andric template <class _Kp> 672*700637cbSDimitry Andric requires __is_compare_transparent lower_bound(const _Kp & __x)673*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Kp& __x) const { 674*700637cbSDimitry Andric return __lower_bound<const_iterator>(*this, __x); 675*700637cbSDimitry Andric } 676*700637cbSDimitry Andric upper_bound(const key_type & __x)677*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __x) { return __upper_bound<iterator>(*this, __x); } 678*700637cbSDimitry Andric upper_bound(const key_type & __x)679*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __x) const { 680*700637cbSDimitry Andric return __upper_bound<const_iterator>(*this, __x); 681*700637cbSDimitry Andric } 682*700637cbSDimitry Andric 683*700637cbSDimitry Andric template <class _Kp> 684*700637cbSDimitry Andric requires __is_compare_transparent upper_bound(const _Kp & __x)685*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Kp& __x) { 686*700637cbSDimitry Andric return __upper_bound<iterator>(*this, __x); 687*700637cbSDimitry Andric } 688*700637cbSDimitry Andric 689*700637cbSDimitry Andric template <class _Kp> 690*700637cbSDimitry Andric requires __is_compare_transparent upper_bound(const _Kp & __x)691*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Kp& __x) const { 692*700637cbSDimitry Andric return __upper_bound<const_iterator>(*this, __x); 693*700637cbSDimitry Andric } 694*700637cbSDimitry Andric equal_range(const key_type & __x)695*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __x) { 696*700637cbSDimitry Andric return __equal_range_impl(*this, __x); 697*700637cbSDimitry Andric } 698*700637cbSDimitry Andric equal_range(const key_type & __x)699*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { 700*700637cbSDimitry Andric return __equal_range_impl(*this, __x); 701*700637cbSDimitry Andric } 702*700637cbSDimitry Andric 703*700637cbSDimitry Andric template <class _Kp> 704*700637cbSDimitry Andric requires __is_compare_transparent equal_range(const _Kp & __x)705*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _Kp& __x) { 706*700637cbSDimitry Andric return __equal_range_impl(*this, __x); 707*700637cbSDimitry Andric } 708*700637cbSDimitry Andric template <class _Kp> 709*700637cbSDimitry Andric requires __is_compare_transparent equal_range(const _Kp & __x)710*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _Kp& __x) const { 711*700637cbSDimitry Andric return __equal_range_impl(*this, __x); 712*700637cbSDimitry Andric } 713*700637cbSDimitry Andric 714*700637cbSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator==(const flat_multimap& __x, const flat_multimap& __y) { 715*700637cbSDimitry Andric return ranges::equal(__x, __y); 716*700637cbSDimitry Andric } 717*700637cbSDimitry Andric 718*700637cbSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_multimap& __x, const flat_multimap& __y) { 719*700637cbSDimitry Andric return std::lexicographical_compare_three_way( 720*700637cbSDimitry Andric __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); 721*700637cbSDimitry Andric } 722*700637cbSDimitry Andric swap(flat_multimap & __x,flat_multimap & __y)723*700637cbSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI void swap(flat_multimap& __x, flat_multimap& __y) noexcept { __x.swap(__y); } 724*700637cbSDimitry Andric 725*700637cbSDimitry Andric private: 726*700637cbSDimitry Andric struct __ctor_uses_allocator_tag { 727*700637cbSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_tag() = default; 728*700637cbSDimitry Andric }; 729*700637cbSDimitry Andric struct __ctor_uses_allocator_empty_tag { 730*700637cbSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_empty_tag() = default; 731*700637cbSDimitry Andric }; 732*700637cbSDimitry Andric 733*700637cbSDimitry Andric template <class _Allocator, class _KeyCont, class _MappedCont, class... _CompArg> 734*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 735*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(__ctor_uses_allocator_tag,const _Allocator & __alloc,_KeyCont && __key_cont,_MappedCont && __mapped_cont,_CompArg &&...__comp)736*700637cbSDimitry Andric flat_multimap(__ctor_uses_allocator_tag, 737*700637cbSDimitry Andric const _Allocator& __alloc, 738*700637cbSDimitry Andric _KeyCont&& __key_cont, 739*700637cbSDimitry Andric _MappedCont&& __mapped_cont, 740*700637cbSDimitry Andric _CompArg&&... __comp) 741*700637cbSDimitry Andric : __containers_{.keys = std::make_obj_using_allocator<key_container_type>( 742*700637cbSDimitry Andric __alloc, std::forward<_KeyCont>(__key_cont)), 743*700637cbSDimitry Andric .values = std::make_obj_using_allocator<mapped_container_type>( 744*700637cbSDimitry Andric __alloc, std::forward<_MappedCont>(__mapped_cont))}, 745*700637cbSDimitry Andric __compare_(std::forward<_CompArg>(__comp)...) {} 746*700637cbSDimitry Andric 747*700637cbSDimitry Andric template <class _Allocator, class... _CompArg> 748*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_multimap(__ctor_uses_allocator_empty_tag,const _Allocator & __alloc,_CompArg &&...__comp)749*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_multimap(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp) 750*700637cbSDimitry Andric : __containers_{.keys = std::make_obj_using_allocator<key_container_type>(__alloc), 751*700637cbSDimitry Andric .values = std::make_obj_using_allocator<mapped_container_type>(__alloc)}, 752*700637cbSDimitry Andric __compare_(std::forward<_CompArg>(__comp)...) {} 753*700637cbSDimitry Andric __is_sorted(auto && __key_container)754*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool __is_sorted(auto&& __key_container) const { 755*700637cbSDimitry Andric return ranges::is_sorted(__key_container, __compare_); 756*700637cbSDimitry Andric } 757*700637cbSDimitry Andric __sort()758*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __sort() { 759*700637cbSDimitry Andric auto __zv = ranges::views::zip(__containers_.keys, __containers_.values); 760*700637cbSDimitry Andric ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); }); 761*700637cbSDimitry Andric } 762*700637cbSDimitry Andric 763*700637cbSDimitry Andric template <class _Self, class _KeyIter> __corresponding_mapped_it(_Self && __self,_KeyIter && __key_iter)764*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static auto __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) { 765*700637cbSDimitry Andric return __self.__containers_.values.begin() + 766*700637cbSDimitry Andric static_cast<ranges::range_difference_t<mapped_container_type>>( 767*700637cbSDimitry Andric ranges::distance(__self.__containers_.keys.begin(), __key_iter)); 768*700637cbSDimitry Andric } 769*700637cbSDimitry Andric 770*700637cbSDimitry Andric template <bool _WasSorted, class _InputIterator, class _Sentinel> __append_sort_merge(_InputIterator __first,_Sentinel __last)771*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __append_sort_merge(_InputIterator __first, _Sentinel __last) { 772*700637cbSDimitry Andric auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 773*700637cbSDimitry Andric size_t __num_appended = __flat_map_utils::__append(*this, std::move(__first), std::move(__last)); 774*700637cbSDimitry Andric if (__num_appended != 0) { 775*700637cbSDimitry Andric auto __zv = ranges::views::zip(__containers_.keys, __containers_.values); 776*700637cbSDimitry Andric auto __append_start_offset = __containers_.keys.size() - __num_appended; 777*700637cbSDimitry Andric auto __end = __zv.end(); 778*700637cbSDimitry Andric auto __compare_key = [this](const auto& __p1, const auto& __p2) { 779*700637cbSDimitry Andric return __compare_(std::get<0>(__p1), std::get<0>(__p2)); 780*700637cbSDimitry Andric }; 781*700637cbSDimitry Andric if constexpr (!_WasSorted) { 782*700637cbSDimitry Andric ranges::sort(__zv.begin() + __append_start_offset, __end, __compare_key); 783*700637cbSDimitry Andric } else { 784*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 785*700637cbSDimitry Andric __is_sorted(__containers_.keys | ranges::views::drop(__append_start_offset)), 786*700637cbSDimitry Andric "Key container is not sorted"); 787*700637cbSDimitry Andric } 788*700637cbSDimitry Andric ranges::inplace_merge(__zv.begin(), __zv.begin() + __append_start_offset, __end, __compare_key); 789*700637cbSDimitry Andric } 790*700637cbSDimitry Andric __on_failure.__complete(); 791*700637cbSDimitry Andric } 792*700637cbSDimitry Andric 793*700637cbSDimitry Andric template <class _Self, class _Kp> __find_impl(_Self && __self,const _Kp & __key)794*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static auto __find_impl(_Self&& __self, const _Kp& __key) { 795*700637cbSDimitry Andric auto __it = __self.lower_bound(__key); 796*700637cbSDimitry Andric auto __last = __self.end(); 797*700637cbSDimitry Andric if (__it == __last || __self.__compare_(__key, __it->first)) { 798*700637cbSDimitry Andric return __last; 799*700637cbSDimitry Andric } 800*700637cbSDimitry Andric return __it; 801*700637cbSDimitry Andric } 802*700637cbSDimitry Andric 803*700637cbSDimitry Andric template <class _Self, class _Kp> __equal_range_impl(_Self && __self,const _Kp & __key)804*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) { 805*700637cbSDimitry Andric auto [__key_first, __key_last] = 806*700637cbSDimitry Andric std::equal_range(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_); 807*700637cbSDimitry Andric 808*700637cbSDimitry Andric using __iterator_type = ranges::iterator_t<decltype(__self)>; 809*700637cbSDimitry Andric return std::make_pair(__iterator_type(__key_first, __corresponding_mapped_it(__self, __key_first)), 810*700637cbSDimitry Andric __iterator_type(__key_last, __corresponding_mapped_it(__self, __key_last))); 811*700637cbSDimitry Andric } 812*700637cbSDimitry Andric 813*700637cbSDimitry Andric template <class _Res, class _Self, class _Kp> __lower_bound(_Self && __self,_Kp & __x)814*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) { 815*700637cbSDimitry Andric auto __key_iter = 816*700637cbSDimitry Andric std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); 817*700637cbSDimitry Andric auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); 818*700637cbSDimitry Andric return _Res(std::move(__key_iter), std::move(__mapped_iter)); 819*700637cbSDimitry Andric } 820*700637cbSDimitry Andric 821*700637cbSDimitry Andric template <class _Res, class _Self, class _Kp> __upper_bound(_Self && __self,_Kp & __x)822*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) { 823*700637cbSDimitry Andric auto __key_iter = 824*700637cbSDimitry Andric std::upper_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); 825*700637cbSDimitry Andric auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); 826*700637cbSDimitry Andric return _Res(std::move(__key_iter), std::move(__mapped_iter)); 827*700637cbSDimitry Andric } 828*700637cbSDimitry Andric __reserve(size_t __size)829*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __size) { 830*700637cbSDimitry Andric if constexpr (__container_traits<_KeyContainer>::__reservable) { 831*700637cbSDimitry Andric __containers_.keys.reserve(__size); 832*700637cbSDimitry Andric } 833*700637cbSDimitry Andric 834*700637cbSDimitry Andric if constexpr (__container_traits<_MappedContainer>::__reservable) { 835*700637cbSDimitry Andric __containers_.values.reserve(__size); 836*700637cbSDimitry Andric } 837*700637cbSDimitry Andric } 838*700637cbSDimitry Andric 839*700637cbSDimitry Andric template <class _KIter, class _MIter> __erase(_KIter __key_iter_to_remove,_MIter __mapped_iter_to_remove)840*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI iterator __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) { 841*700637cbSDimitry Andric auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 842*700637cbSDimitry Andric auto __key_iter = __containers_.keys.erase(__key_iter_to_remove); 843*700637cbSDimitry Andric auto __mapped_iter = __containers_.values.erase(__mapped_iter_to_remove); 844*700637cbSDimitry Andric __on_failure.__complete(); 845*700637cbSDimitry Andric return iterator(std::move(__key_iter), std::move(__mapped_iter)); 846*700637cbSDimitry Andric } 847*700637cbSDimitry Andric 848*700637cbSDimitry Andric template <class _Key2, class _Tp2, class _Compare2, class _KeyContainer2, class _MappedContainer2, class _Predicate> 849*700637cbSDimitry Andric friend typename flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type 850*700637cbSDimitry Andric erase_if(flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate); 851*700637cbSDimitry Andric 852*700637cbSDimitry Andric friend __flat_map_utils; 853*700637cbSDimitry Andric 854*700637cbSDimitry Andric containers __containers_; 855*700637cbSDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_; 856*700637cbSDimitry Andric 857*700637cbSDimitry Andric struct __key_equiv { __key_equiv__key_equiv858*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI __key_equiv(key_compare __c) : __comp_(__c) {} operator__key_equiv859*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const { 860*700637cbSDimitry Andric return !__comp_(std::get<0>(__x), std::get<0>(__y)) && !__comp_(std::get<0>(__y), std::get<0>(__x)); 861*700637cbSDimitry Andric } 862*700637cbSDimitry Andric key_compare __comp_; 863*700637cbSDimitry Andric }; 864*700637cbSDimitry Andric }; 865*700637cbSDimitry Andric 866*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>> 867*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 868*700637cbSDimitry Andric !__is_allocator<_MappedContainer>::value && 869*700637cbSDimitry Andric is_invocable_v<const _Compare&, 870*700637cbSDimitry Andric const typename _KeyContainer::value_type&, 871*700637cbSDimitry Andric const typename _KeyContainer::value_type&>) 872*700637cbSDimitry Andric flat_multimap(_KeyContainer, _MappedContainer, _Compare = _Compare()) 873*700637cbSDimitry Andric -> flat_multimap<typename _KeyContainer::value_type, 874*700637cbSDimitry Andric typename _MappedContainer::value_type, 875*700637cbSDimitry Andric _Compare, 876*700637cbSDimitry Andric _KeyContainer, 877*700637cbSDimitry Andric _MappedContainer>; 878*700637cbSDimitry Andric 879*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Allocator> 880*700637cbSDimitry Andric requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> && 881*700637cbSDimitry Andric !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value) 882*700637cbSDimitry Andric flat_multimap(_KeyContainer, _MappedContainer, _Allocator) 883*700637cbSDimitry Andric -> flat_multimap<typename _KeyContainer::value_type, 884*700637cbSDimitry Andric typename _MappedContainer::value_type, 885*700637cbSDimitry Andric less<typename _KeyContainer::value_type>, 886*700637cbSDimitry Andric _KeyContainer, 887*700637cbSDimitry Andric _MappedContainer>; 888*700637cbSDimitry Andric 889*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator> 890*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 891*700637cbSDimitry Andric !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> && 892*700637cbSDimitry Andric uses_allocator_v<_MappedContainer, _Allocator> && 893*700637cbSDimitry Andric is_invocable_v<const _Compare&, 894*700637cbSDimitry Andric const typename _KeyContainer::value_type&, 895*700637cbSDimitry Andric const typename _KeyContainer::value_type&>) 896*700637cbSDimitry Andric flat_multimap(_KeyContainer, _MappedContainer, _Compare, _Allocator) 897*700637cbSDimitry Andric -> flat_multimap<typename _KeyContainer::value_type, 898*700637cbSDimitry Andric typename _MappedContainer::value_type, 899*700637cbSDimitry Andric _Compare, 900*700637cbSDimitry Andric _KeyContainer, 901*700637cbSDimitry Andric _MappedContainer>; 902*700637cbSDimitry Andric 903*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>> 904*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 905*700637cbSDimitry Andric !__is_allocator<_MappedContainer>::value && 906*700637cbSDimitry Andric is_invocable_v<const _Compare&, 907*700637cbSDimitry Andric const typename _KeyContainer::value_type&, 908*700637cbSDimitry Andric const typename _KeyContainer::value_type&>) 909*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Compare = _Compare()) 910*700637cbSDimitry Andric -> flat_multimap<typename _KeyContainer::value_type, 911*700637cbSDimitry Andric typename _MappedContainer::value_type, 912*700637cbSDimitry Andric _Compare, 913*700637cbSDimitry Andric _KeyContainer, 914*700637cbSDimitry Andric _MappedContainer>; 915*700637cbSDimitry Andric 916*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Allocator> 917*700637cbSDimitry Andric requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> && 918*700637cbSDimitry Andric !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value) 919*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Allocator) 920*700637cbSDimitry Andric -> flat_multimap<typename _KeyContainer::value_type, 921*700637cbSDimitry Andric typename _MappedContainer::value_type, 922*700637cbSDimitry Andric less<typename _KeyContainer::value_type>, 923*700637cbSDimitry Andric _KeyContainer, 924*700637cbSDimitry Andric _MappedContainer>; 925*700637cbSDimitry Andric 926*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator> 927*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 928*700637cbSDimitry Andric !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> && 929*700637cbSDimitry Andric uses_allocator_v<_MappedContainer, _Allocator> && 930*700637cbSDimitry Andric is_invocable_v<const _Compare&, 931*700637cbSDimitry Andric const typename _KeyContainer::value_type&, 932*700637cbSDimitry Andric const typename _KeyContainer::value_type&>) 933*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, _KeyContainer, _MappedContainer, _Compare, _Allocator) 934*700637cbSDimitry Andric -> flat_multimap<typename _KeyContainer::value_type, 935*700637cbSDimitry Andric typename _MappedContainer::value_type, 936*700637cbSDimitry Andric _Compare, 937*700637cbSDimitry Andric _KeyContainer, 938*700637cbSDimitry Andric _MappedContainer>; 939*700637cbSDimitry Andric 940*700637cbSDimitry Andric template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>> 941*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value) 942*700637cbSDimitry Andric flat_multimap(_InputIterator, _InputIterator, _Compare = _Compare()) 943*700637cbSDimitry Andric -> flat_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>; 944*700637cbSDimitry Andric 945*700637cbSDimitry Andric template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>> 946*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value) 947*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, _InputIterator, _InputIterator, _Compare = _Compare()) 948*700637cbSDimitry Andric -> flat_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>; 949*700637cbSDimitry Andric 950*700637cbSDimitry Andric template <ranges::input_range _Range, 951*700637cbSDimitry Andric class _Compare = less<__range_key_type<_Range>>, 952*700637cbSDimitry Andric class _Allocator = allocator<byte>, 953*700637cbSDimitry Andric class = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>> 954*700637cbSDimitry Andric flat_multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_multimap< 955*700637cbSDimitry Andric __range_key_type<_Range>, 956*700637cbSDimitry Andric __range_mapped_type<_Range>, 957*700637cbSDimitry Andric _Compare, 958*700637cbSDimitry Andric vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>, 959*700637cbSDimitry Andric vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>; 960*700637cbSDimitry Andric 961*700637cbSDimitry Andric template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>> 962*700637cbSDimitry Andric flat_multimap(from_range_t, _Range&&, _Allocator) -> flat_multimap< 963*700637cbSDimitry Andric __range_key_type<_Range>, 964*700637cbSDimitry Andric __range_mapped_type<_Range>, 965*700637cbSDimitry Andric less<__range_key_type<_Range>>, 966*700637cbSDimitry Andric vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>, 967*700637cbSDimitry Andric vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>; 968*700637cbSDimitry Andric 969*700637cbSDimitry Andric template <class _Key, class _Tp, class _Compare = less<_Key>> 970*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value) 971*700637cbSDimitry Andric flat_multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) -> flat_multimap<_Key, _Tp, _Compare>; 972*700637cbSDimitry Andric 973*700637cbSDimitry Andric template <class _Key, class _Tp, class _Compare = less<_Key>> 974*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value) 975*700637cbSDimitry Andric flat_multimap(sorted_equivalent_t, initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) 976*700637cbSDimitry Andric -> flat_multimap<_Key, _Tp, _Compare>; 977*700637cbSDimitry Andric 978*700637cbSDimitry Andric template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Allocator> 979*700637cbSDimitry Andric struct uses_allocator<flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>, _Allocator> 980*700637cbSDimitry Andric : bool_constant<uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator>> {}; 981*700637cbSDimitry Andric 982*700637cbSDimitry Andric template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Predicate> 983*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type 984*700637cbSDimitry Andric erase_if(flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_multimap, _Predicate __pred) { 985*700637cbSDimitry Andric auto __zv = ranges::views::zip(__flat_multimap.__containers_.keys, __flat_multimap.__containers_.values); 986*700637cbSDimitry Andric auto __first = __zv.begin(); 987*700637cbSDimitry Andric auto __last = __zv.end(); 988*700637cbSDimitry Andric auto __guard = std::__make_exception_guard([&] { __flat_multimap.clear(); }); 989*700637cbSDimitry Andric auto __it = std::remove_if(__first, __last, [&](auto&& __zipped) -> bool { 990*700637cbSDimitry Andric using _Ref = typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::const_reference; 991*700637cbSDimitry Andric return __pred(_Ref(std::get<0>(__zipped), std::get<1>(__zipped))); 992*700637cbSDimitry Andric }); 993*700637cbSDimitry Andric auto __res = __last - __it; 994*700637cbSDimitry Andric auto __offset = __it - __first; 995*700637cbSDimitry Andric 996*700637cbSDimitry Andric const auto __erase_container = [&](auto& __cont) { __cont.erase(__cont.begin() + __offset, __cont.end()); }; 997*700637cbSDimitry Andric 998*700637cbSDimitry Andric __erase_container(__flat_multimap.__containers_.keys); 999*700637cbSDimitry Andric __erase_container(__flat_multimap.__containers_.values); 1000*700637cbSDimitry Andric 1001*700637cbSDimitry Andric __guard.__complete(); 1002*700637cbSDimitry Andric return __res; 1003*700637cbSDimitry Andric } 1004*700637cbSDimitry Andric 1005*700637cbSDimitry Andric _LIBCPP_END_NAMESPACE_STD 1006*700637cbSDimitry Andric 1007*700637cbSDimitry Andric #endif // _LIBCPP_STD_VER >= 23 1008*700637cbSDimitry Andric 1009*700637cbSDimitry Andric _LIBCPP_POP_MACROS 1010*700637cbSDimitry Andric 1011*700637cbSDimitry Andric #endif // _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H 1012