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