xref: /llvm-project/libcxx/include/__flat_map/flat_map.h (revision def50f701f6a2c1e0550bb341fd8b64bed299e72)
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