xref: /freebsd/contrib/llvm-project/libcxx/include/__flat_set/flat_set.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_SET_FLAT_SET_H
11*700637cbSDimitry Andric #define _LIBCPP___FLAT_SET_FLAT_SET_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/ptrdiff_t.h>
28*700637cbSDimitry Andric #include <__flat_map/sorted_unique.h>
29*700637cbSDimitry Andric #include <__flat_set/ra_iterator.h>
30*700637cbSDimitry Andric #include <__flat_set/utils.h>
31*700637cbSDimitry Andric #include <__functional/invoke.h>
32*700637cbSDimitry Andric #include <__functional/is_transparent.h>
33*700637cbSDimitry Andric #include <__functional/operations.h>
34*700637cbSDimitry Andric #include <__fwd/vector.h>
35*700637cbSDimitry Andric #include <__iterator/concepts.h>
36*700637cbSDimitry Andric #include <__iterator/distance.h>
37*700637cbSDimitry Andric #include <__iterator/iterator_traits.h>
38*700637cbSDimitry Andric #include <__iterator/next.h>
39*700637cbSDimitry Andric #include <__iterator/prev.h>
40*700637cbSDimitry Andric #include <__iterator/ranges_iterator_traits.h>
41*700637cbSDimitry Andric #include <__iterator/reverse_iterator.h>
42*700637cbSDimitry Andric #include <__memory/allocator_traits.h>
43*700637cbSDimitry Andric #include <__memory/uses_allocator.h>
44*700637cbSDimitry Andric #include <__memory/uses_allocator_construction.h>
45*700637cbSDimitry Andric #include <__ranges/access.h>
46*700637cbSDimitry Andric #include <__ranges/concepts.h>
47*700637cbSDimitry Andric #include <__ranges/container_compatible_range.h>
48*700637cbSDimitry Andric #include <__ranges/drop_view.h>
49*700637cbSDimitry Andric #include <__ranges/from_range.h>
50*700637cbSDimitry Andric #include <__ranges/ref_view.h>
51*700637cbSDimitry Andric #include <__ranges/size.h>
52*700637cbSDimitry Andric #include <__ranges/subrange.h>
53*700637cbSDimitry Andric #include <__type_traits/conjunction.h>
54*700637cbSDimitry Andric #include <__type_traits/container_traits.h>
55*700637cbSDimitry Andric #include <__type_traits/invoke.h>
56*700637cbSDimitry Andric #include <__type_traits/is_allocator.h>
57*700637cbSDimitry Andric #include <__type_traits/is_const.h>
58*700637cbSDimitry Andric #include <__type_traits/is_nothrow_constructible.h>
59*700637cbSDimitry Andric #include <__type_traits/is_same.h>
60*700637cbSDimitry Andric #include <__type_traits/remove_reference.h>
61*700637cbSDimitry Andric #include <__utility/as_const.h>
62*700637cbSDimitry Andric #include <__utility/exception_guard.h>
63*700637cbSDimitry Andric #include <__utility/move.h>
64*700637cbSDimitry Andric #include <__utility/pair.h>
65*700637cbSDimitry Andric #include <__utility/scope_guard.h>
66*700637cbSDimitry Andric #include <__vector/vector.h>
67*700637cbSDimitry Andric #include <initializer_list>
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, class _Compare = less<_Key>, class _KeyContainer = vector<_Key>>
81*700637cbSDimitry Andric class flat_set {
82*700637cbSDimitry Andric   template <class, class, class>
83*700637cbSDimitry Andric   friend class flat_set;
84*700637cbSDimitry Andric 
85*700637cbSDimitry Andric   friend __flat_set_utils;
86*700637cbSDimitry Andric 
87*700637cbSDimitry Andric   static_assert(is_same_v<_Key, typename _KeyContainer::value_type>);
88*700637cbSDimitry Andric   static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
89*700637cbSDimitry Andric 
90*700637cbSDimitry Andric   using __key_iterator _LIBCPP_NODEBUG = typename _KeyContainer::const_iterator;
91*700637cbSDimitry Andric 
92*700637cbSDimitry Andric public:
93*700637cbSDimitry Andric   // types
94*700637cbSDimitry Andric   using key_type               = _Key;
95*700637cbSDimitry Andric   using value_type             = _Key;
96*700637cbSDimitry Andric   using key_compare            = __type_identity_t<_Compare>;
97*700637cbSDimitry Andric   using value_compare          = _Compare;
98*700637cbSDimitry Andric   using reference              = value_type&;
99*700637cbSDimitry Andric   using const_reference        = const value_type&;
100*700637cbSDimitry Andric   using size_type              = typename _KeyContainer::size_type;
101*700637cbSDimitry Andric   using difference_type        = typename _KeyContainer::difference_type;
102*700637cbSDimitry Andric   using iterator               = __ra_iterator<flat_set, typename _KeyContainer::const_iterator>;
103*700637cbSDimitry Andric   using const_iterator         = iterator;
104*700637cbSDimitry Andric   using reverse_iterator       = std::reverse_iterator<iterator>;
105*700637cbSDimitry Andric   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
106*700637cbSDimitry Andric   using container_type         = _KeyContainer;
107*700637cbSDimitry Andric 
108*700637cbSDimitry Andric public:
109*700637cbSDimitry Andric   // [flat.set.cons], construct/copy/destroy
110*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
flat_set()111*700637cbSDimitry Andric   flat_set() noexcept(is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_Compare>)
112*700637cbSDimitry Andric       : __keys_(), __compare_() {}
113*700637cbSDimitry Andric 
114*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(const flat_set&) = default;
115*700637cbSDimitry Andric 
flat_set(flat_set && __other)116*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(flat_set&& __other) noexcept(
117*700637cbSDimitry Andric       is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_Compare>)
118*700637cbSDimitry Andric #  if _LIBCPP_HAS_EXCEPTIONS
119*700637cbSDimitry Andric       try
120*700637cbSDimitry Andric #  endif // _LIBCPP_HAS_EXCEPTIONS
121*700637cbSDimitry Andric       : __keys_(std::move(__other.__keys_)), __compare_(std::move(__other.__compare_)) {
122*700637cbSDimitry Andric     __other.clear();
123*700637cbSDimitry Andric #  if _LIBCPP_HAS_EXCEPTIONS
124*700637cbSDimitry Andric   } catch (...) {
125*700637cbSDimitry Andric     __other.clear();
126*700637cbSDimitry Andric     // gcc does not like the `throw` keyword in a conditionally noexcept function
127*700637cbSDimitry Andric     if constexpr (!(is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_Compare>)) {
128*700637cbSDimitry Andric       throw;
129*700637cbSDimitry Andric     }
130*700637cbSDimitry Andric #  endif // _LIBCPP_HAS_EXCEPTIONS
131*700637cbSDimitry Andric   }
132*700637cbSDimitry Andric 
flat_set(const key_compare & __comp)133*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_set(const key_compare& __comp)
134*700637cbSDimitry Andric       : __keys_(), __compare_(__comp) {}
135*700637cbSDimitry Andric 
136*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI
137*700637cbSDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_set(container_type __keys, const key_compare& __comp = key_compare())
__keys_(std::move (__keys))138*700637cbSDimitry Andric       : __keys_(std::move(__keys)), __compare_(__comp) {
139*700637cbSDimitry Andric     __sort_and_unique();
140*700637cbSDimitry Andric   }
141*700637cbSDimitry Andric 
142*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
143*700637cbSDimitry Andric   flat_set(sorted_unique_t, container_type __keys, const key_compare& __comp = key_compare())
__keys_(std::move (__keys))144*700637cbSDimitry Andric       : __keys_(std::move(__keys)), __compare_(__comp) {
145*700637cbSDimitry Andric     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
146*700637cbSDimitry Andric         __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
147*700637cbSDimitry Andric   }
148*700637cbSDimitry Andric 
149*700637cbSDimitry Andric   template <class _InputIterator>
150*700637cbSDimitry Andric     requires __has_input_iterator_category<_InputIterator>::value
151*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
152*700637cbSDimitry Andric   flat_set(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
__keys_()153*700637cbSDimitry Andric       : __keys_(), __compare_(__comp) {
154*700637cbSDimitry Andric     insert(__first, __last);
155*700637cbSDimitry Andric   }
156*700637cbSDimitry Andric 
157*700637cbSDimitry Andric   template <class _InputIterator>
158*700637cbSDimitry Andric     requires __has_input_iterator_category<_InputIterator>::value
159*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
160*700637cbSDimitry Andric   flat_set(sorted_unique_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
__keys_(__first,__last)161*700637cbSDimitry Andric       : __keys_(__first, __last), __compare_(__comp) {
162*700637cbSDimitry Andric     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
163*700637cbSDimitry Andric         __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
164*700637cbSDimitry Andric   }
165*700637cbSDimitry Andric 
166*700637cbSDimitry Andric   template <_ContainerCompatibleRange<value_type> _Range>
flat_set(from_range_t,_Range && __rg)167*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(from_range_t, _Range&& __rg)
168*700637cbSDimitry Andric       : flat_set(from_range, std::forward<_Range>(__rg), key_compare()) {}
169*700637cbSDimitry Andric 
170*700637cbSDimitry Andric   template <_ContainerCompatibleRange<value_type> _Range>
flat_set(from_range_t,_Range && __rg,const key_compare & __comp)171*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(from_range_t, _Range&& __rg, const key_compare& __comp)
172*700637cbSDimitry Andric       : flat_set(__comp) {
173*700637cbSDimitry Andric     insert_range(std::forward<_Range>(__rg));
174*700637cbSDimitry Andric   }
175*700637cbSDimitry Andric 
176*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
177*700637cbSDimitry Andric   flat_set(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
178*700637cbSDimitry Andric       : flat_set(__il.begin(), __il.end(), __comp) {}
179*700637cbSDimitry Andric 
180*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
181*700637cbSDimitry Andric   flat_set(sorted_unique_t, initializer_list<value_type> __il, const key_compare& __comp = key_compare())
182*700637cbSDimitry Andric       : flat_set(sorted_unique, __il.begin(), __il.end(), __comp) {}
183*700637cbSDimitry Andric 
184*700637cbSDimitry Andric   template <class _Allocator>
185*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
flat_set(const _Allocator & __alloc)186*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_set(const _Allocator& __alloc)
187*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_() {}
188*700637cbSDimitry Andric 
189*700637cbSDimitry Andric   template <class _Allocator>
190*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
flat_set(const key_compare & __comp,const _Allocator & __alloc)191*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(const key_compare& __comp, const _Allocator& __alloc)
192*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_(__comp) {}
193*700637cbSDimitry Andric 
194*700637cbSDimitry Andric   template <class _Allocator>
195*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
flat_set(const container_type & __keys,const _Allocator & __alloc)196*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(const container_type& __keys, const _Allocator& __alloc)
197*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __keys)), __compare_() {
198*700637cbSDimitry Andric     __sort_and_unique();
199*700637cbSDimitry Andric   }
200*700637cbSDimitry Andric 
201*700637cbSDimitry Andric   template <class _Allocator>
202*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
203*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
flat_set(const container_type & __keys,const key_compare & __comp,const _Allocator & __alloc)204*700637cbSDimitry Andric   flat_set(const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc)
205*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __keys)), __compare_(__comp) {
206*700637cbSDimitry Andric     __sort_and_unique();
207*700637cbSDimitry Andric   }
208*700637cbSDimitry Andric 
209*700637cbSDimitry Andric   template <class _Allocator>
210*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
211*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
flat_set(sorted_unique_t,const container_type & __keys,const _Allocator & __alloc)212*700637cbSDimitry Andric   flat_set(sorted_unique_t, const container_type& __keys, const _Allocator& __alloc)
213*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __keys)), __compare_() {
214*700637cbSDimitry Andric     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
215*700637cbSDimitry Andric         __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
216*700637cbSDimitry Andric   }
217*700637cbSDimitry Andric 
218*700637cbSDimitry Andric   template <class _Allocator>
219*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
220*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
flat_set(sorted_unique_t,const container_type & __keys,const key_compare & __comp,const _Allocator & __alloc)221*700637cbSDimitry Andric   flat_set(sorted_unique_t, const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc)
222*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __keys)), __compare_(__comp) {
223*700637cbSDimitry Andric     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
224*700637cbSDimitry Andric         __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
225*700637cbSDimitry Andric   }
226*700637cbSDimitry Andric 
227*700637cbSDimitry Andric   template <class _Allocator>
228*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
flat_set(const flat_set & __other,const _Allocator & __alloc)229*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(const flat_set& __other, const _Allocator& __alloc)
230*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __other.__keys_)),
231*700637cbSDimitry Andric         __compare_(__other.__compare_) {}
232*700637cbSDimitry Andric 
233*700637cbSDimitry Andric   template <class _Allocator>
234*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
flat_set(flat_set && __other,const _Allocator & __alloc)235*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(flat_set&& __other, const _Allocator& __alloc)
236*700637cbSDimitry Andric #  if _LIBCPP_HAS_EXCEPTIONS
237*700637cbSDimitry Andric       try
238*700637cbSDimitry Andric #  endif // _LIBCPP_HAS_EXCEPTIONS
239*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc, std::move(__other.__keys_))),
240*700637cbSDimitry Andric         __compare_(std::move(__other.__compare_)) {
241*700637cbSDimitry Andric     __other.clear();
242*700637cbSDimitry Andric #  if _LIBCPP_HAS_EXCEPTIONS
243*700637cbSDimitry Andric   } catch (...) {
244*700637cbSDimitry Andric     __other.clear();
245*700637cbSDimitry Andric     throw;
246*700637cbSDimitry Andric #  endif // _LIBCPP_HAS_EXCEPTIONS
247*700637cbSDimitry Andric   }
248*700637cbSDimitry Andric 
249*700637cbSDimitry Andric   template <class _InputIterator, class _Allocator>
requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type,_Allocator>::value)250*700637cbSDimitry Andric     requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
251*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
252*700637cbSDimitry Andric   flat_set(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
253*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_() {
254*700637cbSDimitry Andric     insert(__first, __last);
255*700637cbSDimitry Andric   }
256*700637cbSDimitry Andric 
257*700637cbSDimitry Andric   template <class _InputIterator, class _Allocator>
requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type,_Allocator>::value)258*700637cbSDimitry Andric     requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
259*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
260*700637cbSDimitry Andric   flat_set(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc)
261*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_(__comp) {
262*700637cbSDimitry Andric     insert(__first, __last);
263*700637cbSDimitry Andric   }
264*700637cbSDimitry Andric 
265*700637cbSDimitry Andric   template <class _InputIterator, class _Allocator>
requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type,_Allocator>::value)266*700637cbSDimitry Andric     requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
267*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
268*700637cbSDimitry Andric   flat_set(sorted_unique_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
269*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __first, __last)), __compare_() {
270*700637cbSDimitry Andric     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
271*700637cbSDimitry Andric         __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
272*700637cbSDimitry Andric   }
273*700637cbSDimitry Andric 
274*700637cbSDimitry Andric   template <class _InputIterator, class _Allocator>
requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type,_Allocator>::value)275*700637cbSDimitry Andric     requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator<container_type, _Allocator>::value)
276*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(
277*700637cbSDimitry Andric       sorted_unique_t,
278*700637cbSDimitry Andric       _InputIterator __first,
279*700637cbSDimitry Andric       _InputIterator __last,
280*700637cbSDimitry Andric       const key_compare& __comp,
281*700637cbSDimitry Andric       const _Allocator& __alloc)
282*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc, __first, __last)), __compare_(__comp) {
283*700637cbSDimitry Andric     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
284*700637cbSDimitry Andric         __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates");
285*700637cbSDimitry Andric   }
286*700637cbSDimitry Andric 
287*700637cbSDimitry Andric   template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
288*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
flat_set(from_range_t,_Range && __rg,const _Allocator & __alloc)289*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(from_range_t, _Range&& __rg, const _Allocator& __alloc)
290*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_() {
291*700637cbSDimitry Andric     insert_range(std::forward<_Range>(__rg));
292*700637cbSDimitry Andric   }
293*700637cbSDimitry Andric 
294*700637cbSDimitry Andric   template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
295*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
296*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
flat_set(from_range_t,_Range && __rg,const key_compare & __comp,const _Allocator & __alloc)297*700637cbSDimitry Andric   flat_set(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc)
298*700637cbSDimitry Andric       : __keys_(std::make_obj_using_allocator<container_type>(__alloc)), __compare_(__comp) {
299*700637cbSDimitry Andric     insert_range(std::forward<_Range>(__rg));
300*700637cbSDimitry Andric   }
301*700637cbSDimitry Andric 
302*700637cbSDimitry Andric   template <class _Allocator>
303*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
304*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
flat_set(initializer_list<value_type> __il,const _Allocator & __alloc)305*700637cbSDimitry Andric   flat_set(initializer_list<value_type> __il, const _Allocator& __alloc)
306*700637cbSDimitry Andric       : flat_set(__il.begin(), __il.end(), __alloc) {}
307*700637cbSDimitry Andric 
308*700637cbSDimitry Andric   template <class _Allocator>
309*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
310*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
flat_set(initializer_list<value_type> __il,const key_compare & __comp,const _Allocator & __alloc)311*700637cbSDimitry Andric   flat_set(initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
312*700637cbSDimitry Andric       : flat_set(__il.begin(), __il.end(), __comp, __alloc) {}
313*700637cbSDimitry Andric 
314*700637cbSDimitry Andric   template <class _Allocator>
315*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
316*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
flat_set(sorted_unique_t,initializer_list<value_type> __il,const _Allocator & __alloc)317*700637cbSDimitry Andric   flat_set(sorted_unique_t, initializer_list<value_type> __il, const _Allocator& __alloc)
318*700637cbSDimitry Andric       : flat_set(sorted_unique, __il.begin(), __il.end(), __alloc) {}
319*700637cbSDimitry Andric 
320*700637cbSDimitry Andric   template <class _Allocator>
321*700637cbSDimitry Andric     requires uses_allocator<container_type, _Allocator>::value
322*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
flat_set(sorted_unique_t,initializer_list<value_type> __il,const key_compare & __comp,const _Allocator & __alloc)323*700637cbSDimitry Andric   flat_set(sorted_unique_t, initializer_list<value_type> __il, const key_compare& __comp, const _Allocator& __alloc)
324*700637cbSDimitry Andric       : flat_set(sorted_unique, __il.begin(), __il.end(), __comp, __alloc) {}
325*700637cbSDimitry Andric 
326*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set& operator=(initializer_list<value_type> __il) {
327*700637cbSDimitry Andric     clear();
328*700637cbSDimitry Andric     insert(__il);
329*700637cbSDimitry Andric     return *this;
330*700637cbSDimitry Andric   }
331*700637cbSDimitry Andric 
332*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set& operator=(const flat_set&) = default;
333*700637cbSDimitry Andric 
noexcept(is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_Compare>)334*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set& operator=(flat_set&& __other) noexcept(
335*700637cbSDimitry Andric       is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_Compare>) {
336*700637cbSDimitry Andric     // No matter what happens, we always want to clear the other container before returning
337*700637cbSDimitry Andric     // since we moved from it
338*700637cbSDimitry Andric     auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; });
339*700637cbSDimitry Andric     {
340*700637cbSDimitry Andric       // If an exception is thrown, we have no choice but to clear *this to preserve invariants
341*700637cbSDimitry Andric       auto __on_exception = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
342*700637cbSDimitry Andric       __keys_             = std::move(__other.__keys_);
343*700637cbSDimitry Andric       __compare_          = std::move(__other.__compare_);
344*700637cbSDimitry Andric       __on_exception.__complete();
345*700637cbSDimitry Andric     }
346*700637cbSDimitry Andric     return *this;
347*700637cbSDimitry Andric   }
348*700637cbSDimitry Andric 
349*700637cbSDimitry Andric   // iterators
begin()350*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept {
351*700637cbSDimitry Andric     return iterator(std::as_const(__keys_).begin());
352*700637cbSDimitry Andric   }
begin()353*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept {
354*700637cbSDimitry Andric     return const_iterator(__keys_.begin());
355*700637cbSDimitry Andric   }
end()356*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept {
357*700637cbSDimitry Andric     return iterator(std::as_const(__keys_).end());
358*700637cbSDimitry Andric   }
end()359*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept {
360*700637cbSDimitry Andric     return const_iterator(__keys_.end());
361*700637cbSDimitry Andric   }
362*700637cbSDimitry Andric 
rbegin()363*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept {
364*700637cbSDimitry Andric     return reverse_iterator(end());
365*700637cbSDimitry Andric   }
rbegin()366*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept {
367*700637cbSDimitry Andric     return const_reverse_iterator(end());
368*700637cbSDimitry Andric   }
rend()369*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept {
370*700637cbSDimitry Andric     return reverse_iterator(begin());
371*700637cbSDimitry Andric   }
rend()372*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept {
373*700637cbSDimitry Andric     return const_reverse_iterator(begin());
374*700637cbSDimitry Andric   }
375*700637cbSDimitry Andric 
cbegin()376*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); }
cend()377*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); }
crbegin()378*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept {
379*700637cbSDimitry Andric     return const_reverse_iterator(end());
380*700637cbSDimitry Andric   }
crend()381*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept {
382*700637cbSDimitry Andric     return const_reverse_iterator(begin());
383*700637cbSDimitry Andric   }
384*700637cbSDimitry Andric 
385*700637cbSDimitry Andric   // [flat.set.capacity], capacity
empty()386*700637cbSDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const noexcept {
387*700637cbSDimitry Andric     return __keys_.empty();
388*700637cbSDimitry Andric   }
389*700637cbSDimitry Andric 
size()390*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { return __keys_.size(); }
391*700637cbSDimitry Andric 
max_size()392*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return __keys_.max_size(); }
393*700637cbSDimitry Andric 
394*700637cbSDimitry Andric   // [flat.set.modifiers], modifiers
395*700637cbSDimitry Andric   template <class... _Args>
emplace(_Args &&...__args)396*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> emplace(_Args&&... __args) {
397*700637cbSDimitry Andric     if constexpr (sizeof...(__args) == 1 && (is_same_v<remove_cvref_t<_Args>, _Key> && ...)) {
398*700637cbSDimitry Andric       return __emplace(std::forward<_Args>(__args)...);
399*700637cbSDimitry Andric     } else {
400*700637cbSDimitry Andric       return __emplace(_Key(std::forward<_Args>(__args)...));
401*700637cbSDimitry Andric     }
402*700637cbSDimitry Andric   }
403*700637cbSDimitry Andric 
404*700637cbSDimitry Andric   template <class... _Args>
emplace_hint(const_iterator __hint,_Args &&...__args)405*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace_hint(const_iterator __hint, _Args&&... __args) {
406*700637cbSDimitry Andric     if constexpr (sizeof...(__args) == 1 && (is_same_v<remove_cvref_t<_Args>, _Key> && ...)) {
407*700637cbSDimitry Andric       return __emplace_hint(std::move(__hint), std::forward<_Args>(__args)...);
408*700637cbSDimitry Andric     } else {
409*700637cbSDimitry Andric       return __emplace_hint(std::move(__hint), _Key(std::forward<_Args>(__args)...));
410*700637cbSDimitry Andric     }
411*700637cbSDimitry Andric   }
412*700637cbSDimitry Andric 
insert(const value_type & __x)413*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert(const value_type& __x) {
414*700637cbSDimitry Andric     return emplace(__x);
415*700637cbSDimitry Andric   }
416*700637cbSDimitry Andric 
insert(value_type && __x)417*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert(value_type&& __x) {
418*700637cbSDimitry Andric     return emplace(std::move(__x));
419*700637cbSDimitry Andric   }
420*700637cbSDimitry Andric 
421*700637cbSDimitry Andric   template <class _Kp>
requires(__is_transparent_v<_Compare> && is_constructible_v<value_type,_Kp>)422*700637cbSDimitry Andric     requires(__is_transparent_v<_Compare> && is_constructible_v<value_type, _Kp>)
423*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert(_Kp&& __x) {
424*700637cbSDimitry Andric     return __emplace(std::forward<_Kp>(__x));
425*700637cbSDimitry Andric   }
insert(const_iterator __hint,const value_type & __x)426*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, const value_type& __x) {
427*700637cbSDimitry Andric     return emplace_hint(__hint, __x);
428*700637cbSDimitry Andric   }
429*700637cbSDimitry Andric 
insert(const_iterator __hint,value_type && __x)430*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, value_type&& __x) {
431*700637cbSDimitry Andric     return emplace_hint(__hint, std::move(__x));
432*700637cbSDimitry Andric   }
433*700637cbSDimitry Andric 
434*700637cbSDimitry Andric   template <class _Kp>
requires(__is_transparent_v<_Compare> && is_constructible_v<value_type,_Kp>)435*700637cbSDimitry Andric     requires(__is_transparent_v<_Compare> && is_constructible_v<value_type, _Kp>)
436*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, _Kp&& __x) {
437*700637cbSDimitry Andric     return __emplace_hint(__hint, std::forward<_Kp>(__x));
438*700637cbSDimitry Andric   }
439*700637cbSDimitry Andric 
440*700637cbSDimitry Andric   template <class _InputIterator>
441*700637cbSDimitry Andric     requires __has_input_iterator_category<_InputIterator>::value
insert(_InputIterator __first,_InputIterator __last)442*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(_InputIterator __first, _InputIterator __last) {
443*700637cbSDimitry Andric     if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
444*700637cbSDimitry Andric       __reserve(__last - __first);
445*700637cbSDimitry Andric     }
446*700637cbSDimitry Andric     __append_sort_merge_unique</*WasSorted = */ false>(std::move(__first), std::move(__last));
447*700637cbSDimitry Andric   }
448*700637cbSDimitry Andric 
449*700637cbSDimitry Andric   template <class _InputIterator>
450*700637cbSDimitry Andric     requires __has_input_iterator_category<_InputIterator>::value
451*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
insert(sorted_unique_t,_InputIterator __first,_InputIterator __last)452*700637cbSDimitry Andric   insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) {
453*700637cbSDimitry Andric     if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) {
454*700637cbSDimitry Andric       __reserve(__last - __first);
455*700637cbSDimitry Andric     }
456*700637cbSDimitry Andric 
457*700637cbSDimitry Andric     __append_sort_merge_unique</*WasSorted = */ true>(std::move(__first), std::move(__last));
458*700637cbSDimitry Andric   }
459*700637cbSDimitry Andric 
460*700637cbSDimitry Andric   template <_ContainerCompatibleRange<value_type> _Range>
insert_range(_Range && __range)461*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(_Range&& __range) {
462*700637cbSDimitry Andric     if constexpr (ranges::sized_range<_Range>) {
463*700637cbSDimitry Andric       __reserve(ranges::size(__range));
464*700637cbSDimitry Andric     }
465*700637cbSDimitry Andric 
466*700637cbSDimitry Andric     __append_sort_merge_unique</*WasSorted = */ false>(std::forward<_Range>(__range));
467*700637cbSDimitry Andric   }
468*700637cbSDimitry Andric 
insert(initializer_list<value_type> __il)469*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list<value_type> __il) {
470*700637cbSDimitry Andric     insert(__il.begin(), __il.end());
471*700637cbSDimitry Andric   }
472*700637cbSDimitry Andric 
insert(sorted_unique_t,initializer_list<value_type> __il)473*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(sorted_unique_t, initializer_list<value_type> __il) {
474*700637cbSDimitry Andric     insert(sorted_unique, __il.begin(), __il.end());
475*700637cbSDimitry Andric   }
476*700637cbSDimitry Andric 
extract()477*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && {
478*700637cbSDimitry Andric     auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; });
479*700637cbSDimitry Andric     auto __ret   = std::move(__keys_);
480*700637cbSDimitry Andric     return __ret;
481*700637cbSDimitry Andric   }
482*700637cbSDimitry Andric 
replace(container_type && __keys)483*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void replace(container_type&& __keys) {
484*700637cbSDimitry Andric     _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
485*700637cbSDimitry Andric         __is_sorted_and_unique(__keys), "Either the key container is not sorted or it contains duplicates");
486*700637cbSDimitry Andric     auto __guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
487*700637cbSDimitry Andric     __keys_      = std::move(__keys);
488*700637cbSDimitry Andric     __guard.__complete();
489*700637cbSDimitry Andric   }
490*700637cbSDimitry Andric 
erase(iterator __position)491*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(iterator __position) {
492*700637cbSDimitry Andric     auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
493*700637cbSDimitry Andric     auto __key_iter   = __keys_.erase(__position.__base());
494*700637cbSDimitry Andric     __on_failure.__complete();
495*700637cbSDimitry Andric     return iterator(__key_iter);
496*700637cbSDimitry Andric   }
497*700637cbSDimitry Andric 
498*700637cbSDimitry Andric   // The following overload is the same as the iterator overload
499*700637cbSDimitry Andric   // iterator erase(const_iterator __position);
500*700637cbSDimitry Andric 
erase(const key_type & __x)501*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(const key_type& __x) {
502*700637cbSDimitry Andric     auto __iter = find(__x);
503*700637cbSDimitry Andric     if (__iter != end()) {
504*700637cbSDimitry Andric       erase(__iter);
505*700637cbSDimitry Andric       return 1;
506*700637cbSDimitry Andric     }
507*700637cbSDimitry Andric     return 0;
508*700637cbSDimitry Andric   }
509*700637cbSDimitry Andric 
510*700637cbSDimitry Andric   template <class _Kp>
511*700637cbSDimitry Andric     requires(__is_transparent_v<_Compare> && !is_convertible_v<_Kp &&, iterator> &&
512*700637cbSDimitry Andric              !is_convertible_v<_Kp &&, const_iterator>)
erase(_Kp && __x)513*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(_Kp&& __x) {
514*700637cbSDimitry Andric     auto [__first, __last] = equal_range(__x);
515*700637cbSDimitry Andric     auto __res             = __last - __first;
516*700637cbSDimitry Andric     erase(__first, __last);
517*700637cbSDimitry Andric     return __res;
518*700637cbSDimitry Andric   }
519*700637cbSDimitry Andric 
erase(const_iterator __first,const_iterator __last)520*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __first, const_iterator __last) {
521*700637cbSDimitry Andric     auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
522*700637cbSDimitry Andric     auto __key_it     = __keys_.erase(__first.__base(), __last.__base());
523*700637cbSDimitry Andric     __on_failure.__complete();
524*700637cbSDimitry Andric     return iterator(std::move(__key_it));
525*700637cbSDimitry Andric   }
526*700637cbSDimitry Andric 
swap(flat_set & __y)527*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_set& __y) noexcept {
528*700637cbSDimitry Andric     // warning: The spec has unconditional noexcept, which means that
529*700637cbSDimitry Andric     // if any of the following functions throw an exception,
530*700637cbSDimitry Andric     // std::terminate will be called.
531*700637cbSDimitry Andric     // This is discussed in P2767, which hasn't been voted on yet.
532*700637cbSDimitry Andric     ranges::swap(__compare_, __y.__compare_);
533*700637cbSDimitry Andric     ranges::swap(__keys_, __y.__keys_);
534*700637cbSDimitry Andric   }
535*700637cbSDimitry Andric 
clear()536*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __keys_.clear(); }
537*700637cbSDimitry Andric 
538*700637cbSDimitry Andric   // observers
key_comp()539*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; }
value_comp()540*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { return __compare_; }
541*700637cbSDimitry Andric 
542*700637cbSDimitry Andric   // set operations
find(const key_type & __x)543*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) {
544*700637cbSDimitry Andric     return __find_impl(*this, __x);
545*700637cbSDimitry Andric   }
546*700637cbSDimitry Andric 
find(const key_type & __x)547*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const {
548*700637cbSDimitry Andric     return __find_impl(*this, __x);
549*700637cbSDimitry Andric   }
550*700637cbSDimitry Andric 
551*700637cbSDimitry Andric   template <class _Kp>
552*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
find(const _Kp & __x)553*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) {
554*700637cbSDimitry Andric     return __find_impl(*this, __x);
555*700637cbSDimitry Andric   }
556*700637cbSDimitry Andric 
557*700637cbSDimitry Andric   template <class _Kp>
558*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
find(const _Kp & __x)559*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const {
560*700637cbSDimitry Andric     return __find_impl(*this, __x);
561*700637cbSDimitry Andric   }
562*700637cbSDimitry Andric 
count(const key_type & __x)563*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const {
564*700637cbSDimitry Andric     return contains(__x) ? 1 : 0;
565*700637cbSDimitry Andric   }
566*700637cbSDimitry Andric 
567*700637cbSDimitry Andric   template <class _Kp>
568*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
count(const _Kp & __x)569*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const {
570*700637cbSDimitry Andric     return contains(__x) ? 1 : 0;
571*700637cbSDimitry Andric   }
572*700637cbSDimitry Andric 
contains(const key_type & __x)573*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const {
574*700637cbSDimitry Andric     return find(__x) != end();
575*700637cbSDimitry Andric   }
576*700637cbSDimitry Andric 
577*700637cbSDimitry Andric   template <class _Kp>
578*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
contains(const _Kp & __x)579*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const {
580*700637cbSDimitry Andric     return find(__x) != end();
581*700637cbSDimitry Andric   }
582*700637cbSDimitry Andric 
lower_bound(const key_type & __x)583*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) {
584*700637cbSDimitry Andric     const auto& __keys = __keys_;
585*700637cbSDimitry Andric     return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
586*700637cbSDimitry Andric   }
587*700637cbSDimitry Andric 
lower_bound(const key_type & __x)588*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const {
589*700637cbSDimitry Andric     return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
590*700637cbSDimitry Andric   }
591*700637cbSDimitry Andric 
592*700637cbSDimitry Andric   template <class _Kp>
593*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
lower_bound(const _Kp & __x)594*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) {
595*700637cbSDimitry Andric     const auto& __keys = __keys_;
596*700637cbSDimitry Andric     return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_));
597*700637cbSDimitry Andric   }
598*700637cbSDimitry Andric 
599*700637cbSDimitry Andric   template <class _Kp>
600*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
lower_bound(const _Kp & __x)601*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const {
602*700637cbSDimitry Andric     return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
603*700637cbSDimitry Andric   }
604*700637cbSDimitry Andric 
upper_bound(const key_type & __x)605*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) {
606*700637cbSDimitry Andric     const auto& __keys = __keys_;
607*700637cbSDimitry Andric     return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
608*700637cbSDimitry Andric   }
609*700637cbSDimitry Andric 
upper_bound(const key_type & __x)610*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const {
611*700637cbSDimitry Andric     return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
612*700637cbSDimitry Andric   }
613*700637cbSDimitry Andric 
614*700637cbSDimitry Andric   template <class _Kp>
615*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
upper_bound(const _Kp & __x)616*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) {
617*700637cbSDimitry Andric     const auto& __keys = __keys_;
618*700637cbSDimitry Andric     return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_));
619*700637cbSDimitry Andric   }
620*700637cbSDimitry Andric 
621*700637cbSDimitry Andric   template <class _Kp>
622*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
upper_bound(const _Kp & __x)623*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const {
624*700637cbSDimitry Andric     return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_));
625*700637cbSDimitry Andric   }
626*700637cbSDimitry Andric 
equal_range(const key_type & __x)627*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __x) {
628*700637cbSDimitry Andric     return __equal_range_impl(*this, __x);
629*700637cbSDimitry Andric   }
630*700637cbSDimitry Andric 
631*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
equal_range(const key_type & __x)632*700637cbSDimitry Andric   equal_range(const key_type& __x) const {
633*700637cbSDimitry Andric     return __equal_range_impl(*this, __x);
634*700637cbSDimitry Andric   }
635*700637cbSDimitry Andric 
636*700637cbSDimitry Andric   template <class _Kp>
637*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
equal_range(const _Kp & __x)638*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _Kp& __x) {
639*700637cbSDimitry Andric     return __equal_range_impl(*this, __x);
640*700637cbSDimitry Andric   }
641*700637cbSDimitry Andric   template <class _Kp>
642*700637cbSDimitry Andric     requires __is_transparent_v<_Compare>
643*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
equal_range(const _Kp & __x)644*700637cbSDimitry Andric   equal_range(const _Kp& __x) const {
645*700637cbSDimitry Andric     return __equal_range_impl(*this, __x);
646*700637cbSDimitry Andric   }
647*700637cbSDimitry Andric 
648*700637cbSDimitry Andric   friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator==(const flat_set& __x, const flat_set& __y) {
649*700637cbSDimitry Andric     return ranges::equal(__x, __y);
650*700637cbSDimitry Andric   }
651*700637cbSDimitry Andric 
652*700637cbSDimitry Andric   friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto
653*700637cbSDimitry Andric   operator<=>(const flat_set& __x, const flat_set& __y) {
654*700637cbSDimitry Andric     return std::lexicographical_compare_three_way(
655*700637cbSDimitry Andric         __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
656*700637cbSDimitry Andric   }
657*700637cbSDimitry Andric 
swap(flat_set & __x,flat_set & __y)658*700637cbSDimitry Andric   friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_set& __x, flat_set& __y) noexcept {
659*700637cbSDimitry Andric     __x.swap(__y);
660*700637cbSDimitry Andric   }
661*700637cbSDimitry Andric 
662*700637cbSDimitry Andric private:
__is_sorted_and_unique(auto && __key_container)663*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted_and_unique(auto&& __key_container) const {
664*700637cbSDimitry Andric     auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); };
665*700637cbSDimitry Andric     return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container);
666*700637cbSDimitry Andric   }
667*700637cbSDimitry Andric 
668*700637cbSDimitry Andric   // This function is only used in constructors. So there is not exception handling in this function.
669*700637cbSDimitry Andric   // If the function exits via an exception, there will be no flat_set object constructed, thus, there
670*700637cbSDimitry Andric   // is no invariant state to preserve
__sort_and_unique()671*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __sort_and_unique() {
672*700637cbSDimitry Andric     ranges::sort(__keys_, __compare_);
673*700637cbSDimitry Andric     auto __dup_start = ranges::unique(__keys_, __key_equiv(__compare_)).begin();
674*700637cbSDimitry Andric     __keys_.erase(__dup_start, __keys_.end());
675*700637cbSDimitry Andric   }
676*700637cbSDimitry Andric 
677*700637cbSDimitry Andric   template <bool _WasSorted, class... _Args>
__append_sort_merge_unique(_Args &&...__args)678*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __append_sort_merge_unique(_Args&&... __args) {
679*700637cbSDimitry Andric     auto __on_failure    = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; });
680*700637cbSDimitry Andric     size_type __old_size = size();
681*700637cbSDimitry Andric     __flat_set_utils::__append(*this, std::forward<_Args>(__args)...);
682*700637cbSDimitry Andric     if (size() != __old_size) {
683*700637cbSDimitry Andric       if constexpr (!_WasSorted) {
684*700637cbSDimitry Andric         ranges::sort(__keys_.begin() + __old_size, __keys_.end(), __compare_);
685*700637cbSDimitry Andric       } else {
686*700637cbSDimitry Andric         _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted_and_unique(__keys_ | ranges::views::drop(__old_size)),
687*700637cbSDimitry Andric                                             "Either the key container is not sorted or it contains duplicates");
688*700637cbSDimitry Andric       }
689*700637cbSDimitry Andric       ranges::inplace_merge(__keys_.begin(), __keys_.begin() + __old_size, __keys_.end(), __compare_);
690*700637cbSDimitry Andric 
691*700637cbSDimitry Andric       auto __dup_start = ranges::unique(__keys_, __key_equiv(__compare_)).begin();
692*700637cbSDimitry Andric       __keys_.erase(__dup_start, __keys_.end());
693*700637cbSDimitry Andric     }
694*700637cbSDimitry Andric     __on_failure.__complete();
695*700637cbSDimitry Andric   }
696*700637cbSDimitry Andric 
697*700637cbSDimitry Andric   template <class _Self, class _Kp>
__find_impl(_Self && __self,const _Kp & __key)698*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __find_impl(_Self&& __self, const _Kp& __key) {
699*700637cbSDimitry Andric     auto __it   = __self.lower_bound(__key);
700*700637cbSDimitry Andric     auto __last = __self.end();
701*700637cbSDimitry Andric     if (__it == __last || __self.__compare_(__key, *__it)) {
702*700637cbSDimitry Andric       return __last;
703*700637cbSDimitry Andric     }
704*700637cbSDimitry Andric     return __it;
705*700637cbSDimitry Andric   }
706*700637cbSDimitry Andric 
707*700637cbSDimitry Andric   template <class _Self, class _Kp>
__equal_range_impl(_Self && __self,const _Kp & __key)708*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __equal_range_impl(_Self&& __self, const _Kp& __key) {
709*700637cbSDimitry Andric     using __iter = _If<is_const_v<__libcpp_remove_reference_t<_Self>>, const_iterator, iterator>;
710*700637cbSDimitry Andric     auto __it    = std::lower_bound(__self.__keys_.begin(), __self.__keys_.end(), __key, __self.__compare_);
711*700637cbSDimitry Andric     auto __last  = __self.__keys_.end();
712*700637cbSDimitry Andric     if (__it == __last || __self.__compare_(__key, *__it)) {
713*700637cbSDimitry Andric       return std::make_pair(__iter(__it), __iter(__it));
714*700637cbSDimitry Andric     }
715*700637cbSDimitry Andric     return std::make_pair(__iter(__it), __iter(std::next(__it)));
716*700637cbSDimitry Andric   }
717*700637cbSDimitry Andric 
718*700637cbSDimitry Andric   template <class _Kp>
__emplace(_Kp && __key)719*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> __emplace(_Kp&& __key) {
720*700637cbSDimitry Andric     auto __it = lower_bound(__key);
721*700637cbSDimitry Andric     if (__it == end() || __compare_(__key, *__it)) {
722*700637cbSDimitry Andric       return pair<iterator, bool>(__flat_set_utils::__emplace_exact_pos(*this, __it, std::forward<_Kp>(__key)), true);
723*700637cbSDimitry Andric     } else {
724*700637cbSDimitry Andric       return pair<iterator, bool>(std::move(__it), false);
725*700637cbSDimitry Andric     }
726*700637cbSDimitry Andric   }
727*700637cbSDimitry Andric 
728*700637cbSDimitry Andric   template <class _Kp>
__is_hint_correct(const_iterator __hint,_Kp && __key)729*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_hint_correct(const_iterator __hint, _Kp&& __key) {
730*700637cbSDimitry Andric     if (__hint != cbegin() && !__compare_(*std::prev(__hint), __key)) {
731*700637cbSDimitry Andric       return false;
732*700637cbSDimitry Andric     }
733*700637cbSDimitry Andric     if (__hint != cend() && __compare_(*__hint, __key)) {
734*700637cbSDimitry Andric       return false;
735*700637cbSDimitry Andric     }
736*700637cbSDimitry Andric     return true;
737*700637cbSDimitry Andric   }
738*700637cbSDimitry Andric 
739*700637cbSDimitry Andric   template <class _Kp>
__emplace_hint(const_iterator __hint,_Kp && __key)740*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __emplace_hint(const_iterator __hint, _Kp&& __key) {
741*700637cbSDimitry Andric     if (__is_hint_correct(__hint, __key)) {
742*700637cbSDimitry Andric       if (__hint == cend() || __compare_(__key, *__hint)) {
743*700637cbSDimitry Andric         return __flat_set_utils::__emplace_exact_pos(*this, __hint, std::forward<_Kp>(__key));
744*700637cbSDimitry Andric       } else {
745*700637cbSDimitry Andric         // we already have an equal key
746*700637cbSDimitry Andric         return __hint;
747*700637cbSDimitry Andric       }
748*700637cbSDimitry Andric     } else {
749*700637cbSDimitry Andric       return __emplace(std::forward<_Kp>(__key)).first;
750*700637cbSDimitry Andric     }
751*700637cbSDimitry Andric   }
752*700637cbSDimitry Andric 
__reserve(size_t __size)753*700637cbSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __reserve(size_t __size) {
754*700637cbSDimitry Andric     if constexpr (__container_traits<_KeyContainer>::__reservable) {
755*700637cbSDimitry Andric       __keys_.reserve(__size);
756*700637cbSDimitry Andric     }
757*700637cbSDimitry Andric   }
758*700637cbSDimitry Andric 
759*700637cbSDimitry Andric   template <class _Key2, class _Compare2, class _KeyContainer2, class _Predicate>
760*700637cbSDimitry Andric   friend typename flat_set<_Key2, _Compare2, _KeyContainer2>::size_type _LIBCPP_CONSTEXPR_SINCE_CXX26
761*700637cbSDimitry Andric   erase_if(flat_set<_Key2, _Compare2, _KeyContainer2>&, _Predicate);
762*700637cbSDimitry Andric 
763*700637cbSDimitry Andric   _KeyContainer __keys_;
764*700637cbSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_;
765*700637cbSDimitry Andric 
766*700637cbSDimitry Andric   struct __key_equiv {
__key_equiv__key_equiv767*700637cbSDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_equiv(key_compare __c) : __comp_(__c) {}
768*700637cbSDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
operator__key_equiv769*700637cbSDimitry Andric     operator()(const_reference __x, const_reference __y) const {
770*700637cbSDimitry Andric       return !__comp_(__x, __y) && !__comp_(__y, __x);
771*700637cbSDimitry Andric     }
772*700637cbSDimitry Andric     key_compare __comp_;
773*700637cbSDimitry Andric   };
774*700637cbSDimitry Andric };
775*700637cbSDimitry Andric 
776*700637cbSDimitry Andric template <class _KeyContainer, class _Compare = less<typename _KeyContainer::value_type>>
777*700637cbSDimitry Andric   requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
778*700637cbSDimitry Andric            is_invocable_v<const _Compare&,
779*700637cbSDimitry Andric                           const typename _KeyContainer::value_type&,
780*700637cbSDimitry Andric                           const typename _KeyContainer::value_type&>)
781*700637cbSDimitry Andric flat_set(_KeyContainer, _Compare = _Compare()) -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
782*700637cbSDimitry Andric 
783*700637cbSDimitry Andric template <class _KeyContainer, class _Allocator>
784*700637cbSDimitry Andric   requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator<_KeyContainer>::value)
785*700637cbSDimitry Andric flat_set(_KeyContainer, _Allocator)
786*700637cbSDimitry Andric     -> flat_set<typename _KeyContainer::value_type, less<typename _KeyContainer::value_type>, _KeyContainer>;
787*700637cbSDimitry Andric 
788*700637cbSDimitry Andric template <class _KeyContainer, class _Compare, class _Allocator>
789*700637cbSDimitry Andric   requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
790*700637cbSDimitry Andric            uses_allocator_v<_KeyContainer, _Allocator> &&
791*700637cbSDimitry Andric            is_invocable_v<const _Compare&,
792*700637cbSDimitry Andric                           const typename _KeyContainer::value_type&,
793*700637cbSDimitry Andric                           const typename _KeyContainer::value_type&>)
794*700637cbSDimitry Andric flat_set(_KeyContainer, _Compare, _Allocator) -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
795*700637cbSDimitry Andric 
796*700637cbSDimitry Andric template <class _KeyContainer, class _Compare = less<typename _KeyContainer::value_type>>
797*700637cbSDimitry Andric   requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
798*700637cbSDimitry Andric            is_invocable_v<const _Compare&,
799*700637cbSDimitry Andric                           const typename _KeyContainer::value_type&,
800*700637cbSDimitry Andric                           const typename _KeyContainer::value_type&>)
801*700637cbSDimitry Andric flat_set(sorted_unique_t, _KeyContainer, _Compare = _Compare())
802*700637cbSDimitry Andric     -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
803*700637cbSDimitry Andric 
804*700637cbSDimitry Andric template <class _KeyContainer, class _Allocator>
805*700637cbSDimitry Andric   requires(uses_allocator_v<_KeyContainer, _Allocator> && !__is_allocator<_KeyContainer>::value)
806*700637cbSDimitry Andric flat_set(sorted_unique_t, _KeyContainer, _Allocator)
807*700637cbSDimitry Andric     -> flat_set<typename _KeyContainer::value_type, less<typename _KeyContainer::value_type>, _KeyContainer>;
808*700637cbSDimitry Andric 
809*700637cbSDimitry Andric template <class _KeyContainer, class _Compare, class _Allocator>
810*700637cbSDimitry Andric   requires(!__is_allocator<_Compare>::value && !__is_allocator<_KeyContainer>::value &&
811*700637cbSDimitry Andric            uses_allocator_v<_KeyContainer, _Allocator> &&
812*700637cbSDimitry Andric            is_invocable_v<const _Compare&,
813*700637cbSDimitry Andric                           const typename _KeyContainer::value_type&,
814*700637cbSDimitry Andric                           const typename _KeyContainer::value_type&>)
815*700637cbSDimitry Andric flat_set(sorted_unique_t, _KeyContainer, _Compare, _Allocator)
816*700637cbSDimitry Andric     -> flat_set<typename _KeyContainer::value_type, _Compare, _KeyContainer>;
817*700637cbSDimitry Andric 
818*700637cbSDimitry Andric template <class _InputIterator, class _Compare = less<__iter_value_type<_InputIterator>>>
819*700637cbSDimitry Andric   requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
820*700637cbSDimitry Andric flat_set(_InputIterator, _InputIterator, _Compare = _Compare())
821*700637cbSDimitry Andric     -> flat_set<__iter_value_type<_InputIterator>, _Compare>;
822*700637cbSDimitry Andric 
823*700637cbSDimitry Andric template <class _InputIterator, class _Compare = less<__iter_value_type<_InputIterator>>>
824*700637cbSDimitry Andric   requires(__has_input_iterator_category<_InputIterator>::value && !__is_allocator<_Compare>::value)
825*700637cbSDimitry Andric flat_set(sorted_unique_t, _InputIterator, _InputIterator, _Compare = _Compare())
826*700637cbSDimitry Andric     -> flat_set<__iter_value_type<_InputIterator>, _Compare>;
827*700637cbSDimitry Andric 
828*700637cbSDimitry Andric template <ranges::input_range _Range,
829*700637cbSDimitry Andric           class _Compare   = less<ranges::range_value_t<_Range>>,
830*700637cbSDimitry Andric           class _Allocator = allocator<ranges::range_value_t<_Range>>,
831*700637cbSDimitry Andric           class            = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
832*700637cbSDimitry Andric flat_set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_set<
833*700637cbSDimitry Andric     ranges::range_value_t<_Range>,
834*700637cbSDimitry Andric     _Compare,
835*700637cbSDimitry Andric     vector<ranges::range_value_t<_Range>, __allocator_traits_rebind_t<_Allocator, ranges::range_value_t<_Range>>>>;
836*700637cbSDimitry Andric 
837*700637cbSDimitry Andric template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>>
838*700637cbSDimitry Andric flat_set(from_range_t, _Range&&, _Allocator) -> flat_set<
839*700637cbSDimitry Andric     ranges::range_value_t<_Range>,
840*700637cbSDimitry Andric     less<ranges::range_value_t<_Range>>,
841*700637cbSDimitry Andric     vector<ranges::range_value_t<_Range>, __allocator_traits_rebind_t<_Allocator, ranges::range_value_t<_Range>>>>;
842*700637cbSDimitry Andric 
843*700637cbSDimitry Andric template <class _Key, class _Compare = less<_Key>>
844*700637cbSDimitry Andric   requires(!__is_allocator<_Compare>::value)
845*700637cbSDimitry Andric flat_set(initializer_list<_Key>, _Compare = _Compare()) -> flat_set<_Key, _Compare>;
846*700637cbSDimitry Andric 
847*700637cbSDimitry Andric template <class _Key, class _Compare = less<_Key>>
848*700637cbSDimitry Andric   requires(!__is_allocator<_Compare>::value)
849*700637cbSDimitry Andric flat_set(sorted_unique_t, initializer_list<_Key>, _Compare = _Compare()) -> flat_set<_Key, _Compare>;
850*700637cbSDimitry Andric 
851*700637cbSDimitry Andric template <class _Key, class _Compare, class _KeyContainer, class _Allocator>
852*700637cbSDimitry Andric struct uses_allocator<flat_set<_Key, _Compare, _KeyContainer>, _Allocator>
853*700637cbSDimitry Andric     : bool_constant<uses_allocator_v<_KeyContainer, _Allocator>> {};
854*700637cbSDimitry Andric 
855*700637cbSDimitry Andric template <class _Key, class _Compare, class _KeyContainer, class _Predicate>
856*700637cbSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 typename flat_set<_Key, _Compare, _KeyContainer>::size_type
857*700637cbSDimitry Andric erase_if(flat_set<_Key, _Compare, _KeyContainer>& __flat_set, _Predicate __pred) {
858*700637cbSDimitry Andric   auto __guard = std::__make_exception_guard([&] { __flat_set.clear(); });
859*700637cbSDimitry Andric   auto __it    = std::remove_if(__flat_set.__keys_.begin(), __flat_set.__keys_.end(), [&](const auto& __e) -> bool {
860*700637cbSDimitry Andric     return static_cast<bool>(__pred(__e));
861*700637cbSDimitry Andric   });
862*700637cbSDimitry Andric   auto __res   = __flat_set.__keys_.end() - __it;
863*700637cbSDimitry Andric   __flat_set.__keys_.erase(__it, __flat_set.__keys_.end());
864*700637cbSDimitry Andric   __guard.__complete();
865*700637cbSDimitry Andric   return __res;
866*700637cbSDimitry Andric }
867*700637cbSDimitry Andric 
868*700637cbSDimitry Andric _LIBCPP_END_NAMESPACE_STD
869*700637cbSDimitry Andric 
870*700637cbSDimitry Andric #endif // _LIBCPP_STD_VER >= 23
871*700637cbSDimitry Andric 
872*700637cbSDimitry Andric _LIBCPP_POP_MACROS
873*700637cbSDimitry Andric 
874*700637cbSDimitry Andric #endif // _LIBCPP___FLAT_SET_FLAT_SET_H
875