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