From 36ee538e5ba4977e78d0f240154c225a6c1eb62a Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sun, 13 Jul 2025 10:08:01 +0100 Subject: [PATCH 1/4] [libc++] constexpr flat_multimap --- libcxx/include/__flat_map/flat_multimap.h | 355 +++++++++++------- .../flat.multimap.capacity/empty.pass.cpp | 18 +- .../flat.multimap.capacity/max_size.pass.cpp | 12 +- .../flat.multimap.capacity/size.pass.cpp | 19 +- .../flat.multimap.cons/alloc.pass.cpp | 48 ++- .../assign_initializer_list.pass.cpp | 41 +- .../flat.multimap.cons/compare.pass.cpp | 108 ++++-- .../flat.multimap.cons/containers.pass.cpp | 207 ++++++---- .../flat.multimap.cons/copy.pass.cpp | 36 +- .../flat.multimap.cons/copy_alloc.pass.cpp | 58 ++- .../flat.multimap.cons/copy_assign.pass.cpp | 56 ++- .../flat.multimap.cons/default.pass.cpp | 40 +- .../default_noexcept.pass.cpp | 15 +- .../flat.multimap.cons/dtor_noexcept.pass.cpp | 43 ++- .../initializer_list.pass.cpp | 160 ++++---- .../flat.multimap.cons/iter_iter.pass.cpp | 231 +++++++++--- .../flat.multimap.cons/move.pass.cpp | 34 +- .../flat.multimap.cons/move_alloc.pass.cpp | 76 ++-- .../flat.multimap.cons/move_assign.pass.cpp | 35 +- .../move_assign_clears.pass.cpp | 66 +++- ... => move_assign_noexcept.compile.pass.cpp} | 4 +- .../flat.multimap.cons/range.pass.cpp | 287 ++++++++++---- .../sorted_container.pass.cpp | 158 ++++---- .../sorted_initializer_list.pass.cpp | 164 ++++---- .../sorted_iter_iter.pass.cpp | 165 ++++---- .../flat.multimap.erasure/erase_if.pass.cpp | 28 +- .../flat.multimap.iterators/iterator.pass.cpp | 18 +- .../iterator_comparison.pass.cpp | 18 +- .../reverse_iterator.pass.cpp | 98 +++-- .../flat.multimap.modifiers/clear.pass.cpp | 17 +- .../flat.multimap.modifiers/emplace.pass.cpp | 27 +- .../emplace_hint.pass.cpp | 29 +- .../erase_iter.pass.cpp | 59 ++- .../erase_iter_iter.pass.cpp | 34 +- .../erase_key.pass.cpp | 19 +- .../erase_key_transparent.pass.cpp | 42 ++- .../flat.multimap.modifiers/extract.pass.cpp | 27 +- .../insert_cv.pass.cpp | 20 +- .../insert_initializer_list.pass.cpp | 24 +- .../insert_iter_cv.pass.cpp | 20 +- .../insert_iter_iter.pass.cpp | 27 +- .../insert_iter_rv.pass.cpp | 25 +- .../insert_range.pass.cpp | 22 +- .../insert_rv.pass.cpp | 21 +- .../insert_sorted_initializer_list.pass.cpp | 23 +- .../insert_sorted_iter_iter.pass.cpp | 19 +- .../insert_transparent.pass.cpp | 121 +++--- .../flat.multimap.modifiers/replace.pass.cpp | 21 +- .../swap_free.pass.cpp | 17 +- .../swap_member.pass.cpp | 18 +- .../flat.multimap.observers/comp.pass.cpp | 16 +- .../keys_values.pass.cpp | 31 +- .../contains.pass.cpp | 17 +- .../contains_transparent.pass.cpp | 19 +- .../flat.multimap.operations/count.pass.cpp | 18 +- .../count_transparent.pass.cpp | 18 +- .../equal_range.pass.cpp | 17 +- .../equal_range_transparent.pass.cpp | 20 +- .../flat.multimap.operations/find.pass.cpp | 17 +- .../find_transparent.pass.cpp | 17 +- .../lower_bound.pass.cpp | 17 +- .../lower_bound_transparent.pass.cpp | 17 +- .../upper_bound.pass.cpp | 17 +- .../upper_bound_transparent.pass.cpp | 17 +- .../flat.multimap/helpers.h | 11 +- 65 files changed, 2426 insertions(+), 1073 deletions(-) rename libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/{move_assign_noexcept.pass.cpp => move_assign_noexcept.compile.pass.cpp} (99%) diff --git a/libcxx/include/__flat_map/flat_multimap.h b/libcxx/include/__flat_map/flat_multimap.h index 0af6aac00c383..260d93ed25785 100644 --- a/libcxx/include/__flat_map/flat_multimap.h +++ b/libcxx/include/__flat_map/flat_multimap.h @@ -114,11 +114,12 @@ class flat_multimap { class value_compare { private: _LIBCPP_NO_UNIQUE_ADDRESS key_compare __comp_; - _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : __comp_(__c) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare(key_compare __c) : __comp_(__c) {} friend flat_multimap; public: - _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool + operator()(const_reference __x, const_reference __y) const { return __comp_(__x.first, __y.first); } }; @@ -137,17 +138,17 @@ class flat_multimap { public: // [flat.map.cons], construct/copy/destroy - _LIBCPP_HIDE_FROM_ABI flat_multimap() noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap() noexcept( is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_MappedContainer> && is_nothrow_default_constructible_v<_Compare>) : __containers_(), __compare_() {} - _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap&) = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(const flat_multimap&) = 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_multimap(flat_multimap&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(flat_multimap&& __other) noexcept( is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_MappedContainer> && is_nothrow_move_constructible_v<_Compare>) # if _LIBCPP_HAS_EXCEPTIONS @@ -168,7 +169,8 @@ class flat_multimap { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(const flat_multimap& __other, const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __other.__containers_.keys, @@ -177,7 +179,7 @@ class flat_multimap { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap(flat_multimap&& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(flat_multimap&& __other, const _Allocator& __alloc) # if _LIBCPP_HAS_EXCEPTIONS try # endif // _LIBCPP_HAS_EXCEPTIONS @@ -194,7 +196,7 @@ class flat_multimap { # endif // _LIBCPP_HAS_EXCEPTIONS } - _LIBCPP_HIDE_FROM_ABI flat_multimap( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( key_container_type __key_cont, mapped_container_type __mapped_cont, const key_compare& __comp = key_compare()) : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), @@ -204,7 +206,7 @@ class flat_multimap { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), @@ -214,22 +216,22 @@ class flat_multimap { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI - flat_multimap(const key_container_type& __key_cont, - const mapped_container_type& __mapped_cont, - const key_compare& __comp, - const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( + const key_container_type& __key_cont, + const mapped_container_type& __mapped_cont, + const key_compare& __comp, + const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), "flat_multimap keys and mapped containers have different size"); __sort(); } - _LIBCPP_HIDE_FROM_ABI - flat_multimap(sorted_equivalent_t, - key_container_type __key_cont, - mapped_container_type __mapped_cont, - const key_compare& __comp = key_compare()) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( + sorted_equivalent_t, + key_container_type __key_cont, + mapped_container_type __mapped_cont, + const key_compare& __comp = key_compare()) : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), "flat_multimap keys and mapped containers have different size"); @@ -238,11 +240,11 @@ class flat_multimap { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI - flat_multimap(sorted_equivalent_t, - const key_container_type& __key_cont, - const mapped_container_type& __mapped_cont, - const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( + sorted_equivalent_t, + const key_container_type& __key_cont, + const mapped_container_type& __mapped_cont, + const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), "flat_multimap keys and mapped containers have different size"); @@ -251,33 +253,35 @@ class flat_multimap { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI - flat_multimap(sorted_equivalent_t, - const key_container_type& __key_cont, - const mapped_container_type& __mapped_cont, - const key_compare& __comp, - const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( + sorted_equivalent_t, + const key_container_type& __key_cont, + const mapped_container_type& __mapped_cont, + const key_compare& __comp, + const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), "flat_multimap keys and mapped containers have different size"); _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted"); } - _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const key_compare& __comp) : __containers_(), __compare_(__comp) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multimap(const key_compare& __comp) + : __containers_(), __compare_(__comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap(const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(const key_compare& __comp, const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_multimap(const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {} template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __containers_(), __compare_(__comp) { insert(__first, __last); @@ -285,7 +289,7 @@ class flat_multimap { template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { insert(__first, __last); @@ -293,91 +297,99 @@ class flat_multimap { template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI flat_multimap(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) { insert(__first, __last); } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t __fr, _Range&& __rg) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(from_range_t __fr, _Range&& __rg) : flat_multimap(__fr, std::forward<_Range>(__rg), key_compare()) {} template <_ContainerCompatibleRange _Range, class _Allocator> requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(from_range_t, _Range&& __rg, const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) { insert_range(std::forward<_Range>(__rg)); } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_multimap(__comp) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp) + : flat_multimap(__comp) { insert_range(std::forward<_Range>(__rg)); } template <_ContainerCompatibleRange _Range, class _Allocator> requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { insert_range(std::forward<_Range>(__rg)); } template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI flat_multimap( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __containers_(), __compare_(__comp) { insert(sorted_equivalent, __first, __last); } template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI - flat_multimap(sorted_equivalent_t, - _InputIterator __first, - _InputIterator __last, - const key_compare& __comp, - const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( + sorted_equivalent_t, + _InputIterator __first, + _InputIterator __last, + const key_compare& __comp, + const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { insert(sorted_equivalent, __first, __last); } template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(sorted_equivalent_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc) : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) { insert(sorted_equivalent, __first, __last); } - _LIBCPP_HIDE_FROM_ABI flat_multimap(initializer_list __il, const key_compare& __comp = key_compare()) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(initializer_list __il, const key_compare& __comp = key_compare()) : flat_multimap(__il.begin(), __il.end(), __comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_multimap(__il.begin(), __il.end(), __comp, __alloc) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap(initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(initializer_list __il, const _Allocator& __alloc) : flat_multimap(__il.begin(), __il.end(), __alloc) {} - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap(sorted_equivalent_t, initializer_list __il, const key_compare& __comp = key_compare()) : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( sorted_equivalent_t, initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __comp, __alloc) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap(sorted_equivalent_t, initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(sorted_equivalent_t, initializer_list __il, const _Allocator& __alloc) : flat_multimap(sorted_equivalent, __il.begin(), __il.end(), __alloc) {} - _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(initializer_list __il) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap& operator=(initializer_list __il) { clear(); insert(__il); return *this; @@ -386,9 +398,9 @@ class flat_multimap { // 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_multimap& operator=(const flat_multimap&) = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap& operator=(const flat_multimap&) = default; - _LIBCPP_HIDE_FROM_ABI flat_multimap& operator=(flat_multimap&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap& operator=(flat_multimap&& __other) noexcept( is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> && is_nothrow_move_assignable_v<_Compare>) { auto __clear_other_guard = std::__make_scope_guard([&]() noexcept { __other.clear() /* noexcept */; }); @@ -400,38 +412,54 @@ class flat_multimap { } // iterators - _LIBCPP_HIDE_FROM_ABI iterator begin() noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() noexcept { return iterator(__containers_.keys.begin(), __containers_.values.begin()); } - _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const noexcept { return const_iterator(__containers_.keys.begin(), __containers_.values.begin()); } - _LIBCPP_HIDE_FROM_ABI iterator end() noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() noexcept { return iterator(__containers_.keys.end(), __containers_.values.end()); } - _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const noexcept { return const_iterator(__containers_.keys.end(), __containers_.values.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.map.capacity], capacity - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __containers_.keys.empty(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const noexcept { + return __containers_.keys.empty(); + } - _LIBCPP_HIDE_FROM_ABI size_type size() const noexcept { return __containers_.keys.size(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const noexcept { + return __containers_.keys.size(); + } - _LIBCPP_HIDE_FROM_ABI size_type max_size() const noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const noexcept { return std::min(__containers_.keys.max_size(), __containers_.values.max_size()); } @@ -439,7 +467,7 @@ class flat_multimap { template requires is_constructible_v, _Args...> && is_move_constructible_v && is_move_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace(_Args&&... __args) { std::pair __pair(std::forward<_Args>(__args)...); auto __key_it = std::upper_bound(__containers_.keys.begin(), __containers_.keys.end(), __pair.first, __compare_); auto __mapped_it = __corresponding_mapped_it(*this, __key_it); @@ -450,7 +478,7 @@ class flat_multimap { template requires is_constructible_v, _Args...> - _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) { std::pair __pair(std::forward<_Args>(__args)...); auto __prev_larger = __hint != cbegin() && __compare_(__pair.first, (__hint - 1)->first); @@ -490,33 +518,35 @@ class flat_multimap { *this, __key_iter, __mapped_iter, std::move(__pair.first), std::move(__pair.second)); } - _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 is_constructible_v, _PairLike> - _LIBCPP_HIDE_FROM_ABI iterator insert(_PairLike&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(_PairLike&& __x) { return emplace(std::forward<_PairLike>(__x)); } template requires is_constructible_v, _PairLike> - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, _PairLike&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, _PairLike&& __x) { return emplace_hint(__hint, std::forward<_PairLike>(__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); } @@ -525,7 +555,8 @@ class flat_multimap { 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); } @@ -534,7 +565,7 @@ class flat_multimap { } 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)); } @@ -542,19 +573,23 @@ class flat_multimap { __append_sort_merge(ranges::begin(__range), ranges::end(__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 containers extract() && { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 containers extract() && { auto __guard = std::__make_scope_guard([&]() noexcept { clear() /* noexcept */; }); auto __ret = std::move(__containers_); return __ret; } - _LIBCPP_HIDE_FROM_ABI void replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + replace(key_container_type&& __key_cont, mapped_container_type&& __mapped_cont) { _LIBCPP_ASSERT_VALID_INPUT_RANGE( __key_cont.size() == __mapped_cont.size(), "flat_multimap keys and mapped containers have different size"); @@ -565,15 +600,15 @@ class flat_multimap { __guard.__complete(); } - _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __position) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(iterator __position) { return __erase(__position.__key_iter_, __position.__mapped_iter_); } - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __position) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __position) { return __erase(__position.__key_iter_, __position.__mapped_iter_); } - _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); @@ -583,14 +618,14 @@ class flat_multimap { template requires(__is_compare_transparent && !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 = __containers_.keys.erase(__first.__key_iter_, __last.__key_iter_); auto __mapped_it = __containers_.values.erase(__first.__mapped_iter_, __last.__mapped_iter_); @@ -598,7 +633,7 @@ class flat_multimap { return iterator(std::move(__key_it), std::move(__mapped_it)); } - _LIBCPP_HIDE_FROM_ABI void swap(flat_multimap& __y) noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_multimap& __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 @@ -607,137 +642,160 @@ class flat_multimap { ranges::swap(__containers_.values, __y.__containers_.values); } - _LIBCPP_HIDE_FROM_ABI void clear() noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() noexcept { __containers_.keys.clear(); __containers_.values.clear(); } // observers - _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __compare_; } - _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__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 value_compare(__compare_); + } - _LIBCPP_HIDE_FROM_ABI const key_container_type& keys() const noexcept { return __containers_.keys; } - _LIBCPP_HIDE_FROM_ABI const mapped_container_type& values() const noexcept { return __containers_.values; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const key_container_type& keys() const noexcept { + return __containers_.keys; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_container_type& values() const noexcept { + return __containers_.values; + } // 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_compare_transparent - _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_compare_transparent - _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_compare_transparent - _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_compare_transparent - _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) { return __lower_bound(*this, __x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __x) { + return __lower_bound(*this, __x); + } - _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 __lower_bound(*this, __x); } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _Kp& __x) { return __lower_bound(*this, __x); } template requires __is_compare_transparent - _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 __lower_bound(*this, __x); } - _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __x) { return __upper_bound(*this, __x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __x) { + return __upper_bound(*this, __x); + } - _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 __upper_bound(*this, __x); } template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _Kp& __x) { return __upper_bound(*this, __x); } template requires __is_compare_transparent - _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 __upper_bound(*this, __x); } - _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_compare_transparent - _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_compare_transparent - _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_multimap& __x, const flat_multimap& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool + operator==(const flat_multimap& __x, const flat_multimap& __y) { return ranges::equal(__x, __y); } - friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_multimap& __x, const flat_multimap& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto + operator<=>(const flat_multimap& __x, const flat_multimap& __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_multimap& __x, flat_multimap& __y) noexcept { __x.swap(__y); } + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + swap(flat_multimap& __x, flat_multimap& __y) noexcept { + __x.swap(__y); + } private: struct __ctor_uses_allocator_tag { - explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_tag() = default; + explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __ctor_uses_allocator_tag() = default; }; struct __ctor_uses_allocator_empty_tag { - explicit _LIBCPP_HIDE_FROM_ABI __ctor_uses_allocator_empty_tag() = default; + explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __ctor_uses_allocator_empty_tag() = default; }; template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI - flat_multimap(__ctor_uses_allocator_tag, - const _Allocator& __alloc, - _KeyCont&& __key_cont, - _MappedCont&& __mapped_cont, - _CompArg&&... __comp) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_multimap( + __ctor_uses_allocator_tag, + const _Allocator& __alloc, + _KeyCont&& __key_cont, + _MappedCont&& __mapped_cont, + _CompArg&&... __comp) : __containers_{.keys = std::make_obj_using_allocator( __alloc, std::forward<_KeyCont>(__key_cont)), .values = std::make_obj_using_allocator( @@ -746,29 +804,32 @@ class flat_multimap { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_multimap(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_multimap(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp) : __containers_{.keys = std::make_obj_using_allocator(__alloc), .values = std::make_obj_using_allocator(__alloc)}, __compare_(std::forward<_CompArg>(__comp)...) {} - _LIBCPP_HIDE_FROM_ABI bool __is_sorted(auto&& __key_container) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted(auto&& __key_container) const { return ranges::is_sorted(__key_container, __compare_); } - _LIBCPP_HIDE_FROM_ABI void __sort() { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __sort() { auto __zv = ranges::views::zip(__containers_.keys, __containers_.values); ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); }); } template - _LIBCPP_HIDE_FROM_ABI static auto __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto + __corresponding_mapped_it(_Self&& __self, _KeyIter&& __key_iter) { return __self.__containers_.values.begin() + static_cast>( ranges::distance(__self.__containers_.keys.begin(), __key_iter)); } template - _LIBCPP_HIDE_FROM_ABI void __append_sort_merge(_InputIterator __first, _Sentinel __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + __append_sort_merge(_InputIterator __first, _Sentinel __last) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); size_t __num_appended = __flat_map_utils::__append(*this, std::move(__first), std::move(__last)); if (__num_appended != 0) { @@ -791,7 +852,7 @@ class flat_multimap { } 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->first)) { @@ -801,7 +862,7 @@ class flat_multimap { } 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) { auto [__key_first, __key_last] = std::equal_range(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_); @@ -811,7 +872,7 @@ class flat_multimap { } template - _LIBCPP_HIDE_FROM_ABI static _Res __lower_bound(_Self&& __self, _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static _Res __lower_bound(_Self&& __self, _Kp& __x) { auto __key_iter = std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); @@ -819,14 +880,14 @@ class flat_multimap { } template - _LIBCPP_HIDE_FROM_ABI static _Res __upper_bound(_Self&& __self, _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static _Res __upper_bound(_Self&& __self, _Kp& __x) { auto __key_iter = std::upper_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __x, __self.__compare_); auto __mapped_iter = __corresponding_mapped_it(__self, __key_iter); return _Res(std::move(__key_iter), std::move(__mapped_iter)); } - _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) { __containers_.keys.reserve(__size); } @@ -837,7 +898,8 @@ class flat_multimap { } template - _LIBCPP_HIDE_FROM_ABI iterator __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + __erase(_KIter __key_iter_to_remove, _MIter __mapped_iter_to_remove) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); auto __key_iter = __containers_.keys.erase(__key_iter_to_remove); auto __mapped_iter = __containers_.values.erase(__mapped_iter_to_remove); @@ -847,7 +909,8 @@ class flat_multimap { template friend typename flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type - erase_if(flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate); + _LIBCPP_CONSTEXPR_SINCE_CXX26 + erase_if(flat_multimap<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate); friend __flat_map_utils; @@ -855,8 +918,9 @@ class flat_multimap { _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_; @@ -980,8 +1044,9 @@ struct uses_allocator && uses_allocator_v<_MappedContainer, _Allocator>> {}; template -_LIBCPP_HIDE_FROM_ABI typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type -erase_if(flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_multimap, _Predicate __pred) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type + erase_if(flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_multimap, _Predicate __pred) { auto __zv = ranges::views::zip(__flat_multimap.__containers_.keys, __flat_multimap.__containers_.values); auto __first = __zv.begin(); auto __last = __zv.end(); diff --git a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/empty.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/empty.pass.cpp index 4fa4fd6a69b94..a09bb8c1aa514 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/empty.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/empty.pass.cpp @@ -26,7 +26,7 @@ #include "min_allocator.h" template -void test() { +constexpr void test() { using Key = typename KeyContainer::value_type; using Value = typename ValueContainer::value_type; using M = std::flat_multimap, KeyContainer, ValueContainer>; @@ -41,11 +41,23 @@ void test() { assert(m.empty()); } -int main(int, char**) { +constexpr bool test() { test, std::vector>(); - test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test, std::vector>(); test, MinSequenceContainer>(); test>, std::vector>>(); + 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.multimap/flat.multimap.capacity/max_size.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/max_size.pass.cpp index 0960c43c5a90a..fc35fec10cd95 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/max_size.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/max_size.pass.cpp @@ -26,7 +26,7 @@ #include "test_allocator.h" #include "test_macros.h" -int main(int, char**) { +constexpr bool test() { { using A1 = limited_allocator; using A2 = limited_allocator; @@ -74,5 +74,15 @@ int main(int, char**) { 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.multimap/flat.multimap.capacity/size.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/size.pass.cpp index 533f8da631fc8..64b4f8dff2230 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/size.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/size.pass.cpp @@ -25,7 +25,7 @@ #include "min_allocator.h" template -void test() { +constexpr void test() { using M = std::flat_multimap, KeyContainer, ValueContainer>; { const M m = {{1, 'a'}, {1, 'b'}, {4, 'd'}, {5, 'e'}, {5, 'h'}}; @@ -47,7 +47,7 @@ void test() { } { M m; - std::size_t s = 1000; + std::size_t s = TEST_IS_CONSTANT_EVALUATED ? 100 : 1000; for (auto i = 0u; i < s; ++i) { m.emplace(i, 'a'); } @@ -60,11 +60,22 @@ void test() { } } -int main(int, char**) { +constexpr bool test() { test, std::vector>(); - test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!TEST_IS_CONSTANT_EVALUATED) +#endif + test, std::vector>(); test, MinSequenceContainer>(); test>, std::vector>>(); + 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.multimap/flat.multimap.cons/alloc.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/alloc.pass.cpp index 3e155eb2a1075..596da81f6e940 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/alloc.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/alloc.pass.cpp @@ -8,12 +8,13 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// +// // template // explicit flat_multimap(const Allocator& a); #include +#include #include #include #include @@ -22,7 +23,23 @@ #include "test_allocator.h" #include "../../../test_compare.h" -int main(int, char**) { +template