From 241ea9e622d5df5e5d20116de75e9c7ad200036f Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 21 Sep 2025 09:34:06 +0100 Subject: [PATCH 1/9] [libc++] constexpr flat_multiset --- libcxx/include/__flat_set/flat_multiset.h | 204 +++++++++--------- .../flat.multiset.capacity/empty.pass.cpp | 14 +- .../flat.multiset.capacity/max_size.pass.cpp | 7 +- .../flat.multiset.capacity/size.pass.cpp | 18 +- .../flat.multiset.erasure/erase_if.pass.cpp | 24 ++- .../flat.multiset.iterators/iterator.pass.cpp | 14 +- .../iterator_comparison.pass.cpp | 14 +- .../reverse_iterator.pass.cpp | 92 ++++---- .../flat.multiset.observers/comp.pass.cpp | 9 +- 9 files changed, 234 insertions(+), 162 deletions(-) diff --git a/libcxx/include/__flat_set/flat_multiset.h b/libcxx/include/__flat_set/flat_multiset.h index 44d8af05a56af..391046d456cec 100644 --- a/libcxx/include/__flat_set/flat_multiset.h +++ b/libcxx/include/__flat_set/flat_multiset.h @@ -108,16 +108,16 @@ class flat_multiset { public: // [flat.multiset.cons], constructors - _LIBCPP_HIDE_FROM_ABI flat_multiset() noexcept(is_nothrow_default_constructible_v<_KeyContainer> && + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset() noexcept(is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_Compare>) : __keys_(), __compare_() {} - _LIBCPP_HIDE_FROM_ABI flat_multiset(const flat_multiset&) = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(const flat_multiset&) = default; // The copy/move constructors are not specified in the spec, which means they should be defaulted. // However, the move constructor can potentially leave a moved-from object in an inconsistent // state if an exception is thrown. - _LIBCPP_HIDE_FROM_ABI flat_multiset(flat_multiset&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(flat_multiset&& __other) noexcept( is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_Compare>) # if _LIBCPP_HAS_EXCEPTIONS try @@ -134,14 +134,14 @@ class flat_multiset { # endif // _LIBCPP_HAS_EXCEPTIONS } - _LIBCPP_HIDE_FROM_ABI explicit flat_multiset(const key_compare& __comp) : __keys_(), __compare_(__comp) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multiset(const key_compare& __comp) : __keys_(), __compare_(__comp) {} - _LIBCPP_HIDE_FROM_ABI explicit flat_multiset(container_type __keys, const key_compare& __comp = key_compare()) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multiset(container_type __keys, const key_compare& __comp = key_compare()) : __keys_(std::move(__keys)), __compare_(__comp) { ranges::sort(__keys_, __compare_); } - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(sorted_equivalent_t, container_type __keys, const key_compare& __comp = key_compare()) : __keys_(std::move(__keys)), __compare_(__comp) { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted"); @@ -149,7 +149,7 @@ class flat_multiset { template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __keys_(), __compare_(__comp) { insert(__first, __last); @@ -157,48 +157,48 @@ class flat_multiset { template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI flat_multiset( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset( sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __keys_(__first, __last), __compare_(__comp) { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted"); } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_multiset(from_range_t __fr, _Range&& __rg) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(from_range_t __fr, _Range&& __rg) : flat_multiset(__fr, std::forward<_Range>(__rg), key_compare()) {} template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_multiset(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_multiset(__comp) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_multiset(__comp) { insert_range(std::forward<_Range>(__rg)); } - _LIBCPP_HIDE_FROM_ABI flat_multiset(initializer_list __il, const key_compare& __comp = key_compare()) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(initializer_list __il, const key_compare& __comp = key_compare()) : flat_multiset(__il.begin(), __il.end(), __comp) {} - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(sorted_equivalent_t, initializer_list __il, const key_compare& __comp = key_compare()) : flat_multiset(sorted_equivalent, __il.begin(), __il.end(), __comp) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI explicit flat_multiset(const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multiset(const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc)), __compare_() {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_multiset(const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(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_multiset(const container_type& __keys, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(const container_type& __keys, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __keys)), __compare_() { ranges::sort(__keys_, __compare_); } template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(const container_type& __keys, const key_compare& __comp, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __keys)), __compare_(__comp) { ranges::sort(__keys_, __compare_); @@ -206,14 +206,14 @@ class flat_multiset { template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_multiset(sorted_equivalent_t, const container_type& __keys, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(sorted_equivalent_t, const container_type& __keys, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __keys)), __compare_() { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted"); } template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(sorted_equivalent_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(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted"); @@ -221,13 +221,13 @@ class flat_multiset { template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_multiset(const flat_multiset& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(const flat_multiset& __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_multiset(flat_multiset&& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(flat_multiset&& __other, const _Allocator& __alloc) # if _LIBCPP_HAS_EXCEPTIONS try # endif // _LIBCPP_HAS_EXCEPTIONS @@ -243,14 +243,14 @@ class flat_multiset { template requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator::value) - _LIBCPP_HIDE_FROM_ABI flat_multiset(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(_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_multiset(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc)), __compare_(__comp) { insert(__first, __last); @@ -258,7 +258,7 @@ class flat_multiset { template requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator::value) - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc) : __keys_(std::make_obj_using_allocator(__alloc, __first, __last)), __compare_() { _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(ranges::is_sorted(__keys_, __compare_), "Key container is not sorted"); @@ -266,7 +266,7 @@ class flat_multiset { template requires(__has_input_iterator_category<_InputIterator>::value && uses_allocator::value) - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(sorted_equivalent_t, _InputIterator __first, _InputIterator __last, @@ -278,41 +278,41 @@ class flat_multiset { template <_ContainerCompatibleRange _Range, class _Allocator> requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_multiset(from_range_t, _Range&& __rg, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(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_multiset(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(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_multiset(initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(initializer_list __il, const _Allocator& __alloc) : flat_multiset(__il.begin(), __il.end(), __alloc) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_multiset(__il.begin(), __il.end(), __comp, __alloc) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_multiset(sorted_equivalent_t, initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset(sorted_equivalent_t, initializer_list __il, const _Allocator& __alloc) : flat_multiset(sorted_equivalent, __il.begin(), __il.end(), __alloc) {} template requires uses_allocator::value - _LIBCPP_HIDE_FROM_ABI flat_multiset( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset( sorted_equivalent_t, initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_multiset(sorted_equivalent, __il.begin(), __il.end(), __comp, __alloc) {} - _LIBCPP_HIDE_FROM_ABI flat_multiset& operator=(initializer_list __il) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset& operator=(initializer_list __il) { clear(); insert(__il); return *this; @@ -321,9 +321,9 @@ class flat_multiset { // copy/move assignment are not specified in the spec (defaulted) // but move assignment can potentially leave moved from object in an inconsistent // state if an exception is thrown - _LIBCPP_HIDE_FROM_ABI flat_multiset& operator=(const flat_multiset&) = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset& operator=(const flat_multiset&) = default; - _LIBCPP_HIDE_FROM_ABI flat_multiset& operator=(flat_multiset&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multiset& operator=(flat_multiset&& __other) noexcept( is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_Compare>) { auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; }); auto __clear_self_guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); @@ -334,30 +334,30 @@ class flat_multiset { } // 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()); } // capacity - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __keys_.empty(); } - _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __keys_.size(); } - _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept { return __keys_.max_size(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const noexcept { return __keys_.empty(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { return __keys_.size(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return __keys_.max_size(); } // [flat.multiset.modifiers], modifiers template requires is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace(_Args&&... __args) { if constexpr (sizeof...(__args) == 1 && (is_same_v, _Key> && ...)) { return __emplace(std::forward<_Args>(__args)...); } else { @@ -367,7 +367,7 @@ class flat_multiset { template requires is_constructible_v - _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 { @@ -375,21 +375,21 @@ class flat_multiset { } } - _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __x) { return emplace(__x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const value_type& __x) { return emplace(__x); } - _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __x) { return emplace(std::move(__x)); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(value_type&& __x) { return emplace(std::move(__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 __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); } @@ -398,7 +398,7 @@ class flat_multiset { template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI void insert(sorted_equivalent_t, _InputIterator __first, _InputIterator __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(sorted_equivalent_t, _InputIterator __first, _InputIterator __last) { if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { __reserve(__last - __first); } @@ -407,7 +407,7 @@ class flat_multiset { } 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)); } @@ -415,26 +415,26 @@ class flat_multiset { __append_sort_merge(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_equivalent_t, initializer_list __il) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(sorted_equivalent_t, initializer_list __il) { insert(sorted_equivalent, __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(ranges::is_sorted(__keys, __compare_), "Key container is not sorted"); auto __guard = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); __keys_ = std::move(__keys); __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(); @@ -444,7 +444,7 @@ class flat_multiset { // 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 [__first, __last] = equal_range(__x); auto __res = __last - __first; erase(__first, __last); @@ -454,21 +454,21 @@ class flat_multiset { 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_multiset& __y) noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_multiset& __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 @@ -477,126 +477,126 @@ class flat_multiset { 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_; } // map 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 { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const { auto [__first, __last] = equal_range(__x); return __last - __first; } 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 { auto [__first, __last] = equal_range(__x); return __last - __first; } - _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_multiset& __x, const flat_multiset& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator==(const flat_multiset& __x, const flat_multiset& __y) { return ranges::equal(__x, __y); } - friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_multiset& __x, const flat_multiset& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto operator<=>(const flat_multiset& __x, const flat_multiset& __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_multiset& __x, flat_multiset& __y) noexcept { __x.swap(__y); } + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_multiset& __x, flat_multiset& __y) noexcept { __x.swap(__y); } private: template - _LIBCPP_HIDE_FROM_ABI void __append_sort_merge(_Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __append_sort_merge(_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)...); @@ -611,13 +611,13 @@ class flat_multiset { } template - _LIBCPP_HIDE_FROM_ABI iterator __emplace(_Kp&& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __emplace(_Kp&& __key) { auto __it = upper_bound(__key); return __flat_set_utils::__emplace_exact_pos(*this, __it, std::forward<_Kp>(__key)); } 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) { auto __prev_larger = __hint != cbegin() && __compare_(__key, *std::prev(__hint)); auto __next_smaller = __hint != cend() && __compare_(*__hint, __key); @@ -649,7 +649,7 @@ class flat_multiset { } 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)) { @@ -659,14 +659,14 @@ class flat_multiset { } 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 [__key_first, __key_last] = std::equal_range(__self.__keys_.begin(), __self.__keys_.end(), __key, __self.__compare_); return std::make_pair(__iter(__key_first), __iter(__key_last)); } - _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); } @@ -674,14 +674,14 @@ class flat_multiset { template friend typename flat_multiset<_Key2, _Compare2, _KeyContainer2>::size_type - erase_if(flat_multiset<_Key2, _Compare2, _KeyContainer2>&, _Predicate); + _LIBCPP_CONSTEXPR_SINCE_CXX26 erase_if(flat_multiset<_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_(std::get<0>(__x), std::get<0>(__y)) && !__comp_(std::get<0>(__y), std::get<0>(__x)); } key_compare __comp_; @@ -770,7 +770,7 @@ struct uses_allocator, _Allocator> : bool_constant > {}; template -_LIBCPP_HIDE_FROM_ABI typename flat_multiset<_Key, _Compare, _KeyContainer>::size_type +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 typename flat_multiset<_Key, _Compare, _KeyContainer>::size_type erase_if(flat_multiset<_Key, _Compare, _KeyContainer>& __flat_multiset, _Predicate __pred) { auto __guard = std::__make_exception_guard([&] { __flat_multiset.clear(); }); auto __it = diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/empty.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/empty.pass.cpp index 52f77438df2ce..88a76d3c1c8b8 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/empty.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.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_multiset, 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 (!TEST_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.multiset/flat.multiset.capacity/max_size.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/max_size.pass.cpp index 4e3d1414b28af..fb9c38f592262 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/max_size.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.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_multiset, 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.multiset/flat.multiset.capacity/size.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/size.pass.cpp index 4aff08b8127b6..156bb27fae992 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/size.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.capacity/size.pass.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=200000000 +// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=800000000 // @@ -23,7 +25,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using M = std::flat_multiset, KeyContainer>; using S = typename M::size_type; { @@ -46,7 +48,7 @@ void test_one() { } { M m; - S s = 500000; + S s = 5000; for (std::size_t i = 0u; i < s; ++i) { m.emplace(i); m.emplace(i); @@ -57,15 +59,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/flat.multiset.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.erasure/erase_if.pass.cpp index 21f3c918dec0d..c62ccc44936b3 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.erasure/erase_if.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.erasure/erase_if.pass.cpp @@ -32,7 +32,7 @@ static_assert(HasStdErase>); static_assert(!HasStdErase>); template -M make(std::initializer_list vals) { +constexpr M make(std::initializer_list vals) { M ret; for (int v : vals) ret.emplace(v); @@ -40,7 +40,7 @@ M make(std::initializer_list vals) { } template -void test0( +constexpr void test0( std::initializer_list vals, Pred p, std::initializer_list expected, std::size_t expected_erased_count) { M s = make(vals); ASSERT_SAME_TYPE(typename M::size_type, decltype(std::erase_if(s, p))); @@ -50,11 +50,11 @@ void test0( struct NotBool { bool b; - explicit operator bool() const { return b; } + explicit constexpr operator bool() const { return b; } }; template -void test_one() { +constexpr void test_one() { // Test all the plausible signatures for this predicate. auto is1 = [](typename S::const_reference v) { return v == 1; }; auto is2 = [](typename S::value_type v) { return v == 2; }; @@ -96,18 +96,28 @@ void test_one() { test0({1, 1, 2, 2, 3}, nonBoolIs1, {2, 2, 3}, 2); } -void test() { +constexpr bool test() { test_one>(); test_one, std::vector>>>(); test_one, std::vector>>>(); - test_one, std::deque>>>(); - test_one, std::deque>>>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + { + test_one, std::deque>>>(); + test_one, std::deque>>>(); + } 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.multiset/flat.multiset.iterators/iterator.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp index 809f03df47977..878b2b2094f71 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator.pass.cpp @@ -30,7 +30,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; @@ -68,9 +68,12 @@ void test_one() { assert(i == m.begin()); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -89,10 +92,15 @@ void test() { assert(!(ii1 != cii)); assert(!(cii != ii1)); } + + 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.multiset/flat.multiset.iterators/iterator_comparison.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator_comparison.pass.cpp index cbf69d6e04904..ff4ad3f8f0279 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator_comparison.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/iterator_comparison.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_multiset, KeyContainer>; using I = M::iterator; @@ -141,15 +141,23 @@ void test_one() { assert(cri2 <=> cri1 == std::strong_ordering::greater); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/flat.multiset.iterators/reverse_iterator.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/reverse_iterator.pass.cpp index e25d786d9b3b4..678109b88f9fb 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/reverse_iterator.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.iterators/reverse_iterator.pass.cpp @@ -25,46 +25,59 @@ #include +#include "MinSequenceContainer.h" #include "test_macros.h" +#include "min_allocator.h" -void test() { - { - using M = std::flat_multiset, std::deque>; - M m = {1, 1, 2, 2, 3, 4}; - int expected[] = {1, 1, 2, 2, 3, 4}; - const M& cm = m; - ASSERT_SAME_TYPE(decltype(m.rbegin()), M::reverse_iterator); - ASSERT_SAME_TYPE(decltype(m.crbegin()), M::const_reverse_iterator); - ASSERT_SAME_TYPE(decltype(cm.rbegin()), M::const_reverse_iterator); - ASSERT_SAME_TYPE(decltype(m.rend()), M::reverse_iterator); - ASSERT_SAME_TYPE(decltype(m.crend()), M::const_reverse_iterator); - ASSERT_SAME_TYPE(decltype(cm.rend()), M::const_reverse_iterator); - static_assert(noexcept(m.rbegin())); - static_assert(noexcept(cm.rbegin())); - static_assert(noexcept(m.crbegin())); - static_assert(noexcept(m.rend())); - static_assert(noexcept(cm.rend())); - static_assert(noexcept(m.crend())); - assert(m.size() == 6); - assert(std::distance(m.rbegin(), m.rend()) == 6); - assert(std::distance(cm.rbegin(), cm.rend()) == 6); - assert(std::distance(m.crbegin(), m.crend()) == 6); - assert(std::distance(cm.crbegin(), cm.crend()) == 6); - M::reverse_iterator i; // default-construct - ASSERT_SAME_TYPE(decltype(*i), const int&); - i = m.rbegin(); // move-assignment - M::const_reverse_iterator k = i; // converting constructor - assert(i == k); // comparison - for (int j = 5; j >= 0; --j, ++i) { // pre-increment - assert(*i == expected[j]); - } - assert(i == m.rend()); - for (int j = 0; j <= 5; ++j) { - --i; // pre-decrement - assert(*i == expected[j]); - } - assert(i == m.rbegin()); +template +constexpr void test_one() { + using Key = typename KeyContainer::value_type; + using M = std::flat_multiset, KeyContainer>; + M m = {1, 1, 2, 2, 3, 4}; + int expected[] = {1, 1, 2, 2, 3, 4}; + const M& cm = m; + ASSERT_SAME_TYPE(decltype(m.rbegin()), typename M::reverse_iterator); + ASSERT_SAME_TYPE(decltype(m.crbegin()), typename M::const_reverse_iterator); + ASSERT_SAME_TYPE(decltype(cm.rbegin()), typename M::const_reverse_iterator); + ASSERT_SAME_TYPE(decltype(m.rend()), typename M::reverse_iterator); + ASSERT_SAME_TYPE(decltype(m.crend()), typename M::const_reverse_iterator); + ASSERT_SAME_TYPE(decltype(cm.rend()), typename M::const_reverse_iterator); + static_assert(noexcept(m.rbegin())); + static_assert(noexcept(cm.rbegin())); + static_assert(noexcept(m.crbegin())); + static_assert(noexcept(m.rend())); + static_assert(noexcept(cm.rend())); + static_assert(noexcept(m.crend())); + assert(m.size() == 6); + assert(std::distance(m.rbegin(), m.rend()) == 6); + assert(std::distance(cm.rbegin(), cm.rend()) == 6); + assert(std::distance(m.crbegin(), m.crend()) == 6); + assert(std::distance(cm.crbegin(), cm.crend()) == 6); + typename M::reverse_iterator i; // default-construct + ASSERT_SAME_TYPE(decltype(*i), const int&); + i = m.rbegin(); // move-assignment + typename M::const_reverse_iterator k = i; // converting constructor + assert(i == k); // comparison + for (int j = 5; j >= 0; --j, ++i) { // pre-increment + assert(*i == expected[j]); + } + assert(i == m.rend()); + for (int j = 0; j <= 5; ++j) { + --i; // pre-decrement + assert(*i == expected[j]); } + assert(i == m.rbegin()); +} + +constexpr bool test() { + test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); + test_one>(); + test_one>>(); + { // N3644 testing using C = std::flat_multiset; @@ -80,10 +93,15 @@ void test() { assert(!(ii1 != cii)); assert(!(cii != ii1)); } + + 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.multiset/flat.multiset.observers/comp.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.observers/comp.pass.cpp index 4ca64516e242f..74c92f3a3f843 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.observers/comp.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.observers/comp.pass.cpp @@ -21,7 +21,7 @@ #include "test_macros.h" -void test() { +constexpr bool test() { { using M = std::flat_multiset; using Comp = std::less; // the default @@ -36,7 +36,7 @@ void test() { assert(vc(1, 2)); assert(!vc(2, 1)); } - { + if (!TEST_IS_CONSTANT_EVALUATED) { using Comp = std::function; using M = std::flat_multiset; Comp comp = std::greater(); @@ -67,10 +67,15 @@ void test() { assert(vc(1, 2)); assert(!vc(2, 1)); } + + return true; } int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } From 417ed1a4bc0bb91058dfede4cb9a84ca73f92e9b Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 21 Sep 2025 10:09:05 +0100 Subject: [PATCH 2/9] modifiers --- .../flat.multiset.modifiers/clear.pass.cpp | 14 +++++++-- .../flat.multiset.modifiers/emplace.pass.cpp | 21 ++++++++++---- .../emplace_hint.pass.cpp | 19 ++++++++---- .../erase_iter.pass.cpp | 14 +++++++-- .../erase_iter_iter.pass.cpp | 14 +++++++-- .../erase_key.pass.cpp | 14 +++++++-- .../erase_key_transparent.pass.cpp | 29 +++++++++++++------ .../flat.multiset.modifiers/extract.pass.cpp | 14 +++++++-- .../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 +++++++++--- .../insert_range.pass.cpp | 14 +++++++-- .../insert_rv.pass.cpp | 18 +++++++++--- .../insert_sorted_initializer_list.pass.cpp | 14 +++++++-- .../insert_sorted_iter_iter.pass.cpp | 14 +++++++-- .../flat.multiset.modifiers/replace.pass.cpp | 14 +++++++-- .../swap_free.pass.cpp | 14 +++++++-- .../swap_member.pass.cpp | 14 +++++++-- .../flat.multiset/helpers.h | 2 +- 21 files changed, 243 insertions(+), 74 deletions(-) diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/clear.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/clear.pass.cpp index 4d01ece7ed6a6..088a8838ad8ae 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/clear.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/clear.pass.cpp @@ -38,7 +38,7 @@ static_assert(NoExceptClear, ThrowOnMoveC #endif template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; { @@ -58,17 +58,25 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); 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.multiset/flat.multiset.modifiers/emplace.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/emplace.pass.cpp index 3ef13964c905e..6772e17378b70 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/emplace.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/emplace.pass.cpp @@ -28,7 +28,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; using R = typename M::iterator; @@ -91,7 +91,7 @@ void test_one() { } template -void test_emplaceable() { +constexpr void test_emplaceable() { using M = std::flat_multiset, KeyContainer>; using R = typename M::iterator; @@ -111,16 +111,24 @@ void test_emplaceable() { assert(*r == Emplaceable(1, 3.5)); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); test_emplaceable>(); - test_emplaceable>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_emplaceable>(); test_emplaceable>(); test_emplaceable>>(); + + return true; } void test_exception() { @@ -130,6 +138,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/emplace_hint.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/emplace_hint.pass.cpp index 41a2e9c4ce115..ec99a9fcc1d9b 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/emplace_hint.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/emplace_hint.pass.cpp @@ -27,11 +27,11 @@ #include "../helpers.h" struct CompareTensDigit { - bool operator()(auto lhs, auto rhs) const { return (lhs / 10) < (rhs / 10); } + constexpr bool operator()(auto lhs, auto rhs) const { return (lhs / 10) < (rhs / 10); } }; template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; using R = M::iterator; @@ -179,7 +179,6 @@ void test_one() { assert(r == m.begin() + 2); assert(m.size() == 7); assert(*r == 23); - assert(*std::next(r) == 20); } { // hint incorrect and after the last duplicate @@ -196,7 +195,7 @@ void test_one() { } template -void test_emplaceable() { +constexpr void test_emplaceable() { using M = std::flat_multiset, KeyContainer>; using R = M::iterator; @@ -216,9 +215,12 @@ void test_emplaceable() { assert(*r == Emplaceable(1, 3.5)); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -226,6 +228,8 @@ void test() { test_emplaceable>(); test_emplaceable>(); test_emplaceable>>(); + + return true; } void test_exception() { @@ -235,6 +239,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_iter.pass.cpp index 8418efa67bb23..f2cb151d8661b 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_iter.pass.cpp @@ -27,7 +27,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; using I = M::iterator; @@ -94,11 +94,16 @@ void test_one() { assert(i8 == m.end()); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } void test_exception() { @@ -108,6 +113,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_iter_iter.pass.cpp index 2d54fef17b6c0..76078920af1bf 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_iter_iter.pass.cpp @@ -26,7 +26,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; using I = M::iterator; @@ -78,11 +78,16 @@ void test_one() { assert(i5 == m.end()); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } void test_exception() { @@ -92,6 +97,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_key.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_key.pass.cpp index 8175afa5b626e..7ddd3d8657066 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_key.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_key.pass.cpp @@ -26,7 +26,7 @@ #include "min_allocator.h" template > -void test_one() { +constexpr void test_one() { using M = std::flat_multiset; auto make = [](std::initializer_list il) { @@ -74,12 +74,17 @@ void test_one() { assert(m.empty()); } -void test() { +constexpr bool test() { test_one>(); test_one, std::greater<>>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } void test_exception() { @@ -94,6 +99,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_key_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_key_transparent.pass.cpp index a8765495d91d4..0613744ec5e39 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_key_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/erase_key_transparent.pass.cpp @@ -38,10 +38,10 @@ static_assert(!CanErase); template struct HeterogeneousKey { - explicit HeterogeneousKey(Key key, It it) : key_(key), it_(it) {} - operator It() && { return it_; } - auto operator<=>(Key key) const { return key_ <=> key; } - friend bool operator<(const HeterogeneousKey&, const HeterogeneousKey&) { + constexpr explicit HeterogeneousKey(Key key, It it) : key_(key), it_(it) {} + constexpr operator It() && { return it_; } + constexpr auto operator<=>(Key key) const { return key_ <=> key; } + constexpr friend bool operator<(const HeterogeneousKey&, const HeterogeneousKey&) { assert(false); return false; } @@ -50,7 +50,7 @@ struct HeterogeneousKey { }; template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; @@ -70,7 +70,7 @@ void test_one() { } template -void test_transparent_comparator() { +constexpr void test_transparent_comparator() { using M = std::flat_multiset; { M m = {"alpha", "beta", "beta", "epsilon", "epsilon", "epsilon", "eta", "eta", "gamma"}; @@ -95,14 +95,20 @@ void test_transparent_comparator() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); test_transparent_comparator>(); - test_transparent_comparator>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_transparent_comparator>(); test_transparent_comparator>(); test_transparent_comparator>>(); @@ -146,6 +152,8 @@ void test() { assert(n == 2); assert((m == M{"alpha", "epsilon", "eta", "gamma"})); } + + return true; } void test_exception() { @@ -159,6 +167,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/extract.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/extract.pass.cpp index 8a66431396916..bb41cedf85497 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/extract.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/extract.pass.cpp @@ -33,7 +33,7 @@ static_assert(!CanExtract const&>); static_assert(!CanExtract const&&>); template -void test_one() { +constexpr void test_one() { using M = std::flat_multiset, KeyContainer>; { M m = M({1, 1, 3}); @@ -55,9 +55,12 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -70,6 +73,8 @@ void test() { check_invariant(m); LIBCPP_ASSERT(m.empty()); } + + return true; } void test_exception() { @@ -96,6 +101,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_cv.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_cv.pass.cpp index eeb1bdd26ca16..5128a40ada694 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_cv.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_cv.pass.cpp @@ -23,7 +23,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; using R = typename M::iterator; @@ -61,11 +61,16 @@ void test_one() { assert(*r == 1); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } void test_exception() { @@ -79,6 +84,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_initializer_list.pass.cpp index 9c56d3bfb750b..f0b1eaf377c5d 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_initializer_list.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_initializer_list.pass.cpp @@ -23,7 +23,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; @@ -65,11 +65,16 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } void test_exception() { @@ -84,6 +89,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_cv.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_cv.pass.cpp index 61f00f5138118..55a77d576dacc 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_cv.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_cv.pass.cpp @@ -23,7 +23,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; using R = typename M::iterator; @@ -61,11 +61,16 @@ void test_one() { assert(*r == 1); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } void test_exception() { @@ -80,6 +85,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_iter.pass.cpp index 93815686787c4..9b10bf3fbb1a4 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_iter.pass.cpp @@ -37,7 +37,7 @@ static_assert(!CanInsert); static_assert(!CanInsert, cpp20_input_iterator>); template -void test_one() { +constexpr void test_one() { using M = std::flat_multiset, KeyContainer>; int ar1[] = { @@ -75,9 +75,12 @@ void test_one() { assert(m == expected2); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); { @@ -86,6 +89,8 @@ void test() { m.insert(v.begin(), v.end()); assert(std::ranges::equal(m, std::vector{1, 2, 3, 4})); } + + return true; } void test_exception() { @@ -95,6 +100,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_rv.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_rv.pass.cpp index 9976c04c9973a..8bbc6c80e4ef7 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_rv.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_iter_rv.pass.cpp @@ -22,7 +22,7 @@ #include "test_macros.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; using V = Key; @@ -59,15 +59,22 @@ void test_one() { assert(*r == V(1)); } -void test() { +constexpr bool test() { test_one>(); test_one>(); - test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + { + test_one>(); + test_one>(); + } test_one>(); test_one>(); test_one>>(); test_one>>(); + + return true; } void test_exception() { @@ -82,6 +89,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_range.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_range.pass.cpp index 566be3921bf77..a9d8f7e330fed 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_range.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_range.pass.cpp @@ -39,7 +39,7 @@ static_assert(!CanInsertRange*>>) static_assert(!CanInsertRange*>>); template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; { @@ -72,9 +72,12 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); { @@ -85,6 +88,8 @@ void test() { MoveOnly expected[] = {1, 1, 3, 4, 5}; assert(std::ranges::equal(m, expected)); } + + return true; } void test_exception() { @@ -94,6 +99,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_rv.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_rv.pass.cpp index 9328c42fb0cda..67f3036a8dae7 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_rv.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_rv.pass.cpp @@ -25,7 +25,7 @@ #include "../helpers.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset; using R = typename M::iterator; @@ -63,15 +63,22 @@ void test_one() { assert(*r == V(1)); } -void test() { +constexpr bool test() { test_one>(); test_one>(); - test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + { + test_one>(); + test_one>(); + } test_one>(); test_one>(); test_one>>(); test_one>>(); + + return true; } void test_exception() { @@ -86,6 +93,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_sorted_initializer_list.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_sorted_initializer_list.pass.cpp index 11af199c3d1ee..81b7e4e196b30 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_sorted_initializer_list.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_sorted_initializer_list.pass.cpp @@ -23,7 +23,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; { @@ -42,11 +42,16 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } void test_exception() { @@ -61,6 +66,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_sorted_iter_iter.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_sorted_iter_iter.pass.cpp index 07b62d04e0ebc..bfb230718fb6f 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_sorted_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/insert_sorted_iter_iter.pass.cpp @@ -36,7 +36,7 @@ static_assert(!CanInsert); static_assert(!CanInsert, cpp20_input_iterator>); template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; @@ -60,11 +60,16 @@ void test_one() { assert(m == expected2); } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } void test_exception() { @@ -76,6 +81,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/replace.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/replace.pass.cpp index 5fe61389d72a1..3c74cf6ebe995 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/replace.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/replace.pass.cpp @@ -31,7 +31,7 @@ static_assert(CanReplace>); static_assert(!CanReplace&>); template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; { @@ -53,11 +53,16 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); + + return true; } void test_exception() { @@ -82,6 +87,9 @@ void test_exception() { int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif test_exception(); return 0; diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_free.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_free.pass.cpp index 2e3ed02c3c00e..241f2cf9e0a73 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_free.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_free.pass.cpp @@ -38,7 +38,7 @@ static_assert(NoExceptAdlSwap, ThrowOnMov #endif template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; @@ -84,15 +84,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/flat.multiset.modifiers/swap_member.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_member.pass.cpp index 1d0d9152d1c1f..7ad96ed340955 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_member.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.modifiers/swap_member.pass.cpp @@ -37,7 +37,7 @@ static_assert(NoExceptMemberSwap, ThrowOn #endif template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; { @@ -82,15 +82,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/helpers.h b/libcxx/test/std/containers/container.adaptors/flat.multiset/helpers.h index e7ed8a091d3be..82f917756e92c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/helpers.h +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/helpers.h @@ -20,7 +20,7 @@ #include "test_macros.h" template -void check_invariant(const std::flat_multiset& m) { +constexpr void check_invariant(const std::flat_multiset& m) { assert(std::is_sorted(m.begin(), m.end(), m.key_comp())); } From f57f7465367d060b8f6f504a8236e877892b1b00 Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 21 Sep 2025 10:11:09 +0100 Subject: [PATCH 3/9] op --- .../flat.multiset/op_compare.pass.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/op_compare.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/op_compare.pass.cpp index 94f0f2b34abcc..606cdfc3ba7d2 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/op_compare.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/op_compare.pass.cpp @@ -31,7 +31,7 @@ #include "test_container_comparisons.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; { @@ -64,9 +64,12 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -81,7 +84,7 @@ void test() { { // Comparisons use value_type's native operators, not the comparator struct StrongComp { - bool operator()(double a, double b) const { return std::strong_order(a, b) < 0; } + constexpr bool operator()(double a, double b) const { return std::strong_order(a, b) < 0; } }; using C = std::flat_multiset; C s1 = {1}; @@ -96,10 +99,15 @@ void test() { assert(s1 != s2); assert((s1 <=> s2) == std::partial_ordering::unordered); } + + return true; } int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } From 355a23aa6fb67751b7bb891a7b23c0051e8c3270 Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 21 Sep 2025 10:57:35 +0100 Subject: [PATCH 4/9] operations --- .../flat.multiset.operations/contains.pass.cpp | 14 +++++++++++--- .../contains_transparent.pass.cpp | 14 +++++++++++--- .../flat.multiset.operations/count.pass.cpp | 14 +++++++++++--- .../count_transparent.pass.cpp | 14 +++++++++++--- .../flat.multiset.operations/equal_range.pass.cpp | 14 +++++++++++--- .../equal_range_transparent.pass.cpp | 14 +++++++++++--- .../flat.multiset.operations/find.pass.cpp | 14 +++++++++++--- .../find_transparent.pass.cpp | 14 +++++++++++--- .../flat.multiset.operations/lower_bound.pass.cpp | 14 +++++++++++--- .../lower_bound_transparent.pass.cpp | 14 +++++++++++--- .../flat.multiset.operations/upper_bound.pass.cpp | 14 +++++++++++--- .../upper_bound_transparent.pass.cpp | 14 +++++++++++--- 12 files changed, 132 insertions(+), 36 deletions(-) diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/contains.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/contains.pass.cpp index 00fda6c2edd88..a178dfd3d0cb5 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/contains.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/contains.pass.cpp @@ -23,7 +23,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; { using M = std::flat_multiset, KeyContainer>; @@ -66,15 +66,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/flat.multiset.operations/contains_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/contains_transparent.pass.cpp index abee2b1bb12f9..3222762122f88 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/contains_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/contains_transparent.pass.cpp @@ -35,7 +35,7 @@ static_assert(!CanContains); static_assert(!CanContains); template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset; @@ -60,9 +60,12 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -82,10 +85,15 @@ void test() { assert(m.contains("beta")); assert(!m.contains("charlie")); } + + 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.multiset/flat.multiset.operations/count.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/count.pass.cpp index 1752dab0e0e3a..8b034dfa1423c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/count.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/count.pass.cpp @@ -23,7 +23,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using S = typename KeyContainer::size_type; @@ -66,15 +66,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/flat.multiset.operations/count_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/count_transparent.pass.cpp index a9160aebb7517..a1a0d6b1f0310 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/count_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/count_transparent.pass.cpp @@ -35,7 +35,7 @@ static_assert(!CanCount); static_assert(!CanCount); template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset; { @@ -59,9 +59,12 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -81,10 +84,15 @@ void test() { auto n = m.count("beta"); assert(n == 2); } + + 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.multiset/flat.multiset.operations/equal_range.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/equal_range.pass.cpp index 54ae27e9ba19c..b105d1914113a 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/equal_range.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/equal_range.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_multiset, KeyContainer>; @@ -74,15 +74,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/flat.multiset.operations/equal_range_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/equal_range_transparent.pass.cpp index ae16ec1127f31..65bff7a095dc6 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/equal_range_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/equal_range_transparent.pass.cpp @@ -36,7 +36,7 @@ static_assert(!CanEqualRange); static_assert(!CanEqualRange); template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset; @@ -90,9 +90,12 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -113,10 +116,15 @@ void test() { assert(first == m.begin() + 1); assert(last == m.begin() + 3); } + + 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.multiset/flat.multiset.operations/find.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/find.pass.cpp index 49386a6f77fae..bc9a439eecbb9 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/find.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/find.pass.cpp @@ -25,7 +25,7 @@ #include "min_allocator.h" template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset, KeyContainer>; { @@ -50,15 +50,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/flat.multiset.operations/find_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/find_transparent.pass.cpp index 9d0b75c7b52bc..4c9c403464634 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/find_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/find_transparent.pass.cpp @@ -36,7 +36,7 @@ static_assert(!CanFind); static_assert(!CanFind); template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset; @@ -77,9 +77,12 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -101,10 +104,15 @@ void test() { auto it2 = m.find("charlie"); assert(it2 == m.end()); } + + 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.multiset/flat.multiset.operations/lower_bound.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/lower_bound.pass.cpp index ba41b822fda74..07f053316ad32 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/lower_bound.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/lower_bound.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_multiset, KeyContainer>; @@ -66,15 +66,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/flat.multiset.operations/lower_bound_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/lower_bound_transparent.pass.cpp index c03fb27a7c27e..e674c85ab30e6 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/lower_bound_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/lower_bound_transparent.pass.cpp @@ -36,7 +36,7 @@ static_assert(!CanLowerBound); static_assert(!CanLowerBound); template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset; @@ -83,9 +83,12 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -107,10 +110,15 @@ void test() { auto it2 = m.lower_bound("charlie"); assert(it2 == m.begin() + 3); } + + 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.multiset/flat.multiset.operations/upper_bound.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/upper_bound.pass.cpp index 7828f0500c8b9..d4d19926571d7 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/upper_bound.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/upper_bound.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_multiset, KeyContainer>; @@ -67,15 +67,23 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_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.multiset/flat.multiset.operations/upper_bound_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/upper_bound_transparent.pass.cpp index de517fd7e520a..75140a780cceb 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/upper_bound_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.operations/upper_bound_transparent.pass.cpp @@ -36,7 +36,7 @@ static_assert(!CanUpperBound); static_assert(!CanUpperBound); template -void test_one() { +constexpr void test_one() { using Key = typename KeyContainer::value_type; using M = std::flat_multiset; @@ -83,9 +83,12 @@ void test_one() { } } -void test() { +constexpr bool test() { test_one>(); - test_one>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test_one>(); test_one>(); test_one>>(); @@ -105,10 +108,15 @@ void test() { auto it = m.upper_bound("beta"); assert(it == m.begin() + 3); } + + return true; } int main(int, char**) { test(); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } From 2aac2cffdde7a9b77799d60ddfc6d6c51ca7091b Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 21 Sep 2025 14:22:35 +0100 Subject: [PATCH 5/9] ctor --- .../flat.multiset.cons/alloc.pass.cpp | 34 +++-- .../assign_initializer_list.pass.cpp | 14 +- .../flat.multiset.cons/compare.pass.cpp | 86 +++++++---- .../flat.multiset.cons/containers.pass.cpp | 110 ++++++++------ .../flat.multiset.cons/copy.pass.cpp | 22 ++- .../flat.multiset.cons/copy_alloc.pass.cpp | 49 ++++--- .../flat.multiset.cons/copy_assign.pass.cpp | 24 +++- .../flat.multiset.cons/default.pass.cpp | 43 ++++-- .../flat.multiset.cons/dtor_noexcept.pass.cpp | 31 +++- .../initializer_list.pass.cpp | 124 +++++++++------- .../flat.multiset.cons/iter_iter.pass.cpp | 80 ++++++----- .../flat.multiset.cons/move.pass.cpp | 24 +++- .../flat.multiset.cons/move_alloc.pass.cpp | 51 ++++--- .../flat.multiset.cons/move_assign.pass.cpp | 49 ++++--- .../flat.multiset.cons/range.pass.cpp | 78 +++++----- .../sorted_container.pass.cpp | 92 +++++++----- .../sorted_initializer_list.pass.cpp | 135 ++++++++++-------- .../sorted_iter_iter.pass.cpp | 82 ++++++----- 18 files changed, 707 insertions(+), 421 deletions(-) diff --git a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/alloc.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/alloc.pass.cpp index 4fffcb304d20a..1bfd13e0d3cf2 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/alloc.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/alloc.pass.cpp @@ -14,6 +14,7 @@ // explicit flat_multiset(const Allocator& a); #include +#include #include #include #include @@ -22,7 +23,19 @@ #include "test_allocator.h" #include "../../../test_compare.h" -void test() { +template