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_MAP_H 11*700637cbSDimitry Andric #define _LIBCPP___FLAT_MAP_FLAT_MAP_H 12*700637cbSDimitry Andric 13*700637cbSDimitry Andric #include <__algorithm/lexicographical_compare_three_way.h> 14*700637cbSDimitry Andric #include <__algorithm/lower_bound.h> 15*700637cbSDimitry Andric #include <__algorithm/min.h> 16*700637cbSDimitry Andric #include <__algorithm/ranges_adjacent_find.h> 17*700637cbSDimitry Andric #include <__algorithm/ranges_equal.h> 18*700637cbSDimitry Andric #include <__algorithm/ranges_inplace_merge.h> 19*700637cbSDimitry Andric #include <__algorithm/ranges_sort.h> 20*700637cbSDimitry Andric #include <__algorithm/ranges_unique.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/swappable.h> 26*700637cbSDimitry Andric #include <__config> 27*700637cbSDimitry Andric #include <__cstddef/byte.h> 28*700637cbSDimitry Andric #include <__cstddef/ptrdiff_t.h> 29*700637cbSDimitry Andric #include <__flat_map/key_value_iterator.h> 30*700637cbSDimitry Andric #include <__flat_map/sorted_unique.h> 31*700637cbSDimitry Andric #include <__flat_map/utils.h> 32*700637cbSDimitry Andric #include <__functional/invoke.h> 33*700637cbSDimitry Andric #include <__functional/is_transparent.h> 34*700637cbSDimitry Andric #include <__functional/operations.h> 35*700637cbSDimitry Andric #include <__fwd/memory.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/next.h> 41*700637cbSDimitry Andric #include <__iterator/ranges_iterator_traits.h> 42*700637cbSDimitry Andric #include <__iterator/reverse_iterator.h> 43*700637cbSDimitry Andric #include <__memory/allocator_traits.h> 44*700637cbSDimitry Andric #include <__memory/uses_allocator.h> 45*700637cbSDimitry Andric #include <__memory/uses_allocator_construction.h> 46*700637cbSDimitry Andric #include <__ranges/access.h> 47*700637cbSDimitry Andric #include <__ranges/concepts.h> 48*700637cbSDimitry Andric #include <__ranges/container_compatible_range.h> 49*700637cbSDimitry Andric #include <__ranges/drop_view.h> 50*700637cbSDimitry Andric #include <__ranges/from_range.h> 51*700637cbSDimitry Andric #include <__ranges/ref_view.h> 52*700637cbSDimitry Andric #include <__ranges/size.h> 53*700637cbSDimitry Andric #include <__ranges/subrange.h> 54*700637cbSDimitry Andric #include <__ranges/zip_view.h> 55*700637cbSDimitry Andric #include <__type_traits/conjunction.h> 56*700637cbSDimitry Andric #include <__type_traits/container_traits.h> 57*700637cbSDimitry Andric #include <__type_traits/invoke.h> 58*700637cbSDimitry Andric #include <__type_traits/is_allocator.h> 59*700637cbSDimitry Andric #include <__type_traits/is_nothrow_constructible.h> 60*700637cbSDimitry Andric #include <__type_traits/is_same.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_map { 86*700637cbSDimitry Andric template <class, class, class, class, class> 87*700637cbSDimitry Andric friend class flat_map; 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_map, _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 _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare(key_compare __c) : __comp_(__c) {} 118*700637cbSDimitry Andric friend flat_map; 119*700637cbSDimitry Andric 120*700637cbSDimitry Andric public: 121*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator()122*700637cbSDimitry Andric operator()(const_reference __x, const_reference __y) const { 123*700637cbSDimitry Andric return __comp_(__x.first, __y.first); 124*700637cbSDimitry Andric } 125*700637cbSDimitry Andric }; 126*700637cbSDimitry Andric 127*700637cbSDimitry Andric struct containers { 128*700637cbSDimitry Andric key_container_type keys; 129*700637cbSDimitry Andric mapped_container_type values; 130*700637cbSDimitry Andric }; 131*700637cbSDimitry Andric 132*700637cbSDimitry Andric private: 133*700637cbSDimitry Andric template <class _Allocator> 134*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool __allocator_ctor_constraint = 135*700637cbSDimitry Andric _And<uses_allocator<key_container_type, _Allocator>, uses_allocator<mapped_container_type, _Allocator>>::value; 136*700637cbSDimitry Andric 137*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_compare_transparent = __is_transparent_v<_Compare>; 138*700637cbSDimitry Andric 139*700637cbSDimitry Andric public: 140*700637cbSDimitry Andric // [flat.map.cons], construct/copy/destroy flat_map()141*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map() noexcept( 142*700637cbSDimitry Andric is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_MappedContainer> && 143*700637cbSDimitry Andric is_nothrow_default_constructible_v<_Compare>) 144*700637cbSDimitry Andric : __containers_(), __compare_() {} 145*700637cbSDimitry Andric 146*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI flat_map(const flat_map&) = default; 147*700637cbSDimitry Andric flat_map(flat_map && __other)148*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(flat_map&& __other) noexcept( 149*700637cbSDimitry Andric is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_MappedContainer> && 150*700637cbSDimitry Andric is_nothrow_move_constructible_v<_Compare>) 151*700637cbSDimitry Andric # if _LIBCPP_HAS_EXCEPTIONS 152*700637cbSDimitry Andric try 153*700637cbSDimitry Andric # endif // _LIBCPP_HAS_EXCEPTIONS 154*700637cbSDimitry Andric : __containers_(std::move(__other.__containers_)), __compare_(std::move(__other.__compare_)) { 155*700637cbSDimitry Andric __other.clear(); 156*700637cbSDimitry Andric # if _LIBCPP_HAS_EXCEPTIONS 157*700637cbSDimitry Andric } catch (...) { 158*700637cbSDimitry Andric __other.clear(); 159*700637cbSDimitry Andric // gcc does not like the `throw` keyword in a conditionally noexcept function 160*700637cbSDimitry Andric if constexpr (!(is_nothrow_move_constructible_v<_KeyContainer> && 161*700637cbSDimitry Andric is_nothrow_move_constructible_v<_MappedContainer> && is_nothrow_move_constructible_v<_Compare>)) { 162*700637cbSDimitry Andric throw; 163*700637cbSDimitry Andric } 164*700637cbSDimitry Andric # endif // _LIBCPP_HAS_EXCEPTIONS 165*700637cbSDimitry Andric } 166*700637cbSDimitry Andric 167*700637cbSDimitry Andric template <class _Allocator> 168*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_map(const flat_map & __other,const _Allocator & __alloc)169*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const flat_map& __other, const _Allocator& __alloc) 170*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_tag{}, 171*700637cbSDimitry Andric __alloc, 172*700637cbSDimitry Andric __other.__containers_.keys, 173*700637cbSDimitry Andric __other.__containers_.values, 174*700637cbSDimitry Andric __other.__compare_) {} 175*700637cbSDimitry Andric 176*700637cbSDimitry Andric template <class _Allocator> 177*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_map(flat_map && __other,const _Allocator & __alloc)178*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(flat_map&& __other, const _Allocator& __alloc) 179*700637cbSDimitry Andric # if _LIBCPP_HAS_EXCEPTIONS 180*700637cbSDimitry Andric try 181*700637cbSDimitry Andric # endif // _LIBCPP_HAS_EXCEPTIONS 182*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_tag{}, 183*700637cbSDimitry Andric __alloc, 184*700637cbSDimitry Andric std::move(__other.__containers_.keys), 185*700637cbSDimitry Andric std::move(__other.__containers_.values), 186*700637cbSDimitry Andric std::move(__other.__compare_)) { 187*700637cbSDimitry Andric __other.clear(); 188*700637cbSDimitry Andric # if _LIBCPP_HAS_EXCEPTIONS catch(...)189*700637cbSDimitry Andric } catch (...) { 190*700637cbSDimitry Andric __other.clear(); 191*700637cbSDimitry Andric throw; 192*700637cbSDimitry Andric # endif // _LIBCPP_HAS_EXCEPTIONS 193*700637cbSDimitry Andric } 194*700637cbSDimitry Andric 195*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( 196*700637cbSDimitry Andric key_container_type __key_cont, mapped_container_type __mapped_cont, const key_compare& __comp = key_compare()) 197*700637cbSDimitry Andric : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) { 198*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 199*700637cbSDimitry Andric "flat_map keys and mapped containers have different size"); 200*700637cbSDimitry Andric __sort_and_unique(); 201*700637cbSDimitry Andric } 202*700637cbSDimitry Andric 203*700637cbSDimitry Andric template <class _Allocator> 204*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 205*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const key_container_type & __key_cont,const mapped_container_type & __mapped_cont,const _Allocator & __alloc)206*700637cbSDimitry Andric flat_map(const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const _Allocator& __alloc) 207*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { 208*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 209*700637cbSDimitry Andric "flat_map keys and mapped containers have different size"); 210*700637cbSDimitry Andric __sort_and_unique(); 211*700637cbSDimitry Andric } 212*700637cbSDimitry Andric 213*700637cbSDimitry Andric template <class _Allocator> 214*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 215*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const key_container_type & __key_cont,const mapped_container_type & __mapped_cont,const key_compare & __comp,const _Allocator & __alloc)216*700637cbSDimitry Andric flat_map(const key_container_type& __key_cont, 217*700637cbSDimitry Andric const mapped_container_type& __mapped_cont, 218*700637cbSDimitry Andric const key_compare& __comp, 219*700637cbSDimitry Andric const _Allocator& __alloc) 220*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) { 221*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 222*700637cbSDimitry Andric "flat_map keys and mapped containers have different size"); 223*700637cbSDimitry Andric __sort_and_unique(); 224*700637cbSDimitry Andric } 225*700637cbSDimitry Andric 226*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 227*700637cbSDimitry Andric flat_map(sorted_unique_t, 228*700637cbSDimitry Andric key_container_type __key_cont, 229*700637cbSDimitry Andric mapped_container_type __mapped_cont, 230*700637cbSDimitry Andric const key_compare& __comp = key_compare()) 231*700637cbSDimitry Andric : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) { 232*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 233*700637cbSDimitry Andric "flat_map keys and mapped containers have different size"); 234*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 235*700637cbSDimitry Andric __is_sorted_and_unique(__containers_.keys), "Either the key container is not sorted or it contains duplicates"); 236*700637cbSDimitry Andric } 237*700637cbSDimitry Andric 238*700637cbSDimitry Andric template <class _Allocator> 239*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 240*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t,const key_container_type & __key_cont,const mapped_container_type & __mapped_cont,const _Allocator & __alloc)241*700637cbSDimitry Andric flat_map(sorted_unique_t, 242*700637cbSDimitry Andric const key_container_type& __key_cont, 243*700637cbSDimitry Andric const mapped_container_type& __mapped_cont, 244*700637cbSDimitry Andric const _Allocator& __alloc) 245*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { 246*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 247*700637cbSDimitry Andric "flat_map keys and mapped containers have different size"); 248*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 249*700637cbSDimitry Andric __is_sorted_and_unique(__containers_.keys), "Either the key container is not sorted or it contains duplicates"); 250*700637cbSDimitry Andric } 251*700637cbSDimitry Andric 252*700637cbSDimitry Andric template <class _Allocator> 253*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_map(sorted_unique_t,const key_container_type & __key_cont,const mapped_container_type & __mapped_cont,const key_compare & __comp,const _Allocator & __alloc)254*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( 255*700637cbSDimitry Andric sorted_unique_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_map(__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_map keys and mapped containers have different size"); 263*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 264*700637cbSDimitry Andric __is_sorted_and_unique(__containers_.keys), "Either the key container is not sorted or it contains duplicates"); 265*700637cbSDimitry Andric } 266*700637cbSDimitry Andric flat_map(const key_compare & __comp)267*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_map(const key_compare& __comp) 268*700637cbSDimitry Andric : __containers_(), __compare_(__comp) {} 269*700637cbSDimitry Andric 270*700637cbSDimitry Andric template <class _Allocator> 271*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_map(const key_compare & __comp,const _Allocator & __alloc)272*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const key_compare& __comp, const _Allocator& __alloc) 273*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {} 274*700637cbSDimitry Andric 275*700637cbSDimitry Andric template <class _Allocator> 276*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_map(const _Allocator & __alloc)277*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_map(const _Allocator& __alloc) 278*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) {} 279*700637cbSDimitry Andric 280*700637cbSDimitry Andric template <class _InputIterator> 281*700637cbSDimitry Andric requires __has_input_iterator_category<_InputIterator>::value 282*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 283*700637cbSDimitry Andric flat_map(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) __containers_()284*700637cbSDimitry Andric : __containers_(), __compare_(__comp) { 285*700637cbSDimitry Andric insert(__first, __last); 286*700637cbSDimitry Andric } 287*700637cbSDimitry Andric 288*700637cbSDimitry Andric template <class _InputIterator, class _Allocator> requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)289*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 290*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 291*700637cbSDimitry Andric flat_map(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc) 292*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { 293*700637cbSDimitry Andric insert(__first, __last); 294*700637cbSDimitry Andric } 295*700637cbSDimitry Andric 296*700637cbSDimitry Andric template <class _InputIterator, class _Allocator> requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)297*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 298*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 299*700637cbSDimitry Andric flat_map(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) 300*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { 301*700637cbSDimitry Andric insert(__first, __last); 302*700637cbSDimitry Andric } 303*700637cbSDimitry Andric 304*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range> flat_map(from_range_t __fr,_Range && __rg)305*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t __fr, _Range&& __rg) 306*700637cbSDimitry Andric : flat_map(__fr, std::forward<_Range>(__rg), key_compare()) {} 307*700637cbSDimitry Andric 308*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range, class _Allocator> 309*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_map(from_range_t,_Range && __rg,const _Allocator & __alloc)310*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t, _Range&& __rg, const _Allocator& __alloc) 311*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { 312*700637cbSDimitry Andric insert_range(std::forward<_Range>(__rg)); 313*700637cbSDimitry Andric } 314*700637cbSDimitry Andric 315*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range> flat_map(from_range_t,_Range && __rg,const key_compare & __comp)316*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t, _Range&& __rg, const key_compare& __comp) 317*700637cbSDimitry Andric : flat_map(__comp) { 318*700637cbSDimitry Andric insert_range(std::forward<_Range>(__rg)); 319*700637cbSDimitry Andric } 320*700637cbSDimitry Andric 321*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range, class _Allocator> 322*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 323*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t,_Range && __rg,const key_compare & __comp,const _Allocator & __alloc)324*700637cbSDimitry Andric flat_map(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) 325*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { 326*700637cbSDimitry Andric insert_range(std::forward<_Range>(__rg)); 327*700637cbSDimitry Andric } 328*700637cbSDimitry Andric 329*700637cbSDimitry Andric template <class _InputIterator> 330*700637cbSDimitry Andric requires __has_input_iterator_category<_InputIterator>::value 331*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 332*700637cbSDimitry Andric flat_map(sorted_unique_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) __containers_()333*700637cbSDimitry Andric : __containers_(), __compare_(__comp) { 334*700637cbSDimitry Andric insert(sorted_unique, __first, __last); 335*700637cbSDimitry Andric } 336*700637cbSDimitry Andric template <class _InputIterator, class _Allocator> requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)337*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 338*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( 339*700637cbSDimitry Andric sorted_unique_t, 340*700637cbSDimitry Andric _InputIterator __first, 341*700637cbSDimitry Andric _InputIterator __last, 342*700637cbSDimitry Andric const key_compare& __comp, 343*700637cbSDimitry Andric const _Allocator& __alloc) 344*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { 345*700637cbSDimitry Andric insert(sorted_unique, __first, __last); 346*700637cbSDimitry Andric } 347*700637cbSDimitry Andric 348*700637cbSDimitry Andric template <class _InputIterator, class _Allocator> requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)349*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 350*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 351*700637cbSDimitry Andric flat_map(sorted_unique_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc) 352*700637cbSDimitry Andric : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { 353*700637cbSDimitry Andric insert(sorted_unique, __first, __last); 354*700637cbSDimitry Andric } 355*700637cbSDimitry Andric 356*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 357*700637cbSDimitry Andric flat_map(initializer_list<value_type> __il, const key_compare& __comp = key_compare()) 358*700637cbSDimitry Andric : flat_map(__il.begin(), __il.end(), __comp) {} 359*700637cbSDimitry Andric 360*700637cbSDimitry Andric template <class _Allocator> 361*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 362*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(initializer_list<value_type> __il,const key_compare & __comp,const _Allocator & __alloc)363*700637cbSDimitry Andric flat_map(initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc) 364*700637cbSDimitry Andric : flat_map(__il.begin(), __il.end(), __comp, __alloc) {} 365*700637cbSDimitry Andric 366*700637cbSDimitry Andric template <class _Allocator> 367*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 368*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(initializer_list<value_type> __il,const _Allocator & __alloc)369*700637cbSDimitry Andric flat_map(initializer_list<value_type> __il, const _Allocator& __alloc) 370*700637cbSDimitry Andric : flat_map(__il.begin(), __il.end(), __alloc) {} 371*700637cbSDimitry Andric 372*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 373*700637cbSDimitry Andric flat_map(sorted_unique_t, initializer_list<value_type> __il, const key_compare& __comp = key_compare()) 374*700637cbSDimitry Andric : flat_map(sorted_unique, __il.begin(), __il.end(), __comp) {} 375*700637cbSDimitry Andric 376*700637cbSDimitry Andric template <class _Allocator> 377*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 378*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t,initializer_list<value_type> __il,const key_compare & __comp,const _Allocator & __alloc)379*700637cbSDimitry Andric flat_map(sorted_unique_t, initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc) 380*700637cbSDimitry Andric : flat_map(sorted_unique, __il.begin(), __il.end(), __comp, __alloc) {} 381*700637cbSDimitry Andric 382*700637cbSDimitry Andric template <class _Allocator> 383*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 384*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t,initializer_list<value_type> __il,const _Allocator & __alloc)385*700637cbSDimitry Andric flat_map(sorted_unique_t, initializer_list<value_type> __il, const _Allocator& __alloc) 386*700637cbSDimitry Andric : flat_map(sorted_unique, __il.begin(), __il.end(), __alloc) {} 387*700637cbSDimitry Andric 388*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map& operator=(initializer_list<value_type> __il) { 389*700637cbSDimitry Andric clear(); 390*700637cbSDimitry Andric insert(__il); 391*700637cbSDimitry Andric return *this; 392*700637cbSDimitry Andric } 393*700637cbSDimitry Andric 394*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map& operator=(const flat_map&) = default; 395*700637cbSDimitry Andric noexcept(is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> && is_nothrow_move_assignable_v<_Compare>)396*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map& operator=(flat_map&& __other) noexcept( 397*700637cbSDimitry Andric is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> && 398*700637cbSDimitry Andric is_nothrow_move_assignable_v<_Compare>) { 399*700637cbSDimitry Andric // No matter what happens, we always want to clear the other container before returning 400*700637cbSDimitry Andric // since we moved from it 401*700637cbSDimitry Andric auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; }); 402*700637cbSDimitry Andric { 403*700637cbSDimitry Andric // If an exception is thrown, we have no choice but to clear *this to preserve invariants 404*700637cbSDimitry Andric auto __on_exception = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 405*700637cbSDimitry Andric __containers_ = std::move(__other.__containers_); 406*700637cbSDimitry Andric __compare_ = std::move(__other.__compare_); 407*700637cbSDimitry Andric __on_exception.__complete(); 408*700637cbSDimitry Andric } 409*700637cbSDimitry Andric return *this; 410*700637cbSDimitry Andric } 411*700637cbSDimitry Andric 412*700637cbSDimitry Andric // iterators begin()413*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept { 414*700637cbSDimitry Andric return iterator(__containers_.keys.begin(), __containers_.values.begin()); 415*700637cbSDimitry Andric } 416*700637cbSDimitry Andric begin()417*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept { 418*700637cbSDimitry Andric return const_iterator(__containers_.keys.begin(), __containers_.values.begin()); 419*700637cbSDimitry Andric } 420*700637cbSDimitry Andric end()421*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept { 422*700637cbSDimitry Andric return iterator(__containers_.keys.end(), __containers_.values.end()); 423*700637cbSDimitry Andric } 424*700637cbSDimitry Andric end()425*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept { 426*700637cbSDimitry Andric return const_iterator(__containers_.keys.end(), __containers_.values.end()); 427*700637cbSDimitry Andric } 428*700637cbSDimitry Andric rbegin()429*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept { 430*700637cbSDimitry Andric return reverse_iterator(end()); 431*700637cbSDimitry Andric } rbegin()432*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept { 433*700637cbSDimitry Andric return const_reverse_iterator(end()); 434*700637cbSDimitry Andric } rend()435*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept { 436*700637cbSDimitry Andric return reverse_iterator(begin()); 437*700637cbSDimitry Andric } rend()438*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept { 439*700637cbSDimitry Andric return const_reverse_iterator(begin()); 440*700637cbSDimitry Andric } 441*700637cbSDimitry Andric cbegin()442*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); } cend()443*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); } crbegin()444*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept { 445*700637cbSDimitry Andric return const_reverse_iterator(end()); 446*700637cbSDimitry Andric } crend()447*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept { 448*700637cbSDimitry Andric return const_reverse_iterator(begin()); 449*700637cbSDimitry Andric } 450*700637cbSDimitry Andric 451*700637cbSDimitry Andric // [flat.map.capacity], capacity empty()452*700637cbSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const noexcept { 453*700637cbSDimitry Andric return __containers_.keys.empty(); 454*700637cbSDimitry Andric } 455*700637cbSDimitry Andric size()456*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { 457*700637cbSDimitry Andric return __containers_.keys.size(); 458*700637cbSDimitry Andric } 459*700637cbSDimitry Andric max_size()460*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { 461*700637cbSDimitry Andric return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size()); 462*700637cbSDimitry Andric } 463*700637cbSDimitry Andric 464*700637cbSDimitry Andric // [flat.map.access], element access 465*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](const key_type& __x) 466*700637cbSDimitry Andric requires is_constructible_v<mapped_type> 467*700637cbSDimitry Andric { 468*700637cbSDimitry Andric return try_emplace(__x).first->second; 469*700637cbSDimitry Andric } 470*700637cbSDimitry Andric 471*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](key_type&& __x) 472*700637cbSDimitry Andric requires is_constructible_v<mapped_type> 473*700637cbSDimitry Andric { 474*700637cbSDimitry Andric return try_emplace(std::move(__x)).first->second; 475*700637cbSDimitry Andric } 476*700637cbSDimitry Andric 477*700637cbSDimitry Andric template <class _Kp> 478*700637cbSDimitry Andric requires(__is_compare_transparent && is_constructible_v<key_type, _Kp> && is_constructible_v<mapped_type> && 479*700637cbSDimitry Andric !is_convertible_v<_Kp &&, const_iterator> && !is_convertible_v<_Kp &&, iterator>) 480*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](_Kp&& __x) { 481*700637cbSDimitry Andric return try_emplace(std::forward<_Kp>(__x)).first->second; 482*700637cbSDimitry Andric } 483*700637cbSDimitry Andric at(const key_type & __x)484*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __x) { 485*700637cbSDimitry Andric auto __it = find(__x); 486*700637cbSDimitry Andric if (__it == end()) { 487*700637cbSDimitry Andric std::__throw_out_of_range("flat_map::at(const key_type&): Key does not exist"); 488*700637cbSDimitry Andric } 489*700637cbSDimitry Andric return __it->second; 490*700637cbSDimitry Andric } 491*700637cbSDimitry Andric at(const key_type & __x)492*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const key_type& __x) const { 493*700637cbSDimitry Andric auto __it = find(__x); 494*700637cbSDimitry Andric if (__it == end()) { 495*700637cbSDimitry Andric std::__throw_out_of_range("flat_map::at(const key_type&) const: Key does not exist"); 496*700637cbSDimitry Andric } 497*700637cbSDimitry Andric return __it->second; 498*700637cbSDimitry Andric } 499*700637cbSDimitry Andric 500*700637cbSDimitry Andric template <class _Kp> 501*700637cbSDimitry Andric requires __is_compare_transparent at(const _Kp & __x)502*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const _Kp& __x) { 503*700637cbSDimitry Andric auto __it = find(__x); 504*700637cbSDimitry Andric if (__it == end()) { 505*700637cbSDimitry Andric std::__throw_out_of_range("flat_map::at(const K&): Key does not exist"); 506*700637cbSDimitry Andric } 507*700637cbSDimitry Andric return __it->second; 508*700637cbSDimitry Andric } 509*700637cbSDimitry Andric 510*700637cbSDimitry Andric template <class _Kp> 511*700637cbSDimitry Andric requires __is_compare_transparent at(const _Kp & __x)512*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const _Kp& __x) const { 513*700637cbSDimitry Andric auto __it = find(__x); 514*700637cbSDimitry Andric if (__it == end()) { 515*700637cbSDimitry Andric std::__throw_out_of_range("flat_map::at(const K&) const: Key does not exist"); 516*700637cbSDimitry Andric } 517*700637cbSDimitry Andric return __it->second; 518*700637cbSDimitry Andric } 519*700637cbSDimitry Andric 520*700637cbSDimitry Andric // [flat.map.modifiers], modifiers 521*700637cbSDimitry Andric template <class... _Args> 522*700637cbSDimitry Andric requires is_constructible_v<pair<key_type, mapped_type>, _Args...> emplace(_Args &&...__args)523*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> emplace(_Args&&... __args) { 524*700637cbSDimitry Andric std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...); 525*700637cbSDimitry Andric return __try_emplace(std::move(__pair.first), std::move(__pair.second)); 526*700637cbSDimitry Andric } 527*700637cbSDimitry Andric 528*700637cbSDimitry Andric template <class... _Args> 529*700637cbSDimitry Andric requires is_constructible_v<pair<key_type, mapped_type>, _Args...> emplace_hint(const_iterator __hint,_Args &&...__args)530*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace_hint(const_iterator __hint, _Args&&... __args) { 531*700637cbSDimitry Andric std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...); 532*700637cbSDimitry Andric return __try_emplace_hint(__hint, std::move(__pair.first), std::move(__pair.second)).first; 533*700637cbSDimitry Andric } 534*700637cbSDimitry Andric insert(const value_type & __x)535*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert(const value_type& __x) { 536*700637cbSDimitry Andric return emplace(__x); 537*700637cbSDimitry Andric } 538*700637cbSDimitry Andric insert(value_type && __x)539*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert(value_type&& __x) { 540*700637cbSDimitry Andric return emplace(std::move(__x)); 541*700637cbSDimitry Andric } 542*700637cbSDimitry Andric insert(const_iterator __hint,const value_type & __x)543*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, const value_type& __x) { 544*700637cbSDimitry Andric return emplace_hint(__hint, __x); 545*700637cbSDimitry Andric } 546*700637cbSDimitry Andric insert(const_iterator __hint,value_type && __x)547*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, value_type&& __x) { 548*700637cbSDimitry Andric return emplace_hint(__hint, std::move(__x)); 549*700637cbSDimitry Andric } 550*700637cbSDimitry Andric 551*700637cbSDimitry Andric template <class _PairLike> 552*700637cbSDimitry Andric requires is_constructible_v<pair<key_type, mapped_type>, _PairLike> insert(_PairLike && __x)553*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert(_PairLike&& __x) { 554*700637cbSDimitry Andric return emplace(std::forward<_PairLike>(__x)); 555*700637cbSDimitry Andric } 556*700637cbSDimitry Andric 557*700637cbSDimitry Andric template <class _PairLike> 558*700637cbSDimitry Andric requires is_constructible_v<pair<key_type, mapped_type>, _PairLike> insert(const_iterator __hint,_PairLike && __x)559*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, _PairLike&& __x) { 560*700637cbSDimitry Andric return emplace_hint(__hint, std::forward<_PairLike>(__x)); 561*700637cbSDimitry Andric } 562*700637cbSDimitry Andric 563*700637cbSDimitry Andric template <class _InputIterator> 564*700637cbSDimitry Andric requires __has_input_iterator_category<_InputIterator>::value insert(_InputIterator __first,_InputIterator __last)565*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(_InputIterator __first, _InputIterator __last) { 566*700637cbSDimitry Andric if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { 567*700637cbSDimitry Andric __reserve(__last - __first); 568*700637cbSDimitry Andric } 569*700637cbSDimitry Andric __append_sort_merge_unique</*WasSorted = */ false>(std::move(__first), std::move(__last)); 570*700637cbSDimitry Andric } 571*700637cbSDimitry Andric 572*700637cbSDimitry Andric template <class _InputIterator> 573*700637cbSDimitry Andric requires __has_input_iterator_category<_InputIterator>::value 574*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(sorted_unique_t,_InputIterator __first,_InputIterator __last)575*700637cbSDimitry Andric insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) { 576*700637cbSDimitry Andric if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { 577*700637cbSDimitry Andric __reserve(__last - __first); 578*700637cbSDimitry Andric } 579*700637cbSDimitry Andric 580*700637cbSDimitry Andric __append_sort_merge_unique</*WasSorted = */ true>(std::move(__first), std::move(__last)); 581*700637cbSDimitry Andric } 582*700637cbSDimitry Andric 583*700637cbSDimitry Andric template <_ContainerCompatibleRange<value_type> _Range> insert_range(_Range && __range)584*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(_Range&& __range) { 585*700637cbSDimitry Andric if constexpr (ranges::sized_range<_Range>) { 586*700637cbSDimitry Andric __reserve(ranges::size(__range)); 587*700637cbSDimitry Andric } 588*700637cbSDimitry Andric 589*700637cbSDimitry Andric __append_sort_merge_unique</*WasSorted = */ false>(ranges::begin(__range), ranges::end(__range)); 590*700637cbSDimitry Andric } 591*700637cbSDimitry Andric insert(initializer_list<value_type> __il)592*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list<value_type> __il) { 593*700637cbSDimitry Andric insert(__il.begin(), __il.end()); 594*700637cbSDimitry Andric } 595*700637cbSDimitry Andric insert(sorted_unique_t,initializer_list<value_type> __il)596*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(sorted_unique_t, initializer_list<value_type> __il) { 597*700637cbSDimitry Andric insert(sorted_unique, __il.begin(), __il.end()); 598*700637cbSDimitry Andric } 599*700637cbSDimitry Andric extract()600*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && { 601*700637cbSDimitry Andric auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; }); 602*700637cbSDimitry Andric auto __ret = std::move(__containers_); 603*700637cbSDimitry Andric return __ret; 604*700637cbSDimitry Andric } 605*700637cbSDimitry Andric 606*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void replace(key_container_type && __key_cont,mapped_container_type && __mapped_cont)607*700637cbSDimitry Andric replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) { 608*700637cbSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE( 609*700637cbSDimitry Andric __key_cont.size() == __mapped_cont.size(), "flat_map keys and mapped containers have different size"); 610*700637cbSDimitry Andric 611*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 612*700637cbSDimitry Andric __is_sorted_and_unique(__key_cont), "Either the key container is not sorted or it contains duplicates"); 613*700637cbSDimitry Andric auto __guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 614*700637cbSDimitry Andric __containers_.keys = std::move(__key_cont); 615*700637cbSDimitry Andric __containers_.values = std::move(__mapped_cont); 616*700637cbSDimitry Andric __guard.__complete(); 617*700637cbSDimitry Andric } 618*700637cbSDimitry Andric 619*700637cbSDimitry Andric template <class... _Args> 620*700637cbSDimitry Andric requires is_constructible_v<mapped_type, _Args...> 621*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> try_emplace(const key_type & __key,_Args &&...__args)622*700637cbSDimitry Andric try_emplace(const key_type& __key, _Args&&... __args) { 623*700637cbSDimitry Andric return __try_emplace(__key, std::forward<_Args>(__args)...); 624*700637cbSDimitry Andric } 625*700637cbSDimitry Andric 626*700637cbSDimitry Andric template <class... _Args> 627*700637cbSDimitry Andric requires is_constructible_v<mapped_type, _Args...> 628*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> try_emplace(key_type && __key,_Args &&...__args)629*700637cbSDimitry Andric try_emplace(key_type&& __key, _Args&&... __args) { 630*700637cbSDimitry Andric return __try_emplace(std::move(__key), std::forward<_Args>(__args)...); 631*700637cbSDimitry Andric } 632*700637cbSDimitry Andric 633*700637cbSDimitry Andric template <class _Kp, class... _Args> 634*700637cbSDimitry Andric requires(__is_compare_transparent && is_constructible_v<key_type, _Kp> && 635*700637cbSDimitry Andric is_constructible_v<mapped_type, _Args...> && !is_convertible_v<_Kp &&, const_iterator> && 636*700637cbSDimitry Andric !is_convertible_v<_Kp &&, iterator>) try_emplace(_Kp && __key,_Args &&...__args)637*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> try_emplace(_Kp&& __key, _Args&&... __args) { 638*700637cbSDimitry Andric return __try_emplace(std::forward<_Kp>(__key), std::forward<_Args>(__args)...); 639*700637cbSDimitry Andric } 640*700637cbSDimitry Andric 641*700637cbSDimitry Andric template <class... _Args> 642*700637cbSDimitry Andric requires is_constructible_v<mapped_type, _Args...> 643*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator try_emplace(const_iterator __hint,const key_type & __key,_Args &&...__args)644*700637cbSDimitry Andric try_emplace(const_iterator __hint, const key_type& __key, _Args&&... __args) { 645*700637cbSDimitry Andric return __try_emplace_hint(__hint, __key, std::forward<_Args>(__args)...).first; 646*700637cbSDimitry Andric } 647*700637cbSDimitry Andric 648*700637cbSDimitry Andric template <class... _Args> 649*700637cbSDimitry Andric requires is_constructible_v<mapped_type, _Args...> 650*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator try_emplace(const_iterator __hint,key_type && __key,_Args &&...__args)651*700637cbSDimitry Andric try_emplace(const_iterator __hint, key_type&& __key, _Args&&... __args) { 652*700637cbSDimitry Andric return __try_emplace_hint(__hint, std::move(__key), std::forward<_Args>(__args)...).first; 653*700637cbSDimitry Andric } 654*700637cbSDimitry Andric 655*700637cbSDimitry Andric template <class _Kp, class... _Args> 656*700637cbSDimitry Andric requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_constructible_v<mapped_type, _Args...> 657*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator try_emplace(const_iterator __hint,_Kp && __key,_Args &&...__args)658*700637cbSDimitry Andric try_emplace(const_iterator __hint, _Kp&& __key, _Args&&... __args) { 659*700637cbSDimitry Andric return __try_emplace_hint(__hint, std::forward<_Kp>(__key), std::forward<_Args>(__args)...).first; 660*700637cbSDimitry Andric } 661*700637cbSDimitry Andric 662*700637cbSDimitry Andric template <class _Mapped> 663*700637cbSDimitry Andric requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped> 664*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert_or_assign(const key_type & __key,_Mapped && __obj)665*700637cbSDimitry Andric insert_or_assign(const key_type& __key, _Mapped&& __obj) { 666*700637cbSDimitry Andric return __insert_or_assign(__key, std::forward<_Mapped>(__obj)); 667*700637cbSDimitry Andric } 668*700637cbSDimitry Andric 669*700637cbSDimitry Andric template <class _Mapped> 670*700637cbSDimitry Andric requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped> 671*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert_or_assign(key_type && __key,_Mapped && __obj)672*700637cbSDimitry Andric insert_or_assign(key_type&& __key, _Mapped&& __obj) { 673*700637cbSDimitry Andric return __insert_or_assign(std::move(__key), std::forward<_Mapped>(__obj)); 674*700637cbSDimitry Andric } 675*700637cbSDimitry Andric 676*700637cbSDimitry Andric template <class _Kp, class _Mapped> 677*700637cbSDimitry Andric requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_assignable_v<mapped_type&, _Mapped> && 678*700637cbSDimitry Andric is_constructible_v<mapped_type, _Mapped> 679*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert_or_assign(_Kp && __key,_Mapped && __obj)680*700637cbSDimitry Andric insert_or_assign(_Kp&& __key, _Mapped&& __obj) { 681*700637cbSDimitry Andric return __insert_or_assign(std::forward<_Kp>(__key), std::forward<_Mapped>(__obj)); 682*700637cbSDimitry Andric } 683*700637cbSDimitry Andric 684*700637cbSDimitry Andric template <class _Mapped> 685*700637cbSDimitry Andric requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped> 686*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert_or_assign(const_iterator __hint,const key_type & __key,_Mapped && __obj)687*700637cbSDimitry Andric insert_or_assign(const_iterator __hint, const key_type& __key, _Mapped&& __obj) { 688*700637cbSDimitry Andric return __insert_or_assign(__hint, __key, std::forward<_Mapped>(__obj)); 689*700637cbSDimitry Andric } 690*700637cbSDimitry Andric 691*700637cbSDimitry Andric template <class _Mapped> 692*700637cbSDimitry Andric requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped> 693*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert_or_assign(const_iterator __hint,key_type && __key,_Mapped && __obj)694*700637cbSDimitry Andric insert_or_assign(const_iterator __hint, key_type&& __key, _Mapped&& __obj) { 695*700637cbSDimitry Andric return __insert_or_assign(__hint, std::move(__key), std::forward<_Mapped>(__obj)); 696*700637cbSDimitry Andric } 697*700637cbSDimitry Andric 698*700637cbSDimitry Andric template <class _Kp, class _Mapped> 699*700637cbSDimitry Andric requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_assignable_v<mapped_type&, _Mapped> && 700*700637cbSDimitry Andric is_constructible_v<mapped_type, _Mapped> 701*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert_or_assign(const_iterator __hint,_Kp && __key,_Mapped && __obj)702*700637cbSDimitry Andric insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __obj) { 703*700637cbSDimitry Andric return __insert_or_assign(__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__obj)); 704*700637cbSDimitry Andric } 705*700637cbSDimitry Andric erase(iterator __position)706*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(iterator __position) { 707*700637cbSDimitry Andric return __erase(__position.__key_iter_, __position.__mapped_iter_); 708*700637cbSDimitry Andric } 709*700637cbSDimitry Andric erase(const_iterator __position)710*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __position) { 711*700637cbSDimitry Andric return __erase(__position.__key_iter_, __position.__mapped_iter_); 712*700637cbSDimitry Andric } 713*700637cbSDimitry Andric erase(const key_type & __x)714*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(const key_type& __x) { 715*700637cbSDimitry Andric auto __iter = find(__x); 716*700637cbSDimitry Andric if (__iter != end()) { 717*700637cbSDimitry Andric erase(__iter); 718*700637cbSDimitry Andric return 1; 719*700637cbSDimitry Andric } 720*700637cbSDimitry Andric return 0; 721*700637cbSDimitry Andric } 722*700637cbSDimitry Andric 723*700637cbSDimitry Andric template <class _Kp> 724*700637cbSDimitry Andric requires(__is_compare_transparent && !is_convertible_v<_Kp &&, iterator> && 725*700637cbSDimitry Andric !is_convertible_v<_Kp &&, const_iterator>) erase(_Kp && __x)726*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(_Kp&& __x) { 727*700637cbSDimitry Andric auto [__first, __last] = equal_range(__x); 728*700637cbSDimitry Andric auto __res = __last - __first; 729*700637cbSDimitry Andric erase(__first, __last); 730*700637cbSDimitry Andric return __res; 731*700637cbSDimitry Andric } 732*700637cbSDimitry Andric erase(const_iterator __first,const_iterator __last)733*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __first, const_iterator __last) { 734*700637cbSDimitry Andric auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 735*700637cbSDimitry Andric auto __key_it = __containers_.keys.erase(__first.__key_iter_, __last.__key_iter_); 736*700637cbSDimitry Andric auto __mapped_it = __containers_.values.erase(__first.__mapped_iter_, __last.__mapped_iter_); 737*700637cbSDimitry Andric __on_failure.__complete(); 738*700637cbSDimitry Andric return iterator(std::move(__key_it), std::move(__mapped_it)); 739*700637cbSDimitry Andric } 740*700637cbSDimitry Andric swap(flat_map & __y)741*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __y) noexcept { 742*700637cbSDimitry Andric // warning: The spec has unconditional noexcept, which means that 743*700637cbSDimitry Andric // if any of the following functions throw an exception, 744*700637cbSDimitry Andric // std::terminate will be called. 745*700637cbSDimitry Andric // This is discussed in P2767, which hasn't been voted on yet. 746*700637cbSDimitry Andric ranges::swap(__compare_, __y.__compare_); 747*700637cbSDimitry Andric ranges::swap(__containers_.keys, __y.__containers_.keys); 748*700637cbSDimitry Andric ranges::swap(__containers_.values, __y.__containers_.values); 749*700637cbSDimitry Andric } 750*700637cbSDimitry Andric clear()751*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { 752*700637cbSDimitry Andric __containers_.keys.clear(); 753*700637cbSDimitry Andric __containers_.values.clear(); 754*700637cbSDimitry Andric } 755*700637cbSDimitry Andric 756*700637cbSDimitry Andric // observers key_comp()757*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; } value_comp()758*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { 759*700637cbSDimitry Andric return value_compare(__compare_); 760*700637cbSDimitry Andric } 761*700637cbSDimitry Andric keys()762*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept { 763*700637cbSDimitry Andric return __containers_.keys; 764*700637cbSDimitry Andric } values()765*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type& values() const noexcept { 766*700637cbSDimitry Andric return __containers_.values; 767*700637cbSDimitry Andric } 768*700637cbSDimitry Andric 769*700637cbSDimitry Andric // map operations find(const key_type & __x)770*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) { 771*700637cbSDimitry Andric return __find_impl(*this, __x); 772*700637cbSDimitry Andric } 773*700637cbSDimitry Andric find(const key_type & __x)774*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const { 775*700637cbSDimitry Andric return __find_impl(*this, __x); 776*700637cbSDimitry Andric } 777*700637cbSDimitry Andric 778*700637cbSDimitry Andric template <class _Kp> 779*700637cbSDimitry Andric requires __is_compare_transparent find(const _Kp & __x)780*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) { 781*700637cbSDimitry Andric return __find_impl(*this, __x); 782*700637cbSDimitry Andric } 783*700637cbSDimitry Andric 784*700637cbSDimitry Andric template <class _Kp> 785*700637cbSDimitry Andric requires __is_compare_transparent find(const _Kp & __x)786*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const { 787*700637cbSDimitry Andric return __find_impl(*this, __x); 788*700637cbSDimitry Andric } 789*700637cbSDimitry Andric count(const key_type & __x)790*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const { 791*700637cbSDimitry Andric return contains(__x) ? 1 : 0; 792*700637cbSDimitry Andric } 793*700637cbSDimitry Andric 794*700637cbSDimitry Andric template <class _Kp> 795*700637cbSDimitry Andric requires __is_compare_transparent count(const _Kp & __x)796*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const { 797*700637cbSDimitry Andric return contains(__x) ? 1 : 0; 798*700637cbSDimitry Andric } 799*700637cbSDimitry Andric contains(const key_type & __x)800*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const { 801*700637cbSDimitry Andric return find(__x) != end(); 802*700637cbSDimitry Andric } 803*700637cbSDimitry Andric 804*700637cbSDimitry Andric template <class _Kp> 805*700637cbSDimitry Andric requires __is_compare_transparent contains(const _Kp & __x)806*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const { 807*700637cbSDimitry Andric return find(__x) != end(); 808*700637cbSDimitry Andric } 809*700637cbSDimitry Andric lower_bound(const key_type & __x)810*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) { 811*700637cbSDimitry Andric return __lower_bound<iterator>(*this, __x); 812*700637cbSDimitry Andric } 813*700637cbSDimitry Andric lower_bound(const key_type & __x)814*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const { 815*700637cbSDimitry Andric return __lower_bound<const_iterator>(*this, __x); 816*700637cbSDimitry Andric } 817*700637cbSDimitry Andric 818*700637cbSDimitry Andric template <class _Kp> 819*700637cbSDimitry Andric requires __is_compare_transparent lower_bound(const _Kp & __x)820*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) { 821*700637cbSDimitry Andric return __lower_bound<iterator>(*this, __x); 822*700637cbSDimitry Andric } 823*700637cbSDimitry Andric 824*700637cbSDimitry Andric template <class _Kp> 825*700637cbSDimitry Andric requires __is_compare_transparent lower_bound(const _Kp & __x)826*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const { 827*700637cbSDimitry Andric return __lower_bound<const_iterator>(*this, __x); 828*700637cbSDimitry Andric } 829*700637cbSDimitry Andric upper_bound(const key_type & __x)830*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) { 831*700637cbSDimitry Andric return __upper_bound<iterator>(*this, __x); 832*700637cbSDimitry Andric } 833*700637cbSDimitry Andric upper_bound(const key_type & __x)834*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const { 835*700637cbSDimitry Andric return __upper_bound<const_iterator>(*this, __x); 836*700637cbSDimitry Andric } 837*700637cbSDimitry Andric 838*700637cbSDimitry Andric template <class _Kp> 839*700637cbSDimitry Andric requires __is_compare_transparent upper_bound(const _Kp & __x)840*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) { 841*700637cbSDimitry Andric return __upper_bound<iterator>(*this, __x); 842*700637cbSDimitry Andric } 843*700637cbSDimitry Andric 844*700637cbSDimitry Andric template <class _Kp> 845*700637cbSDimitry Andric requires __is_compare_transparent upper_bound(const _Kp & __x)846*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const { 847*700637cbSDimitry Andric return __upper_bound<const_iterator>(*this, __x); 848*700637cbSDimitry Andric } 849*700637cbSDimitry Andric equal_range(const key_type & __x)850*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) { 851*700637cbSDimitry Andric return __equal_range_impl(*this, __x); 852*700637cbSDimitry Andric } 853*700637cbSDimitry Andric 854*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> equal_range(const key_type & __x)855*700637cbSDimitry Andric equal_range(const key_type& __x) const { 856*700637cbSDimitry Andric return __equal_range_impl(*this, __x); 857*700637cbSDimitry Andric } 858*700637cbSDimitry Andric 859*700637cbSDimitry Andric template <class _Kp> 860*700637cbSDimitry Andric requires __is_compare_transparent equal_range(const _Kp & __x)861*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) { 862*700637cbSDimitry Andric return __equal_range_impl(*this, __x); 863*700637cbSDimitry Andric } 864*700637cbSDimitry Andric template <class _Kp> 865*700637cbSDimitry Andric requires __is_compare_transparent 866*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator> equal_range(const _Kp & __x)867*700637cbSDimitry Andric equal_range(const _Kp& __x) const { 868*700637cbSDimitry Andric return __equal_range_impl(*this, __x); 869*700637cbSDimitry Andric } 870*700637cbSDimitry Andric 871*700637cbSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator==(const flat_map& __x, const flat_map& __y) { 872*700637cbSDimitry Andric return ranges::equal(__x, __y); 873*700637cbSDimitry Andric } 874*700637cbSDimitry Andric 875*700637cbSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto 876*700637cbSDimitry Andric operator<=>(const flat_map& __x, const flat_map& __y) { 877*700637cbSDimitry Andric return std::lexicographical_compare_three_way( 878*700637cbSDimitry Andric __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); 879*700637cbSDimitry Andric } 880*700637cbSDimitry Andric swap(flat_map & __x,flat_map & __y)881*700637cbSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __x, flat_map& __y) noexcept { 882*700637cbSDimitry Andric __x.swap(__y); 883*700637cbSDimitry Andric } 884*700637cbSDimitry Andric 885*700637cbSDimitry Andric private: 886*700637cbSDimitry Andric struct __ctor_uses_allocator_tag { 887*700637cbSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __ctor_uses_allocator_tag() = default; 888*700637cbSDimitry Andric }; 889*700637cbSDimitry Andric struct __ctor_uses_allocator_empty_tag { 890*700637cbSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __ctor_uses_allocator_empty_tag() = default; 891*700637cbSDimitry Andric }; 892*700637cbSDimitry Andric 893*700637cbSDimitry Andric template <class _Allocator, class _KeyCont, class _MappedCont, class... _CompArg> 894*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> flat_map(__ctor_uses_allocator_tag,const _Allocator & __alloc,_KeyCont && __key_cont,_MappedCont && __mapped_cont,_CompArg &&...__comp)895*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( 896*700637cbSDimitry Andric __ctor_uses_allocator_tag, 897*700637cbSDimitry Andric const _Allocator& __alloc, 898*700637cbSDimitry Andric _KeyCont&& __key_cont, 899*700637cbSDimitry Andric _MappedCont&& __mapped_cont, 900*700637cbSDimitry Andric _CompArg&&... __comp) 901*700637cbSDimitry Andric : __containers_{.keys = std::make_obj_using_allocator<key_container_type>( 902*700637cbSDimitry Andric __alloc, std::forward<_KeyCont>(__key_cont)), 903*700637cbSDimitry Andric .values = std::make_obj_using_allocator<mapped_container_type>( 904*700637cbSDimitry Andric __alloc, std::forward<_MappedCont>(__mapped_cont))}, 905*700637cbSDimitry Andric __compare_(std::forward<_CompArg>(__comp)...) {} 906*700637cbSDimitry Andric 907*700637cbSDimitry Andric template <class _Allocator, class... _CompArg> 908*700637cbSDimitry Andric requires __allocator_ctor_constraint<_Allocator> 909*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(__ctor_uses_allocator_empty_tag,const _Allocator & __alloc,_CompArg &&...__comp)910*700637cbSDimitry Andric flat_map(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp) 911*700637cbSDimitry Andric : __containers_{.keys = std::make_obj_using_allocator<key_container_type>(__alloc), 912*700637cbSDimitry Andric .values = std::make_obj_using_allocator<mapped_container_type>(__alloc)}, 913*700637cbSDimitry Andric __compare_(std::forward<_CompArg>(__comp)...) {} 914*700637cbSDimitry Andric __is_sorted_and_unique(auto && __key_container)915*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted_and_unique(auto&& __key_container) const { 916*700637cbSDimitry Andric auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); }; 917*700637cbSDimitry Andric return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container); 918*700637cbSDimitry Andric } 919*700637cbSDimitry Andric 920*700637cbSDimitry Andric // This function is only used in constructors. So there is not exception handling in this function. 921*700637cbSDimitry Andric // If the function exits via an exception, there will be no flat_map object constructed, thus, there 922*700637cbSDimitry Andric // is no invariant state to preserve __sort_and_unique()923*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __sort_and_unique() { 924*700637cbSDimitry Andric auto __zv = ranges::views::zip(__containers_.keys, __containers_.values); 925*700637cbSDimitry Andric ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); }); 926*700637cbSDimitry Andric auto __dup_start = ranges::unique(__zv, __key_equiv(__compare_)).begin(); 927*700637cbSDimitry Andric auto __dist = ranges::distance(__zv.begin(), __dup_start); 928*700637cbSDimitry Andric __containers_.keys.erase(__containers_.keys.begin() + __dist, __containers_.keys.end()); 929*700637cbSDimitry Andric __containers_.values.erase(__containers_.values.begin() + __dist, __containers_.values.end()); 930*700637cbSDimitry Andric } 931*700637cbSDimitry Andric 932*700637cbSDimitry Andric template <class _Self, class _KeyIter> 933*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __corresponding_mapped_it(_Self && __self,_KeyIter && __key_iter)934*700637cbSDimitry Andric __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) { 935*700637cbSDimitry Andric return __self.__containers_.values.begin() + 936*700637cbSDimitry Andric static_cast<ranges::range_difference_t<mapped_container_type>>( 937*700637cbSDimitry Andric ranges::distance(__self.__containers_.keys.begin(), __key_iter)); 938*700637cbSDimitry Andric } 939*700637cbSDimitry Andric 940*700637cbSDimitry Andric template <bool _WasSorted, class _InputIterator, class _Sentinel> 941*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __append_sort_merge_unique(_InputIterator __first,_Sentinel __last)942*700637cbSDimitry Andric __append_sort_merge_unique(_InputIterator __first, _Sentinel __last) { 943*700637cbSDimitry Andric auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 944*700637cbSDimitry Andric size_t __num_of_appended = __flat_map_utils::__append(*this, std::move(__first), std::move(__last)); 945*700637cbSDimitry Andric if (__num_of_appended != 0) { 946*700637cbSDimitry Andric auto __zv = ranges::views::zip(__containers_.keys, __containers_.values); 947*700637cbSDimitry Andric auto __append_start_offset = __containers_.keys.size() - __num_of_appended; 948*700637cbSDimitry Andric auto __end = __zv.end(); 949*700637cbSDimitry Andric auto __compare_key = [this](const auto& __p1, const auto& __p2) { 950*700637cbSDimitry Andric return __compare_(std::get<0>(__p1), std::get<0>(__p2)); 951*700637cbSDimitry Andric }; 952*700637cbSDimitry Andric if constexpr (!_WasSorted) { 953*700637cbSDimitry Andric ranges::sort(__zv.begin() + __append_start_offset, __end, __compare_key); 954*700637cbSDimitry Andric } else { 955*700637cbSDimitry Andric _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 956*700637cbSDimitry Andric __is_sorted_and_unique(__containers_.keys | ranges::views::drop(__append_start_offset)), 957*700637cbSDimitry Andric "Either the key container is not sorted or it contains duplicates"); 958*700637cbSDimitry Andric } 959*700637cbSDimitry Andric ranges::inplace_merge(__zv.begin(), __zv.begin() + __append_start_offset, __end, __compare_key); 960*700637cbSDimitry Andric 961*700637cbSDimitry Andric auto __dup_start = ranges::unique(__zv, __key_equiv(__compare_)).begin(); 962*700637cbSDimitry Andric auto __dist = ranges::distance(__zv.begin(), __dup_start); 963*700637cbSDimitry Andric __containers_.keys.erase(__containers_.keys.begin() + __dist, __containers_.keys.end()); 964*700637cbSDimitry Andric __containers_.values.erase(__containers_.values.begin() + __dist, __containers_.values.end()); 965*700637cbSDimitry Andric } 966*700637cbSDimitry Andric __on_failure.__complete(); 967*700637cbSDimitry Andric } 968*700637cbSDimitry Andric 969*700637cbSDimitry Andric template <class _Self, class _Kp> __find_impl(_Self && __self,const _Kp & __key)970*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __find_impl(_Self&& __self, const _Kp& __key) { 971*700637cbSDimitry Andric auto __it = __self.lower_bound(__key); 972*700637cbSDimitry Andric auto __last = __self.end(); 973*700637cbSDimitry Andric if (__it == __last || __self.__compare_(__key, __it->first)) { 974*700637cbSDimitry Andric return __last; 975*700637cbSDimitry Andric } 976*700637cbSDimitry Andric return __it; 977*700637cbSDimitry Andric } 978*700637cbSDimitry Andric 979*700637cbSDimitry Andric template <class _Self, class _Kp> __key_equal_range(_Self && __self,const _Kp & __key)980*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __key_equal_range(_Self&& __self, const _Kp& __key) { 981*700637cbSDimitry Andric auto __it = 982*700637cbSDimitry Andric std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_); 983*700637cbSDimitry Andric auto __last = __self.__containers_.keys.end(); 984*700637cbSDimitry Andric if (__it == __last || __self.__compare_(__key, *__it)) { 985*700637cbSDimitry Andric return std::make_pair(__it, __it); 986*700637cbSDimitry Andric } 987*700637cbSDimitry Andric return std::make_pair(__it, std::next(__it)); 988*700637cbSDimitry Andric } 989*700637cbSDimitry Andric 990*700637cbSDimitry Andric template <class _Self, class _Kp> __equal_range_impl(_Self && __self,const _Kp & __key)991*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __equal_range_impl(_Self&& __self, const _Kp& __key) { 992*700637cbSDimitry Andric auto [__key_first, __key_last] = __key_equal_range(__self, __key); 993*700637cbSDimitry Andric using __iterator_type = ranges::iterator_t<decltype(__self)>; 994*700637cbSDimitry Andric return std::make_pair(__iterator_type(__key_first, __corresponding_mapped_it(__self, __key_first)), 995*700637cbSDimitry Andric __iterator_type(__key_last, __corresponding_mapped_it(__self, __key_last))); 996*700637cbSDimitry Andric } 997*700637cbSDimitry Andric 998*700637cbSDimitry Andric template <class _Res, class _Self, class _Kp> __lower_bound(_Self && __self,_Kp & __x)999*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static _Res __lower_bound(_Self&& __self, _Kp& __x) { 1000*700637cbSDimitry Andric auto __key_iter = 1001*700637cbSDimitry Andric std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); 1002*700637cbSDimitry Andric auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); 1003*700637cbSDimitry Andric return _Res(std::move(__key_iter), std::move(__mapped_iter)); 1004*700637cbSDimitry Andric } 1005*700637cbSDimitry Andric 1006*700637cbSDimitry Andric template <class _Res, class _Self, class _Kp> __upper_bound(_Self && __self,_Kp & __x)1007*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static _Res __upper_bound(_Self&& __self, _Kp& __x) { 1008*700637cbSDimitry Andric auto __key_iter = 1009*700637cbSDimitry Andric std::upper_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); 1010*700637cbSDimitry Andric auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); 1011*700637cbSDimitry Andric return _Res(std::move(__key_iter), std::move(__mapped_iter)); 1012*700637cbSDimitry Andric } 1013*700637cbSDimitry Andric 1014*700637cbSDimitry Andric template <class _KeyArg, class... _MArgs> 1015*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> __try_emplace(_KeyArg && __key,_MArgs &&...__mapped_args)1016*700637cbSDimitry Andric __try_emplace(_KeyArg&& __key, _MArgs&&... __mapped_args) { 1017*700637cbSDimitry Andric auto __key_it = std::lower_bound(__containers_.keys.begin(), __containers_.keys.end(), __key, __compare_); 1018*700637cbSDimitry Andric auto __mapped_it = __containers_.values.begin() + ranges::distance(__containers_.keys.begin(), __key_it); 1019*700637cbSDimitry Andric 1020*700637cbSDimitry Andric if (__key_it == __containers_.keys.end() || __compare_(__key, *__key_it)) { 1021*700637cbSDimitry Andric return pair<iterator, bool>( 1022*700637cbSDimitry Andric __flat_map_utils::__emplace_exact_pos( 1023*700637cbSDimitry Andric *this, 1024*700637cbSDimitry Andric std::move(__key_it), 1025*700637cbSDimitry Andric std::move(__mapped_it), 1026*700637cbSDimitry Andric std::forward<_KeyArg>(__key), 1027*700637cbSDimitry Andric std::forward<_MArgs>(__mapped_args)...), 1028*700637cbSDimitry Andric true); 1029*700637cbSDimitry Andric } else { 1030*700637cbSDimitry Andric return pair<iterator, bool>(iterator(std::move(__key_it), std::move(__mapped_it)), false); 1031*700637cbSDimitry Andric } 1032*700637cbSDimitry Andric } 1033*700637cbSDimitry Andric 1034*700637cbSDimitry Andric template <class _Kp> __is_hint_correct(const_iterator __hint,_Kp && __key)1035*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_hint_correct(const_iterator __hint, _Kp&& __key) { 1036*700637cbSDimitry Andric if (__hint != cbegin() && !__compare_((__hint - 1)->first, __key)) { 1037*700637cbSDimitry Andric return false; 1038*700637cbSDimitry Andric } 1039*700637cbSDimitry Andric if (__hint != cend() && __compare_(__hint->first, __key)) { 1040*700637cbSDimitry Andric return false; 1041*700637cbSDimitry Andric } 1042*700637cbSDimitry Andric return true; 1043*700637cbSDimitry Andric } 1044*700637cbSDimitry Andric 1045*700637cbSDimitry Andric template <class _Kp, class... _Args> 1046*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> __try_emplace_hint(const_iterator __hint,_Kp && __key,_Args &&...__args)1047*700637cbSDimitry Andric __try_emplace_hint(const_iterator __hint, _Kp&& __key, _Args&&... __args) { 1048*700637cbSDimitry Andric if (__is_hint_correct(__hint, __key)) { 1049*700637cbSDimitry Andric if (__hint == cend() || __compare_(__key, __hint->first)) { 1050*700637cbSDimitry Andric return {__flat_map_utils::__emplace_exact_pos( 1051*700637cbSDimitry Andric *this, 1052*700637cbSDimitry Andric __hint.__key_iter_, 1053*700637cbSDimitry Andric __hint.__mapped_iter_, 1054*700637cbSDimitry Andric std::forward<_Kp>(__key), 1055*700637cbSDimitry Andric std::forward<_Args>(__args)...), 1056*700637cbSDimitry Andric true}; 1057*700637cbSDimitry Andric } else { 1058*700637cbSDimitry Andric // key equals 1059*700637cbSDimitry Andric auto __dist = __hint - cbegin(); 1060*700637cbSDimitry Andric return {iterator(__containers_.keys.begin() + __dist, __containers_.values.begin() + __dist), false}; 1061*700637cbSDimitry Andric } 1062*700637cbSDimitry Andric } else { 1063*700637cbSDimitry Andric return __try_emplace(std::forward<_Kp>(__key), std::forward<_Args>(__args)...); 1064*700637cbSDimitry Andric } 1065*700637cbSDimitry Andric } 1066*700637cbSDimitry Andric 1067*700637cbSDimitry Andric template <class _Kp, class _Mapped> 1068*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> __insert_or_assign(_Kp && __key,_Mapped && __mapped)1069*700637cbSDimitry Andric __insert_or_assign(_Kp&& __key, _Mapped&& __mapped) { 1070*700637cbSDimitry Andric auto __r = try_emplace(std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped)); 1071*700637cbSDimitry Andric if (!__r.second) { 1072*700637cbSDimitry Andric __r.first->second = std::forward<_Mapped>(__mapped); 1073*700637cbSDimitry Andric } 1074*700637cbSDimitry Andric return __r; 1075*700637cbSDimitry Andric } 1076*700637cbSDimitry Andric 1077*700637cbSDimitry Andric template <class _Kp, class _Mapped> 1078*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __insert_or_assign(const_iterator __hint,_Kp && __key,_Mapped && __mapped)1079*700637cbSDimitry Andric __insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __mapped) { 1080*700637cbSDimitry Andric auto __r = __try_emplace_hint(__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped)); 1081*700637cbSDimitry Andric if (!__r.second) { 1082*700637cbSDimitry Andric __r.first->second = std::forward<_Mapped>(__mapped); 1083*700637cbSDimitry Andric } 1084*700637cbSDimitry Andric return __r.first; 1085*700637cbSDimitry Andric } 1086*700637cbSDimitry Andric __reserve(size_t __size)1087*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __reserve(size_t __size) { 1088*700637cbSDimitry Andric if constexpr (__container_traits<_KeyContainer>::__reservable) { 1089*700637cbSDimitry Andric __containers_.keys.reserve(__size); 1090*700637cbSDimitry Andric } 1091*700637cbSDimitry Andric 1092*700637cbSDimitry Andric if constexpr (__container_traits<_MappedContainer>::__reservable) { 1093*700637cbSDimitry Andric __containers_.values.reserve(__size); 1094*700637cbSDimitry Andric } 1095*700637cbSDimitry Andric } 1096*700637cbSDimitry Andric 1097*700637cbSDimitry Andric template <class _KIter, class _MIter> 1098*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __erase(_KIter __key_iter_to_remove,_MIter __mapped_iter_to_remove)1099*700637cbSDimitry Andric __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) { 1100*700637cbSDimitry Andric auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 1101*700637cbSDimitry Andric auto __key_iter = __containers_.keys.erase(__key_iter_to_remove); 1102*700637cbSDimitry Andric auto __mapped_iter = __containers_.values.erase(__mapped_iter_to_remove); 1103*700637cbSDimitry Andric __on_failure.__complete(); 1104*700637cbSDimitry Andric return iterator(std::move(__key_iter), std::move(__mapped_iter)); 1105*700637cbSDimitry Andric } 1106*700637cbSDimitry Andric 1107*700637cbSDimitry Andric template <class _Key2, class _Tp2, class _Compare2, class _KeyContainer2, class _MappedContainer2, class _Predicate> 1108*700637cbSDimitry Andric friend typename flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type 1109*700637cbSDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX26 1110*700637cbSDimitry Andric erase_if(flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate); 1111*700637cbSDimitry Andric 1112*700637cbSDimitry Andric friend __flat_map_utils; 1113*700637cbSDimitry Andric 1114*700637cbSDimitry Andric containers __containers_; 1115*700637cbSDimitry Andric _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_; 1116*700637cbSDimitry Andric 1117*700637cbSDimitry Andric struct __key_equiv { __key_equiv__key_equiv1118*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_equiv(key_compare __c) : __comp_(__c) {} 1119*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator__key_equiv1120*700637cbSDimitry Andric operator()(const_reference __x, const_reference __y) const { 1121*700637cbSDimitry Andric return !__comp_(std::get<0>(__x), std::get<0>(__y)) && !__comp_(std::get<0>(__y), std::get<0>(__x)); 1122*700637cbSDimitry Andric } 1123*700637cbSDimitry Andric key_compare __comp_; 1124*700637cbSDimitry Andric }; 1125*700637cbSDimitry Andric }; 1126*700637cbSDimitry Andric 1127*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>> 1128*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 1129*700637cbSDimitry Andric !__is_allocator<_MappedContainer>::value && 1130*700637cbSDimitry Andric is_invocable_v<const _Compare&, 1131*700637cbSDimitry Andric const typename _KeyContainer::value_type&, 1132*700637cbSDimitry Andric const typename _KeyContainer::value_type&>) 1133*700637cbSDimitry Andric flat_map(_KeyContainer, _MappedContainer, _Compare = _Compare()) 1134*700637cbSDimitry Andric -> flat_map<typename _KeyContainer::value_type, 1135*700637cbSDimitry Andric typename _MappedContainer::value_type, 1136*700637cbSDimitry Andric _Compare, 1137*700637cbSDimitry Andric _KeyContainer, 1138*700637cbSDimitry Andric _MappedContainer>; 1139*700637cbSDimitry Andric 1140*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Allocator> 1141*700637cbSDimitry Andric requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> && 1142*700637cbSDimitry Andric !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value) 1143*700637cbSDimitry Andric flat_map(_KeyContainer, _MappedContainer, _Allocator) 1144*700637cbSDimitry Andric -> flat_map<typename _KeyContainer::value_type, 1145*700637cbSDimitry Andric typename _MappedContainer::value_type, 1146*700637cbSDimitry Andric less<typename _KeyContainer::value_type>, 1147*700637cbSDimitry Andric _KeyContainer, 1148*700637cbSDimitry Andric _MappedContainer>; 1149*700637cbSDimitry Andric 1150*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator> 1151*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 1152*700637cbSDimitry Andric !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> && 1153*700637cbSDimitry Andric uses_allocator_v<_MappedContainer, _Allocator> && 1154*700637cbSDimitry Andric is_invocable_v<const _Compare&, 1155*700637cbSDimitry Andric const typename _KeyContainer::value_type&, 1156*700637cbSDimitry Andric const typename _KeyContainer::value_type&>) 1157*700637cbSDimitry Andric flat_map(_KeyContainer, _MappedContainer, _Compare, _Allocator) 1158*700637cbSDimitry Andric -> flat_map<typename _KeyContainer::value_type, 1159*700637cbSDimitry Andric typename _MappedContainer::value_type, 1160*700637cbSDimitry Andric _Compare, 1161*700637cbSDimitry Andric _KeyContainer, 1162*700637cbSDimitry Andric _MappedContainer>; 1163*700637cbSDimitry Andric 1164*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>> 1165*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 1166*700637cbSDimitry Andric !__is_allocator<_MappedContainer>::value && 1167*700637cbSDimitry Andric is_invocable_v<const _Compare&, 1168*700637cbSDimitry Andric const typename _KeyContainer::value_type&, 1169*700637cbSDimitry Andric const typename _KeyContainer::value_type&>) 1170*700637cbSDimitry Andric flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Compare = _Compare()) 1171*700637cbSDimitry Andric -> flat_map<typename _KeyContainer::value_type, 1172*700637cbSDimitry Andric typename _MappedContainer::value_type, 1173*700637cbSDimitry Andric _Compare, 1174*700637cbSDimitry Andric _KeyContainer, 1175*700637cbSDimitry Andric _MappedContainer>; 1176*700637cbSDimitry Andric 1177*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Allocator> 1178*700637cbSDimitry Andric requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> && 1179*700637cbSDimitry Andric !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value) 1180*700637cbSDimitry Andric flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Allocator) 1181*700637cbSDimitry Andric -> flat_map<typename _KeyContainer::value_type, 1182*700637cbSDimitry Andric typename _MappedContainer::value_type, 1183*700637cbSDimitry Andric less<typename _KeyContainer::value_type>, 1184*700637cbSDimitry Andric _KeyContainer, 1185*700637cbSDimitry Andric _MappedContainer>; 1186*700637cbSDimitry Andric 1187*700637cbSDimitry Andric template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator> 1188*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 1189*700637cbSDimitry Andric !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> && 1190*700637cbSDimitry Andric uses_allocator_v<_MappedContainer, _Allocator> && 1191*700637cbSDimitry Andric is_invocable_v<const _Compare&, 1192*700637cbSDimitry Andric const typename _KeyContainer::value_type&, 1193*700637cbSDimitry Andric const typename _KeyContainer::value_type&>) 1194*700637cbSDimitry Andric flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Compare, _Allocator) 1195*700637cbSDimitry Andric -> flat_map<typename _KeyContainer::value_type, 1196*700637cbSDimitry Andric typename _MappedContainer::value_type, 1197*700637cbSDimitry Andric _Compare, 1198*700637cbSDimitry Andric _KeyContainer, 1199*700637cbSDimitry Andric _MappedContainer>; 1200*700637cbSDimitry Andric 1201*700637cbSDimitry Andric template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>> 1202*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value) 1203*700637cbSDimitry Andric flat_map(_InputIterator, _InputIterator, _Compare = _Compare()) 1204*700637cbSDimitry Andric -> flat_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>; 1205*700637cbSDimitry Andric 1206*700637cbSDimitry Andric template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>> 1207*700637cbSDimitry Andric requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value) 1208*700637cbSDimitry Andric flat_map(sorted_unique_t, _InputIterator, _InputIterator, _Compare = _Compare()) 1209*700637cbSDimitry Andric -> flat_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>; 1210*700637cbSDimitry Andric 1211*700637cbSDimitry Andric template <ranges::input_range _Range, 1212*700637cbSDimitry Andric class _Compare = less<__range_key_type<_Range>>, 1213*700637cbSDimitry Andric class _Allocator = allocator<byte>, 1214*700637cbSDimitry Andric class = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>> 1215*700637cbSDimitry Andric flat_map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_map< 1216*700637cbSDimitry Andric __range_key_type<_Range>, 1217*700637cbSDimitry Andric __range_mapped_type<_Range>, 1218*700637cbSDimitry Andric _Compare, 1219*700637cbSDimitry Andric vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>, 1220*700637cbSDimitry Andric vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>; 1221*700637cbSDimitry Andric 1222*700637cbSDimitry Andric template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>> 1223*700637cbSDimitry Andric flat_map(from_range_t, _Range&&, _Allocator) -> flat_map< 1224*700637cbSDimitry Andric __range_key_type<_Range>, 1225*700637cbSDimitry Andric __range_mapped_type<_Range>, 1226*700637cbSDimitry Andric less<__range_key_type<_Range>>, 1227*700637cbSDimitry Andric vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>, 1228*700637cbSDimitry Andric vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>; 1229*700637cbSDimitry Andric 1230*700637cbSDimitry Andric template <class _Key, class _Tp, class _Compare = less<_Key>> 1231*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value) 1232*700637cbSDimitry Andric flat_map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) -> flat_map<_Key, _Tp, _Compare>; 1233*700637cbSDimitry Andric 1234*700637cbSDimitry Andric template <class _Key, class _Tp, class _Compare = less<_Key>> 1235*700637cbSDimitry Andric requires(!__is_allocator<_Compare>::value) 1236*700637cbSDimitry Andric flat_map(sorted_unique_t, initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) -> flat_map<_Key, _Tp, _Compare>; 1237*700637cbSDimitry Andric 1238*700637cbSDimitry Andric template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Allocator> 1239*700637cbSDimitry Andric struct uses_allocator<flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>, _Allocator> 1240*700637cbSDimitry Andric : bool_constant<uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator>> {}; 1241*700637cbSDimitry Andric 1242*700637cbSDimitry Andric template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Predicate> 1243*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 1244*700637cbSDimitry Andric typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type 1245*700637cbSDimitry Andric erase_if(flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_map, _Predicate __pred) { 1246*700637cbSDimitry Andric auto __zv = ranges::views::zip(__flat_map.__containers_.keys, __flat_map.__containers_.values); 1247*700637cbSDimitry Andric auto __first = __zv.begin(); 1248*700637cbSDimitry Andric auto __last = __zv.end(); 1249*700637cbSDimitry Andric auto __guard = std::__make_exception_guard([&] { __flat_map.clear(); }); 1250*700637cbSDimitry Andric auto __it = std::remove_if(__first, __last, [&](auto&& __zipped) -> bool { 1251*700637cbSDimitry Andric using _Ref = typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::const_reference; 1252*700637cbSDimitry Andric return __pred(_Ref(std::get<0>(__zipped), std::get<1>(__zipped))); 1253*700637cbSDimitry Andric }); 1254*700637cbSDimitry Andric auto __res = __last - __it; 1255*700637cbSDimitry Andric auto __offset = __it - __first; 1256*700637cbSDimitry Andric 1257*700637cbSDimitry Andric const auto __erase_container = [&](auto& __cont) { __cont.erase(__cont.begin() + __offset, __cont.end()); }; 1258*700637cbSDimitry Andric 1259*700637cbSDimitry Andric __erase_container(__flat_map.__containers_.keys); 1260*700637cbSDimitry Andric __erase_container(__flat_map.__containers_.values); 1261*700637cbSDimitry Andric 1262*700637cbSDimitry Andric __guard.__complete(); 1263*700637cbSDimitry Andric return __res; 1264*700637cbSDimitry Andric } 1265*700637cbSDimitry Andric 1266*700637cbSDimitry Andric _LIBCPP_END_NAMESPACE_STD 1267*700637cbSDimitry Andric 1268*700637cbSDimitry Andric #endif // _LIBCPP_STD_VER >= 23 1269*700637cbSDimitry Andric 1270*700637cbSDimitry Andric _LIBCPP_POP_MACROS 1271*700637cbSDimitry Andric 1272*700637cbSDimitry Andric #endif // _LIBCPP___FLAT_MAP_FLAT_MAP_H 1273