From 22b63c9463a9f98ac5d201a56f07f4f82da32bae Mon Sep 17 00:00:00 2001 From: Hui Xie Date: Sat, 26 Apr 2025 11:05:21 +0100 Subject: [PATCH 01/11] [libc++] constexpr flat_map --- libcxx/include/__flat_map/flat_map.h | 388 +++++++++++------- .../include/__flat_map/key_value_iterator.h | 58 ++- libcxx/include/__flat_map/utils.h | 4 +- libcxx/test/std/containers/Emplaceable.h | 4 +- .../flat.map/flat.map.access/at.pass.cpp | 41 +- .../flat.map.access/at_transparent.pass.cpp | 40 +- .../flat.map.access/index_key.pass.cpp | 25 +- .../flat.map.access/index_rv_key.pass.cpp | 23 +- .../index_transparent.pass.cpp | 25 +- .../flat.map/flat.map.capacity/empty.pass.cpp | 22 +- .../flat.map.capacity/max_size.pass.cpp | 12 +- .../flat.map/flat.map.capacity/size.pass.cpp | 23 +- .../flat.map/flat.map.cons/alloc.pass.cpp | 46 ++- .../assign_initializer_list.pass.cpp | 22 +- .../flat.map/flat.map.cons/compare.pass.cpp | 108 +++-- .../flat.map.cons/containers.pass.cpp | 153 ++++--- .../flat.map/flat.map.cons/copy.pass.cpp | 32 +- .../flat.map.cons/copy_alloc.pass.cpp | 58 ++- .../flat.map.cons/copy_assign.pass.cpp | 35 +- .../flat.map/flat.map.cons/default.pass.cpp | 40 +- .../flat.map.cons/default_noexcept.pass.cpp | 16 +- .../flat.map.cons/dtor_noexcept.pass.cpp | 41 +- .../flat.map.cons/initializer_list.pass.cpp | 159 +++---- .../flat.map/flat.map.cons/iter_iter.pass.cpp | 189 ++++++--- .../flat.map/flat.map.cons/move.pass.cpp | 35 +- .../flat.map.cons/move_alloc.pass.cpp | 64 ++- .../flat.map.cons/move_assign.pass.cpp | 31 +- .../flat.map.cons/move_assign_clears.pass.cpp | 43 +- ... => move_assign_noexcept.compile.pass.cpp} | 4 +- .../flat.map/flat.map.cons/range.pass.cpp | 241 +++++++---- .../flat.map.cons/sorted_container.pass.cpp | 118 +++--- .../sorted_initializer_list.pass.cpp | 164 ++++---- .../flat.map.cons/sorted_iter_iter.pass.cpp | 127 ++++-- .../flat.map.erasure/erase_if.pass.cpp | 28 +- .../flat.map.iterators/iterator.pass.cpp | 20 +- .../iterator_comparison.pass.cpp | 20 +- .../reverse_iterator.pass.cpp | 100 +++-- .../flat.map.modifiers/clear.pass.cpp | 20 +- .../flat.map.modifiers/emplace.pass.cpp | 26 +- .../flat.map.modifiers/emplace_hint.pass.cpp | 27 +- .../flat.map.modifiers/erase_iter.pass.cpp | 23 +- .../erase_iter_iter.pass.cpp | 24 +- .../flat.map.modifiers/erase_key.pass.cpp | 23 +- .../erase_key_transparent.pass.cpp | 33 +- .../flat.map.modifiers/extract.pass.cpp | 23 +- .../flat.map.modifiers/insert_cv.pass.cpp | 23 +- .../insert_initializer_list.pass.cpp | 39 +- .../insert_iter_cv.pass.cpp | 23 +- .../insert_iter_iter.pass.cpp | 48 ++- .../insert_iter_rv.pass.cpp | 26 +- .../insert_or_assign.pass.cpp | 24 +- .../insert_or_assign_transparent.pass.cpp | 52 ++- .../flat.map.modifiers/insert_range.pass.cpp | 27 +- .../flat.map.modifiers/insert_rv.pass.cpp | 24 +- .../insert_sorted_initializer_list.pass.cpp | 39 +- .../insert_sorted_iter_iter.pass.cpp | 22 +- .../insert_transparent.pass.cpp | 159 +++---- .../flat.map.modifiers/replace.pass.cpp | 23 +- .../flat.map.modifiers/swap_free.pass.cpp | 20 +- .../flat.map.modifiers/swap_member.pass.cpp | 20 +- .../flat.map.modifiers/try_emplace.pass.cpp | 94 +++-- .../try_emplace_transparent.pass.cpp | 54 ++- .../flat.map/flat.map.observers/comp.pass.cpp | 17 +- .../flat.map.observers/keys_values.pass.cpp | 20 +- .../flat.map.operations/contains.pass.cpp | 20 +- .../contains_transparent.pass.cpp | 21 +- .../flat.map.operations/count.pass.cpp | 20 +- .../count_transparent.pass.cpp | 20 +- .../flat.map.operations/equal_range.pass.cpp | 20 +- .../equal_range_transparent.pass.cpp | 20 +- .../flat.map.operations/find.pass.cpp | 20 +- .../find_transparent.pass.cpp | 20 +- .../flat.map.operations/lower_bound.pass.cpp | 20 +- .../lower_bound_transparent.pass.cpp | 20 +- .../flat.map.operations/upper_bound.pass.cpp | 20 +- .../upper_bound_transparent.pass.cpp | 20 +- .../container.adaptors/flat.map/helpers.h | 11 +- .../flat.map/incomplete_type.pass.cpp | 17 +- .../flat.map/op_compare.pass.cpp | 23 +- .../container.adaptors/flat_helpers.h | 37 +- libcxx/test/std/containers/test_compare.h | 18 +- libcxx/test/support/MinSequenceContainer.h | 51 ++- 82 files changed, 2690 insertions(+), 1220 deletions(-) rename libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/{move_assign_noexcept.pass.cpp => move_assign_noexcept.compile.pass.cpp} (99%) diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h index 8f01882934b7a..cd5a41bfe46f1 100644 --- a/libcxx/include/__flat_map/flat_map.h +++ b/libcxx/include/__flat_map/flat_map.h @@ -114,11 +114,12 @@ class flat_map { 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_map; 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,14 +138,14 @@ class flat_map { public: // [flat.map.cons], construct/copy/destroy - _LIBCPP_HIDE_FROM_ABI flat_map() noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map() 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_map(const flat_map&) = default; - _LIBCPP_HIDE_FROM_ABI flat_map(flat_map&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(flat_map&& __other) noexcept( is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_MappedContainer> && is_nothrow_move_constructible_v<_Compare>) # if _LIBCPP_HAS_EXCEPTIONS @@ -165,7 +166,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(const flat_map& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const flat_map& __other, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_tag{}, __alloc, __other.__containers_.keys, @@ -174,7 +175,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(flat_map&& __other, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(flat_map&& __other, const _Allocator& __alloc) # if _LIBCPP_HAS_EXCEPTIONS try # endif // _LIBCPP_HAS_EXCEPTIONS @@ -191,7 +192,7 @@ class flat_map { # endif // _LIBCPP_HAS_EXCEPTIONS } - _LIBCPP_HIDE_FROM_ABI flat_map( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( 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(), @@ -201,7 +202,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), @@ -211,7 +212,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const key_compare& __comp, @@ -222,7 +223,7 @@ class flat_map { __sort_and_unique(); } - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, key_container_type __key_cont, mapped_container_type __mapped_cont, @@ -236,7 +237,7 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, @@ -250,12 +251,12 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI - flat_map(sorted_unique_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_map( + sorted_unique_t, + const key_container_type& __key_cont, + const mapped_container_type& __mapped_cont, + const key_compare& __comp, + const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) { _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(), "flat_map keys and mapped containers have different size"); @@ -263,21 +264,22 @@ class flat_map { __is_sorted_and_unique(__containers_.keys), "Either the key container is not sorted or it contains duplicates"); } - _LIBCPP_HIDE_FROM_ABI explicit flat_map(const key_compare& __comp) : __containers_(), __compare_(__comp) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_map(const key_compare& __comp) + : __containers_(), __compare_(__comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(const key_compare& __comp, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI explicit flat_map(const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit flat_map(const _Allocator& __alloc) : flat_map(__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_map(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __containers_(), __compare_(__comp) { insert(__first, __last); @@ -285,7 +287,7 @@ class flat_map { 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_map(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { insert(__first, __last); @@ -293,99 +295,105 @@ class flat_map { template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI flat_map(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { insert(__first, __last); } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t __fr, _Range&& __rg) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t __fr, _Range&& __rg) : flat_map(__fr, std::forward<_Range>(__rg), key_compare()) {} template <_ContainerCompatibleRange _Range, class _Allocator> requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t, _Range&& __rg, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t, _Range&& __rg, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { insert_range(std::forward<_Range>(__rg)); } template <_ContainerCompatibleRange _Range> - _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_map(__comp) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(from_range_t, _Range&& __rg, const key_compare& __comp) + : flat_map(__comp) { insert_range(std::forward<_Range>(__rg)); } template <_ContainerCompatibleRange _Range, class _Allocator> requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc) : flat_map(__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 + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, _InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare()) : __containers_(), __compare_(__comp) { insert(sorted_unique, __first, __last); } template requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>) - _LIBCPP_HIDE_FROM_ABI - flat_map(sorted_unique_t, - _InputIterator __first, - _InputIterator __last, - const key_compare& __comp, - const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( + sorted_unique_t, + _InputIterator __first, + _InputIterator __last, + const key_compare& __comp, + const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) { insert(sorted_unique, __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_map(sorted_unique_t, _InputIterator __first, _InputIterator __last, const _Allocator& __alloc) : flat_map(__ctor_uses_allocator_empty_tag{}, __alloc) { insert(sorted_unique, __first, __last); } - _LIBCPP_HIDE_FROM_ABI flat_map(initializer_list __il, const key_compare& __comp = key_compare()) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(initializer_list __il, const key_compare& __comp = key_compare()) : flat_map(__il.begin(), __il.end(), __comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_map(__il.begin(), __il.end(), __comp, __alloc) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(initializer_list __il, const _Allocator& __alloc) : flat_map(__il.begin(), __il.end(), __alloc) {} - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, initializer_list __il, const key_compare& __comp = key_compare()) : flat_map(sorted_unique, __il.begin(), __il.end(), __comp) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map(sorted_unique_t, initializer_list __il, const key_compare& __comp, const _Allocator& __alloc) : flat_map(sorted_unique, __il.begin(), __il.end(), __comp, __alloc) {} template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(sorted_unique_t, initializer_list __il, const _Allocator& __alloc) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(sorted_unique_t, initializer_list __il, const _Allocator& __alloc) : flat_map(sorted_unique, __il.begin(), __il.end(), __alloc) {} - _LIBCPP_HIDE_FROM_ABI flat_map& operator=(initializer_list __il) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map& operator=(initializer_list __il) { clear(); insert(__il); return *this; } - _LIBCPP_HIDE_FROM_ABI flat_map& operator=(const flat_map&) = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map& operator=(const flat_map&) = default; - _LIBCPP_HIDE_FROM_ABI flat_map& operator=(flat_map&& __other) noexcept( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map& operator=(flat_map&& __other) noexcept( is_nothrow_move_assignable_v<_KeyContainer> && is_nothrow_move_assignable_v<_MappedContainer> && is_nothrow_move_assignable_v<_Compare>) { // No matter what happens, we always want to clear the other container before returning @@ -402,49 +410,65 @@ class flat_map { } // 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()); } // [flat.map.access], element access - _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __x) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](const key_type& __x) requires is_constructible_v { return try_emplace(__x).first->second; } - _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __x) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](key_type&& __x) requires is_constructible_v { return try_emplace(std::move(__x)).first->second; @@ -453,11 +477,11 @@ class flat_map { template requires(__is_compare_transparent && is_constructible_v && is_constructible_v && !is_convertible_v<_Kp &&, const_iterator> && !is_convertible_v<_Kp &&, iterator>) - _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](_Kp&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](_Kp&& __x) { return try_emplace(std::forward<_Kp>(__x)).first->second; } - _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __x) { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const key_type&): Key does not exist"); @@ -465,7 +489,7 @@ class flat_map { return __it->second; } - _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const key_type& __x) const { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const key_type&) const: Key does not exist"); @@ -475,7 +499,7 @@ class flat_map { template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI mapped_type& at(const _Kp& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const _Kp& __x) { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const K&): Key does not exist"); @@ -485,7 +509,7 @@ class flat_map { template requires __is_compare_transparent - _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const _Kp& __x) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(const _Kp& __x) const { auto __it = find(__x); if (__it == end()) { std::__throw_out_of_range("flat_map::at(const K&) const: Key does not exist"); @@ -496,45 +520,49 @@ class flat_map { // [flat.map.modifiers], modifiers template requires is_constructible_v, _Args...> - _LIBCPP_HIDE_FROM_ABI pair emplace(_Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair emplace(_Args&&... __args) { std::pair __pair(std::forward<_Args>(__args)...); return __try_emplace(std::move(__pair.first), std::move(__pair.second)); } 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)...); return __try_emplace_hint(__hint, std::move(__pair.first), std::move(__pair.second)).first; } - _LIBCPP_HIDE_FROM_ABI pair insert(const value_type& __x) { return emplace(__x); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair insert(const value_type& __x) { + return emplace(__x); + } - _LIBCPP_HIDE_FROM_ABI pair insert(value_type&& __x) { return emplace(std::move(__x)); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair insert(value_type&& __x) { + return emplace(std::move(__x)); + } - _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 pair insert(_PairLike&& __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair 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); } @@ -543,7 +571,8 @@ class flat_map { template requires __has_input_iterator_category<_InputIterator>::value - _LIBCPP_HIDE_FROM_ABI void insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + insert(sorted_unique_t, _InputIterator __first, _InputIterator __last) { if constexpr (sized_sentinel_for<_InputIterator, _InputIterator>) { __reserve(__last - __first); } @@ -552,7 +581,7 @@ class flat_map { } 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)); } @@ -560,19 +589,22 @@ class flat_map { __append_sort_merge_unique(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_unique_t, initializer_list __il) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(sorted_unique_t, initializer_list __il) { insert(sorted_unique, __il.begin(), __il.end()); } - _LIBCPP_HIDE_FROM_ABI 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_map keys and mapped containers have different size"); @@ -586,13 +618,15 @@ class flat_map { template requires is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair try_emplace(const key_type& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + try_emplace(const key_type& __key, _Args&&... __args) { return __try_emplace(__key, std::forward<_Args>(__args)...); } template requires is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair try_emplace(key_type&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + try_emplace(key_type&& __key, _Args&&... __args) { return __try_emplace(std::move(__key), std::forward<_Args>(__args)...); } @@ -600,75 +634,84 @@ class flat_map { requires(__is_compare_transparent && is_constructible_v && is_constructible_v && !is_convertible_v<_Kp &&, const_iterator> && !is_convertible_v<_Kp &&, iterator>) - _LIBCPP_HIDE_FROM_ABI pair try_emplace(_Kp&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair try_emplace(_Kp&& __key, _Args&&... __args) { return __try_emplace(std::forward<_Kp>(__key), std::forward<_Args>(__args)...); } template requires is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __hint, const key_type& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + try_emplace(const_iterator __hint, const key_type& __key, _Args&&... __args) { return __try_emplace_hint(__hint, __key, std::forward<_Args>(__args)...).first; } template requires is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __hint, key_type&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + try_emplace(const_iterator __hint, key_type&& __key, _Args&&... __args) { return __try_emplace_hint(__hint, std::move(__key), std::forward<_Args>(__args)...).first; } template requires __is_compare_transparent && is_constructible_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __hint, _Kp&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + try_emplace(const_iterator __hint, _Kp&& __key, _Args&&... __args) { return __try_emplace_hint(__hint, std::forward<_Kp>(__key), std::forward<_Args>(__args)...).first; } template requires is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair insert_or_assign(const key_type& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + insert_or_assign(const key_type& __key, _Mapped&& __obj) { return __insert_or_assign(__key, std::forward<_Mapped>(__obj)); } template requires is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair insert_or_assign(key_type&& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + insert_or_assign(key_type&& __key, _Mapped&& __obj) { return __insert_or_assign(std::move(__key), std::forward<_Mapped>(__obj)); } template requires __is_compare_transparent && is_constructible_v && is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI pair insert_or_assign(_Kp&& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + insert_or_assign(_Kp&& __key, _Mapped&& __obj) { return __insert_or_assign(std::forward<_Kp>(__key), std::forward<_Mapped>(__obj)); } template requires is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __hint, const key_type& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + insert_or_assign(const_iterator __hint, const key_type& __key, _Mapped&& __obj) { return __insert_or_assign(__hint, __key, std::forward<_Mapped>(__obj)); } template requires is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __hint, key_type&& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + insert_or_assign(const_iterator __hint, key_type&& __key, _Mapped&& __obj) { return __insert_or_assign(__hint, std::move(__key), std::forward<_Mapped>(__obj)); } template requires __is_compare_transparent && is_constructible_v && is_assignable_v && is_constructible_v - _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __obj) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __obj) { return __insert_or_assign(__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__obj)); } - _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 __iter = find(__x); if (__iter != end()) { erase(__iter); @@ -680,14 +723,14 @@ class flat_map { 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_); @@ -695,7 +738,7 @@ class flat_map { return iterator(std::move(__key_it), std::move(__mapped_it)); } - _LIBCPP_HIDE_FROM_ABI void swap(flat_map& __y) noexcept { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __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. @@ -705,133 +748,156 @@ class flat_map { 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 { return contains(__x) ? 1 : 0; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __x) const { + return contains(__x) ? 1 : 0; + } template requires __is_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 { return contains(__x) ? 1 : 0; } - _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __x) const { return find(__x) != end(); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __x) const { + return find(__x) != end(); + } template requires __is_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_map& __x, const flat_map& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator==(const flat_map& __x, const flat_map& __y) { return ranges::equal(__x, __y); } - friend _LIBCPP_HIDE_FROM_ABI auto operator<=>(const flat_map& __x, const flat_map& __y) { + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto + operator<=>(const flat_map& __x, const flat_map& __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_map& __x, flat_map& __y) noexcept { __x.swap(__y); } + friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(flat_map& __x, flat_map& __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_map(__ctor_uses_allocator_tag, - const _Allocator& __alloc, - _KeyCont&& __key_cont, - _MappedCont&& __mapped_cont, - _CompArg&&... __comp) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 flat_map( + __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( @@ -840,12 +906,13 @@ class flat_map { template requires __allocator_ctor_constraint<_Allocator> - _LIBCPP_HIDE_FROM_ABI flat_map(__ctor_uses_allocator_empty_tag, const _Allocator& __alloc, _CompArg&&... __comp) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + flat_map(__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_and_unique(auto&& __key_container) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_sorted_and_unique(auto&& __key_container) const { auto __greater_or_equal_to = [this](const auto& __x, const auto& __y) { return !__compare_(__x, __y); }; return ranges::adjacent_find(__key_container, __greater_or_equal_to) == ranges::end(__key_container); } @@ -853,7 +920,7 @@ class flat_map { // This function is only used in constructors. So there is not exception handling in this function. // If the function exits via an exception, there will be no flat_map object constructed, thus, there // is no invariant state to preserve - _LIBCPP_HIDE_FROM_ABI void __sort_and_unique() { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __sort_and_unique() { auto __zv = ranges::views::zip(__containers_.keys, __containers_.values); ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); }); auto __dup_start = ranges::unique(__zv, __key_equiv(__compare_)).begin(); @@ -870,7 +937,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI void __append_sort_merge_unique(_InputIterator __first, _Sentinel __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void + __append_sort_merge_unique(_InputIterator __first, _Sentinel __last) { auto __on_failure = std::__make_exception_guard([&]() noexcept { clear() /* noexcept */; }); size_t __num_of_appended = __flat_map_utils::__append(*this, std::move(__first), std::move(__last)); if (__num_of_appended != 0) { @@ -898,7 +966,7 @@ class flat_map { } 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)) { @@ -908,7 +976,7 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI static auto __key_equal_range(_Self&& __self, const _Kp& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto __key_equal_range(_Self&& __self, const _Kp& __key) { auto __it = std::lower_bound(__self.__containers_.keys.begin(), __self.__containers_.keys.end(), __key, __self.__compare_); auto __last = __self.__containers_.keys.end(); @@ -919,7 +987,7 @@ class flat_map { } 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] = __key_equal_range(__self, __key); using __iterator_type = ranges::iterator_t; return std::make_pair(__iterator_type(__key_first, __corresponding_mapped_it(__self, __key_first)), @@ -927,7 +995,7 @@ class flat_map { } 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); @@ -935,7 +1003,7 @@ class flat_map { } 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); @@ -943,7 +1011,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI pair __try_emplace(_KeyArg&& __key, _MArgs&&... __mapped_args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + __try_emplace(_KeyArg&& __key, _MArgs&&... __mapped_args) { auto __key_it = std::lower_bound(__containers_.keys.begin(), __containers_.keys.end(), __key, __compare_); auto __mapped_it = __containers_.values.begin() + ranges::distance(__containers_.keys.begin(), __key_it); @@ -962,7 +1031,7 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI bool __is_hint_correct(const_iterator __hint, _Kp&& __key) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __is_hint_correct(const_iterator __hint, _Kp&& __key) { if (__hint != cbegin() && !__compare_((__hint - 1)->first, __key)) { return false; } @@ -973,7 +1042,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI pair __try_emplace_hint(const_iterator __hint, _Kp&& __key, _Args&&... __args) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + __try_emplace_hint(const_iterator __hint, _Kp&& __key, _Args&&... __args) { if (__is_hint_correct(__hint, __key)) { if (__hint == cend() || __compare_(__key, __hint->first)) { return {__flat_map_utils::__emplace_exact_pos( @@ -994,7 +1064,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI pair __insert_or_assign(_Kp&& __key, _Mapped&& __mapped) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair + __insert_or_assign(_Kp&& __key, _Mapped&& __mapped) { auto __r = try_emplace(std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped)); if (!__r.second) { __r.first->second = std::forward<_Mapped>(__mapped); @@ -1003,7 +1074,8 @@ class flat_map { } template - _LIBCPP_HIDE_FROM_ABI iterator __insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __mapped) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator + __insert_or_assign(const_iterator __hint, _Kp&& __key, _Mapped&& __mapped) { auto __r = __try_emplace_hint(__hint, std::forward<_Kp>(__key), std::forward<_Mapped>(__mapped)); if (!__r.second) { __r.first->second = std::forward<_Mapped>(__mapped); @@ -1011,7 +1083,7 @@ class flat_map { return __r.first; } - _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); } @@ -1022,7 +1094,8 @@ class flat_map { } 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); @@ -1032,7 +1105,8 @@ class flat_map { template friend typename flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>::size_type - erase_if(flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate); + _LIBCPP_CONSTEXPR_SINCE_CXX26 + erase_if(flat_map<_Key2, _Tp2, _Compare2, _KeyContainer2, _MappedContainer2>&, _Predicate); friend __flat_map_utils; @@ -1040,8 +1114,9 @@ class flat_map { _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_; @@ -1164,8 +1239,9 @@ struct uses_allocator && uses_allocator_v<_MappedContainer, _Allocator>> {}; template -_LIBCPP_HIDE_FROM_ABI typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type -erase_if(flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_map, _Predicate __pred) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + typename flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type + erase_if(flat_map<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_map, _Predicate __pred) { auto __zv = ranges::views::zip(__flat_map.__containers_.keys, __flat_map.__containers_.values); auto __first = __zv.begin(); auto __last = __zv.end(); diff --git a/libcxx/include/__flat_map/key_value_iterator.h b/libcxx/include/__flat_map/key_value_iterator.h index 3ebb653deb197..f163dfc28706d 100644 --- a/libcxx/include/__flat_map/key_value_iterator.h +++ b/libcxx/include/__flat_map/key_value_iterator.h @@ -46,7 +46,7 @@ struct __key_value_iterator { struct __arrow_proxy { __reference __ref_; - _LIBCPP_HIDE_FROM_ABI __reference* operator->() { return std::addressof(__ref_); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __reference* operator->() { return std::addressof(__ref_); } }; __key_iterator __key_iter_; @@ -69,99 +69,113 @@ struct __key_value_iterator { _LIBCPP_HIDE_FROM_ABI __key_value_iterator() = default; - _LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i) requires _Const && convertible_to && convertible_to : __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {} - _LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + __key_value_iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter) : __key_iter_(std::move(__key_iter)), __mapped_iter_(std::move(__mapped_iter)) {} - _LIBCPP_HIDE_FROM_ABI __reference operator*() const { return __reference(*__key_iter_, *__mapped_iter_); } - _LIBCPP_HIDE_FROM_ABI __arrow_proxy operator->() const { return __arrow_proxy{**this}; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __reference operator*() const { + return __reference(*__key_iter_, *__mapped_iter_); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __arrow_proxy operator->() const { return __arrow_proxy{**this}; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator++() { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator++() { ++__key_iter_; ++__mapped_iter_; return *this; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator operator++(int) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator operator++(int) { __key_value_iterator __tmp(*this); ++*this; return __tmp; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator--() { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator--() { --__key_iter_; --__mapped_iter_; return *this; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator operator--(int) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator operator--(int) { __key_value_iterator __tmp(*this); --*this; return __tmp; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator+=(difference_type __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator+=(difference_type __x) { __key_iter_ += __x; __mapped_iter_ += __x; return *this; } - _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator-=(difference_type __x) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __key_value_iterator& operator-=(difference_type __x) { __key_iter_ -= __x; __mapped_iter_ -= __x; return *this; } - _LIBCPP_HIDE_FROM_ABI __reference operator[](difference_type __n) const { return *(*this + __n); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __reference operator[](difference_type __n) const { + return *(*this + __n); + } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool operator==(const __key_value_iterator& __x, const __key_value_iterator& __y) { return __x.__key_iter_ == __y.__key_iter_; } - _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool + operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) { return __x.__key_iter_ < __y.__key_iter_; } - _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool + operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) { return __y < __x; } - _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool + operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) { return !(__y < __x); } - _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend bool + operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) { return !(__x < __y); } - _LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend auto + operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y) requires three_way_comparable<__key_iterator> { return __x.__key_iter_ <=> __y.__key_iter_; } - _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(const __key_value_iterator& __i, difference_type __n) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend __key_value_iterator + operator+(const __key_value_iterator& __i, difference_type __n) { auto __tmp = __i; __tmp += __n; return __tmp; } - _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(difference_type __n, const __key_value_iterator& __i) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend __key_value_iterator + operator+(difference_type __n, const __key_value_iterator& __i) { return __i + __n; } - _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator-(const __key_value_iterator& __i, difference_type __n) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend __key_value_iterator + operator-(const __key_value_iterator& __i, difference_type __n) { auto __tmp = __i; __tmp -= __n; return __tmp; } - _LIBCPP_HIDE_FROM_ABI friend difference_type + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend difference_type operator-(const __key_value_iterator& __x, const __key_value_iterator& __y) { return difference_type(__x.__key_iter_ - __y.__key_iter_); } diff --git a/libcxx/include/__flat_map/utils.h b/libcxx/include/__flat_map/utils.h index acb7dca7ffe96..27687ae8de3bc 100644 --- a/libcxx/include/__flat_map/utils.h +++ b/libcxx/include/__flat_map/utils.h @@ -35,7 +35,7 @@ struct __flat_map_utils { // roll back the changes it made to the map. If it cannot roll back the changes, it will // clear the map. template - _LIBCPP_HIDE_FROM_ABI static typename _Map::iterator __emplace_exact_pos( + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static typename _Map::iterator __emplace_exact_pos( _Map& __map, _IterK&& __it_key, _IterM&& __it_mapped, _KeyArg&& __key, _MArgs&&... __mapped_args) { auto __on_key_failed = std::__make_exception_guard([&]() noexcept { using _KeyContainer = typename _Map::key_container_type; @@ -82,7 +82,7 @@ struct __flat_map_utils { // TODO: We could optimize this, see // https://github.com/llvm/llvm-project/issues/108624 template - _LIBCPP_HIDE_FROM_ABI static typename _Map::size_type + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static typename _Map::size_type __append(_Map& __map, _InputIterator __first, _Sentinel __last) { typename _Map::size_type __num_appended = 0; for (; __first != __last; ++__first) { diff --git a/libcxx/test/std/containers/Emplaceable.h b/libcxx/test/std/containers/Emplaceable.h index 246d5b255d6b1..f2aec0fd5f25d 100644 --- a/libcxx/test/std/containers/Emplaceable.h +++ b/libcxx/test/std/containers/Emplaceable.h @@ -24,11 +24,11 @@ class Emplaceable { public: TEST_CONSTEXPR Emplaceable() : int_(0), double_(0) {} TEST_CONSTEXPR Emplaceable(int i, double d) : int_(i), double_(d) {} - TEST_CONSTEXPR_CXX14 Emplaceable(Emplaceable&& x) : int_(x.int_), double_(x.double_) { + TEST_CONSTEXPR Emplaceable(Emplaceable&& x) : int_(x.int_), double_(x.double_) { x.int_ = 0; x.double_ = 0; } - TEST_CONSTEXPR_CXX14 Emplaceable& operator=(Emplaceable&& x) { + TEST_CONSTEXPR Emplaceable& operator=(Emplaceable&& x) { int_ = x.int_; x.int_ = 0; double_ = x.double_; diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at.pass.cpp index d30055bf1701c..bb4dd6453dd94 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at.pass.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "MinSequenceContainer.h" @@ -25,7 +26,7 @@ #include "test_macros.h" template -void test() { +constexpr void test() { using P = std::pair; P ar[] = { P(1, 1.5), @@ -49,10 +50,12 @@ void test() { assert(m.at(4) == 4.5); assert(m.at(5) == 5.5); #ifndef TEST_HAS_NO_EXCEPTIONS - try { - TEST_IGNORE_NODISCARD m.at(6); - assert(false); - } catch (std::out_of_range&) { + if (!std::is_constant_evaluated()) { + try { + TEST_IGNORE_NODISCARD m.at(6); + assert(false); + } catch (std::out_of_range&) { + } } #endif assert(m.at(7) == 7.5); @@ -70,10 +73,12 @@ void test() { assert(m.at(4) == 4.5); assert(m.at(5) == 5.5); #ifndef TEST_HAS_NO_EXCEPTIONS - try { - TEST_IGNORE_NODISCARD m.at(6); - assert(false); - } catch (std::out_of_range&) { + if (!std::is_constant_evaluated()) { + try { + TEST_IGNORE_NODISCARD m.at(6); + assert(false); + } catch (std::out_of_range&) { + } } #endif assert(m.at(7) == 7.5); @@ -82,11 +87,25 @@ void test() { } } -int main(int, char**) { +constexpr bool test() { test, std::vector>(); - test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!std::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.map/flat.map.access/at_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp index bc3fbfca5762b..1f84415c77ca4 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/at_transparent.pass.cpp @@ -35,7 +35,7 @@ static_assert(!CanAt); static_assert(!CanAt); template -void test() { +constexpr void test() { using P = std::pair; P ar[] = { P(1, 1.5), @@ -60,10 +60,12 @@ void test() { assert(m.at(Transparent{4}) == 4.5); assert(m.at(Transparent{5}) == 5.5); #ifndef TEST_HAS_NO_EXCEPTIONS - try { - TEST_IGNORE_NODISCARD m.at(Transparent{6}); - assert(false); - } catch (std::out_of_range&) { + if (!std::is_constant_evaluated()) { + try { + TEST_IGNORE_NODISCARD m.at(Transparent{6}); + assert(false); + } catch (std::out_of_range&) { + } } #endif assert(m.at(Transparent{7}) == 7.5); @@ -81,10 +83,12 @@ void test() { assert(m.at(Transparent{4}) == 4.5); assert(m.at(Transparent{5}) == 5.5); #ifndef TEST_HAS_NO_EXCEPTIONS - try { - TEST_IGNORE_NODISCARD m.at(Transparent{6}); - assert(false); - } catch (std::out_of_range&) { + if (!std::is_constant_evaluated()) { + try { + TEST_IGNORE_NODISCARD m.at(Transparent{6}); + assert(false); + } catch (std::out_of_range&) { + } } #endif assert(m.at(Transparent{7}) == 7.5); @@ -93,9 +97,14 @@ void test() { } } -int main(int, char**) { +constexpr bool test() { test, std::vector>(); - test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!std::is_constant_evaluated()) +#endif + { + test, std::vector>(); + } test, MinSequenceContainer>(); test>, std::vector>>(); { @@ -114,5 +123,14 @@ int main(int, char**) { assert(x == 1); } + 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.map/flat.map.access/index_key.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_key.pass.cpp index ea2f5d800878a..a7d613de399ed 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_key.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_key.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "MinSequenceContainer.h" @@ -31,7 +32,7 @@ static_assert(CanIndex, const int&>); static_assert(!CanIndex, const int&>); template -void test() { +constexpr void test() { using P = std::pair; P ar[] = { P(1, 1.5), @@ -58,13 +59,18 @@ void test() { assert(m.size() == 8); } -int main(int, char**) { +constexpr bool test() { test, std::vector>(); - test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!std::is_constant_evaluated()) +#endif + { + test, std::vector>(); + } test, MinSequenceContainer>(); test>, std::vector>>(); - { + if (!std::is_constant_evaluated()) { auto index_func = [](auto& m, auto key_arg, auto value_arg) { using FlatMap = std::decay_t; const typename FlatMap::key_type key = key_arg; @@ -73,5 +79,16 @@ int main(int, char**) { }; test_emplace_exception_guarantee(index_func); } + + 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.map/flat.map.access/index_rv_key.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_rv_key.pass.cpp index faacc3cfe8f96..4843e7c63b15c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_rv_key.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_rv_key.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "MinSequenceContainer.h" #include "../helpers.h" @@ -31,7 +32,7 @@ static_assert(CanIndex, int&&>); static_assert(!CanIndex, int&&>); template -void test() { +constexpr void test() { { std::flat_map, KeyContainer, ValueContainer> m; ASSERT_SAME_TYPE(decltype(m[MoveOnly{}]), double&); @@ -49,13 +50,18 @@ void test() { } } -int main(int, char**) { +constexpr bool test() { test, std::vector>(); - test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!std::is_constant_evaluated()) +#endif + { + test, std::vector>(); + } test, MinSequenceContainer>(); test>, std::vector>>(); - { + if (!std::is_constant_evaluated()) { auto index_func = [](auto& m, auto key_arg, auto value_arg) { using FlatMap = std::decay_t; typename FlatMap::key_type key = key_arg; @@ -64,5 +70,14 @@ int main(int, char**) { }; test_emplace_exception_guarantee(index_func); } + 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.map/flat.map.access/index_transparent.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp index 760ec69ae878d..8e012aace0164 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.access/index_transparent.pass.cpp @@ -50,7 +50,7 @@ static_assert(!CanIndex); static_assert(!CanIndex); template -void test() { +constexpr void test() { using P = std::pair; P ar[] = { P(1, 1.5), @@ -81,11 +81,17 @@ void test() { } } -int main(int, char**) { +constexpr bool test() { test, std::vector>(); - test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!std::is_constant_evaluated()) +#endif + { + test, std::vector>(); + } test, MinSequenceContainer>(); test>, std::vector>>(); + { bool transparent_used = false; TransparentComparator c(transparent_used); @@ -101,7 +107,8 @@ int main(int, char**) { int& x = m["alpha"]; assert(x == 1); } - { + + if (!std::is_constant_evaluated()) { auto index_func = [](auto& m, auto key_arg, auto value_arg) { using FlatMap = std::decay_t; using Key = typename FlatMap::key_type; @@ -110,5 +117,15 @@ int main(int, char**) { }; test_emplace_exception_guarantee(index_func); } + + 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.map/flat.map.capacity/empty.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.capacity/empty.pass.cpp index 05efe063c1e17..8027cab4b4260 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.capacity/empty.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.capacity/empty.pass.cpp @@ -24,10 +24,10 @@ #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>; + using M = std::flat_map, KeyContainer, ValueContainer>; M m; ASSERT_SAME_TYPE(decltype(m.empty()), bool); ASSERT_NOEXCEPT(m.empty()); @@ -39,11 +39,25 @@ void test() { assert(m.empty()); } -int main(int, char**) { +constexpr bool test() { test, std::vector>(); - test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!std::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.map/flat.map.capacity/max_size.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.capacity/max_size.pass.cpp index 87acdfd2cf625..ee01f8eb1dfe4 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.capacity/max_size.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.capacity/max_size.pass.cpp @@ -24,7 +24,7 @@ #include "test_allocator.h" #include "test_macros.h" -int main(int, char**) { +constexpr bool test() { { using A1 = limited_allocator; using A2 = limited_allocator; @@ -72,5 +72,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.map/flat.map.capacity/size.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.capacity/size.pass.cpp index 957a860450091..08cfb0e9da062 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.capacity/size.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.capacity/size.pass.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "MinSequenceContainer.h" @@ -23,7 +24,7 @@ #include "min_allocator.h" template -void test() { +constexpr void test() { using M = std::flat_map, KeyContainer, ValueContainer>; { const M m = {{1, 'a'}, {1, 'b'}, {4, 'd'}, {5, 'e'}, {5, 'h'}}; @@ -45,7 +46,7 @@ void test() { } { M m; - std::size_t s = 1000000; + std::size_t s = std::is_constant_evaluated() ? 100 : 1000000; for (auto i = 0u; i < s; ++i) { m.emplace(i, 'a'); } @@ -55,11 +56,25 @@ void test() { } } -int main(int, char**) { +constexpr bool test() { test, std::vector>(); - test, std::vector>(); +#ifndef __cpp_lib_constexpr_deque + if (!std::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.map/flat.map.cons/alloc.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/alloc.pass.cpp index 3f8d2ed332d6b..54dbe2309c43c 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/alloc.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/alloc.pass.cpp @@ -14,6 +14,7 @@ // explicit flat_map(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