10be1883cSHui // -*- C++ -*- 20be1883cSHui //===----------------------------------------------------------------------===// 30be1883cSHui // 40be1883cSHui // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50be1883cSHui // See https://llvm.org/LICENSE.txt for license information. 60be1883cSHui // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70be1883cSHui // 80be1883cSHui //===----------------------------------------------------------------------===// 90be1883cSHui 100be1883cSHui #ifndef _LIBCPP___FLAT_MAP_FLAT_MAP_H 110be1883cSHui #define _LIBCPP___FLAT_MAP_FLAT_MAP_H 120be1883cSHui 130be1883cSHui #include <__algorithm/lexicographical_compare_three_way.h> 14332fda86SNikolas Klauser #include <__algorithm/min.h> 150be1883cSHui #include <__algorithm/ranges_adjacent_find.h> 160be1883cSHui #include <__algorithm/ranges_equal.h> 170be1883cSHui #include <__algorithm/ranges_inplace_merge.h> 180be1883cSHui #include <__algorithm/ranges_lower_bound.h> 190be1883cSHui #include <__algorithm/ranges_partition_point.h> 20162397f9SHui #include <__algorithm/ranges_sort.h> 210be1883cSHui #include <__algorithm/ranges_unique.h> 220be1883cSHui #include <__algorithm/ranges_upper_bound.h> 23332fda86SNikolas Klauser #include <__algorithm/remove_if.h> 24332fda86SNikolas Klauser #include <__assert> 250be1883cSHui #include <__compare/synth_three_way.h> 260be1883cSHui #include <__concepts/swappable.h> 270be1883cSHui #include <__config> 28e99c4906SNikolas Klauser #include <__cstddef/byte.h> 29332fda86SNikolas Klauser #include <__cstddef/ptrdiff_t.h> 30f22ecdd9SHui #include <__flat_map/key_value_iterator.h> 310be1883cSHui #include <__flat_map/sorted_unique.h> 32*def50f70SHui #include <__flat_map/utils.h> 330be1883cSHui #include <__functional/invoke.h> 340be1883cSHui #include <__functional/is_transparent.h> 350be1883cSHui #include <__functional/operations.h> 36*def50f70SHui #include <__fwd/vector.h> 370be1883cSHui #include <__iterator/concepts.h> 380be1883cSHui #include <__iterator/distance.h> 390be1883cSHui #include <__iterator/iterator_traits.h> 400be1883cSHui #include <__iterator/next.h> 410be1883cSHui #include <__iterator/ranges_iterator_traits.h> 420be1883cSHui #include <__iterator/reverse_iterator.h> 430be1883cSHui #include <__memory/allocator_traits.h> 440be1883cSHui #include <__memory/uses_allocator.h> 450be1883cSHui #include <__memory/uses_allocator_construction.h> 46332fda86SNikolas Klauser #include <__ranges/access.h> 470be1883cSHui #include <__ranges/concepts.h> 480be1883cSHui #include <__ranges/container_compatible_range.h> 490be1883cSHui #include <__ranges/drop_view.h> 50332fda86SNikolas Klauser #include <__ranges/from_range.h> 510be1883cSHui #include <__ranges/ref_view.h> 52332fda86SNikolas Klauser #include <__ranges/size.h> 530be1883cSHui #include <__ranges/subrange.h> 540be1883cSHui #include <__ranges/zip_view.h> 550be1883cSHui #include <__type_traits/conjunction.h> 560be1883cSHui #include <__type_traits/container_traits.h> 570be1883cSHui #include <__type_traits/invoke.h> 580be1883cSHui #include <__type_traits/is_allocator.h> 590be1883cSHui #include <__type_traits/is_nothrow_constructible.h> 600be1883cSHui #include <__type_traits/is_same.h> 610be1883cSHui #include <__utility/exception_guard.h> 62f22ecdd9SHui #include <__utility/move.h> 630be1883cSHui #include <__utility/pair.h> 645098b56dSNikolas Klauser #include <__utility/scope_guard.h> 65332fda86SNikolas Klauser #include <__vector/vector.h> 660be1883cSHui #include <initializer_list> 670be1883cSHui #include <stdexcept> 680be1883cSHui 690be1883cSHui #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 700be1883cSHui # pragma GCC system_header 710be1883cSHui #endif 720be1883cSHui 730be1883cSHui _LIBCPP_PUSH_MACROS 740be1883cSHui #include <__undef_macros> 750be1883cSHui 760be1883cSHui #if _LIBCPP_STD_VER >= 23 770be1883cSHui 780be1883cSHui _LIBCPP_BEGIN_NAMESPACE_STD 790be1883cSHui 800be1883cSHui template <class _Key, 810be1883cSHui class _Tp, 820be1883cSHui class _Compare = less<_Key>, 830be1883cSHui class _KeyContainer = vector<_Key>, 840be1883cSHui class _MappedContainer = vector<_Tp>> 850be1883cSHui class flat_map { 860be1883cSHui template <class, class, class, class, class> 870be1883cSHui friend class flat_map; 880be1883cSHui 890be1883cSHui static_assert(is_same_v<_Key, typename _KeyContainer::value_type>); 900be1883cSHui static_assert(is_same_v<_Tp, typename _MappedContainer::value_type>); 910be1883cSHui static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container"); 920be1883cSHui static_assert(!is_same_v<_MappedContainer, std::vector<bool>>, "vector<bool> is not a sequence container"); 930be1883cSHui 94f22ecdd9SHui template <bool _Const> 95f6958523SNikolas Klauser using __iterator _LIBCPP_NODEBUG = __key_value_iterator<flat_map, _KeyContainer, _MappedContainer, _Const>; 96f22ecdd9SHui 970be1883cSHui public: 980be1883cSHui // types 990be1883cSHui using key_type = _Key; 1000be1883cSHui using mapped_type = _Tp; 1010be1883cSHui using value_type = pair<key_type, mapped_type>; 1020be1883cSHui using key_compare = __type_identity_t<_Compare>; 1030be1883cSHui using reference = pair<const key_type&, mapped_type&>; 1040be1883cSHui using const_reference = pair<const key_type&, const mapped_type&>; 1050be1883cSHui using size_type = size_t; 1060be1883cSHui using difference_type = ptrdiff_t; 1070be1883cSHui using iterator = __iterator<false>; // see [container.requirements] 1080be1883cSHui using const_iterator = __iterator<true>; // see [container.requirements] 1090be1883cSHui using reverse_iterator = std::reverse_iterator<iterator>; 1100be1883cSHui using const_reverse_iterator = std::reverse_iterator<const_iterator>; 1110be1883cSHui using key_container_type = _KeyContainer; 1120be1883cSHui using mapped_container_type = _MappedContainer; 1130be1883cSHui 1140be1883cSHui class value_compare { 1150be1883cSHui private: 1160be1883cSHui key_compare __comp_; 11781118676SNikolas Klauser _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : __comp_(__c) {} 1180be1883cSHui friend flat_map; 1190be1883cSHui 1200be1883cSHui public: 1210be1883cSHui _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const { 1220be1883cSHui return __comp_(__x.first, __y.first); 1230be1883cSHui } 1240be1883cSHui }; 1250be1883cSHui 1260be1883cSHui struct containers { 1270be1883cSHui key_container_type keys; 1280be1883cSHui mapped_container_type values; 1290be1883cSHui }; 1300be1883cSHui 1310be1883cSHui private: 1320be1883cSHui template <class _Allocator> 1330be1883cSHui _LIBCPP_HIDE_FROM_ABI static constexpr bool __allocator_ctor_constraint = 1340be1883cSHui _And<uses_allocator<key_container_type, _Allocator>, uses_allocator<mapped_container_type, _Allocator>>::value; 1350be1883cSHui 136*def50f70SHui _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_compare_transparent = __is_transparent_v<_Compare>; 1370be1883cSHui 1380be1883cSHui public: 1390be1883cSHui // [flat.map.cons], construct/copy/destroy 1400be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map() noexcept( 1410be1883cSHui is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_MappedContainer> && 1420be1883cSHui is_nothrow_default_constructible_v<_Compare>) 1430be1883cSHui : __containers_(), __compare_() {} 1440be1883cSHui 1450be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(const flat_map&) = default; 1460be1883cSHui 1470be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(flat_map&& __other) noexcept( 1480be1883cSHui is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_MappedContainer> && 1490be1883cSHui is_nothrow_move_constructible_v<_Compare>) 1500be1883cSHui # if _LIBCPP_HAS_EXCEPTIONS 1510be1883cSHui try 1520be1883cSHui # endif // _LIBCPP_HAS_EXCEPTIONS 1530be1883cSHui : __containers_(std::move(__other.__containers_)), __compare_(std::move(__other.__compare_)) { 1540be1883cSHui __other.clear(); 1550be1883cSHui # if _LIBCPP_HAS_EXCEPTIONS 1560be1883cSHui } catch (...) { 1570be1883cSHui __other.clear(); 158*def50f70SHui // gcc does not like the `throw` keyword in a conditionally noexcept function 1590be1883cSHui if constexpr (!(is_nothrow_move_constructible_v<_KeyContainer> && 1600be1883cSHui is_nothrow_move_constructible_v<_MappedContainer> && is_nothrow_move_constructible_v<_Compare>)) { 1610be1883cSHui throw; 1620be1883cSHui } 1630be1883cSHui # endif // _LIBCPP_HAS_EXCEPTIONS 1640be1883cSHui } 1650be1883cSHui 1660be1883cSHui template <class _Allocator> 1670be1883cSHui requires __allocator_ctor_constraint<_Allocator> 1680be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(const flat_map& __other, const _Allocator& __alloc) 1690be1883cSHui : flat_map(__ctor_uses_allocator_tag{}, 1700be1883cSHui __alloc, 1710be1883cSHui __other.__containers_.keys, 1720be1883cSHui __other.__containers_.values, 1730be1883cSHui __other.__compare_) {} 1740be1883cSHui 1750be1883cSHui template <class _Allocator> 1760be1883cSHui requires __allocator_ctor_constraint<_Allocator> 1770be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(flat_map&& __other, const _Allocator& __alloc) 1780be1883cSHui # if _LIBCPP_HAS_EXCEPTIONS 1790be1883cSHui try 1800be1883cSHui # endif // _LIBCPP_HAS_EXCEPTIONS 1810be1883cSHui : flat_map(__ctor_uses_allocator_tag{}, 1820be1883cSHui __alloc, 1830be1883cSHui std::move(__other.__containers_.keys), 1840be1883cSHui std::move(__other.__containers_.values), 1850be1883cSHui std::move(__other.__compare_)) { 1860be1883cSHui __other.clear(); 1870be1883cSHui # if _LIBCPP_HAS_EXCEPTIONS 1880be1883cSHui } catch (...) { 1890be1883cSHui __other.clear(); 1900be1883cSHui throw; 1910be1883cSHui # endif // _LIBCPP_HAS_EXCEPTIONS 1920be1883cSHui } 1930be1883cSHui 1940be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map( 1950be1883cSHui key_container_type __key_cont, mapped_container_type __mapped_cont, const key_compare& __comp = key_compare()) 1960be1883cSHui : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) { 1970be1883cSHui _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 1980be1883cSHui "flat_map keys and mapped containers have different size"); 1990be1883cSHui __sort_and_unique(); 2000be1883cSHui } 2010be1883cSHui 2020be1883cSHui template <class _Allocator> 2030be1883cSHui requires __allocator_ctor_constraint<_Allocator> 2040be1883cSHui _LIBCPP_HIDE_FROM_ABI 2050be1883cSHui flat_map(const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const _Allocator& __alloc) 2060be1883cSHui : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { 2070be1883cSHui _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 2080be1883cSHui "flat_map keys and mapped containers have different size"); 2090be1883cSHui __sort_and_unique(); 2100be1883cSHui } 2110be1883cSHui 2120be1883cSHui template <class _Allocator> 2130be1883cSHui requires __allocator_ctor_constraint<_Allocator> 2140be1883cSHui _LIBCPP_HIDE_FROM_ABI 2150be1883cSHui flat_map(const key_container_type& __key_cont, 2160be1883cSHui const mapped_container_type& __mapped_cont, 2170be1883cSHui const key_compare& __comp, 2180be1883cSHui const _Allocator& __alloc) 2190be1883cSHui : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) { 2200be1883cSHui _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 2210be1883cSHui "flat_map keys and mapped containers have different size"); 2220be1883cSHui __sort_and_unique(); 2230be1883cSHui } 2240be1883cSHui 2250be1883cSHui _LIBCPP_HIDE_FROM_ABI 2260be1883cSHui flat_map(sorted_unique_t, 2270be1883cSHui key_container_type __key_cont, 2280be1883cSHui mapped_container_type __mapped_cont, 2290be1883cSHui const key_compare& __comp = key_compare()) 2300be1883cSHui : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) { 2310be1883cSHui _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 2320be1883cSHui "flat_map keys and mapped containers have different size"); 2330be1883cSHui _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 2340be1883cSHui __is_sorted_and_unique(__containers_.keys), "Either the key container is not sorted or it contains duplicates"); 2350be1883cSHui } 2360be1883cSHui 2370be1883cSHui template <class _Allocator> 2380be1883cSHui requires __allocator_ctor_constraint<_Allocator> 2390be1883cSHui _LIBCPP_HIDE_FROM_ABI 2400be1883cSHui flat_map(sorted_unique_t, 2410be1883cSHui const key_container_type& __key_cont, 2420be1883cSHui const mapped_container_type& __mapped_cont, 2430be1883cSHui const _Allocator& __alloc) 2440be1883cSHui : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { 2450be1883cSHui _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 2460be1883cSHui "flat_map keys and mapped containers have different size"); 2470be1883cSHui _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 2480be1883cSHui __is_sorted_and_unique(__containers_.keys), "Either the key container is not sorted or it contains duplicates"); 2490be1883cSHui } 2500be1883cSHui 2510be1883cSHui template <class _Allocator> 2520be1883cSHui requires __allocator_ctor_constraint<_Allocator> 2530be1883cSHui _LIBCPP_HIDE_FROM_ABI 2540be1883cSHui flat_map(sorted_unique_t, 2550be1883cSHui const key_container_type& __key_cont, 2560be1883cSHui const mapped_container_type& __mapped_cont, 2570be1883cSHui const key_compare& __comp, 2580be1883cSHui const _Allocator& __alloc) 2590be1883cSHui : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) { 2600be1883cSHui _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), 2610be1883cSHui "flat_map keys and mapped containers have different size"); 2620be1883cSHui _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 2630be1883cSHui __is_sorted_and_unique(__containers_.keys), "Either the key container is not sorted or it contains duplicates"); 2640be1883cSHui } 2650be1883cSHui 2660be1883cSHui _LIBCPP_HIDE_FROM_ABI explicit flat_map(const key_compare& __comp) : __containers_(), __compare_(__comp) {} 2670be1883cSHui 2680be1883cSHui template <class _Allocator> 2690be1883cSHui requires __allocator_ctor_constraint<_Allocator> 2700be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(const key_compare& __comp, const _Allocator& __alloc) 2710be1883cSHui : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {} 2720be1883cSHui 2730be1883cSHui template <class _Allocator> 2740be1883cSHui requires __allocator_ctor_constraint<_Allocator> 2750be1883cSHui _LIBCPP_HIDE_FROM_ABI explicit flat_map(const _Allocator& __alloc) 2760be1883cSHui : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) {} 2770be1883cSHui 2780be1883cSHui template <class _InputIterator> 2790be1883cSHui requires __has_input_iterator_category<_InputIterator>::value 2800be1883cSHui _LIBCPP_HIDE_FROM_ABI 2810be1883cSHui flat_map(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) 2820be1883cSHui : __containers_(), __compare_(__comp) { 2830be1883cSHui insert(__first, __last); 2840be1883cSHui } 2850be1883cSHui 2860be1883cSHui template <class _InputIterator, class _Allocator> 2870be1883cSHui requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 2880be1883cSHui _LIBCPP_HIDE_FROM_ABI 2890be1883cSHui flat_map(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc) 2900be1883cSHui : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { 2910be1883cSHui insert(__first, __last); 2920be1883cSHui } 2930be1883cSHui 2940be1883cSHui template <class _InputIterator, class _Allocator> 2950be1883cSHui requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 2960be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) 2970be1883cSHui : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { 2980be1883cSHui insert(__first, __last); 2990be1883cSHui } 3000be1883cSHui 3010be1883cSHui template <_ContainerCompatibleRange<value_type> _Range> 3020be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t __fr, _Range&& __rg) 3030be1883cSHui : flat_map(__fr, std::forward<_Range>(__rg), key_compare()) {} 3040be1883cSHui 3050be1883cSHui template <_ContainerCompatibleRange<value_type> _Range, class _Allocator> 3060be1883cSHui requires __allocator_ctor_constraint<_Allocator> 3070be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t, _Range&& __rg, const _Allocator& __alloc) 3080be1883cSHui : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { 3090be1883cSHui insert_range(std::forward<_Range>(__rg)); 3100be1883cSHui } 3110be1883cSHui 3120be1883cSHui template <_ContainerCompatibleRange<value_type> _Range> 3130be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_map(__comp) { 3140be1883cSHui insert_range(std::forward<_Range>(__rg)); 3150be1883cSHui } 3160be1883cSHui 3170be1883cSHui template <_ContainerCompatibleRange<value_type> _Range, class _Allocator> 3180be1883cSHui requires __allocator_ctor_constraint<_Allocator> 3190be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) 3200be1883cSHui : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { 3210be1883cSHui insert_range(std::forward<_Range>(__rg)); 3220be1883cSHui } 3230be1883cSHui 3240be1883cSHui template <class _InputIterator> 3250be1883cSHui requires __has_input_iterator_category<_InputIterator>::value 3260be1883cSHui _LIBCPP_HIDE_FROM_ABI 3270be1883cSHui flat_map(sorted_unique_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) 3280be1883cSHui : __containers_(), __compare_(__comp) { 3290be1883cSHui insert(sorted_unique, __first, __last); 3300be1883cSHui } 3310be1883cSHui template <class _InputIterator, class _Allocator> 3320be1883cSHui requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 3330be1883cSHui _LIBCPP_HIDE_FROM_ABI 3340be1883cSHui flat_map(sorted_unique_t, 3350be1883cSHui _InputIterator __first, 3360be1883cSHui _InputIterator __last, 3370be1883cSHui const key_compare& __comp, 3380be1883cSHui const _Allocator& __alloc) 3390be1883cSHui : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { 3400be1883cSHui insert(sorted_unique, __first, __last); 3410be1883cSHui } 3420be1883cSHui 3430be1883cSHui template <class _InputIterator, class _Allocator> 3440be1883cSHui requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) 3450be1883cSHui _LIBCPP_HIDE_FROM_ABI 3460be1883cSHui flat_map(sorted_unique_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc) 3470be1883cSHui : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { 3480be1883cSHui insert(sorted_unique, __first, __last); 3490be1883cSHui } 3500be1883cSHui 3510be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(initializer_list<value_type> __il, const key_compare& __comp = key_compare()) 3520be1883cSHui : flat_map(__il.begin(), __il.end(), __comp) {} 3530be1883cSHui 3540be1883cSHui template <class _Allocator> 3550be1883cSHui requires __allocator_ctor_constraint<_Allocator> 3560be1883cSHui _LIBCPP_HIDE_FROM_ABI 3570be1883cSHui flat_map(initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc) 3580be1883cSHui : flat_map(__il.begin(), __il.end(), __comp, __alloc) {} 3590be1883cSHui 3600be1883cSHui template <class _Allocator> 3610be1883cSHui requires __allocator_ctor_constraint<_Allocator> 3620be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(initializer_list<value_type> __il, const _Allocator& __alloc) 3630be1883cSHui : flat_map(__il.begin(), __il.end(), __alloc) {} 3640be1883cSHui 3650be1883cSHui _LIBCPP_HIDE_FROM_ABI 3660be1883cSHui flat_map(sorted_unique_t, initializer_list<value_type> __il, const key_compare& __comp = key_compare()) 3670be1883cSHui : flat_map(sorted_unique, __il.begin(), __il.end(), __comp) {} 3680be1883cSHui 3690be1883cSHui template <class _Allocator> 3700be1883cSHui requires __allocator_ctor_constraint<_Allocator> 3710be1883cSHui _LIBCPP_HIDE_FROM_ABI 3720be1883cSHui flat_map(sorted_unique_t, initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc) 3730be1883cSHui : flat_map(sorted_unique, __il.begin(), __il.end(), __comp, __alloc) {} 3740be1883cSHui 3750be1883cSHui template <class _Allocator> 3760be1883cSHui requires __allocator_ctor_constraint<_Allocator> 3770be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(sorted_unique_t, initializer_list<value_type> __il, const _Allocator& __alloc) 3780be1883cSHui : flat_map(sorted_unique, __il.begin(), __il.end(), __alloc) {} 3790be1883cSHui 3800be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map& operator=(initializer_list<value_type> __il) { 3810be1883cSHui clear(); 3820be1883cSHui insert(__il); 3830be1883cSHui return *this; 3840be1883cSHui } 3850be1883cSHui 3860be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map& operator=(const flat_map&) = default; 3870be1883cSHui 3880be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map& operator=(flat_map&& __other) noexcept( 3890be1883cSHui is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> && 3900be1883cSHui is_nothrow_move_assignable_v<_Compare>) { 3910be1883cSHui // No matter what happens, we always want to clear the other container before returning 3920be1883cSHui // since we moved from it 3930be1883cSHui auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; }); 3940be1883cSHui { 3950be1883cSHui // If an exception is thrown, we have no choice but to clear *this to preserve invariants 3960be1883cSHui auto __on_exception = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 3970be1883cSHui __containers_ = std::move(__other.__containers_); 3980be1883cSHui __compare_ = std::move(__other.__compare_); 3990be1883cSHui __on_exception.__complete(); 4000be1883cSHui } 4010be1883cSHui return *this; 4020be1883cSHui } 4030be1883cSHui 4040be1883cSHui // iterators 4050be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator begin() noexcept { 4060be1883cSHui return iterator(__containers_.keys.begin(), __containers_.values.begin()); 4070be1883cSHui } 4080be1883cSHui 4090be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { 4100be1883cSHui return const_iterator(__containers_.keys.begin(), __containers_.values.begin()); 4110be1883cSHui } 4120be1883cSHui 4130be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator end() noexcept { 4140be1883cSHui return iterator(__containers_.keys.end(), __containers_.values.end()); 4150be1883cSHui } 4160be1883cSHui 4170be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { 4180be1883cSHui return const_iterator(__containers_.keys.end(), __containers_.values.end()); 4190be1883cSHui } 4200be1883cSHui 4210be1883cSHui _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } 4220be1883cSHui _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } 4230be1883cSHui _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() noexcept { return reverse_iterator(begin()); } 4240be1883cSHui _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } 4250be1883cSHui 4260be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return begin(); } 4270be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return end(); } 4280be1883cSHui _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } 4290be1883cSHui _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } 4300be1883cSHui 4310be1883cSHui // [flat.map.capacity], capacity 4320be1883cSHui [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __containers_.keys.empty(); } 4330be1883cSHui 4340be1883cSHui _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __containers_.keys.size(); } 4350be1883cSHui 4360be1883cSHui _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept { 4370be1883cSHui return std::min<size_type>(__containers_.keys.max_size(), __containers_.values.max_size()); 4380be1883cSHui } 4390be1883cSHui 4400be1883cSHui // [flat.map.access], element access 4410be1883cSHui _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __x) 4420be1883cSHui requires is_constructible_v<mapped_type> 4430be1883cSHui { 4440be1883cSHui return try_emplace(__x).first->second; 4450be1883cSHui } 4460be1883cSHui 4470be1883cSHui _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __x) 4480be1883cSHui requires is_constructible_v<mapped_type> 4490be1883cSHui { 4500be1883cSHui return try_emplace(std::move(__x)).first->second; 4510be1883cSHui } 4520be1883cSHui 4530be1883cSHui template <class _Kp> 4540be1883cSHui requires(__is_compare_transparent && is_constructible_v<key_type, _Kp> && is_constructible_v<mapped_type> && 4550be1883cSHui !is_convertible_v<_Kp &&, const_iterator> && !is_convertible_v<_Kp &&, iterator>) 4560be1883cSHui _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](_Kp&& __x) { 4570be1883cSHui return try_emplace(std::forward<_Kp>(__x)).first->second; 4580be1883cSHui } 4590be1883cSHui 4600be1883cSHui _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __x) { 4610be1883cSHui auto __it = find(__x); 4620be1883cSHui if (__it == end()) { 4630be1883cSHui std::__throw_out_of_range("flat_map::at(const key_type&): Key does not exist"); 4640be1883cSHui } 4650be1883cSHui return __it->second; 4660be1883cSHui } 4670be1883cSHui 4680be1883cSHui _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __x) const { 4690be1883cSHui auto __it = find(__x); 4700be1883cSHui if (__it == end()) { 4710be1883cSHui std::__throw_out_of_range("flat_map::at(const key_type&) const: Key does not exist"); 4720be1883cSHui } 4730be1883cSHui return __it->second; 4740be1883cSHui } 4750be1883cSHui 4760be1883cSHui template <class _Kp> 4770be1883cSHui requires __is_compare_transparent 4780be1883cSHui _LIBCPP_HIDE_FROM_ABI mapped_type& at(const _Kp& __x) { 4790be1883cSHui auto __it = find(__x); 4800be1883cSHui if (__it == end()) { 4810be1883cSHui std::__throw_out_of_range("flat_map::at(const K&): Key does not exist"); 4820be1883cSHui } 4830be1883cSHui return __it->second; 4840be1883cSHui } 4850be1883cSHui 4860be1883cSHui template <class _Kp> 4870be1883cSHui requires __is_compare_transparent 4880be1883cSHui _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const _Kp& __x) const { 4890be1883cSHui auto __it = find(__x); 4900be1883cSHui if (__it == end()) { 4910be1883cSHui std::__throw_out_of_range("flat_map::at(const K&) const: Key does not exist"); 4920be1883cSHui } 4930be1883cSHui return __it->second; 4940be1883cSHui } 4950be1883cSHui 4960be1883cSHui // [flat.map.modifiers], modifiers 4970be1883cSHui template <class... _Args> 4980be1883cSHui requires is_constructible_v<pair<key_type, mapped_type>, _Args...> 4990be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> emplace(_Args&&... __args) { 5000be1883cSHui std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...); 5010be1883cSHui return __try_emplace(std::move(__pair.first), std::move(__pair.second)); 5020be1883cSHui } 5030be1883cSHui 5040be1883cSHui template <class... _Args> 5050be1883cSHui requires is_constructible_v<pair<key_type, mapped_type>, _Args...> 5060be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __hint, _Args&&... __args) { 5070be1883cSHui std::pair<key_type, mapped_type> __pair(std::forward<_Args>(__args)...); 5080be1883cSHui return __try_emplace_hint(__hint, std::move(__pair.first), std::move(__pair.second)).first; 5090be1883cSHui } 5100be1883cSHui 5110be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __x) { return emplace(__x); } 5120be1883cSHui 5130be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __x) { return emplace(std::move(__x)); } 5140be1883cSHui 5150be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, const value_type& __x) { 5160be1883cSHui return emplace_hint(__hint, __x); 5170be1883cSHui } 5180be1883cSHui 5190be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, value_type&& __x) { 5200be1883cSHui return emplace_hint(__hint, std::move(__x)); 5210be1883cSHui } 5220be1883cSHui 523*def50f70SHui template <class _PairLike> 524*def50f70SHui requires is_constructible_v<pair<key_type, mapped_type>, _PairLike> 525*def50f70SHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(_PairLike&& __x) { 526*def50f70SHui return emplace(std::forward<_PairLike>(__x)); 5270be1883cSHui } 5280be1883cSHui 529*def50f70SHui template <class _PairLike> 530*def50f70SHui requires is_constructible_v<pair<key_type, mapped_type>, _PairLike> 531*def50f70SHui _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, _PairLike&& __x) { 532*def50f70SHui return emplace_hint(__hint, std::forward<_PairLike>(__x)); 5330be1883cSHui } 5340be1883cSHui 5350be1883cSHui template <class _InputIterator> 5360be1883cSHui requires __has_input_iterator_category<_InputIterator>::value 5370be1883cSHui _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) { 5380be1883cSHui if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { 5390be1883cSHui __reserve(__last - __first); 5400be1883cSHui } 5410be1883cSHui __append_sort_merge_unique</*WasSorted = */ false>(std::move(__first), std::move(__last)); 5420be1883cSHui } 5430be1883cSHui 5440be1883cSHui template <class _InputIterator> 5450be1883cSHui requires __has_input_iterator_category<_InputIterator>::value 54681118676SNikolas Klauser _LIBCPP_HIDE_FROM_ABI void insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) { 5470be1883cSHui if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { 5480be1883cSHui __reserve(__last - __first); 5490be1883cSHui } 5500be1883cSHui 5510be1883cSHui __append_sort_merge_unique</*WasSorted = */ true>(std::move(__first), std::move(__last)); 5520be1883cSHui } 5530be1883cSHui 5540be1883cSHui template <_ContainerCompatibleRange<value_type> _Range> 5550be1883cSHui _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) { 5560be1883cSHui if constexpr (ranges::sized_range<_Range>) { 5570be1883cSHui __reserve(ranges::size(__range)); 5580be1883cSHui } 5590be1883cSHui 5600be1883cSHui __append_sort_merge_unique</*WasSorted = */ false>(ranges::begin(__range), ranges::end(__range)); 5610be1883cSHui } 5620be1883cSHui 5630be1883cSHui _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); } 5640be1883cSHui 5650be1883cSHui _LIBCPP_HIDE_FROM_ABI void insert(sorted_unique_t, initializer_list<value_type> __il) { 5660be1883cSHui insert(sorted_unique, __il.begin(), __il.end()); 5670be1883cSHui } 5680be1883cSHui 5690be1883cSHui _LIBCPP_HIDE_FROM_ABI containers extract() && { 5700be1883cSHui auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; }); 5710be1883cSHui auto __ret = std::move(__containers_); 5720be1883cSHui return __ret; 5730be1883cSHui } 5740be1883cSHui 5750be1883cSHui _LIBCPP_HIDE_FROM_ABI void replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) { 5760be1883cSHui _LIBCPP_ASSERT_VALID_INPUT_RANGE( 5770be1883cSHui __key_cont.size() == __mapped_cont.size(), "flat_map keys and mapped containers have different size"); 5780be1883cSHui 5790be1883cSHui _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 5800be1883cSHui __is_sorted_and_unique(__key_cont), "Either the key container is not sorted or it contains duplicates"); 5810be1883cSHui auto __guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 5820be1883cSHui __containers_.keys = std::move(__key_cont); 5830be1883cSHui __containers_.values = std::move(__mapped_cont); 5840be1883cSHui __guard.__complete(); 5850be1883cSHui } 5860be1883cSHui 5870be1883cSHui template <class... _Args> 5880be1883cSHui requires is_constructible_v<mapped_type, _Args...> 5890be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(const key_type& __key, _Args&&... __args) { 5900be1883cSHui return __try_emplace(__key, std::forward<_Args>(__args)...); 5910be1883cSHui } 5920be1883cSHui 5930be1883cSHui template <class... _Args> 5940be1883cSHui requires is_constructible_v<mapped_type, _Args...> 5950be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(key_type&& __key, _Args&&... __args) { 5960be1883cSHui return __try_emplace(std::move(__key), std::forward<_Args>(__args)...); 5970be1883cSHui } 5980be1883cSHui 5990be1883cSHui template <class _Kp, class... _Args> 6000be1883cSHui requires(__is_compare_transparent && is_constructible_v<key_type, _Kp> && 6010be1883cSHui is_constructible_v<mapped_type, _Args...> && !is_convertible_v<_Kp &&, const_iterator> && 6020be1883cSHui !is_convertible_v<_Kp &&, iterator>) 6030be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(_Kp&& __key, _Args&&... __args) { 6040be1883cSHui return __try_emplace(std::forward<_Kp>(__key), std::forward<_Args>(__args)...); 6050be1883cSHui } 6060be1883cSHui 6070be1883cSHui template <class... _Args> 6080be1883cSHui requires is_constructible_v<mapped_type, _Args...> 6090be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __hint, const key_type& __key, _Args&&... __args) { 6100be1883cSHui return __try_emplace_hint(__hint, __key, std::forward<_Args>(__args)...).first; 6110be1883cSHui } 6120be1883cSHui 6130be1883cSHui template <class... _Args> 6140be1883cSHui requires is_constructible_v<mapped_type, _Args...> 6150be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __hint, key_type&& __key, _Args&&... __args) { 6160be1883cSHui return __try_emplace_hint(__hint, std::move(__key), std::forward<_Args>(__args)...).first; 6170be1883cSHui } 6180be1883cSHui 6190be1883cSHui template <class _Kp, class... _Args> 6200be1883cSHui requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_constructible_v<mapped_type, _Args...> 6210be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __hint, _Kp&& __key, _Args&&... __args) { 6220be1883cSHui return __try_emplace_hint(__hint, std::forward<_Kp>(__key), std::forward<_Args>(__args)...).first; 6230be1883cSHui } 6240be1883cSHui 6250be1883cSHui template <class _Mapped> 6260be1883cSHui requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped> 6270be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(const key_type& __key, _Mapped&& __obj) { 6280be1883cSHui return __insert_or_assign(__key, std::forward<_Mapped>(__obj)); 6290be1883cSHui } 6300be1883cSHui 6310be1883cSHui template <class _Mapped> 6320be1883cSHui requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped> 6330be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(key_type&& __key, _Mapped&& __obj) { 6340be1883cSHui return __insert_or_assign(std::move(__key), std::forward<_Mapped>(__obj)); 6350be1883cSHui } 6360be1883cSHui 6370be1883cSHui template <class _Kp, class _Mapped> 6380be1883cSHui requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_assignable_v<mapped_type&, _Mapped> && 6390be1883cSHui is_constructible_v<mapped_type, _Mapped> 6400be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(_Kp&& __key, _Mapped&& __obj) { 6410be1883cSHui return __insert_or_assign(std::forward<_Kp>(__key), std::forward<_Mapped>(__obj)); 6420be1883cSHui } 6430be1883cSHui 6440be1883cSHui template <class _Mapped> 6450be1883cSHui requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped> 6460be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __hint, const key_type& __key, _Mapped&& __obj) { 6470be1883cSHui return __insert_or_assign(__hint, __key, std::forward<_Mapped>(__obj)); 6480be1883cSHui } 6490be1883cSHui 6500be1883cSHui template <class _Mapped> 6510be1883cSHui requires is_assignable_v<mapped_type&, _Mapped> && is_constructible_v<mapped_type, _Mapped> 6520be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __hint, key_type&& __key, _Mapped&& __obj) { 6530be1883cSHui return __insert_or_assign(__hint, std::move(__key), std::forward<_Mapped>(__obj)); 6540be1883cSHui } 6550be1883cSHui 6560be1883cSHui template <class _Kp, class _Mapped> 6570be1883cSHui requires __is_compare_transparent && is_constructible_v<key_type, _Kp> && is_assignable_v<mapped_type&, _Mapped> && 6580be1883cSHui is_constructible_v<mapped_type, _Mapped> 6590be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __obj) { 6600be1883cSHui return __insert_or_assign(__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__obj)); 6610be1883cSHui } 6620be1883cSHui 6630be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __position) { 6640be1883cSHui return __erase(__position.__key_iter_, __position.__mapped_iter_); 6650be1883cSHui } 6660be1883cSHui 6670be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position) { 6680be1883cSHui return __erase(__position.__key_iter_, __position.__mapped_iter_); 6690be1883cSHui } 6700be1883cSHui 6710be1883cSHui _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __x) { 6720be1883cSHui auto __iter = find(__x); 6730be1883cSHui if (__iter != end()) { 6740be1883cSHui erase(__iter); 6750be1883cSHui return 1; 6760be1883cSHui } 6770be1883cSHui return 0; 6780be1883cSHui } 6790be1883cSHui 6800be1883cSHui template <class _Kp> 6810be1883cSHui requires(__is_compare_transparent && !is_convertible_v<_Kp &&, iterator> && 6820be1883cSHui !is_convertible_v<_Kp &&, const_iterator>) 6830be1883cSHui _LIBCPP_HIDE_FROM_ABI size_type erase(_Kp&& __x) { 6840be1883cSHui auto [__first, __last] = equal_range(__x); 6850be1883cSHui auto __res = __last - __first; 6860be1883cSHui erase(__first, __last); 6870be1883cSHui return __res; 6880be1883cSHui } 6890be1883cSHui 6900be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) { 6910be1883cSHui auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 6920be1883cSHui auto __key_it = __containers_.keys.erase(__first.__key_iter_, __last.__key_iter_); 6930be1883cSHui auto __mapped_it = __containers_.values.erase(__first.__mapped_iter_, __last.__mapped_iter_); 6940be1883cSHui __on_failure.__complete(); 6950be1883cSHui return iterator(std::move(__key_it), std::move(__mapped_it)); 6960be1883cSHui } 6970be1883cSHui 6980be1883cSHui _LIBCPP_HIDE_FROM_ABI void swap(flat_map& __y) noexcept { 6990be1883cSHui // warning: The spec has unconditional noexcept, which means that 7000be1883cSHui // if any of the following functions throw an exception, 7010be1883cSHui // std::terminate will be called. 7020be1883cSHui // This is discussed in P2767, which hasn't been voted on yet. 7030be1883cSHui ranges::swap(__compare_, __y.__compare_); 7040be1883cSHui ranges::swap(__containers_.keys, __y.__containers_.keys); 7050be1883cSHui ranges::swap(__containers_.values, __y.__containers_.values); 7060be1883cSHui } 7070be1883cSHui 7080be1883cSHui _LIBCPP_HIDE_FROM_ABI void clear() noexcept { 7090be1883cSHui __containers_.keys.clear(); 7100be1883cSHui __containers_.values.clear(); 7110be1883cSHui } 7120be1883cSHui 7130be1883cSHui // observers 7140be1883cSHui _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __compare_; } 7150be1883cSHui _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__compare_); } 7160be1883cSHui 7170be1883cSHui _LIBCPP_HIDE_FROM_ABI const key_container_type& keys() const noexcept { return __containers_.keys; } 7180be1883cSHui _LIBCPP_HIDE_FROM_ABI const mapped_container_type& values() const noexcept { return __containers_.values; } 7190be1883cSHui 7200be1883cSHui // map operations 7210be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __x) { return __find_impl(*this, __x); } 7220be1883cSHui 7230be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __x) const { return __find_impl(*this, __x); } 7240be1883cSHui 7250be1883cSHui template <class _Kp> 7260be1883cSHui requires __is_compare_transparent 7270be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator find(const _Kp& __x) { 7280be1883cSHui return __find_impl(*this, __x); 7290be1883cSHui } 7300be1883cSHui 7310be1883cSHui template <class _Kp> 7320be1883cSHui requires __is_compare_transparent 7330be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Kp& __x) const { 7340be1883cSHui return __find_impl(*this, __x); 7350be1883cSHui } 7360be1883cSHui 7370be1883cSHui _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __x) const { return contains(__x) ? 1 : 0; } 7380be1883cSHui 7390be1883cSHui template <class _Kp> 7400be1883cSHui requires __is_compare_transparent 7410be1883cSHui _LIBCPP_HIDE_FROM_ABI size_type count(const _Kp& __x) const { 7420be1883cSHui return contains(__x) ? 1 : 0; 7430be1883cSHui } 7440be1883cSHui 7450be1883cSHui _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __x) const { return find(__x) != end(); } 7460be1883cSHui 7470be1883cSHui template <class _Kp> 7480be1883cSHui requires __is_compare_transparent 7490be1883cSHui _LIBCPP_HIDE_FROM_ABI bool contains(const _Kp& __x) const { 7500be1883cSHui return find(__x) != end(); 7510be1883cSHui } 7520be1883cSHui 7530be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __x) { return __lower_bound<iterator>(*this, __x); } 7540be1883cSHui 7550be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __x) const { 7560be1883cSHui return __lower_bound<const_iterator>(*this, __x); 7570be1883cSHui } 7580be1883cSHui 7590be1883cSHui template <class _Kp> 7600be1883cSHui requires __is_compare_transparent 7610be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Kp& __x) { 7620be1883cSHui return __lower_bound<iterator>(*this, __x); 7630be1883cSHui } 7640be1883cSHui 7650be1883cSHui template <class _Kp> 7660be1883cSHui requires __is_compare_transparent 7670be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Kp& __x) const { 7680be1883cSHui return __lower_bound<const_iterator>(*this, __x); 7690be1883cSHui } 7700be1883cSHui 7710be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __x) { return __upper_bound<iterator>(*this, __x); } 7720be1883cSHui 7730be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __x) const { 7740be1883cSHui return __upper_bound<const_iterator>(*this, __x); 7750be1883cSHui } 7760be1883cSHui 7770be1883cSHui template <class _Kp> 7780be1883cSHui requires __is_compare_transparent 7790be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Kp& __x) { 7800be1883cSHui return __upper_bound<iterator>(*this, __x); 7810be1883cSHui } 7820be1883cSHui 7830be1883cSHui template <class _Kp> 7840be1883cSHui requires __is_compare_transparent 7850be1883cSHui _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Kp& __x) const { 7860be1883cSHui return __upper_bound<const_iterator>(*this, __x); 7870be1883cSHui } 7880be1883cSHui 7890be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __x) { 7900be1883cSHui return __equal_range_impl(*this, __x); 7910be1883cSHui } 7920be1883cSHui 7930be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { 7940be1883cSHui return __equal_range_impl(*this, __x); 7950be1883cSHui } 7960be1883cSHui 7970be1883cSHui template <class _Kp> 7980be1883cSHui requires __is_compare_transparent 7990be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _Kp& __x) { 8000be1883cSHui return __equal_range_impl(*this, __x); 8010be1883cSHui } 8020be1883cSHui template <class _Kp> 8030be1883cSHui requires __is_compare_transparent 8040be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _Kp& __x) const { 8050be1883cSHui return __equal_range_impl(*this, __x); 8060be1883cSHui } 8070be1883cSHui 8080be1883cSHui friend _LIBCPP_HIDE_FROM_ABI bool operator==(const flat_map& __x, const flat_map& __y) { 8090be1883cSHui return ranges::equal(__x, __y); 8100be1883cSHui } 8110be1883cSHui 8120be1883cSHui friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_map& __x, const flat_map& __y) { 8130be1883cSHui return std::lexicographical_compare_three_way( 8140be1883cSHui __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); 8150be1883cSHui } 8160be1883cSHui 8170be1883cSHui friend _LIBCPP_HIDE_FROM_ABI void swap(flat_map& __x, flat_map& __y) noexcept { __x.swap(__y); } 8180be1883cSHui 8190be1883cSHui private: 8200be1883cSHui struct __ctor_uses_allocator_tag { 8210be1883cSHui explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_tag() = default; 8220be1883cSHui }; 8230be1883cSHui struct __ctor_uses_allocator_empty_tag { 8240be1883cSHui explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_empty_tag() = default; 8250be1883cSHui }; 8260be1883cSHui 8270be1883cSHui template <class _Allocator, class _KeyCont, class _MappedCont, class... _CompArg> 8280be1883cSHui requires __allocator_ctor_constraint<_Allocator> 8290be1883cSHui _LIBCPP_HIDE_FROM_ABI 8300be1883cSHui flat_map(__ctor_uses_allocator_tag, 8310be1883cSHui const _Allocator& __alloc, 8320be1883cSHui _KeyCont&& __key_cont, 8330be1883cSHui _MappedCont&& __mapped_cont, 8340be1883cSHui _CompArg&&... __comp) 8350be1883cSHui : __containers_{.keys = std::make_obj_using_allocator<key_container_type>( 8360be1883cSHui __alloc, std::forward<_KeyCont>(__key_cont)), 8370be1883cSHui .values = std::make_obj_using_allocator<mapped_container_type>( 8380be1883cSHui __alloc, std::forward<_MappedCont>(__mapped_cont))}, 8390be1883cSHui __compare_(std::forward<_CompArg>(__comp)...) {} 8400be1883cSHui 8410be1883cSHui template <class _Allocator, class... _CompArg> 8420be1883cSHui requires __allocator_ctor_constraint<_Allocator> 8430be1883cSHui _LIBCPP_HIDE_FROM_ABI flat_map(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp) 8440be1883cSHui : __containers_{.keys = std::make_obj_using_allocator<key_container_type>(__alloc), 8450be1883cSHui .values = std::make_obj_using_allocator<mapped_container_type>(__alloc)}, 8460be1883cSHui __compare_(std::forward<_CompArg>(__comp)...) {} 8470be1883cSHui 8480be1883cSHui _LIBCPP_HIDE_FROM_ABI bool __is_sorted_and_unique(auto&& __key_container) const { 8490be1883cSHui auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); }; 8500be1883cSHui return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container); 8510be1883cSHui } 8520be1883cSHui 8530be1883cSHui // This function is only used in constructors. So there is not exception handling in this function. 8540be1883cSHui // If the function exits via an exception, there will be no flat_map object constructed, thus, there 8550be1883cSHui // is no invariant state to preserve 8560be1883cSHui _LIBCPP_HIDE_FROM_ABI void __sort_and_unique() { 8570be1883cSHui auto __zv = ranges::views::zip(__containers_.keys, __containers_.values); 858162397f9SHui ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); }); 8590be1883cSHui auto __dup_start = ranges::unique(__zv, __key_equiv(__compare_)).begin(); 8600be1883cSHui auto __dist = ranges::distance(__zv.begin(), __dup_start); 8610be1883cSHui __containers_.keys.erase(__containers_.keys.begin() + __dist, __containers_.keys.end()); 8620be1883cSHui __containers_.values.erase(__containers_.values.begin() + __dist, __containers_.values.end()); 8630be1883cSHui } 8640be1883cSHui 8650be1883cSHui template <bool _WasSorted, class _InputIterator, class _Sentinel> 8660be1883cSHui _LIBCPP_HIDE_FROM_ABI void __append_sort_merge_unique(_InputIterator __first, _Sentinel __last) { 8670be1883cSHui auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 868*def50f70SHui size_t __num_of_appended = __flat_map_utils::__append(*this, std::move(__first), std::move(__last)); 8690be1883cSHui if (__num_of_appended != 0) { 8700be1883cSHui auto __zv = ranges::views::zip(__containers_.keys, __containers_.values); 8710be1883cSHui auto __append_start_offset = __containers_.keys.size() - __num_of_appended; 8720be1883cSHui auto __end = __zv.end(); 8730be1883cSHui auto __compare_key = [this](const auto& __p1, const auto& __p2) { 8740be1883cSHui return __compare_(std::get<0>(__p1), std::get<0>(__p2)); 8750be1883cSHui }; 8760be1883cSHui if constexpr (!_WasSorted) { 877162397f9SHui ranges::sort(__zv.begin() + __append_start_offset, __end, __compare_key); 8780be1883cSHui } else { 8790be1883cSHui _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( 8800be1883cSHui __is_sorted_and_unique(__containers_.keys | ranges::views::drop(__append_start_offset)), 8810be1883cSHui "Either the key container is not sorted or it contains duplicates"); 8820be1883cSHui } 8830be1883cSHui ranges::inplace_merge(__zv.begin(), __zv.begin() + __append_start_offset, __end, __compare_key); 8840be1883cSHui 8850be1883cSHui auto __dup_start = ranges::unique(__zv, __key_equiv(__compare_)).begin(); 8860be1883cSHui auto __dist = ranges::distance(__zv.begin(), __dup_start); 8870be1883cSHui __containers_.keys.erase(__containers_.keys.begin() + __dist, __containers_.keys.end()); 8880be1883cSHui __containers_.values.erase(__containers_.values.begin() + __dist, __containers_.values.end()); 8890be1883cSHui } 8900be1883cSHui __on_failure.__complete(); 8910be1883cSHui } 8920be1883cSHui 8930be1883cSHui template <class _Self, class _Kp> 8940be1883cSHui _LIBCPP_HIDE_FROM_ABI static auto __find_impl(_Self&& __self, const _Kp& __key) { 8950be1883cSHui auto __it = __self.lower_bound(__key); 8960be1883cSHui auto __last = __self.end(); 8970be1883cSHui if (__it == __last || __self.__compare_(__key, __it->first)) { 8980be1883cSHui return __last; 8990be1883cSHui } 9000be1883cSHui return __it; 9010be1883cSHui } 9020be1883cSHui 9030be1883cSHui template <class _Self, class _Kp> 9040be1883cSHui _LIBCPP_HIDE_FROM_ABI static auto __key_equal_range(_Self&& __self, const _Kp& __key) { 9050be1883cSHui auto __it = ranges::lower_bound(__self.__containers_.keys, __key, __self.__compare_); 9060be1883cSHui auto __last = __self.__containers_.keys.end(); 9070be1883cSHui if (__it == __last || __self.__compare_(__key, *__it)) { 9080be1883cSHui return std::make_pair(__it, __it); 9090be1883cSHui } 9100be1883cSHui return std::make_pair(__it, std::next(__it)); 9110be1883cSHui } 9120be1883cSHui 9130be1883cSHui template <class _Self, class _Kp> 9140be1883cSHui _LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) { 9150be1883cSHui auto [__key_first, __key_last] = __key_equal_range(__self, __key); 9160be1883cSHui 9170be1883cSHui const auto __make_mapped_iter = [&](const auto& __key_iter) { 9180be1883cSHui return __self.__containers_.values.begin() + 9190be1883cSHui static_cast<ranges::range_difference_t<mapped_container_type>>( 9200be1883cSHui ranges::distance(__self.__containers_.keys.begin(), __key_iter)); 9210be1883cSHui }; 9220be1883cSHui 9230be1883cSHui using __iterator_type = ranges::iterator_t<decltype(__self)>; 9240be1883cSHui return std::make_pair(__iterator_type(__key_first, __make_mapped_iter(__key_first)), 9250be1883cSHui __iterator_type(__key_last, __make_mapped_iter(__key_last))); 9260be1883cSHui } 9270be1883cSHui 9280be1883cSHui template <class _Res, class _Self, class _Kp> 9290be1883cSHui _LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) { 9300be1883cSHui return __binary_search<_Res>(__self, ranges::lower_bound, __x); 9310be1883cSHui } 9320be1883cSHui 9330be1883cSHui template <class _Res, class _Self, class _Kp> 9340be1883cSHui _LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) { 9350be1883cSHui return __binary_search<_Res>(__self, ranges::upper_bound, __x); 9360be1883cSHui } 9370be1883cSHui 9380be1883cSHui template <class _Res, class _Self, class _Fn, class _Kp> 9390be1883cSHui _LIBCPP_HIDE_FROM_ABI static _Res __binary_search(_Self&& __self, _Fn __search_fn, _Kp& __x) { 9400be1883cSHui auto __key_iter = __search_fn(__self.__containers_.keys, __x, __self.__compare_); 9410be1883cSHui auto __mapped_iter = 9420be1883cSHui __self.__containers_.values.begin() + 9430be1883cSHui static_cast<ranges::range_difference_t<mapped_container_type>>( 9440be1883cSHui ranges::distance(__self.__containers_.keys.begin(), __key_iter)); 9450be1883cSHui 9460be1883cSHui return _Res(std::move(__key_iter), std::move(__mapped_iter)); 9470be1883cSHui } 9480be1883cSHui 9490be1883cSHui template <class _KeyArg, class... _MArgs> 9500be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __try_emplace(_KeyArg&& __key, _MArgs&&... __mapped_args) { 9510be1883cSHui auto __key_it = ranges::lower_bound(__containers_.keys, __key, __compare_); 9520be1883cSHui auto __mapped_it = __containers_.values.begin() + ranges::distance(__containers_.keys.begin(), __key_it); 9530be1883cSHui 9540be1883cSHui if (__key_it == __containers_.keys.end() || __compare_(__key, *__key_it)) { 9550be1883cSHui return pair<iterator, bool>( 956*def50f70SHui __flat_map_utils::__emplace_exact_pos( 957*def50f70SHui *this, 9580be1883cSHui std::move(__key_it), 9590be1883cSHui std::move(__mapped_it), 9600be1883cSHui std::forward<_KeyArg>(__key), 9610be1883cSHui std::forward<_MArgs>(__mapped_args)...), 9620be1883cSHui true); 9630be1883cSHui } else { 9640be1883cSHui return pair<iterator, bool>(iterator(std::move(__key_it), std::move(__mapped_it)), false); 9650be1883cSHui } 9660be1883cSHui } 9670be1883cSHui 9680be1883cSHui template <class _Kp> 9690be1883cSHui _LIBCPP_HIDE_FROM_ABI bool __is_hint_correct(const_iterator __hint, _Kp&& __key) { 9700be1883cSHui if (__hint != cbegin() && !__compare_((__hint - 1)->first, __key)) { 9710be1883cSHui return false; 9720be1883cSHui } 9730be1883cSHui if (__hint != cend() && __compare_(__hint->first, __key)) { 9740be1883cSHui return false; 9750be1883cSHui } 9760be1883cSHui return true; 9770be1883cSHui } 9780be1883cSHui 9790be1883cSHui template <class _Kp, class... _Args> 9800be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __try_emplace_hint(const_iterator __hint, _Kp&& __key, _Args&&... __args) { 9810be1883cSHui if (__is_hint_correct(__hint, __key)) { 9820be1883cSHui if (__hint == cend() || __compare_(__key, __hint->first)) { 983*def50f70SHui return {__flat_map_utils::__emplace_exact_pos( 984*def50f70SHui *this, 985*def50f70SHui __hint.__key_iter_, 986*def50f70SHui __hint.__mapped_iter_, 987*def50f70SHui std::forward<_Kp>(__key), 988*def50f70SHui std::forward<_Args>(__args)...), 9890be1883cSHui true}; 9900be1883cSHui } else { 9910be1883cSHui // key equals 9920be1883cSHui auto __dist = __hint - cbegin(); 9930be1883cSHui return {iterator(__containers_.keys.begin() + __dist, __containers_.values.begin() + __dist), false}; 9940be1883cSHui } 9950be1883cSHui } else { 9960be1883cSHui return __try_emplace(std::forward<_Kp>(__key), std::forward<_Args>(__args)...); 9970be1883cSHui } 9980be1883cSHui } 9990be1883cSHui 10000be1883cSHui template <class _Kp, class _Mapped> 10010be1883cSHui _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_or_assign(_Kp&& __key, _Mapped&& __mapped) { 10020be1883cSHui auto __r = try_emplace(std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped)); 10030be1883cSHui if (!__r.second) { 10040be1883cSHui __r.first->second = std::forward<_Mapped>(__mapped); 10050be1883cSHui } 10060be1883cSHui return __r; 10070be1883cSHui } 10080be1883cSHui 10090be1883cSHui template <class _Kp, class _Mapped> 10100be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator __insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __mapped) { 10110be1883cSHui auto __r = __try_emplace_hint(__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped)); 10120be1883cSHui if (!__r.second) { 10130be1883cSHui __r.first->second = std::forward<_Mapped>(__mapped); 10140be1883cSHui } 10150be1883cSHui return __r.first; 10160be1883cSHui } 10170be1883cSHui 10180be1883cSHui _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __size) { 10190be1883cSHui if constexpr (requires { __containers_.keys.reserve(__size); }) { 10200be1883cSHui __containers_.keys.reserve(__size); 10210be1883cSHui } 10220be1883cSHui 10230be1883cSHui if constexpr (requires { __containers_.values.reserve(__size); }) { 10240be1883cSHui __containers_.values.reserve(__size); 10250be1883cSHui } 10260be1883cSHui } 10270be1883cSHui 10280be1883cSHui template <class _KIter, class _MIter> 10290be1883cSHui _LIBCPP_HIDE_FROM_ABI iterator __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) { 10300be1883cSHui auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); 10310be1883cSHui auto __key_iter = __containers_.keys.erase(__key_iter_to_remove); 10320be1883cSHui auto __mapped_iter = __containers_.values.erase(__mapped_iter_to_remove); 10330be1883cSHui __on_failure.__complete(); 10340be1883cSHui return iterator(std::move(__key_iter), std::move(__mapped_iter)); 10350be1883cSHui } 10360be1883cSHui 10370be1883cSHui template <class _Key2, class _Tp2, class _Compare2, class _KeyContainer2, class _MappedContainer2, class _Predicate> 10380be1883cSHui friend typename flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type 10390be1883cSHui erase_if(flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate); 10400be1883cSHui 1041*def50f70SHui friend __flat_map_utils; 1042*def50f70SHui 10430be1883cSHui containers __containers_; 1044*def50f70SHui _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_; 10450be1883cSHui 10460be1883cSHui struct __key_equiv { 10470be1883cSHui _LIBCPP_HIDE_FROM_ABI __key_equiv(key_compare __c) : __comp_(__c) {} 10480be1883cSHui _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const { 10490be1883cSHui return !__comp_(std::get<0>(__x), std::get<0>(__y)) && !__comp_(std::get<0>(__y), std::get<0>(__x)); 10500be1883cSHui } 10510be1883cSHui key_compare __comp_; 10520be1883cSHui }; 10530be1883cSHui }; 10540be1883cSHui 10550be1883cSHui template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>> 10560be1883cSHui requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 10570be1883cSHui !__is_allocator<_MappedContainer>::value && 10580be1883cSHui is_invocable_v<const _Compare&, 10590be1883cSHui const typename _KeyContainer::value_type&, 10600be1883cSHui const typename _KeyContainer::value_type&>) 10610be1883cSHui flat_map(_KeyContainer, _MappedContainer, _Compare = _Compare()) 10620be1883cSHui -> flat_map<typename _KeyContainer::value_type, 10630be1883cSHui typename _MappedContainer::value_type, 10640be1883cSHui _Compare, 10650be1883cSHui _KeyContainer, 10660be1883cSHui _MappedContainer>; 10670be1883cSHui 10680be1883cSHui template <class _KeyContainer, class _MappedContainer, class _Allocator> 10690be1883cSHui requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> && 10700be1883cSHui !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value) 10710be1883cSHui flat_map(_KeyContainer, _MappedContainer, _Allocator) 10720be1883cSHui -> flat_map<typename _KeyContainer::value_type, 10730be1883cSHui typename _MappedContainer::value_type, 10740be1883cSHui less<typename _KeyContainer::value_type>, 10750be1883cSHui _KeyContainer, 10760be1883cSHui _MappedContainer>; 10770be1883cSHui 10780be1883cSHui template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator> 10790be1883cSHui requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 10800be1883cSHui !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> && 10810be1883cSHui uses_allocator_v<_MappedContainer, _Allocator> && 10820be1883cSHui is_invocable_v<const _Compare&, 10830be1883cSHui const typename _KeyContainer::value_type&, 10840be1883cSHui const typename _KeyContainer::value_type&>) 10850be1883cSHui flat_map(_KeyContainer, _MappedContainer, _Compare, _Allocator) 10860be1883cSHui -> flat_map<typename _KeyContainer::value_type, 10870be1883cSHui typename _MappedContainer::value_type, 10880be1883cSHui _Compare, 10890be1883cSHui _KeyContainer, 10900be1883cSHui _MappedContainer>; 10910be1883cSHui 10920be1883cSHui template <class _KeyContainer, class _MappedContainer, class _Compare = less<typename _KeyContainer::value_type>> 10930be1883cSHui requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 10940be1883cSHui !__is_allocator<_MappedContainer>::value && 10950be1883cSHui is_invocable_v<const _Compare&, 10960be1883cSHui const typename _KeyContainer::value_type&, 10970be1883cSHui const typename _KeyContainer::value_type&>) 10980be1883cSHui flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Compare = _Compare()) 10990be1883cSHui -> flat_map<typename _KeyContainer::value_type, 11000be1883cSHui typename _MappedContainer::value_type, 11010be1883cSHui _Compare, 11020be1883cSHui _KeyContainer, 11030be1883cSHui _MappedContainer>; 11040be1883cSHui 11050be1883cSHui template <class _KeyContainer, class _MappedContainer, class _Allocator> 11060be1883cSHui requires(uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator> && 11070be1883cSHui !__is_allocator<_KeyContainer>::value && !__is_allocator<_MappedContainer>::value) 11080be1883cSHui flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Allocator) 11090be1883cSHui -> flat_map<typename _KeyContainer::value_type, 11100be1883cSHui typename _MappedContainer::value_type, 11110be1883cSHui less<typename _KeyContainer::value_type>, 11120be1883cSHui _KeyContainer, 11130be1883cSHui _MappedContainer>; 11140be1883cSHui 11150be1883cSHui template <class _KeyContainer, class _MappedContainer, class _Compare, class _Allocator> 11160be1883cSHui requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value && 11170be1883cSHui !__is_allocator<_MappedContainer>::value && uses_allocator_v<_KeyContainer, _Allocator> && 11180be1883cSHui uses_allocator_v<_MappedContainer, _Allocator> && 11190be1883cSHui is_invocable_v<const _Compare&, 11200be1883cSHui const typename _KeyContainer::value_type&, 11210be1883cSHui const typename _KeyContainer::value_type&>) 11220be1883cSHui flat_map(sorted_unique_t, _KeyContainer, _MappedContainer, _Compare, _Allocator) 11230be1883cSHui -> flat_map<typename _KeyContainer::value_type, 11240be1883cSHui typename _MappedContainer::value_type, 11250be1883cSHui _Compare, 11260be1883cSHui _KeyContainer, 11270be1883cSHui _MappedContainer>; 11280be1883cSHui 11290be1883cSHui template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>> 11300be1883cSHui requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value) 11310be1883cSHui flat_map(_InputIterator, _InputIterator, _Compare = _Compare()) 11320be1883cSHui -> flat_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>; 11330be1883cSHui 11340be1883cSHui template <class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>> 11350be1883cSHui requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value) 11360be1883cSHui flat_map(sorted_unique_t, _InputIterator, _InputIterator, _Compare = _Compare()) 11370be1883cSHui -> flat_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare>; 11380be1883cSHui 11390be1883cSHui template <ranges::input_range _Range, 11400be1883cSHui class _Compare = less<__range_key_type<_Range>>, 11410be1883cSHui class _Allocator = allocator<byte>, 11420be1883cSHui class = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>> 1143*def50f70SHui flat_map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_map< 11440be1883cSHui __range_key_type<_Range>, 11450be1883cSHui __range_mapped_type<_Range>, 11460be1883cSHui _Compare, 11470be1883cSHui vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>, 11480be1883cSHui vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>; 11490be1883cSHui 11500be1883cSHui template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>> 1151*def50f70SHui flat_map(from_range_t, _Range&&, _Allocator) -> flat_map< 11520be1883cSHui __range_key_type<_Range>, 11530be1883cSHui __range_mapped_type<_Range>, 11540be1883cSHui less<__range_key_type<_Range>>, 11550be1883cSHui vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>, 11560be1883cSHui vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>; 11570be1883cSHui 11580be1883cSHui template <class _Key, class _Tp, class _Compare = less<_Key>> 11590be1883cSHui requires(!__is_allocator<_Compare>::value) 11600be1883cSHui flat_map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) -> flat_map<_Key, _Tp, _Compare>; 11610be1883cSHui 11620be1883cSHui template <class _Key, class _Tp, class _Compare = less<_Key>> 11630be1883cSHui requires(!__is_allocator<_Compare>::value) 11640be1883cSHui flat_map(sorted_unique_t, initializer_list<pair<_Key, _Tp>>, _Compare = _Compare()) -> flat_map<_Key, _Tp, _Compare>; 11650be1883cSHui 11660be1883cSHui template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Allocator> 11670be1883cSHui struct uses_allocator<flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>, _Allocator> 11680be1883cSHui : bool_constant<uses_allocator_v<_KeyContainer, _Allocator> && uses_allocator_v<_MappedContainer, _Allocator>> {}; 11690be1883cSHui 11700be1883cSHui template <class _Key, class _Tp, class _Compare, class _KeyContainer, class _MappedContainer, class _Predicate> 11710be1883cSHui _LIBCPP_HIDE_FROM_ABI typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type 11720be1883cSHui erase_if(flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_map, _Predicate __pred) { 11730be1883cSHui auto __zv = ranges::views::zip(__flat_map.__containers_.keys, __flat_map.__containers_.values); 11740be1883cSHui auto __first = __zv.begin(); 11750be1883cSHui auto __last = __zv.end(); 11760be1883cSHui auto __guard = std::__make_exception_guard([&] { __flat_map.clear(); }); 11770be1883cSHui auto __it = std::remove_if(__first, __last, [&](auto&& __zipped) -> bool { 11780be1883cSHui using _Ref = typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::const_reference; 11790be1883cSHui return __pred(_Ref(std::get<0>(__zipped), std::get<1>(__zipped))); 11800be1883cSHui }); 11810be1883cSHui auto __res = __last - __it; 11820be1883cSHui auto __offset = __it - __first; 11830be1883cSHui 11840be1883cSHui const auto __erase_container = [&](auto& __cont) { __cont.erase(__cont.begin() + __offset, __cont.end()); }; 11850be1883cSHui 11860be1883cSHui __erase_container(__flat_map.__containers_.keys); 11870be1883cSHui __erase_container(__flat_map.__containers_.values); 11880be1883cSHui 11890be1883cSHui __guard.__complete(); 11900be1883cSHui return __res; 11910be1883cSHui } 11920be1883cSHui 11930be1883cSHui _LIBCPP_END_NAMESPACE_STD 11940be1883cSHui 11950be1883cSHui #endif // _LIBCPP_STD_VER >= 23 11960be1883cSHui 11970be1883cSHui _LIBCPP_POP_MACROS 11980be1883cSHui 11990be1883cSHui #endif // _LIBCPP___FLAT_MAP_FLAT_MAP_H 1200