From 42aa499acf7794d1d516c0f55f928988bff2c394 Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 4 May 2025 13:33:59 +0100 Subject: [PATCH 1/4] constexpr flat_set --- libcxx/include/__flat_set/flat_set.h | 278 +++++++++++------- libcxx/include/__flat_set/utils.h | 8 +- libcxx/include/module.modulemap.in | 3 + libcxx/test/std/containers/Emplaceable.h | 8 - .../flat.set/flat.set.capacity/empty.pass.cpp | 14 +- .../flat.set.capacity/max_size.pass.cpp | 7 +- .../flat.set/flat.set.capacity/size.pass.cpp | 17 +- .../flat.set/flat.set.cons/alloc.pass.cpp | 26 +- .../assign_initializer_list.pass.cpp | 14 +- .../flat.set/flat.set.cons/compare.pass.cpp | 80 +++-- .../flat.set.cons/containers.pass.cpp | 106 ++++--- .../flat.set/flat.set.cons/copy.pass.cpp | 21 +- .../flat.set.cons/copy_alloc.pass.cpp | 47 +-- .../flat.set.cons/copy_assign.pass.cpp | 27 +- .../flat.set/flat.set.cons/default.pass.cpp | 42 ++- .../flat.set.cons/dtor_noexcept.pass.cpp | 28 +- .../flat.set.cons/initializer_list.pass.cpp | 121 ++++---- .../flat.set/flat.set.cons/iter_iter.pass.cpp | 98 +++--- .../flat.set/flat.set.cons/move.pass.cpp | 64 ++-- .../flat.set.cons/move_alloc.pass.cpp | 51 ++-- .../flat.set.cons/move_assign.pass.cpp | 51 +++- .../flat.set/flat.set.cons/range.pass.cpp | 93 ++++-- .../flat.set.cons/sorted_container.pass.cpp | 91 +++--- .../sorted_initializer_list.pass.cpp | 122 ++++---- .../flat.set.cons/sorted_iter_iter.pass.cpp | 93 +++--- .../flat.set.erasure/erase_if.pass.cpp | 26 +- .../flat.set.iterators/iterator.pass.cpp | 14 +- .../iterator_comparison.pass.cpp | 14 +- .../reverse_iterator.pass.cpp | 52 ++-- .../flat.set.modifiers/clear.pass.cpp | 15 +- .../flat.set.modifiers/emplace.pass.cpp | 21 +- .../flat.set.modifiers/emplace_hint.pass.cpp | 21 +- .../flat.set.modifiers/erase_iter.pass.cpp | 14 +- .../erase_iter_iter.pass.cpp | 14 +- .../flat.set.modifiers/erase_key.pass.cpp | 14 +- .../erase_key_transparent.pass.cpp | 29 +- .../flat.set.modifiers/extract.pass.cpp | 14 +- .../flat.set.modifiers/insert_cv.pass.cpp | 14 +- .../insert_initializer_list.pass.cpp | 14 +- .../insert_iter_cv.pass.cpp | 14 +- .../insert_iter_iter.pass.cpp | 14 +- .../insert_iter_rv.pass.cpp | 18 +- .../flat.set.modifiers/insert_range.pass.cpp | 16 +- .../flat.set.modifiers/insert_rv.pass.cpp | 18 +- .../insert_sorted_initializer_list.pass.cpp | 14 +- .../insert_sorted_iter_iter.pass.cpp | 14 +- .../insert_transparent.pass.cpp | 14 +- .../flat.set.modifiers/replace.pass.cpp | 14 +- .../flat.set.modifiers/swap_free.pass.cpp | 15 +- .../flat.set.modifiers/swap_member.pass.cpp | 14 +- .../flat.set/flat.set.observers/comp.pass.cpp | 9 +- .../flat.set.operations/contains.pass.cpp | 14 +- .../contains_transparent.pass.cpp | 14 +- .../flat.set.operations/count.pass.cpp | 14 +- .../count_transparent.pass.cpp | 14 +- .../flat.set.operations/equal_range.pass.cpp | 14 +- .../equal_range_transparent.pass.cpp | 14 +- .../flat.set.operations/find.pass.cpp | 14 +- .../find_transparent.pass.cpp | 12 +- .../flat.set.operations/lower_bound.pass.cpp | 14 +- .../lower_bound_transparent.pass.cpp | 14 +- .../flat.set.operations/upper_bound.pass.cpp | 14 +- .../upper_bound_transparent.pass.cpp | 14 +- .../container.adaptors/flat.set/helpers.h | 2 +- .../flat.set/incomplete_type.pass.cpp | 11 +- .../flat.set/op_compare.pass.cpp | 16 +- .../container.adaptors/flat_helpers.h | 20 +- 67 files changed, 1443 insertions(+), 732 deletions(-) diff --git a/libcxx/include/__flat_set/flat_set.h b/libcxx/include/__flat_set/flat_set.h index b8edd8eee0cfa..e677f67655842 100644 --- a/libcxx/include/__flat_set/flat_set.h +++ b/libcxx/include/__flat_set/flat_set.h @@ -107,13 +107,13 @@ class flat_set { public: // [flat.set.cons], construct/copy/destroy - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set() noexcept(is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_Compare>) : __keys_(), __compare_() {} - _LIBCPP_HIDE_FROM_ABI flat_set(const flat_set&) = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(const flat_set&) = default; - _LIBCPP_HIDE_FROM_ABI flat_set(flat_set&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(flat_set&& __other) noexcept( is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_Compare>) # if _LIBCPP_HAS_EXCEPTIONS try @@ -130,14 +130,17 @@ class flat_set { # endif // _LIBCPP_HAS_EXCEPTIONS } - _LIBCPP_HIDE_FROM_ABI explicit flat_set(const key_compare& __comp) : __keys_(), __compare_(__comp) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_set(const key_compare& __comp) + : __keys_(), __compare_(__comp) {} - _LIBCPP_HIDE_FROM_ABI explicit flat_set(container_type __keys, const key_compare& __comp = key_compare()) + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_set(container_type __keys, const key_compare& __comp = key_compare()) : __keys_(std::move(__keys)), __compare_(__comp) { __sort_and_unique(); } - _LIBCPP_HIDE_FROM_ABI flat_set(sorted_unique_t, container_type __keys, const key_compare& __comp = key_compare()) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_set(sorted_unique_t, container_type __keys, const key_compare& __comp = key_compare()) : __keys_(std::move(__keys)), __compare_(__comp) { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates"); @@ -145,7 +148,7 @@ class flat_set { template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __keys_(), __compare_(__comp) { insert(__first, __last); @@ -153,7 +156,7 @@ class flat_set { template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(sorted_unique_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __keys_(__first, __last), __compare_(__comp) { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( @@ -161,48 +164,52 @@ class flat_set { } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_set(from_range_t, _Range&& __rg) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(from_range_t, _Range&& __rg) : flat_set(from_range, std::forward<_Range>(__rg), key_compare()) {} template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_set(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_set(__comp) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(from_range_t, _Range&& __rg, const key_compare& __comp) + : flat_set(__comp) { insert_range(std::forward<_Range>(__rg)); } - _LIBCPP_HIDE_FROM_ABI flat_set(initializer_list __il, const key_compare& __comp = key_compare()) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_set(initializer_list __il, const key_compare& __comp = key_compare()) : flat_set(__il.begin(), __il.end(), __comp) {} - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(sorted_unique_t, initializer_list __il, const key_compare& __comp = key_compare()) : flat_set(sorted_unique, __il.begin(), __il.end(), __comp) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI explicit flat_set(const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_set(const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc)), __compare_() {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(const key_compare& __comp, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc)), __compare_(__comp) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(const container_type& __keys, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(const container_type& __keys, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __keys)), __compare_() { __sort_and_unique(); } template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_set(const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __keys)), __compare_(__comp) { __sort_and_unique(); } template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(sorted_unique_t, const container_type& __keys, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_set(sorted_unique_t, const container_type& __keys, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __keys)), __compare_() { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates"); @@ -210,7 +217,7 @@ class flat_set { template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(sorted_unique_t, const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __keys)), __compare_(__comp) { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( @@ -219,13 +226,13 @@ class flat_set { template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(const flat_set& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(const flat_set& __other, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __other.__keys_)), __compare_(__other.__compare_) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(flat_set&& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(flat_set&& __other, const _Allocator& __alloc) # if _LIBCPP_HAS_EXCEPTIONS try # endif // _LIBCPP_HAS_EXCEPTIONS @@ -241,14 +248,15 @@ class flat_set { template requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator::value) - _LIBCPP_HIDE_FROM_ABI flat_set(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_set(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc)), __compare_() { insert(__first, __last); } template requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator::value) - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc)), __compare_(__comp) { insert(__first, __last); @@ -256,7 +264,7 @@ class flat_set { template requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator::value) - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(sorted_unique_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __first, __last)), __compare_() { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( @@ -265,12 +273,12 @@ class flat_set { template requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator::value) - _LIBCPP_HIDE_FROM_ABI - flat_set(sorted_unique_t, - _InputIterator __first, - _InputIterator __last, - const key_compare& __comp, - const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set( + sorted_unique_t, + _InputIterator __first, + _InputIterator __last, + const key_compare& __comp, + const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __first, __last)), __compare_(__comp) { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( __is_sorted_and_unique(__keys_), "Either the key container is not sorted or it contains duplicates"); @@ -278,49 +286,52 @@ class flat_set { template <_ContainerCompatibleRange _Range, class _Allocator> requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(from_range_t, _Range&& __rg, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(from_range_t, _Range&& __rg, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc)), __compare_() { insert_range(std::forward<_Range>(__rg)); } template <_ContainerCompatibleRange _Range, class _Allocator> requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_set(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc)), __compare_(__comp) { insert_range(std::forward<_Range>(__rg)); } template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_set(initializer_list __il, const _Allocator& __alloc) : flat_set(__il.begin(), __il.end(), __alloc) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_set(__il.begin(), __il.end(), __comp, __alloc) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_set(sorted_unique_t, initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_set(sorted_unique_t, initializer_list __il, const _Allocator& __alloc) : flat_set(sorted_unique, __il.begin(), __il.end(), __alloc) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set(sorted_unique_t, initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_set(sorted_unique, __il.begin(), __il.end(), __comp, __alloc) {} - _LIBCPP_HIDE_FROM_ABI flat_set& operator=(initializer_list __il) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set& operator=(initializer_list __il) { clear(); insert(__il); return *this; } - _LIBCPP_HIDE_FROM_ABI flat_set& operator=(const flat_set&) = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set& operator=(const flat_set&) = default; - _LIBCPP_HIDE_FROM_ABI flat_set& operator=(flat_set&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_set& operator=(flat_set&& __other) noexcept( is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_Compare>) { // No matter what happens, we always want to clear the other container before returning // since we moved from it @@ -336,31 +347,53 @@ class flat_set { } // iterators - _LIBCPP_HIDE_FROM_ABI iterator begin() noexcept { return iterator(std::as_const(__keys_).begin()); } - _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return const_iterator(__keys_.begin()); } - _LIBCPP_HIDE_FROM_ABI iterator end() noexcept { return iterator(std::as_const(__keys_).end()); } - _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return const_iterator(__keys_.end()); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept { + return iterator(std::as_const(__keys_).begin()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept { + return const_iterator(__keys_.begin()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept { + return iterator(std::as_const(__keys_).end()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept { + return const_iterator(__keys_.end()); + } - _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() noexcept { + return reverse_iterator(end()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator(end()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() noexcept { + return reverse_iterator(begin()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const noexcept { + return const_reverse_iterator(begin()); + } - _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return begin(); } - _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return end(); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const noexcept { return begin(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const noexcept { return end(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crbegin() const noexcept { + return const_reverse_iterator(end()); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const noexcept { + return const_reverse_iterator(begin()); + } // [flat.set.capacity], capacity - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __keys_.empty(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const noexcept { + return __keys_.empty(); + } - _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __keys_.size(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { return __keys_.size(); } - _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept { return __keys_.max_size(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return __keys_.max_size(); } // [flat.set.modifiers], modifiers template - _LIBCPP_HIDE_FROM_ABI pair emplace(_Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair emplace(_Args&&... __args) { if constexpr (sizeof...(__args) == 1 && (is_same_v, _Key> && ...)) { return __emplace(std::forward<_Args>(__args)...); } else { @@ -369,7 +402,7 @@ class flat_set { } template - _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __hint, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace_hint(const_iterator __hint, _Args&&... __args) { if constexpr (sizeof...(__args) == 1 && (is_same_v, _Key> && ...)) { return __emplace_hint(std::move(__hint), std::forward<_Args>(__args)...); } else { @@ -377,32 +410,36 @@ class flat_set { } } - _LIBCPP_HIDE_FROM_ABI pair insert(const value_type& __x) { return emplace(__x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair insert(const value_type& __x) { + return emplace(__x); + } - _LIBCPP_HIDE_FROM_ABI pair insert(value_type&& __x) { return emplace(std::move(__x)); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair insert(value_type&& __x) { + return emplace(std::move(__x)); + } template requires(__is_transparent_v<_Compare> && is_constructible_v) - _LIBCPP_HIDE_FROM_ABI pair insert(_Kp&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair insert(_Kp&& __x) { return __emplace(std::forward<_Kp>(__x)); } - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, const value_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, const value_type& __x) { return emplace_hint(__hint, __x); } - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, value_type&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, value_type&& __x) { return emplace_hint(__hint, std::move(__x)); } template requires(__is_transparent_v<_Compare> && is_constructible_v) - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, _Kp&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, _Kp&& __x) { return __emplace_hint(__hint, std::forward<_Kp>(__x)); } template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(_InputIterator __first, _InputIterator __last) { if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { __reserve(__last - __first); } @@ -411,7 +448,8 @@ class flat_set { template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI void insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) { if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { __reserve(__last - __first); } @@ -420,7 +458,7 @@ class flat_set { } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(_Range&& __range) { if constexpr (ranges::sized_range<_Range>) { __reserve(ranges::size(__range)); } @@ -428,19 +466,21 @@ class flat_set { __append_sort_merge_unique(std::forward<_Range>(__range)); } - _LIBCPP_HIDE_FROM_ABI void insert(initializer_list __il) { insert(__il.begin(), __il.end()); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list __il) { + insert(__il.begin(), __il.end()); + } - _LIBCPP_HIDE_FROM_ABI void insert(sorted_unique_t, initializer_list __il) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(sorted_unique_t, initializer_list __il) { insert(sorted_unique, __il.begin(), __il.end()); } - _LIBCPP_HIDE_FROM_ABI container_type extract() && { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 container_type extract() && { auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; }); auto __ret = std::move(__keys_); return __ret; } - _LIBCPP_HIDE_FROM_ABI void replace(container_type&& __keys) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void replace(container_type&& __keys) { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( __is_sorted_and_unique(__keys), "Either the key container is not sorted or it contains duplicates"); auto __guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); @@ -448,7 +488,7 @@ class flat_set { __guard.__complete(); } - _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __position) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(iterator __position) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); auto __key_iter = __keys_.erase(__position.__base()); __on_failure.__complete(); @@ -458,7 +498,7 @@ class flat_set { // The following overload is the same as the iterator overload // iterator erase(const_iterator __position); - _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(const key_type& __x) { auto __iter = find(__x); if (__iter != end()) { erase(__iter); @@ -470,21 +510,21 @@ class flat_set { template requires(__is_transparent_v<_Compare> && !is_convertible_v<_Kp &&, iterator> && !is_convertible_v<_Kp &&, const_iterator>) - _LIBCPP_HIDE_FROM_ABI size_type erase(_Kp&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(_Kp&& __x) { auto [__first, __last] = equal_range(__x); auto __res = __last - __first; erase(__first, __last); return __res; } - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __first, const_iterator __last) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); auto __key_it = __keys_.erase(__first.__base(), __last.__base()); __on_failure.__complete(); return iterator(std::move(__key_it)); } - _LIBCPP_HIDE_FROM_ABI void swap(flat_set& __y) noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_set& __y) noexcept { // warning: The spec has unconditional noexcept, which means that // if any of the following functions throw an exception, // std::terminate will be called. @@ -493,121 +533,134 @@ class flat_set { ranges::swap(__keys_, __y.__keys_); } - _LIBCPP_HIDE_FROM_ABI void clear() noexcept { __keys_.clear(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __keys_.clear(); } // observers - _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __compare_; } - _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return __compare_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const { return __compare_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const { return __compare_; } // set operations - _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __x) { return __find_impl(*this, __x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __x) { + return __find_impl(*this, __x); + } - _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __x) const { return __find_impl(*this, __x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __x) const { + return __find_impl(*this, __x); + } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI iterator find(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Kp& __x) { return __find_impl(*this, __x); } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Kp& __x) const { return __find_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __x) const { return contains(__x) ? 1 : 0; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const { + return contains(__x) ? 1 : 0; + } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI size_type count(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _Kp& __x) const { return contains(__x) ? 1 : 0; } - _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __x) const { return find(__x) != end(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const { + return find(__x) != end(); + } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI bool contains(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _Kp& __x) const { return find(__x) != end(); } - _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) { const auto& __keys = __keys_; return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_)); } - _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const key_type& __x) const { return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_)); } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) { const auto& __keys = __keys_; return iterator(std::lower_bound(__keys.begin(), __keys.end(), __x, __compare_)); } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator lower_bound(const _Kp& __x) const { return const_iterator(std::lower_bound(__keys_.begin(), __keys_.end(), __x, __compare_)); } - _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) { const auto& __keys = __keys_; return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_)); } - _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const key_type& __x) const { return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_)); } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) { const auto& __keys = __keys_; return iterator(std::upper_bound(__keys.begin(), __keys.end(), __x, __compare_)); } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator upper_bound(const _Kp& __x) const { return const_iterator(std::upper_bound(__keys_.begin(), __keys_.end(), __x, __compare_)); } - _LIBCPP_HIDE_FROM_ABI pair equal_range(const key_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair equal_range(const key_type& __x) { return __equal_range_impl(*this, __x); } - _LIBCPP_HIDE_FROM_ABI pair equal_range(const key_type& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + equal_range(const key_type& __x) const { return __equal_range_impl(*this, __x); } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI pair equal_range(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair equal_range(const _Kp& __x) { return __equal_range_impl(*this, __x); } template requires __is_transparent_v<_Compare> - _LIBCPP_HIDE_FROM_ABI pair equal_range(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + equal_range(const _Kp& __x) const { return __equal_range_impl(*this, __x); } - friend _LIBCPP_HIDE_FROM_ABI bool operator==(const flat_set& __x, const flat_set& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator==(const flat_set& __x, const flat_set& __y) { return ranges::equal(__x, __y); } - friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_set& __x, const flat_set& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto + operator<=>(const flat_set& __x, const flat_set& __y) { return std::lexicographical_compare_three_way( __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); } - friend _LIBCPP_HIDE_FROM_ABI void swap(flat_set& __x, flat_set& __y) noexcept { __x.swap(__y); } + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_set& __x, flat_set& __y) noexcept { + __x.swap(__y); + } private: - _LIBCPP_HIDE_FROM_ABI bool __is_sorted_and_unique(auto&& __key_container) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted_and_unique(auto&& __key_container) const { auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); }; return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container); } @@ -615,14 +668,14 @@ class flat_set { // This function is only used in constructors. So there is not exception handling in this function. // If the function exits via an exception, there will be no flat_set object constructed, thus, there // is no invariant state to preserve - _LIBCPP_HIDE_FROM_ABI void __sort_and_unique() { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __sort_and_unique() { ranges::sort(__keys_, __compare_); auto __dup_start = ranges::unique(__keys_, __key_equiv(__compare_)).begin(); __keys_.erase(__dup_start, __keys_.end()); } template - _LIBCPP_HIDE_FROM_ABI void __append_sort_merge_unique(_Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __append_sort_merge_unique(_Args&&... __args) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); size_type __old_size = size(); __flat_set_utils::__append(*this, std::forward<_Args>(__args)...); @@ -642,7 +695,7 @@ class flat_set { } template - _LIBCPP_HIDE_FROM_ABI static auto __find_impl(_Self&& __self, const _Kp& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __find_impl(_Self&& __self, const _Kp& __key) { auto __it = __self.lower_bound(__key); auto __last = __self.end(); if (__it == __last || __self.__compare_(__key, *__it)) { @@ -652,7 +705,7 @@ class flat_set { } template - _LIBCPP_HIDE_FROM_ABI static auto __equal_range_impl(_Self&& __self, const _Kp& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __equal_range_impl(_Self&& __self, const _Kp& __key) { using __iter = _If>, const_iterator, iterator>; auto __it = std::lower_bound(__self.__keys_.begin(), __self.__keys_.end(), __key, __self.__compare_); auto __last = __self.__keys_.end(); @@ -663,7 +716,7 @@ class flat_set { } template - _LIBCPP_HIDE_FROM_ABI pair __emplace(_Kp&& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair __emplace(_Kp&& __key) { auto __it = lower_bound(__key); if (__it == end() || __compare_(__key, *__it)) { return pair(__flat_set_utils::__emplace_exact_pos(*this, __it, std::forward<_Kp>(__key)), true); @@ -673,7 +726,7 @@ class flat_set { } template - _LIBCPP_HIDE_FROM_ABI bool __is_hint_correct(const_iterator __hint, _Kp&& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_hint_correct(const_iterator __hint, _Kp&& __key) { if (__hint != cbegin() && !__compare_(*std::prev(__hint), __key)) { return false; } @@ -684,7 +737,7 @@ class flat_set { } template - _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint(const_iterator __hint, _Kp&& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __emplace_hint(const_iterator __hint, _Kp&& __key) { if (__is_hint_correct(__hint, __key)) { if (__hint == cend() || __compare_(__key, *__hint)) { return __flat_set_utils::__emplace_exact_pos(*this, __hint, std::forward<_Kp>(__key)); @@ -697,7 +750,7 @@ class flat_set { } } - _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __size) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __reserve(size_t __size) { if constexpr (__container_traits<_KeyContainer>::__reservable) { __keys_.reserve(__size); } @@ -705,14 +758,15 @@ class flat_set { template friend typename flat_set<_Key2, _Compare2, _KeyContainer2>::size_type - erase_if(flat_set<_Key2, _Compare2, _KeyContainer2>&, _Predicate); + _LIBCPP_CONSTEXPR_SINCE_CXX26 erase_if(flat_set<_Key2, _Compare2, _KeyContainer2>&, _Predicate); _KeyContainer __keys_; _LIBCPP_NO_UNIQUE_ADDRESS key_compare __compare_; struct __key_equiv { - _LIBCPP_HIDE_FROM_ABI __key_equiv(key_compare __c) : __comp_(__c) {} - _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_equiv(key_compare __c) : __comp_(__c) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool + operator()(const_reference __x, const_reference __y) const { return !__comp_(__x, __y) && !__comp_(__y, __x); } key_compare __comp_; @@ -799,7 +853,7 @@ struct uses_allocator, _Allocator> : bool_constant> {}; template -_LIBCPP_HIDE_FROM_ABI typename flat_set<_Key, _Compare, _KeyContainer>::size_type +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 typename flat_set<_Key, _Compare, _KeyContainer>::size_type erase_if(flat_set<_Key, _Compare, _KeyContainer>& __flat_set, _Predicate __pred) { auto __guard = std::__make_exception_guard([&] { __flat_set.clear(); }); auto __it = std::remove_if(__flat_set.__keys_.begin(), __flat_set.__keys_.end(), [&](const auto& __e) -> bool { diff --git a/libcxx/include/__flat_set/utils.h b/libcxx/include/__flat_set/utils.h index 542bfd886aef5..8a7f93a00465d 100644 --- a/libcxx/include/__flat_set/utils.h +++ b/libcxx/include/__flat_set/utils.h @@ -38,7 +38,8 @@ struct __flat_set_utils { // When an exception is thrown during the emplacement, the function will clear the set if the container does not // have strong exception safety guarantee on emplacement. template - _LIBCPP_HIDE_FROM_ABI static auto __emplace_exact_pos(_Set& __set, _Iter&& __iter, _KeyArg&& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto + __emplace_exact_pos(_Set& __set, _Iter&& __iter, _KeyArg&& __key) { using _KeyContainer = typename decay_t<_Set>::container_type; auto __on_failure = std::__make_exception_guard([&]() noexcept { if constexpr (!__container_traits<_KeyContainer>::__emplacement_has_strong_exception_safety_guarantee) { @@ -51,12 +52,13 @@ struct __flat_set_utils { } template - _LIBCPP_HIDE_FROM_ABI static void __append(_Set& __set, _InputIterator __first, _InputIterator __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void + __append(_Set& __set, _InputIterator __first, _InputIterator __last) { __set.__keys_.insert(__set.__keys_.end(), std::move(__first), std::move(__last)); } template - _LIBCPP_HIDE_FROM_ABI static void __append(_Set& __set, _Range&& __rng) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void __append(_Set& __set, _Range&& __rng) { if constexpr (requires { __set.__keys_.insert_range(__set.__keys_.end(), std::forward<_Range>(__rng)); }) { // C++23 Sequence Container should have insert_range member function // Note that not all Sequence Containers provide append_range. diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index b00a8ebd54623..da39ac6103897 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1320,6 +1320,9 @@ module std [system] { export std.flat_map.sorted_unique export std.flat_map.sorted_equivalent export * + export std.algorithm.ranges_sort + export std.ranges.zip_view + export std.tuple } module format { diff --git a/libcxx/test/std/containers/Emplaceable.h b/libcxx/test/std/containers/Emplaceable.h index d8d3407791731..e84a6381ab0f3 100644 --- a/libcxx/test/std/containers/Emplaceable.h +++ b/libcxx/test/std/containers/Emplaceable.h @@ -44,13 +44,5 @@ class Emplaceable { TEST_CONSTEXPR_CXX20 int get() const { return int_; } }; -template <> -struct std::hash { - typedef Emplaceable argument_type; - typedef std::size_t result_type; - - TEST_CONSTEXPR_CXX20 std::size_t operator()(const Emplaceable& x) const { return static_cast(x.get()); } -}; - #endif // TEST_STD_VER >= 11 #endif // EMPLACEABLE_H diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/empty.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/empty.pass.cpp index 223b92fc3e8e8..076102c616d44 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/empty.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/empty.pass.cpp @@ -24,7 +24,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_set, KeyContainer>; M m; @@ -38,15 +38,23 @@ void test_one() { assert(m.empty()); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!std::is_constant_evaluated()) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/max_size.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/max_size.pass.cpp index dde1f7092e5b1..e2f52ab458c4c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/max_size.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/max_size.pass.cpp @@ -24,7 +24,7 @@ #include "test_allocator.h" #include "test_macros.h" -void test() { +constexpr bool test() { { using A1 = limited_allocator; using C = std::flat_set, std::vector>; @@ -59,10 +59,15 @@ void test() { assert(c.max_size() <= max_dist); assert(c.max_size() <= alloc_max_size(std::allocator())); } + + return true; } int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/size.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/size.pass.cpp index 9f5ffdd066351..278d5ea2cdefd 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/size.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.capacity/size.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "MinSequenceContainer.h" @@ -23,7 +24,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using M = std::flat_set, KeyContainer>; using S = typename M::size_type; { @@ -46,7 +47,7 @@ void test_one() { } { M m; - S s = 1000000; + S s = std::is_constant_evaluated() ? 100 : 1000000; for (auto i = 0u; i < s; ++i) { m.emplace(i); } @@ -56,15 +57,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!std::is_constant_evaluated()) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/alloc.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/alloc.pass.cpp index d14e883dd5e93..00a0d4849c2ed 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/alloc.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/alloc.pass.cpp @@ -14,15 +14,18 @@ // explicit flat_set(const Allocator& a); #include +#include #include #include #include +#include "MinSequenceContainer.h" #include "test_macros.h" #include "test_allocator.h" #include "../../../test_compare.h" -void test() { +template