[libcxx-commits] [libcxx] 6e6c51b - [libc++] Make `<map>` `std::map` constexpr as part of P3372R3 (#134330)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jun 3 01:00:02 PDT 2026
Author: Vinay Deshmukh
Date: 2026-06-03T09:59:57+02:00
New Revision: 6e6c51be667e95ee456efdc6d28b2184ceb6ed32
URL: https://github.com/llvm/llvm-project/commit/6e6c51be667e95ee456efdc6d28b2184ceb6ed32
DIFF: https://github.com/llvm/llvm-project/commit/6e6c51be667e95ee456efdc6d28b2184ceb6ed32.diff
LOG: [libc++] Make `<map>` `std::map` constexpr as part of P3372R3 (#134330)
Fixes https://github.com/llvm/llvm-project/issues/128660
Adds `constexpr` support for `std::map` as per P3372R3
---------
Co-authored-by: A. Jiang <de34 at live.cn>
Added:
libcxx/test/support/CopyConstructible.h
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/include/__iterator/erase_if_container.h
libcxx/include/__node_handle
libcxx/include/__tree
libcxx/include/__type_traits/make_transparent.h
libcxx/include/__utility/default_three_way_comparator.h
libcxx/include/__utility/lazy_synth_three_way_comparator.h
libcxx/include/__utility/try_key_extraction.h
libcxx/include/map
libcxx/include/version
libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/for_each.associative.pass.cpp
libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/ranges.for_each.associative.pass.cpp
libcxx/test/std/containers/associative/from_range_associative_containers.h
libcxx/test/std/containers/associative/map/compare.pass.cpp
libcxx/test/std/containers/associative/map/get_allocator.pass.cpp
libcxx/test/std/containers/associative/map/incomplete_type.pass.cpp
libcxx/test/std/containers/associative/map/map.access/at.pass.cpp
libcxx/test/std/containers/associative/map/map.access/empty.pass.cpp
libcxx/test/std/containers/associative/map/map.access/index_key.pass.cpp
libcxx/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
libcxx/test/std/containers/associative/map/map.access/index_tuple.pass.cpp
libcxx/test/std/containers/associative/map/map.access/iterator.pass.cpp
libcxx/test/std/containers/associative/map/map.access/max_size.pass.cpp
libcxx/test/std/containers/associative/map/map.access/size.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/alloc.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/compare.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/copy.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/deduct.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/deduct_const.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/default.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/default_noexcept.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/from_range.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/initializer_list.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/initializer_list_compare.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/iter_iter.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/move.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/move_assign.pass.cpp
libcxx/test/std/containers/associative/map/map.cons/move_noexcept.pass.cpp
libcxx/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/clear.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/emplace.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/emplace_hint.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/erase_iter.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/erase_key.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/extract_iterator.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/extract_key.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_cv.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type_hint.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_or_assign.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_range.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/insert_rv.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
libcxx/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp
libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.pass.cpp
libcxx/test/std/containers/associative/map/map.nonmember/op_compare.pass.cpp
libcxx/test/std/containers/associative/map/map.observers/key_comp.pass.cpp
libcxx/test/std/containers/associative/map/map.observers/value_comp.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/contains.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/count.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/equal_range.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/find.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/lower_bound.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/upper_bound.pass.cpp
libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
libcxx/test/std/containers/associative/map/map.special/member_swap.pass.cpp
libcxx/test/std/containers/associative/map/map.special/non_member_swap.pass.cpp
libcxx/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp
libcxx/test/std/containers/associative/map/map.value_compare/invoke.pass.cpp
libcxx/test/std/containers/associative/map/types.pass.cpp
libcxx/test/std/containers/container.node/node_handle.pass.cpp
libcxx/test/std/containers/insert_range_maps_sets.h
libcxx/test/std/language.support/support.limits/support.limits.general/map.version.compile.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
libcxx/test/support/is_transparent.h
libcxx/test/support/private_constructor.h
libcxx/utils/generate_feature_test_macro_components.py
Removed:
################################################################################
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 4eb15fa0eb131..1b748e37293df 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -444,6 +444,8 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_constexpr_list`` ``202502L``
---------------------------------------------------------- -----------------
+ ``__cpp_lib_constexpr_map`` ``202502L``
+ ---------------------------------------------------------- -----------------
``__cpp_lib_constexpr_new`` ``202406L``
---------------------------------------------------------- -----------------
``__cpp_lib_constexpr_queue`` ``202502L``
diff --git a/libcxx/include/__iterator/erase_if_container.h b/libcxx/include/__iterator/erase_if_container.h
index 0f87f50cd1c16..8d92d3f1b9dbe 100644
--- a/libcxx/include/__iterator/erase_if_container.h
+++ b/libcxx/include/__iterator/erase_if_container.h
@@ -22,7 +22,8 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Container, class _Predicate>
-_LIBCPP_HIDE_FROM_ABI typename _Container::size_type __libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 typename _Container::size_type
+__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) {
typename _Container::size_type __old_size = __c.size();
const typename _Container::iterator __last = __c.end();
diff --git a/libcxx/include/__node_handle b/libcxx/include/__node_handle
index 50f8b5bc79107..789f2b5f9a52f 100644
--- a/libcxx/include/__node_handle
+++ b/libcxx/include/__node_handle
@@ -31,29 +31,29 @@ private:
public:
// [container.node.cons], constructors, copy, and assignment
constexpr node-handle() noexcept : ptr_(), alloc_() {}
- node-handle(node-handle&&) noexcept;
- node-handle& operator=(node-handle&&);
+ constexpr node-handle(node-handle&&) noexcept; // constexpr since C++26
+ constexpr node-handle& operator=(node-handle&&); // constexpr since C++26
// [container.node.dtor], destructor
- ~node-handle();
+ constexpr ~node-handle(); // constexpr since C++26
// [container.node.observers], observers
- value_type& value() const; // not present for map containers
- key_type& key() const; // not present for set containers
- mapped_type& mapped() const; // not present for set containers
+ value_type& value() const; // not present for map containers
+ key_type& key() const; // not present for set containers
+ constexpr mapped_type& mapped() const; // not present for set containers, constexpr since C++26
- allocator_type get_allocator() const;
- explicit operator bool() const noexcept;
- [[nodiscard]] bool empty() const noexcept; // nodiscard since C++20
+ constexpr allocator_type get_allocator() const; // constexpr since C++26
+ constexpr explicit operator bool() const noexcept; // constexpr since C++26
+ [[nodiscard]] constexpr bool empty() const noexcept; // nodiscard since C++20, constexpr since C++26
// [container.node.modifiers], modifiers
- void swap(node-handle&)
+ constexpr void swap(node-handle&)
noexcept(ator_traits::propagate_on_container_swap::value ||
- ator_traits::is_always_equal::value);
+ ator_traits::is_always_equal::value); // constexpr since C++26
- friend void swap(node-handle& x, node-handle& y) noexcept(noexcept(x.swap(y))) {
+ constexpr friend void swap(node-handle& x, node-handle& y) noexcept(noexcept(x.swap(y))) {
x.swap(y);
- }
+ } // constexpr since C++26
};
*/
@@ -100,12 +100,12 @@ private:
__node_pointer_type __ptr_ = nullptr;
optional<allocator_type> __alloc_;
- _LIBCPP_HIDE_FROM_ABI void __release_ptr() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __release_ptr() {
__ptr_ = nullptr;
__alloc_ = std::nullopt;
}
- _LIBCPP_HIDE_FROM_ABI void __destroy_node_pointer() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __destroy_node_pointer() {
if (__ptr_ != nullptr) {
typedef typename __allocator_traits_rebind< allocator_type, _NodeType>::type __node_alloc_type;
__node_alloc_type __alloc(*__alloc_);
@@ -114,16 +114,17 @@ private:
}
}
- _LIBCPP_HIDE_FROM_ABI __basic_node_handle(__node_pointer_type __ptr, allocator_type const& __alloc)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
+ __basic_node_handle(__node_pointer_type __ptr, allocator_type const& __alloc)
: __ptr_(__ptr), __alloc_(__alloc) {}
public:
- _LIBCPP_HIDE_FROM_ABI __basic_node_handle() = default;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __basic_node_handle() = default;
- _LIBCPP_HIDE_FROM_ABI __basic_node_handle(__basic_node_handle&& __other) noexcept
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __basic_node_handle(__basic_node_handle&& __other) noexcept
: __ptr_(std::exchange(__other.__ptr_, nullptr)), __alloc_(std::exchange(__other.__alloc_, std::nullopt)) {}
- _LIBCPP_HIDE_FROM_ABI __basic_node_handle& operator=(__basic_node_handle&& __other) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __basic_node_handle& operator=(__basic_node_handle&& __other) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
__alloc_ == std::nullopt || __alloc_traits::propagate_on_container_move_assignment::value ||
__alloc_ == __other.__alloc_,
@@ -141,13 +142,13 @@ public:
return *this;
}
- _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const { return *__alloc_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 allocator_type get_allocator() const { return *__alloc_; }
- _LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return __ptr_ != nullptr; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit operator bool() const { return __ptr_ != nullptr; }
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool empty() const { return __ptr_ == nullptr; }
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const { return __ptr_ == nullptr; }
- _LIBCPP_HIDE_FROM_ABI void swap(__basic_node_handle& __other) noexcept(
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(__basic_node_handle& __other) noexcept(
__alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value) {
using std::swap;
swap(__ptr_, __other.__ptr_);
@@ -156,12 +157,12 @@ public:
swap(__alloc_, __other.__alloc_);
}
- _LIBCPP_HIDE_FROM_ABI friend void
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 friend void
swap(__basic_node_handle& __a, __basic_node_handle& __b) noexcept(noexcept(__a.swap(__b))) {
__a.swap(__b);
}
- _LIBCPP_HIDE_FROM_ABI ~__basic_node_handle() { __destroy_node_pointer(); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 ~__basic_node_handle() { __destroy_node_pointer(); }
};
template <class _NodeType, class _Derived>
@@ -176,6 +177,7 @@ struct __map_node_handle_specifics {
using key_type = __remove_const_t<typename _NodeType::__node_value_type::first_type>;
using mapped_type = typename _NodeType::__node_value_type::second_type;
+ // This method is not constexpr as per the standard.
_LIBCPP_HIDE_FROM_ABI key_type& key() const {
return const_cast<key_type&>(static_cast<_Derived const*>(this)->__ptr_->__get_value().first);
}
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 5a81534156293..94c88e273870a 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -113,7 +113,7 @@ __root, have a non-null __parent_ field.
// Returns: true if __x is a left child of its parent, else false
// Precondition: __x != nullptr.
template <class _NodePtr>
-inline _LIBCPP_HIDE_FROM_ABI bool __tree_is_left_child(_NodePtr __x) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __tree_is_left_child(_NodePtr __x) _NOEXCEPT {
return __x == __x->__parent_->__left_;
}
@@ -121,7 +121,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool __tree_is_left_child(_NodePtr __x) _NOEXCEPT {
// __x is a proper subtree, returns the black height (null counts as 1). If
// __x is an improper subtree, returns 0.
template <class _NodePtr>
-unsigned __tree_sub_invariant(_NodePtr __x) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 unsigned __tree_sub_invariant(_NodePtr __x) {
if (__x == nullptr)
return 1;
// parent consistency checked by caller
@@ -153,7 +153,7 @@ unsigned __tree_sub_invariant(_NodePtr __x) {
// __root == nullptr is a proper tree. Returns true if __root is a proper
// red black tree, else returns false.
template <class _NodePtr>
-_LIBCPP_HIDE_FROM_ABI bool __tree_invariant(_NodePtr __root) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __tree_invariant(_NodePtr __root) {
if (__root == nullptr)
return true;
// check __x->__parent_ consistency
@@ -170,7 +170,7 @@ _LIBCPP_HIDE_FROM_ABI bool __tree_invariant(_NodePtr __root) {
// Returns: pointer to the left-most node under __x.
template <class _NodePtr>
-inline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_min(_NodePtr __x) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _NodePtr __tree_min(_NodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null");
while (__x->__left_ != nullptr)
__x = __x->__left_;
@@ -179,7 +179,7 @@ inline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_min(_NodePtr __x) _NOEXCEPT {
// Returns: pointer to the right-most node under __x.
template <class _NodePtr>
-inline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_max(_NodePtr __x) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _NodePtr __tree_max(_NodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null");
while (__x->__right_ != nullptr)
__x = __x->__right_;
@@ -188,7 +188,7 @@ inline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_max(_NodePtr __x) _NOEXCEPT {
// Returns: pointer to the next in-order node after __x.
template <class _NodePtr>
-_LIBCPP_HIDE_FROM_ABI _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
if (__x->__right_ != nullptr)
return std::__tree_min(__x->__right_);
@@ -203,7 +203,7 @@ _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT {
// to the actual root of the tree through a __left_ pointer. Incrementing the end() pointer is UB, so we can assume that
// never happens.
template <class _EndNodePtr, class _NodePtr>
-inline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
if (__x->__right_ != nullptr)
return std::__static_fancy_pointer_cast<_EndNodePtr>(std::__tree_min(__x->__right_));
@@ -215,7 +215,7 @@ inline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEP
// Returns: pointer to the previous in-order node before __x.
// Note: __x may be the end node.
template <class _NodePtr, class _EndNodePtr>
-inline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_prev_iter(_EndNodePtr __x) _NOEXCEPT {
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _NodePtr __tree_prev_iter(_EndNodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
if (__x->__left_ != nullptr)
return std::__tree_max(__x->__left_);
@@ -227,7 +227,7 @@ inline _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_prev_iter(_EndNodePtr __x) _NOEXCEP
// Returns: pointer to a node which has no children
template <class _NodePtr>
-_LIBCPP_HIDE_FROM_ABI _NodePtr __tree_leaf(_NodePtr __x) _NOEXCEPT {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _NodePtr __tree_leaf(_NodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
while (true) {
if (__x->__left_ != nullptr) {
@@ -246,7 +246,7 @@ _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_leaf(_NodePtr __x) _NOEXCEPT {
// Effects: Makes __x->__right_ the subtree root with __x as its left child
// while preserving in-order order.
template <class _NodePtr>
-_LIBCPP_HIDE_FROM_ABI void __tree_left_rotate(_NodePtr __x) _NOEXCEPT {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree_left_rotate(_NodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
_LIBCPP_ASSERT_INTERNAL(__x->__right_ != nullptr, "node should have a right child");
_NodePtr __y = __x->__right_;
@@ -265,7 +265,7 @@ _LIBCPP_HIDE_FROM_ABI void __tree_left_rotate(_NodePtr __x) _NOEXCEPT {
// Effects: Makes __x->__left_ the subtree root with __x as its right child
// while preserving in-order order.
template <class _NodePtr>
-_LIBCPP_HIDE_FROM_ABI void __tree_right_rotate(_NodePtr __x) _NOEXCEPT {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree_right_rotate(_NodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
_LIBCPP_ASSERT_INTERNAL(__x->__left_ != nullptr, "node should have a left child");
_NodePtr __y = __x->__left_;
@@ -289,7 +289,8 @@ _LIBCPP_HIDE_FROM_ABI void __tree_right_rotate(_NodePtr __x) _NOEXCEPT {
// Postcondition: __tree_invariant(end_node->__left_) == true. end_node->__left_
// may be
diff erent than the value passed in as __root.
template <class _NodePtr>
-_LIBCPP_HIDE_FROM_ABI void __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+__tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root of the tree shouldn't be null");
_LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Can't attach null node to a leaf");
__x->__is_black_ = __x == __root;
@@ -345,7 +346,7 @@ _LIBCPP_HIDE_FROM_ABI void __tree_balance_after_insert(_NodePtr __root, _NodePtr
// nor any of its children refer to __z. end_node->__left_
// may be
diff erent than the value passed in as __root.
template <class _NodePtr>
-_LIBCPP_HIDE_FROM_ABI void __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT {
_LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root node should not be null");
_LIBCPP_ASSERT_INTERNAL(__z != nullptr, "The node to remove should not be null");
_LIBCPP_ASSERT_INTERNAL(std::__tree_invariant(__root), "The tree invariants should hold");
@@ -560,7 +561,7 @@ public:
using pointer = _Pointer;
pointer __left_;
- _LIBCPP_HIDE_FROM_ABI __tree_end_node() _NOEXCEPT : __left_() {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_end_node() _NOEXCEPT : __left_() {}
};
template <class _VoidPtr>
@@ -573,9 +574,11 @@ public:
__end_node_pointer __parent_;
bool __is_black_;
- _LIBCPP_HIDE_FROM_ABI pointer __parent_unsafe() const { return std::__static_fancy_pointer_cast<pointer>(__parent_); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pointer __parent_unsafe() const {
+ return std::__static_fancy_pointer_cast<pointer>(__parent_);
+ }
- _LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __p) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __set_parent(pointer __p) {
__parent_ = std::__static_fancy_pointer_cast<__end_node_pointer>(__p);
}
@@ -600,7 +603,7 @@ private:
};
public:
- _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_value_type& __get_value() { return __value_; }
#else
private:
@@ -611,9 +614,10 @@ public:
#endif
template <class _Alloc, class... _Args>
- _LIBCPP_HIDE_FROM_ABI explicit __tree_node(_Alloc& __na, _Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __tree_node(_Alloc& __na, _Args&&... __args) {
allocator_traits<_Alloc>::construct(__na, std::addressof(__get_value()), std::forward<_Args>(__args)...);
}
+
~__tree_node() = delete;
__tree_node(__tree_node const&) = delete;
__tree_node& operator=(__tree_node const&) = delete;
@@ -633,14 +637,15 @@ private:
public:
bool __value_constructed;
- _LIBCPP_HIDE_FROM_ABI __tree_node_destructor(const __tree_node_destructor&) = default;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_node_destructor(const __tree_node_destructor&) = default;
__tree_node_destructor& operator=(const __tree_node_destructor&) = delete;
- _LIBCPP_HIDE_FROM_ABI explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
+ _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT
: __na_(__na),
__value_constructed(__val) {}
- _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void operator()(pointer __p) _NOEXCEPT {
if (__value_constructed)
__alloc_traits::destroy(__na_, std::addressof(__p->__get_value()));
if (__p)
@@ -665,7 +670,8 @@ template <class _Reference, class _Break, class _NodePtr, class _Func, class _Pr
#ifndef _LIBCPP_COMPILER_GCC // This function is recursive, so GCC complains about always_inline.
_LIBCPP_HIDE_FROM_ABI
#endif
-bool __tree_iterate_from_root(_Break __break, _NodePtr __root, _Func& __func, _Proj& __proj) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+__tree_iterate_from_root(_Break __break, _NodePtr __root, _Func& __func, _Proj& __proj) {
if (__root->__left_) {
if (std::__tree_iterate_from_root<_Reference>(__break, static_cast<_NodePtr>(__root->__left_), __func, __proj))
return true;
@@ -680,7 +686,7 @@ bool __tree_iterate_from_root(_Break __break, _NodePtr __root, _Func& __func, _P
// Do an in-order traversal of the tree from __first to __last.
template <class _NodeIter, class _Func, class _Proj>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
__tree_iterate_subrange(_NodeIter __first_it, _NodeIter __last_it, _Func& __func, _Proj& __proj) {
using _NodePtr = typename _NodeIter::__node_pointer;
using _Reference = typename _NodeIter::reference;
@@ -724,45 +730,48 @@ public:
using reference = value_type&;
using pointer = __rebind_pointer_t<_NodePtr, value_type>;
- _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT : __ptr_(nullptr) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_iterator() _NOEXCEPT : __ptr_(nullptr) {}
- _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
- _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reference operator*() const { return __get_np()->__get_value(); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pointer operator->() const {
return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
}
- _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator++() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_iterator& operator++() {
__ptr_ = std::__tree_next_iter<__end_node_pointer>(std::__static_fancy_pointer_cast<__node_base_pointer>(__ptr_));
return *this;
}
- _LIBCPP_HIDE_FROM_ABI __tree_iterator operator++(int) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_iterator operator++(int) {
__tree_iterator __t(*this);
++(*this);
return __t;
}
- _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator--() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_iterator& operator--() {
__ptr_ = std::__static_fancy_pointer_cast<__end_node_pointer>(std::__tree_prev_iter<__node_base_pointer>(__ptr_));
return *this;
}
- _LIBCPP_HIDE_FROM_ABI __tree_iterator operator--(int) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_iterator operator--(int) {
__tree_iterator __t(*this);
--(*this);
return __t;
}
- friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __tree_iterator& __x, const __tree_iterator& __y) {
+ friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+ operator==(const __tree_iterator& __x, const __tree_iterator& __y) {
return __x.__ptr_ == __y.__ptr_;
}
- friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __tree_iterator& __x, const __tree_iterator& __y) {
+ friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+ operator!=(const __tree_iterator& __x, const __tree_iterator& __y) {
return !(__x == __y);
}
private:
- _LIBCPP_HIDE_FROM_ABI explicit __tree_iterator(__node_pointer __p) _NOEXCEPT
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __tree_iterator(__node_pointer __p) _NOEXCEPT
: __ptr_(std::__static_fancy_pointer_cast<__end_node_pointer>(__p)) {}
- _LIBCPP_HIDE_FROM_ABI explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
- _LIBCPP_HIDE_FROM_ABI __node_pointer __get_np() const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT
+ : __ptr_(__p) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer __get_np() const {
return std::__static_fancy_pointer_cast<__node_pointer>(__ptr_);
}
template <class, class, class>
@@ -771,7 +780,7 @@ private:
friend class __tree_const_iterator;
template <class _NodeIter, class _Func, class _Proj>
- friend void __tree_iterate_subrange(_NodeIter, _NodeIter, _Func&, _Proj&);
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 friend void __tree_iterate_subrange(_NodeIter, _NodeIter, _Func&, _Proj&);
};
#ifndef _LIBCPP_CXX03_LANG
@@ -785,7 +794,8 @@ struct __specialized_algorithm<
using __iterator _LIBCPP_NODEBUG = __tree_iterator<_Tp, _NodePtr, _DiffType>;
template <class _Func, class _Proj>
- _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void
+ operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) {
std::__tree_iterate_subrange(__first, __last, __func, __proj);
}
};
@@ -809,50 +819,53 @@ public:
using pointer = __rebind_pointer_t<_NodePtr, const value_type>;
using __non_const_iterator _LIBCPP_NODEBUG = __tree_iterator<_Tp, __node_pointer,
diff erence_type>;
- _LIBCPP_HIDE_FROM_ABI __tree_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_const_iterator() _NOEXCEPT : __ptr_(nullptr) {}
- _LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT
+ : __ptr_(__p.__ptr_) {}
- _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
- _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reference operator*() const { return __get_np()->__get_value(); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pointer operator->() const {
return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
}
- _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator++() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_const_iterator& operator++() {
__ptr_ = std::__tree_next_iter<__end_node_pointer>(std::__static_fancy_pointer_cast<__node_base_pointer>(__ptr_));
return *this;
}
- _LIBCPP_HIDE_FROM_ABI __tree_const_iterator operator++(int) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_const_iterator operator++(int) {
__tree_const_iterator __t(*this);
++(*this);
return __t;
}
- _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator--() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_const_iterator& operator--() {
__ptr_ = std::__static_fancy_pointer_cast<__end_node_pointer>(std::__tree_prev_iter<__node_base_pointer>(__ptr_));
return *this;
}
- _LIBCPP_HIDE_FROM_ABI __tree_const_iterator operator--(int) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_const_iterator operator--(int) {
__tree_const_iterator __t(*this);
--(*this);
return __t;
}
- friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y) {
+ friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+ operator==(const __tree_const_iterator& __x, const __tree_const_iterator& __y) {
return __x.__ptr_ == __y.__ptr_;
}
- friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y) {
+ friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+ operator!=(const __tree_const_iterator& __x, const __tree_const_iterator& __y) {
return !(__x == __y);
}
private:
- _LIBCPP_HIDE_FROM_ABI explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT
: __ptr_(std::__static_fancy_pointer_cast<__end_node_pointer>(__p)) {}
- _LIBCPP_HIDE_FROM_ABI explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT
: __ptr_(std::__static_fancy_pointer_cast<__end_node_pointer>(__p)) {}
- _LIBCPP_HIDE_FROM_ABI __node_pointer __get_np() const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer __get_np() const {
return std::__static_fancy_pointer_cast<__node_pointer>(__ptr_);
}
@@ -860,7 +873,7 @@ private:
friend class __tree;
template <class _NodeIter, class _Func, class _Proj>
- friend void __tree_iterate_subrange(_NodeIter, _NodeIter, _Func&, _Proj&);
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 friend void __tree_iterate_subrange(_NodeIter, _NodeIter, _Func&, _Proj&);
};
#ifndef _LIBCPP_CXX03_LANG
@@ -874,7 +887,8 @@ struct __specialized_algorithm<
using __iterator _LIBCPP_NODEBUG = __tree_const_iterator<_Tp, _NodePtr, _DiffType>;
template <class _Func, class _Proj>
- _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void
+ operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) {
std::__tree_iterate_subrange(__first, __last, __func, __proj);
}
};
@@ -936,55 +950,63 @@ private:
_LIBCPP_COMPRESSED_PAIR(size_type, __size_, value_compare, __value_comp_);
public:
- _LIBCPP_HIDE_FROM_ABI __end_node_pointer __end_node() _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __end_node_pointer __end_node() _NOEXCEPT {
return pointer_traits<__end_node_pointer>::pointer_to(__end_node_);
}
- _LIBCPP_HIDE_FROM_ABI __end_node_pointer __end_node() const _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __end_node_pointer __end_node() const _NOEXCEPT {
return pointer_traits<__end_node_pointer>::pointer_to(const_cast<__end_node_t&>(__end_node_));
}
- _LIBCPP_HIDE_FROM_ABI __node_allocator& __node_alloc() _NOEXCEPT { return __node_alloc_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_allocator& __node_alloc() _NOEXCEPT {
+ return __node_alloc_;
+ }
private:
- _LIBCPP_HIDE_FROM_ABI const __node_allocator& __node_alloc() const _NOEXCEPT { return __node_alloc_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const __node_allocator& __node_alloc() const _NOEXCEPT {
+ return __node_alloc_;
+ }
public:
- _LIBCPP_HIDE_FROM_ABI allocator_type __alloc() const _NOEXCEPT { return allocator_type(__node_alloc()); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 allocator_type __alloc() const _NOEXCEPT {
+ return allocator_type(__node_alloc());
+ }
- _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
- _LIBCPP_HIDE_FROM_ABI value_compare& value_comp() _NOEXCEPT { return __value_comp_; }
- _LIBCPP_HIDE_FROM_ABI const value_compare& value_comp() const _NOEXCEPT { return __value_comp_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const _NOEXCEPT { return __size_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare& value_comp() _NOEXCEPT { return __value_comp_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const value_compare& value_comp() const _NOEXCEPT {
+ return __value_comp_;
+ }
public:
- _LIBCPP_HIDE_FROM_ABI __node_pointer __root() const _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer __root() const _NOEXCEPT {
return std::__static_fancy_pointer_cast<__node_pointer>(__end_node()->__left_);
}
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer* __root_ptr() const _NOEXCEPT {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_base_pointer* __root_ptr() const _NOEXCEPT {
return std::addressof(__end_node()->__left_);
}
using iterator = __tree_iterator<_Tp, __node_pointer,
diff erence_type>;
using const_iterator = __tree_const_iterator<_Tp, __node_pointer,
diff erence_type>;
- _LIBCPP_HIDE_FROM_ABI explicit __tree(const value_compare& __comp) _NOEXCEPT_(
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __tree(const value_compare& __comp) _NOEXCEPT_(
is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_copy_constructible<value_compare>::value)
: __size_(0), __value_comp_(__comp) {
__begin_node_ = __end_node();
}
- _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __tree(const allocator_type& __a)
: __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0) {
__begin_node_ = __end_node();
}
- _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree(const value_compare& __comp, const allocator_type& __a)
: __begin_node_(), __node_alloc_(__node_allocator(__a)), __size_(0), __value_comp_(__comp) {
__begin_node_ = __end_node();
}
- _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree(const __tree& __t);
- _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __other, const allocator_type& __alloc)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree(const __tree& __other, const allocator_type& __alloc)
: __begin_node_(__end_node()), __node_alloc_(__alloc), __size_(0), __value_comp_(__other.value_comp()) {
if (__other.size() == 0)
return;
@@ -995,14 +1017,15 @@ public:
__size_ = __other.size();
}
- _LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree& operator=(const __tree& __t);
template <class _ForwardIterator>
- _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
- _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_(
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+ __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree(__tree&& __t) _NOEXCEPT_(
is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value);
- _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree(__tree&& __t, const allocator_type& __a);
- _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree& operator=(__tree&& __t)
_NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
((__node_traits::propagate_on_container_move_assignment::value &&
is_nothrow_move_assignable<__node_allocator>::value) ||
@@ -1014,23 +1037,27 @@ public:
return *this;
}
- _LIBCPP_HIDE_FROM_ABI ~__tree() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 ~__tree() {
static_assert(is_copy_constructible<value_compare>::value, "Comparator must be copy-constructible.");
destroy(__root());
}
- _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__begin_node_); }
- _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return const_iterator(__begin_node_); }
- _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(__end_node()); }
- _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(__end_node()); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() _NOEXCEPT { return iterator(__begin_node_); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const _NOEXCEPT {
+ return const_iterator(__begin_node_);
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() _NOEXCEPT { return iterator(__end_node()); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const _NOEXCEPT {
+ return const_iterator(__end_node());
+ }
- _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<size_type>(__node_traits::max_size(__node_alloc()), numeric_limits<
diff erence_type >::max());
}
- _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI void swap(__tree& __t)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(__tree& __t)
#if _LIBCPP_STD_VER <= 11
_NOEXCEPT_(__is_nothrow_swappable_v<value_compare> &&
(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>));
@@ -1039,13 +1066,14 @@ public:
#endif
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __emplace_multi(_Args&&... __args);
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
+ __emplace_hint_multi(const_iterator __p, _Args&&... __args);
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> __emplace_unique(_Args&&... __args) {
return std::__try_key_extraction<key_type>(
[this](const key_type& __key, _Args&&... __args2) {
auto [__parent, __child] = __find_equal(__key);
@@ -1075,7 +1103,8 @@ public:
}
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool>
+ __emplace_hint_unique(const_iterator __p, _Args&&... __args) {
return std::__try_key_extraction<key_type>(
[this, __p](const key_type& __key, _Args&&... __args2) {
__node_base_pointer __dummy;
@@ -1105,7 +1134,7 @@ public:
}
template <class _InIter, class _Sent>
- _LIBCPP_HIDE_FROM_ABI void __insert_range_multi(_InIter __first, _Sent __last) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __insert_range_multi(_InIter __first, _Sent __last) {
if (__first == __last)
return;
@@ -1136,7 +1165,7 @@ public:
}
template <class _InIter, class _Sent>
- _LIBCPP_HIDE_FROM_ABI void __insert_range_unique(_InIter __first, _Sent __last) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __insert_range_unique(_InIter __first, _Sent __last) {
if (__first == __last)
return;
@@ -1189,41 +1218,45 @@ public:
}
}
- _LIBCPP_HIDE_FROM_ABI iterator __remove_node_pointer(__node_pointer) _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __remove_node_pointer(__node_pointer) _NOEXCEPT;
#if _LIBCPP_STD_VER >= 17
template <class _NodeHandle, class _InsertReturnType>
- _LIBCPP_HIDE_FROM_ABI _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _InsertReturnType __node_handle_insert_unique(_NodeHandle&&);
template <class _NodeHandle>
- _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
+ __node_handle_insert_unique(const_iterator, _NodeHandle&&);
template <class _Comp2>
- _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(__tree<_Tp, _Comp2, _Allocator>& __source);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+ __node_handle_merge_unique(__tree<_Tp, _Comp2, _Allocator>& __source);
template <class _NodeHandle>
- _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(_NodeHandle&&);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __node_handle_insert_multi(_NodeHandle&&);
template <class _NodeHandle>
- _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
+ __node_handle_insert_multi(const_iterator, _NodeHandle&&);
template <class _Comp2>
- _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(__tree<_Tp, _Comp2, _Allocator>& __source);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+ __node_handle_merge_multi(__tree<_Tp, _Comp2, _Allocator>& __source);
template <class _NodeHandle>
- _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const&);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _NodeHandle __node_handle_extract(key_type const&);
template <class _NodeHandle>
- _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(const_iterator);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _NodeHandle __node_handle_extract(const_iterator);
#endif
- _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p);
- _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __p);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __f, const_iterator __l);
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type __erase_unique(const _Key& __k);
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type __erase_multi(const _Key& __k);
- _LIBCPP_HIDE_FROM_ABI void
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
__insert_node_at(__end_node_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT;
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __key) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _Key& __key) {
auto [__, __match] = __find_equal(__key);
if (__match == nullptr)
return end();
@@ -1231,7 +1264,7 @@ public:
}
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __key) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _Key& __key) const {
auto [__, __match] = __find_equal(__key);
if (__match == nullptr)
return end();
@@ -1239,12 +1272,13 @@ public:
}
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type __count_unique(const _Key& __k) const;
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type __count_multi(const _Key& __k) const;
template <bool _LowerBound, class _Key>
- _LIBCPP_HIDE_FROM_ABI __end_node_pointer __lower_upper_bound_unique_impl(const _Key& __v) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __end_node_pointer
+ __lower_upper_bound_unique_impl(const _Key& __v) const {
auto __rt = __root();
auto __result = __end_node();
auto __comp = __lazy_synth_three_way_comparator<_Compare, _Key, value_type>(value_comp());
@@ -1301,7 +1335,7 @@ public:
#endif // _LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI iterator __lower_bound_unique(const _Key& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __lower_bound_unique(const _Key& __v) {
#if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
return iterator(__lower_bound_unique_compat_impl(__v));
#else
@@ -1310,7 +1344,7 @@ public:
}
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI const_iterator __lower_bound_unique(const _Key& __v) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator __lower_bound_unique(const _Key& __v) const {
#if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
return const_iterator(__lower_bound_unique_compat_impl(__v));
#else
@@ -1319,7 +1353,7 @@ public:
}
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI iterator __upper_bound_unique(const _Key& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __upper_bound_unique(const _Key& __v) {
#if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
return iterator(__upper_bound_unique_compat_impl(__v));
#else
@@ -1328,7 +1362,7 @@ public:
}
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI const_iterator __upper_bound_unique(const _Key& __v) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator __upper_bound_unique(const _Key& __v) const {
#if defined(_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUND)
return iterator(__upper_bound_unique_compat_impl(__v));
#else
@@ -1338,117 +1372,138 @@ public:
private:
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI iterator
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
__lower_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI const_iterator
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
__lower_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
public:
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI iterator __lower_bound_multi(const _Key& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __lower_bound_multi(const _Key& __v) {
return __lower_bound_multi(__v, __root(), __end_node());
}
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI const_iterator __lower_bound_multi(const _Key& __v) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator __lower_bound_multi(const _Key& __v) const {
return __lower_bound_multi(__v, __root(), __end_node());
}
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI iterator __upper_bound_multi(const _Key& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator __upper_bound_multi(const _Key& __v) {
return __upper_bound_multi(__v, __root(), __end_node());
}
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI const_iterator __upper_bound_multi(const _Key& __v) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator __upper_bound_multi(const _Key& __v) const {
return __upper_bound_multi(__v, __root(), __end_node());
}
private:
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI iterator
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
__upper_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result);
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI const_iterator
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
__upper_bound_multi(const _Key& __v, __node_pointer __root, __end_node_pointer __result) const;
public:
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_unique(const _Key& __k);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> __equal_range_unique(const _Key& __k);
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_unique(const _Key& __k) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ __equal_range_unique(const _Key& __k) const;
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> __equal_range_multi(const _Key& __k);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> __equal_range_multi(const _Key& __k);
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_multi(const _Key& __k) const;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ __equal_range_multi(const _Key& __k) const;
using _Dp _LIBCPP_NODEBUG = __tree_node_destructor<__node_allocator>;
using __node_holder _LIBCPP_NODEBUG = unique_ptr<__node, _Dp>;
- _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_holder remove(const_iterator __p) _NOEXCEPT;
// FIXME: Make this function const qualified. Unfortunately doing so
// breaks existing code which uses non-const callable comparators.
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal(const _Key& __v);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<__end_node_pointer, __node_base_pointer&>
+ __find_equal(const _Key& __v);
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal(const _Key& __v) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<__end_node_pointer, __node_base_pointer&>
+ __find_equal(const _Key& __v) const {
return const_cast<__tree*>(this)->__find_equal(__v);
}
template <class _Key>
- _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<__end_node_pointer, __node_base_pointer&>
__find_equal(const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v);
- _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree& __t) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __copy_assign_alloc(const __tree& __t) {
__copy_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_copy_assignment::value>());
}
- _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree& __t, true_type) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __copy_assign_alloc(const __tree& __t, true_type) {
if (__node_alloc() != __t.__node_alloc())
clear();
__node_alloc() = __t.__node_alloc();
}
- _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __tree&, false_type) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __copy_assign_alloc(const __tree&, false_type) {}
private:
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_low(__end_node_pointer& __parent, const value_type& __v);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_base_pointer&
+ __find_leaf_low(__end_node_pointer& __parent, const value_type& __v);
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_high(__end_node_pointer& __parent, const value_type& __v);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_base_pointer&
+ __find_leaf_high(__end_node_pointer& __parent, const value_type& __v);
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_base_pointer&
__find_leaf(const_iterator __hint, __end_node_pointer& __parent, const value_type& __v);
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&&... __args);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_holder __construct_node(_Args&&... __args);
// TODO: Make this _LIBCPP_HIDE_FROM_ABI
- _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT { (__tree_deleter(__node_alloc_))(__nd); }
+ _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX26 void destroy(__node_pointer __nd) _NOEXCEPT {
+ (__tree_deleter(__node_alloc_))(__nd);
+ }
- _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, false_type);
- _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, true_type) _NOEXCEPT_(
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign(__tree& __t, false_type);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign(__tree& __t, true_type) _NOEXCEPT_(
is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value);
- _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign_alloc(__tree& __t)
_NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
is_nothrow_move_assignable<__node_allocator>::value) {
__move_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
}
- _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t, true_type)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign_alloc(__tree& __t, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {
__node_alloc() = std::move(__t.__node_alloc());
}
- _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
template <class _From, class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI static void __assign_value(__get_node_value_type_t<value_type>& __lhs, _From&& __rhs) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void
+ __assign_value(__get_node_value_type_t<value_type>& __lhs, _From&& __rhs) {
using __key_type = __remove_const_t<typename value_type::first_type>;
+#if _LIBCPP_STD_VER >= 26
+ if constexpr (std::is_copy_constructible_v<decltype(__rhs.first)>) {
+ // We need to replace the `const key_type` subobject by reconstruction during constant evaluation to avoid
+ // undefined behavior. Currently, there is no constexpr-friend way to replacing a move-only key subobject.
+ if consteval {
+ std::destroy_at(std::addressof(__lhs));
+ std::construct_at(std::addressof(__lhs), __rhs.first, std::forward<_From>(__rhs).second);
+ return;
+ }
+ }
+#endif
+
// This is technically UB, since the object was constructed as `const`.
// Clang doesn't optimize on this currently though.
const_cast<__key_type&>(__lhs.first) = const_cast<__copy_cvref_t<_From, __key_type>&&>(__rhs.first);
@@ -1466,13 +1521,12 @@ private:
public:
using pointer = __node_pointer;
- _LIBCPP_HIDE_FROM_ABI __tree_deleter(__node_allocator& __alloc) : __alloc_(__alloc) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __tree_deleter(__node_allocator& __alloc) : __alloc_(__alloc) {}
#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
_LIBCPP_HIDE_FROM_ABI
#endif
- void
- operator()(__node_pointer __ptr) {
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 void operator()(__node_pointer __ptr) {
if (!__ptr)
return;
@@ -1495,7 +1549,8 @@ private:
#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
_LIBCPP_HIDE_FROM_ABI
#endif
- __node_pointer __construct_from_tree(__node_pointer __src, _NodeConstructor __construct) {
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer
+ __construct_from_tree(__node_pointer __src, _NodeConstructor __construct) {
if (!__src)
return nullptr;
@@ -1519,19 +1574,29 @@ private:
return __new_node_ptr;
}
- _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_construct_tree(__node_pointer __src) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer __copy_construct_tree(__node_pointer __src) {
return __construct_from_tree(__src, [this](const value_type& __val) { return __construct_node(__val); });
}
template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type_v<_ValueT>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer __move_construct_tree(__node_pointer __src) {
return __construct_from_tree(__src, [this](value_type& __val) {
+
+#if _LIBCPP_STD_VER >= 26
+ // We need to replace the `const key_type` subobject by reconstruction during constant evaluation to avoid
+ // undefined behavior. Currently, there is no constexpr-friend way to replacing a move-only key subobject.
+ if constexpr (std::is_copy_constructible_v<decltype(__val.first)>) {
+ if consteval {
+ return __construct_node(__val.first, std::move(__val.second));
+ }
+ }
+#endif
return __construct_node(const_cast<key_type&&>(__val.first), std::move(__val.second));
});
}
template <class _ValueT = _Tp, __enable_if_t<!__is_tree_value_type_v<_ValueT>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI __node_pointer __move_construct_tree(__node_pointer __src) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer __move_construct_tree(__node_pointer __src) {
return __construct_from_tree(__src, [this](value_type& __val) { return __construct_node(std::move(__val)); });
}
@@ -1542,7 +1607,7 @@ private:
#ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
_LIBCPP_HIDE_FROM_ABI
#endif
- __node_pointer __assign_from_tree(
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer __assign_from_tree(
__node_pointer __dest, __node_pointer __src, _Assignment __assign, _ConstructionAlg __construct_subtree) {
if (!__src) {
destroy(__dest);
@@ -1583,7 +1648,8 @@ private:
return __dest;
}
- _LIBCPP_HIDE_FROM_ABI __node_pointer __copy_assign_tree(__node_pointer __dest, __node_pointer __src) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer
+ __copy_assign_tree(__node_pointer __dest, __node_pointer __src) {
return __assign_from_tree(
__dest,
__src,
@@ -1591,7 +1657,8 @@ private:
[this](__node_pointer __nd) { return __copy_construct_tree(__nd); });
}
- _LIBCPP_HIDE_FROM_ABI __node_pointer __move_assign_tree(__node_pointer __dest, __node_pointer __src) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __node_pointer
+ __move_assign_tree(__node_pointer __dest, __node_pointer __src) {
return __assign_from_tree(
__dest,
__src,
@@ -1610,7 +1677,8 @@ struct __specialized_algorithm<_Algorithm::__for_each, __single_range<__tree<_Tp
using __node_pointer _LIBCPP_NODEBUG = typename __tree<_Tp, _Compare, _Allocator>::__node_pointer;
template <class _Tree, class _Func, class _Proj>
- _LIBCPP_HIDE_FROM_ABI static auto operator()(_Tree&& __range, _Func __func, _Proj __proj) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto
+ operator()(_Tree&& __range, _Func __func, _Proj __proj) {
if (__range.size() != 0)
std::__tree_iterate_from_root<__copy_cvref_t<_Tree, typename __remove_cvref_t<_Tree>::value_type>>(
[](__node_pointer) { return false; }, __range.__root(), __func, __proj);
@@ -1620,7 +1688,8 @@ struct __specialized_algorithm<_Algorithm::__for_each, __single_range<__tree<_Tp
#endif
template <class _Tp, class _Compare, class _Allocator>
-__tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 __tree<_Tp, _Compare, _Allocator>&
+__tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) {
if (this == std::addressof(__t))
return *this;
@@ -1643,7 +1712,7 @@ __tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(
}
template <class _Tp, class _Compare, class _Allocator>
-__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
+_LIBCPP_CONSTEXPR_SINCE_CXX26 __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
: __begin_node_(__end_node()),
__node_alloc_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())),
__size_(0),
@@ -1658,7 +1727,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
}
template <class _Tp, class _Compare, class _Allocator>
-__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
+_LIBCPP_CONSTEXPR_SINCE_CXX26 __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value)
: __begin_node_(std::move(__t.__begin_node_)),
__end_node_(std::move(__t.__end_node_)),
@@ -1676,7 +1745,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
}
template <class _Tp, class _Compare, class _Allocator>
-__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
+_LIBCPP_CONSTEXPR_SINCE_CXX26 __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a)
: __begin_node_(__end_node()),
__node_alloc_(__node_allocator(__a)),
__size_(0),
@@ -1701,7 +1770,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __
}
template <class _Tp, class _Compare, class _Allocator>
-void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
_NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value) {
destroy(std::__static_fancy_pointer_cast<__node_pointer>(__end_node()->__left_));
__begin_node_ = __t.__begin_node_;
@@ -1720,7 +1789,7 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
}
template <class _Tp, class _Compare, class _Allocator>
-void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
if (__node_alloc() == __t.__node_alloc()) {
__move_assign(__t, true_type());
} else {
@@ -1741,7 +1810,7 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
}
template <class _Tp, class _Compare, class _Allocator>
-void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
#if _LIBCPP_STD_VER <= 11
_NOEXCEPT_(__is_nothrow_swappable_v<value_compare> &&
(!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>))
@@ -1766,7 +1835,7 @@ void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
}
template <class _Tp, class _Compare, class _Allocator>
-void __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT {
destroy(__root());
__size_ = 0;
__begin_node_ = __end_node();
@@ -1777,7 +1846,7 @@ void __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT {
// Set __parent to parent of null leaf
// Return reference to null leaf
template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__end_node_pointer& __parent, const value_type& __v) {
__node_pointer __nd = __root();
if (__nd != nullptr) {
@@ -1807,7 +1876,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__end_node_pointer& __parent,
// Set __parent to parent of null leaf
// Return reference to null leaf
template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__end_node_pointer& __parent, const value_type& __v) {
__node_pointer __nd = __root();
if (__nd != nullptr) {
@@ -1840,7 +1909,8 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__end_node_pointer& __parent
// Set __parent to parent of null leaf
// Return reference to null leaf
template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_leaf(
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
+__tree<_Tp, _Compare, _Allocator>::__find_leaf(
const_iterator __hint, __end_node_pointer& __parent, const value_type& __v) {
if (__hint == end() || !value_comp()(*__hint, __v)) // check before
{
@@ -1868,8 +1938,9 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Co
// If __v doesn't exist, return the parent of the null leaf and a reference to the pointer to the null leaf.
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-_LIBCPP_HIDE_FROM_ABI pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
- typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
+_LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX26 pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
+ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
__tree<_Tp, _Compare, _Allocator>::__find_equal(const _Key& __v) {
using _Pair = pair<__end_node_pointer, __node_base_pointer&>;
@@ -1914,8 +1985,9 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const _Key& __v) {
// If __v doesn't exist, return the parent of the null leaf and a reference to the pointer to the null leaf.
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-_LIBCPP_HIDE_FROM_ABI pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
- typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
+_LIBCPP_HIDE_FROM_ABI
+_LIBCPP_CONSTEXPR_SINCE_CXX26 pair<typename __tree<_Tp, _Compare, _Allocator>::__end_node_pointer,
+ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&>
__tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v) {
using _Pair = pair<__end_node_pointer, __node_base_pointer&>;
@@ -1946,12 +2018,12 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, __node_ba
}
// else __v == *__hint
- __dummy = static_cast<__node_base_pointer>(__hint.__ptr_);
+ __dummy = std::__static_fancy_pointer_cast<__node_base_pointer>(__hint.__ptr_);
return _Pair(__hint.__ptr_, __dummy);
}
template <class _Tp, class _Compare, class _Allocator>
-void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
+_LIBCPP_CONSTEXPR_SINCE_CXX26 void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
__end_node_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT {
__new_node->__left_ = nullptr;
__new_node->__right_ = nullptr;
@@ -1966,7 +2038,7 @@ void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
template <class _Tp, class _Compare, class _Allocator>
template <class... _Args>
-typename __tree<_Tp, _Compare, _Allocator>::__node_holder
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::__node_holder
__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
__node_allocator& __na = __node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
@@ -1977,42 +2049,42 @@ __tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
template <class _Tp, class _Compare, class _Allocator>
template <class... _Args>
-typename __tree<_Tp, _Compare, _Allocator>::iterator
+typename __tree<_Tp, _Compare, _Allocator>::iterator _LIBCPP_CONSTEXPR_SINCE_CXX26
__tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) {
__node_holder __h = __construct_node(std::forward<_Args>(__args)...);
__end_node_pointer __parent;
__node_base_pointer& __child = __find_leaf_high(__parent, __h->__get_value());
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
- return iterator(static_cast<__node_pointer>(__h.release()));
+ __insert_node_at(__parent, __child, std::__static_fancy_pointer_cast<__node_base_pointer>(__h.get()));
+ return iterator(std::__static_fancy_pointer_cast<__node_pointer>(__h.release()));
}
template <class _Tp, class _Compare, class _Allocator>
template <class... _Args>
-typename __tree<_Tp, _Compare, _Allocator>::iterator
+typename __tree<_Tp, _Compare, _Allocator>::iterator _LIBCPP_CONSTEXPR_SINCE_CXX26
__tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) {
__node_holder __h = __construct_node(std::forward<_Args>(__args)...);
__end_node_pointer __parent;
__node_base_pointer& __child = __find_leaf(__p, __parent, __h->__get_value());
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
- return iterator(static_cast<__node_pointer>(__h.release()));
+ __insert_node_at(__parent, __child, std::__static_fancy_pointer_cast<__node_base_pointer>(__h.get()));
+ return iterator(std::__static_fancy_pointer_cast<__node_pointer>(__h.release()));
}
template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::iterator
+typename __tree<_Tp, _Compare, _Allocator>::iterator _LIBCPP_CONSTEXPR_SINCE_CXX26
__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT {
iterator __r(__ptr);
++__r;
if (__begin_node_ == __ptr)
__begin_node_ = __r.__ptr_;
--__size_;
- std::__tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__ptr));
+ std::__tree_remove(__end_node()->__left_, std::__static_fancy_pointer_cast<__node_base_pointer>(__ptr));
return __r;
}
#if _LIBCPP_STD_VER >= 17
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle, class _InsertReturnType>
-_LIBCPP_HIDE_FROM_ABI _InsertReturnType
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _InsertReturnType
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __nh) {
if (__nh.empty())
return _InsertReturnType{end(), false, _NodeHandle()};
@@ -2020,16 +2092,17 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __n
__node_pointer __ptr = __nh.__ptr_;
auto [__parent, __child] = __find_equal(__ptr->__get_value());
if (__child != nullptr)
- return _InsertReturnType{iterator(static_cast<__node_pointer>(__child)), false, std::move(__nh)};
+ return _InsertReturnType{
+ iterator(std::__static_fancy_pointer_cast<__node_pointer>(__child)), false, std::move(__nh)};
- __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
+ __insert_node_at(__parent, __child, std::__static_fancy_pointer_cast<__node_base_pointer>(__ptr));
__nh.__release_ptr();
return _InsertReturnType{iterator(__ptr), true, _NodeHandle()};
}
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
-_LIBCPP_HIDE_FROM_ABI typename __tree<_Tp, _Compare, _Allocator>::iterator
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __hint, _NodeHandle&& __nh) {
if (__nh.empty())
return end();
@@ -2048,7 +2121,8 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
-_LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _NodeHandle
+__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(key_type const& __key) {
iterator __it = __lower_bound_multi(__key);
if (__it == end() || __value_comp_(__key, *__it))
return _NodeHandle();
@@ -2057,7 +2131,8 @@ _LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_hand
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
-_LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _NodeHandle
+__tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p) {
__node_pointer __np = __p.__get_np();
__remove_node_pointer(__np);
return _NodeHandle(__np, __alloc());
@@ -2065,7 +2140,7 @@ _LIBCPP_HIDE_FROM_ABI _NodeHandle __tree<_Tp, _Compare, _Allocator>::__node_hand
template <class _Tp, class _Compare, class _Allocator>
template <class _Comp2>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(__tree<_Tp, _Comp2, _Allocator>& __source) {
for (iterator __i = __source.begin(); __i != __source.end();) {
__node_pointer __src_ptr = __i.__get_np();
@@ -2080,7 +2155,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(__tree<_Tp, _Comp2
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
-_LIBCPP_HIDE_FROM_ABI typename __tree<_Tp, _Compare, _Allocator>::iterator
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh) {
if (__nh.empty())
return end();
@@ -2094,7 +2169,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh
template <class _Tp, class _Compare, class _Allocator>
template <class _NodeHandle>
-_LIBCPP_HIDE_FROM_ABI typename __tree<_Tp, _Compare, _Allocator>::iterator
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh) {
if (__nh.empty())
return end();
@@ -2109,7 +2184,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(const_iterator __h
template <class _Tp, class _Compare, class _Allocator>
template <class _Comp2>
-_LIBCPP_HIDE_FROM_ABI void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(__tree<_Tp, _Comp2, _Allocator>& __source) {
for (iterator __i = __source.begin(); __i != __source.end();) {
__node_pointer __src_ptr = __i.__get_np();
@@ -2123,7 +2198,8 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(__tree<_Tp, _Comp2,
#endif // _LIBCPP_STD_VER >= 17
template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26
+ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) {
__node_pointer __np = __p.__get_np();
iterator __r = __remove_node_pointer(__np);
__node_allocator& __na = __node_alloc();
@@ -2133,7 +2209,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allo
}
template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::iterator
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::iterator
__tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l) {
while (__f != __l)
__f = erase(__f);
@@ -2142,7 +2218,7 @@ __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __f, const_iterator __l)
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::size_type
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::size_type
__tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k) {
iterator __i = find(__k);
if (__i == end())
@@ -2153,7 +2229,7 @@ __tree<_Tp, _Compare, _Allocator>::__erase_unique(const _Key& __k) {
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::size_type
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::size_type
__tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) {
pair<iterator, iterator> __p = __equal_range_multi(__k);
size_type __r = 0;
@@ -2164,7 +2240,7 @@ __tree<_Tp, _Compare, _Allocator>::__erase_multi(const _Key& __k) {
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::size_type
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::size_type
__tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const {
__node_pointer __rt = __root();
auto __comp = __lazy_synth_three_way_comparator<value_compare, _Key, value_type>(value_comp());
@@ -2182,7 +2258,7 @@ __tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const {
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::size_type
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::size_type
__tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const {
__end_node_pointer __result = __end_node();
__node_pointer __rt = __root();
@@ -2206,7 +2282,8 @@ __tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const {
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound_multi(
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__lower_bound_multi(
const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
while (__root != nullptr) {
if (!value_comp()(__root->__get_value(), __v)) {
@@ -2220,7 +2297,8 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allo
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound_multi(
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::const_iterator
+__tree<_Tp, _Compare, _Allocator>::__lower_bound_multi(
const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
while (__root != nullptr) {
if (!value_comp()(__root->__get_value(), __v)) {
@@ -2234,7 +2312,8 @@ typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare,
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound_multi(
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::iterator
+__tree<_Tp, _Compare, _Allocator>::__upper_bound_multi(
const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
while (__root != nullptr) {
if (value_comp()(__v, __root->__get_value())) {
@@ -2248,7 +2327,8 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allo
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound_multi(
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::const_iterator
+__tree<_Tp, _Compare, _Allocator>::__upper_bound_multi(
const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
while (__root != nullptr) {
if (value_comp()(__v, __root->__get_value())) {
@@ -2262,8 +2342,9 @@ typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare,
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
-__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26
+ pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
+ __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) {
using _Pp = pair<iterator, iterator>;
__end_node_pointer __result = __end_node();
__node_pointer __rt = __root();
@@ -2271,22 +2352,23 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) {
while (__rt != nullptr) {
auto __comp_res = __comp(__k, __rt->__get_value());
if (__comp_res.__less()) {
- __result = static_cast<__end_node_pointer>(__rt);
- __rt = static_cast<__node_pointer>(__rt->__left_);
+ __result = std::__static_fancy_pointer_cast<__end_node_pointer>(__rt);
+ __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__left_);
} else if (__comp_res.__greater())
- __rt = static_cast<__node_pointer>(__rt->__right_);
+ __rt = std::__static_fancy_pointer_cast<__node_pointer>(__rt->__right_);
else
return _Pp(iterator(__rt),
- iterator(__rt->__right_ != nullptr ? static_cast<__end_node_pointer>(std::__tree_min(__rt->__right_))
- : __result));
+ iterator(__rt->__right_ != nullptr
+ ? std::__static_fancy_pointer_cast<__end_node_pointer>(std::__tree_min(__rt->__right_))
+ : __result));
}
return _Pp(iterator(__result), iterator(__result));
}
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
- typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
+ typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
__tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const {
using _Pp = pair<const_iterator, const_iterator>;
__end_node_pointer __result = __end_node();
@@ -2311,8 +2393,9 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const {
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
-__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26
+ pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, typename __tree<_Tp, _Compare, _Allocator>::iterator>
+ __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) {
using _Pp = pair<iterator, iterator>;
__end_node_pointer __result = __end_node();
__node_pointer __rt = __root();
@@ -2335,8 +2418,8 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) {
template <class _Tp, class _Compare, class _Allocator>
template <class _Key>
-pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
- typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
+_LIBCPP_CONSTEXPR_SINCE_CXX26 pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator,
+ typename __tree<_Tp, _Compare, _Allocator>::const_iterator>
__tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const {
using _Pp = pair<const_iterator, const_iterator>;
__end_node_pointer __result = __end_node();
@@ -2359,7 +2442,7 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const {
}
template <class _Tp, class _Compare, class _Allocator>
-typename __tree<_Tp, _Compare, _Allocator>::__node_holder
+_LIBCPP_CONSTEXPR_SINCE_CXX26 typename __tree<_Tp, _Compare, _Allocator>::__node_holder
__tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT {
__node_pointer __np = __p.__get_np();
if (__begin_node_ == __p.__ptr_) {
@@ -2374,7 +2457,8 @@ __tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT {
}
template <class _Tp, class _Compare, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI void swap(__tree<_Tp, _Compare, _Allocator>& __x, __tree<_Tp, _Compare, _Allocator>& __y)
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+swap(__tree<_Tp, _Compare, _Allocator>& __x, __tree<_Tp, _Compare, _Allocator>& __y)
_NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
__x.swap(__y);
}
diff --git a/libcxx/include/__type_traits/make_transparent.h b/libcxx/include/__type_traits/make_transparent.h
index d3bca66841072..6d4bff08a3140 100644
--- a/libcxx/include/__type_traits/make_transparent.h
+++ b/libcxx/include/__type_traits/make_transparent.h
@@ -36,14 +36,15 @@ using __make_transparent_t _LIBCPP_NODEBUG = typename __make_transparent<_Argume
template <class _ArgumentType,
class _Comparator,
__enable_if_t<is_same<_Comparator, __make_transparent_t<_ArgumentType, _Comparator> >::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _Comparator& __as_transparent(_Comparator& __comp) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Comparator& __as_transparent(_Comparator& __comp) {
return __comp;
}
template <class _ArgumentType,
class _Comparator,
__enable_if_t<!is_same<_Comparator, __make_transparent_t<_ArgumentType, _Comparator> >::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI __make_transparent_t<_ArgumentType, _Comparator> __as_transparent(_Comparator&) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __make_transparent_t<_ArgumentType, _Comparator>
+__as_transparent(_Comparator&) {
static_assert(is_empty<_Comparator>::value);
return __make_transparent_t<_ArgumentType, _Comparator>();
}
diff --git a/libcxx/include/__utility/default_three_way_comparator.h b/libcxx/include/__utility/default_three_way_comparator.h
index 92cdce6aae117..6ed9732b49a56 100644
--- a/libcxx/include/__utility/default_three_way_comparator.h
+++ b/libcxx/include/__utility/default_three_way_comparator.h
@@ -31,7 +31,7 @@ template <class _LHS, class _RHS>
struct __default_three_way_comparator<_LHS,
_RHS,
__enable_if_t<is_arithmetic<_LHS>::value && is_arithmetic<_RHS>::value> > {
- _LIBCPP_HIDE_FROM_ABI static int operator()(_LHS __lhs, _RHS __rhs) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static int operator()(_LHS __lhs, _RHS __rhs) {
if (__lhs < __rhs)
return -1;
if (__lhs > __rhs)
@@ -47,7 +47,7 @@ struct __default_three_way_comparator<
_RHS,
__enable_if_t<!(is_arithmetic<_LHS>::value && is_arithmetic<_RHS>::value) &&
__builtin_lt_synthesizes_from_spaceship(const _LHS&, const _RHS&)>> {
- _LIBCPP_HIDE_FROM_ABI static int operator()(const _LHS& __lhs, const _RHS& __rhs) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static int operator()(const _LHS& __lhs, const _RHS& __rhs) {
auto __res = __lhs <=> __rhs;
if (__res < 0)
return -1;
diff --git a/libcxx/include/__utility/lazy_synth_three_way_comparator.h b/libcxx/include/__utility/lazy_synth_three_way_comparator.h
index 906166bd2a61a..2dc67b61518bf 100644
--- a/libcxx/include/__utility/lazy_synth_three_way_comparator.h
+++ b/libcxx/include/__utility/lazy_synth_three_way_comparator.h
@@ -35,20 +35,20 @@ struct __lazy_compare_result {
const _LHS& __lhs_;
const _RHS& __rhs_;
- _LIBCPP_HIDE_FROM_ABI
- __lazy_compare_result(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator& __comp,
- _LIBCPP_CTOR_LIFETIMEBOUND const _LHS& __lhs,
- _LIBCPP_CTOR_LIFETIMEBOUND const _RHS& __rhs)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __lazy_compare_result(
+ _LIBCPP_CTOR_LIFETIMEBOUND const _Comparator& __comp,
+ _LIBCPP_CTOR_LIFETIMEBOUND const _LHS& __lhs,
+ _LIBCPP_CTOR_LIFETIMEBOUND const _RHS& __rhs)
: __comp_(__comp), __lhs_(__lhs), __rhs_(__rhs) {}
- _LIBCPP_HIDE_FROM_ABI bool __less() const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __less() const {
bool __result = __comp_(__lhs_, __rhs_);
_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__result ? !static_cast<bool>(__comp_(__rhs_, __lhs_)) : true,
"Comparator does not induce a strict weak ordering");
return __result;
}
- _LIBCPP_HIDE_FROM_ABI bool __greater() const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __greater() const {
bool __result = __comp_(__rhs_, __lhs_);
_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__result ? !static_cast<bool>(__comp_(__lhs_, __rhs_)) : true,
"Comparator does not induce a strict weak ordering");
@@ -63,10 +63,11 @@ template <class _Comparator, class _LHS, class _RHS, class = void>
struct __lazy_synth_three_way_comparator {
const _Comparator& __comp_;
- _LIBCPP_HIDE_FROM_ABI __lazy_synth_three_way_comparator(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator& __comp)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
+ __lazy_synth_three_way_comparator(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator& __comp)
: __comp_(__comp) {}
- _LIBCPP_HIDE_FROM_ABI __lazy_compare_result<_Comparator, _LHS, _RHS>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __lazy_compare_result<_Comparator, _LHS, _RHS>
operator()(_LIBCPP_LIFETIMEBOUND const _LHS& __lhs, _LIBCPP_LIFETIMEBOUND const _RHS& __rhs) const {
return __lazy_compare_result<_Comparator, _LHS, _RHS>(__comp_, __lhs, __rhs);
}
@@ -75,10 +76,10 @@ struct __lazy_synth_three_way_comparator {
struct __eager_compare_result {
int __res_;
- _LIBCPP_HIDE_FROM_ABI explicit __eager_compare_result(int __res) : __res_(__res) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit __eager_compare_result(int __res) : __res_(__res) {}
- _LIBCPP_HIDE_FROM_ABI bool __less() const { return __res_ < 0; }
- _LIBCPP_HIDE_FROM_ABI bool __greater() const { return __res_ > 0; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __less() const { return __res_ < 0; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool __greater() const { return __res_ > 0; }
};
template <class _Comparator, class _LHS, class _RHS>
@@ -89,10 +90,11 @@ struct __lazy_synth_three_way_comparator<_Comparator,
__has_default_three_way_comparator<_LHS, _RHS> >::value> > {
// This lifetimebound annotation is technically incorrect, but other specializations actually capture the lifetime of
// the comparator.
- _LIBCPP_HIDE_FROM_ABI __lazy_synth_three_way_comparator(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator&) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
+ __lazy_synth_three_way_comparator(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator&) {}
// Same comment as above.
- _LIBCPP_HIDE_FROM_ABI static __eager_compare_result
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static __eager_compare_result
operator()(_LIBCPP_LIFETIMEBOUND const _LHS& __lhs, _LIBCPP_LIFETIMEBOUND const _RHS& __rhs) {
return __eager_compare_result(__default_three_way_comparator<_LHS, _RHS>()(__lhs, __rhs));
}
@@ -106,10 +108,11 @@ struct __lazy_synth_three_way_comparator<_Comparator,
__has_default_three_way_comparator<_LHS, _RHS> >::value> > {
// This lifetimebound annotation is technically incorrect, but other specializations actually capture the lifetime of
// the comparator.
- _LIBCPP_HIDE_FROM_ABI __lazy_synth_three_way_comparator(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator&) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
+ __lazy_synth_three_way_comparator(_LIBCPP_CTOR_LIFETIMEBOUND const _Comparator&) {}
// Same comment as above.
- _LIBCPP_HIDE_FROM_ABI static __eager_compare_result
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static __eager_compare_result
operator()(_LIBCPP_LIFETIMEBOUND const _LHS& __lhs, _LIBCPP_LIFETIMEBOUND const _RHS& __rhs) {
return __eager_compare_result(-__default_three_way_comparator<_LHS, _RHS>()(__lhs, __rhs));
}
diff --git a/libcxx/include/__utility/try_key_extraction.h b/libcxx/include/__utility/try_key_extraction.h
index 755c08214019f..3423d746dee7f 100644
--- a/libcxx/include/__utility/try_key_extraction.h
+++ b/libcxx/include/__utility/try_key_extraction.h
@@ -28,7 +28,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _KeyT, class _Ret, class _WithKey, class _WithoutKey, class... _Args>
-_LIBCPP_HIDE_FROM_ABI _Ret
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Ret
__try_key_extraction_impl(__priority_tag<0>, _WithKey, _WithoutKey __without_key, _Args&&... __args) {
return __without_key(std::forward<_Args>(__args)...);
}
@@ -39,7 +39,7 @@ template <class _KeyT,
class _WithoutKey,
class _Arg,
__enable_if_t<is_same<_KeyT, __remove_const_ref_t<_Arg> >::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _Ret
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Ret
__try_key_extraction_impl(__priority_tag<1>, _WithKey __with_key, _WithoutKey, _Arg&& __arg) {
return __with_key(__arg, std::forward<_Arg>(__arg));
}
@@ -52,7 +52,7 @@ template <class _KeyT,
__enable_if_t<__is_pair_v<__remove_const_ref_t<_Arg> > &&
is_same<__remove_const_t<typename __remove_const_ref_t<_Arg>::first_type>, _KeyT>::value,
int> = 0>
-_LIBCPP_HIDE_FROM_ABI _Ret
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Ret
__try_key_extraction_impl(__priority_tag<1>, _WithKey __with_key, _WithoutKey, _Arg&& __arg) {
return __with_key(__arg.first, std::forward<_Arg>(__arg));
}
@@ -64,7 +64,7 @@ template <class _KeyT,
class _Arg1,
class _Arg2,
__enable_if_t<is_same<_KeyT, __remove_const_ref_t<_Arg1> >::value, int> = 0>
-_LIBCPP_HIDE_FROM_ABI _Ret
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Ret
__try_key_extraction_impl(__priority_tag<1>, _WithKey __with_key, _WithoutKey, _Arg1&& __arg1, _Arg2&& __arg2) {
return __with_key(__arg1, std::forward<_Arg1>(__arg1), std::forward<_Arg2>(__arg2));
}
@@ -81,7 +81,7 @@ template <class _KeyT,
__is_tuple_v<_Tuple1> && tuple_size<_Tuple1>::value == 1 &&
is_same<__remove_const_ref_t<typename tuple_element<0, _Tuple1>::type>, _KeyT>::value,
int> = 0>
-_LIBCPP_HIDE_FROM_ABI _Ret __try_key_extraction_impl(
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 _Ret __try_key_extraction_impl(
__priority_tag<1>,
_WithKey __with_key,
_WithoutKey,
@@ -102,7 +102,7 @@ _LIBCPP_HIDE_FROM_ABI _Ret __try_key_extraction_impl(
//
// Both `__with_key` and `__without_key` must take all arguments by reference.
template <class _KeyT, class _WithKey, class _WithoutKey, class... _Args>
-_LIBCPP_HIDE_FROM_ABI decltype(std::declval<_WithoutKey>()(std::declval<_Args>()...))
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 decltype(std::declval<_WithoutKey>()(std::declval<_Args>()...))
__try_key_extraction(_WithKey __with_key, _WithoutKey __without_key, _Args&&... __args) {
using _Ret = decltype(__without_key(std::forward<_Args>(__args)...));
return std::__try_key_extraction_impl<_KeyT, _Ret>(
diff --git a/libcxx/include/map b/libcxx/include/map
index 4a15267aa16db..8dd461bfb2bea 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -57,177 +57,175 @@ public:
};
// construct/copy/destroy:
- map()
+ constexpr map()
noexcept(
is_nothrow_default_constructible<allocator_type>::value &&
is_nothrow_default_constructible<key_compare>::value &&
is_nothrow_copy_constructible<key_compare>::value);
- explicit map(const key_compare& comp);
- map(const key_compare& comp, const allocator_type& a);
+ constexpr explicit map(const key_compare& comp);
+ constexpr map(const key_compare& comp, const allocator_type& a);
template <class InputIterator>
- map(InputIterator first, InputIterator last,
+ constexpr map(InputIterator first, InputIterator last,
const key_compare& comp = key_compare());
template <class InputIterator>
- map(InputIterator first, InputIterator last,
+ constexpr map(InputIterator first, InputIterator last,
const key_compare& comp, const allocator_type& a);
template<container-compatible-range<value_type> R>
- map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
- map(const map& m);
- map(map&& m)
+ constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
+ constexpr map(const map& m);
+ constexpr map(map&& m)
noexcept(
is_nothrow_move_constructible<allocator_type>::value &&
is_nothrow_move_constructible<key_compare>::value);
- explicit map(const allocator_type& a);
- map(const map& m, const allocator_type& a);
- map(map&& m, const allocator_type& a);
- map(initializer_list<value_type> il, const key_compare& comp = key_compare());
- map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
+ constexpr explicit map(const allocator_type& a);
+ constexpr map(const map& m, const allocator_type& a);
+ constexpr map(map&& m, const allocator_type& a);
+ constexpr map(initializer_list<value_type> il, const key_compare& comp = key_compare());
+ constexpr map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
template <class InputIterator>
- map(InputIterator first, InputIterator last, const allocator_type& a)
- : map(first, last, Compare(), a) {} // C++14
+ constexpr map(InputIterator first, InputIterator last, const allocator_type& a)
+ : map(first, last, Compare(), a) {} // C++14
template<container-compatible-range<value_type> R>
- map(from_range_t, R&& rg, const Allocator& a))
- : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
- map(initializer_list<value_type> il, const allocator_type& a)
- : map(il, Compare(), a) {} // C++14
- ~map();
-
- map& operator=(const map& m);
- map& operator=(map&& m)
+ constexpr map(from_range_t, R&& rg, const Allocator& a))
+ : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
+ constexpr map(initializer_list<value_type> il, const allocator_type& a)
+ : map(il, Compare(), a) {} // C++14
+ constexpr ~map();
+
+ constexpr map& operator=(const map& m);
+ constexpr map& operator=(map&& m)
noexcept(
allocator_type::propagate_on_container_move_assignment::value &&
is_nothrow_move_assignable<allocator_type>::value &&
is_nothrow_move_assignable<key_compare>::value);
- map& operator=(initializer_list<value_type> il);
+ constexpr map& operator=(initializer_list<value_type> il);
// iterators:
- iterator begin() noexcept;
- const_iterator begin() const noexcept;
- iterator end() noexcept;
- const_iterator end() const noexcept;
+ constexpr iterator begin() noexcept;
+ constexpr const_iterator begin() const noexcept;
+ constexpr iterator end() noexcept;
+ constexpr const_iterator end() const noexcept;
- reverse_iterator rbegin() noexcept;
- const_reverse_iterator rbegin() const noexcept;
- reverse_iterator rend() noexcept;
- const_reverse_iterator rend() const noexcept;
+ constexpr reverse_iterator rbegin() noexcept;
+ constexpr const_reverse_iterator rbegin() const noexcept;
+ constexpr reverse_iterator rend() noexcept;
+ constexpr const_reverse_iterator rend() const noexcept;
- const_iterator cbegin() const noexcept;
- const_iterator cend() const noexcept;
- const_reverse_iterator crbegin() const noexcept;
- const_reverse_iterator crend() const noexcept;
+ constexpr const_iterator cbegin() const noexcept;
+ constexpr const_iterator cend() const noexcept;
+ constexpr const_reverse_iterator crbegin() const noexcept;
+ constexpr const_reverse_iterator crend() const noexcept;
// capacity:
- bool empty() const noexcept;
- size_type size() const noexcept;
- size_type max_size() const noexcept;
+ constexpr bool empty() const noexcept;
+ constexpr size_type size() const noexcept;
+ constexpr size_type max_size() const noexcept;
// element access:
- mapped_type& operator[](const key_type& k);
- mapped_type& operator[](key_type&& k);
+ constexpr mapped_type& operator[](const key_type& k);
+ constexpr mapped_type& operator[](key_type&& k);
- mapped_type& at(const key_type& k);
- const mapped_type& at(const key_type& k) const;
+ constexpr mapped_type& at(const key_type& k);
+ constexpr const mapped_type& at(const key_type& k) const;
// modifiers:
template <class... Args>
- pair<iterator, bool> emplace(Args&&... args);
+ constexpr pair<iterator, bool> emplace(Args&&... args);
template <class... Args>
- iterator emplace_hint(const_iterator position, Args&&... args);
- pair<iterator, bool> insert(const value_type& v);
- pair<iterator, bool> insert( value_type&& v); // C++17
- template <class P>
- pair<iterator, bool> insert(P&& p);
- iterator insert(const_iterator position, const value_type& v);
- iterator insert(const_iterator position, value_type&& v); // C++17
- template <class P>
- iterator insert(const_iterator position, P&& p);
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last);
+ constexpr iterator emplace_hint(const_iterator position, Args&&... args);
+ constexpr pair<iterator, bool> insert(const value_type& v);
+ constexpr pair<iterator, bool> insert( value_type&& v); // C++17
+ template <class P> constexpr pair<iterator, bool> insert(P&& p);
+ constexpr iterator insert(const_iterator position, const value_type& v);
+ constexpr iterator insert(const_iterator position, value_type&& v); // C++17
+ template <class P> constexpr iterator insert(const_iterator position, P&& p);
+ template <class InputIterator> constexpr void insert(InputIterator first, InputIterator last);
+
template<container-compatible-range<value_type> R>
- void insert_range(R&& rg); // C++23
- void insert(initializer_list<value_type> il);
+ constexpr void insert_range(R&& rg); // C++23
+ constexpr void insert(initializer_list<value_type> il);
- node_type extract(const_iterator position); // C++17
- node_type extract(const key_type& x); // C++17
- insert_return_type insert(node_type&& nh); // C++17
- iterator insert(const_iterator hint, node_type&& nh); // C++17
+ constexpr node_type extract(const_iterator position); // C++17
+ constexpr node_type extract(const key_type& x); // C++17
+ constexpr insert_return_type insert(node_type&& nh); // C++17
+ constexpr iterator insert(const_iterator hint, node_type&& nh); // C++17
template <class... Args>
- pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
+ constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
template <class... Args>
- pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
+ constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
template <class... Args>
- iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
+ constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
template <class... Args>
- iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
+ constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
template <class M>
- pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
+ constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
template <class M>
- pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
+ constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
template <class M>
- iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
+ constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
template <class M>
- iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
+ constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
- iterator erase(const_iterator position);
- iterator erase(iterator position); // C++14
- size_type erase(const key_type& k);
- iterator erase(const_iterator first, const_iterator last);
- void clear() noexcept;
+ constexpr iterator erase(const_iterator position);
+ constexpr iterator erase(iterator position); // C++14
+ constexpr size_type erase(const key_type& k);
+ constexpr iterator erase(const_iterator first, const_iterator last);
+ constexpr void clear() noexcept;
template<class C2>
- void merge(map<Key, T, C2, Allocator>& source); // C++17
+ constexpr void merge(map<Key, T, C2, Allocator>& source); // C++17
template<class C2>
- void merge(map<Key, T, C2, Allocator>&& source); // C++17
+ constexpr void merge(map<Key, T, C2, Allocator>&& source); // C++17
template<class C2>
- void merge(multimap<Key, T, C2, Allocator>& source); // C++17
+ constexpr void merge(multimap<Key, T, C2, Allocator>& source); // C++17
template<class C2>
- void merge(multimap<Key, T, C2, Allocator>&& source); // C++17
+ constexpr void merge(multimap<Key, T, C2, Allocator>&& source); // C++17
- void swap(map& m)
+ constexpr void swap(map& m)
noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
- is_nothrow_swappable<key_compare>::value); // C++17
+ is_nothrow_swappable<key_compare>::value); // C++17
// observers:
- allocator_type get_allocator() const noexcept;
- key_compare key_comp() const;
- value_compare value_comp() const;
+ constexpr allocator_type get_allocator() const noexcept;
+ constexpr key_compare key_comp() const;
+ constexpr value_compare value_comp() const;
// map operations:
- iterator find(const key_type& k);
- const_iterator find(const key_type& k) const;
+ constexpr iterator find(const key_type& k);
+ constexpr const_iterator find(const key_type& k) const;
template<typename K>
- iterator find(const K& x); // C++14
+ constexpr iterator find(const K& x); // C++14
template<typename K>
- const_iterator find(const K& x) const; // C++14
+ constexpr const_iterator find(const K& x) const; // C++14
template<typename K>
- size_type count(const K& x) const; // C++14
- size_type count(const key_type& k) const;
+ constexpr size_type count(const K& x) const; // C++14
+ constexpr size_type count(const key_type& k) const;
- bool contains(const key_type& x) const; // C++20
- template<class K> bool contains(const K& x) const; // C++20
+ constexpr bool contains(const key_type& x) const; // C++20
+ template<class K> constexpr bool contains(const K& x) const; // C++20
- iterator lower_bound(const key_type& k);
- const_iterator lower_bound(const key_type& k) const;
+ constexpr iterator lower_bound(const key_type& k);
+ constexpr const_iterator lower_bound(const key_type& k) const;
template<typename K>
- iterator lower_bound(const K& x); // C++14
+ constexpr iterator lower_bound(const K& x); // C++14
template<typename K>
- const_iterator lower_bound(const K& x) const; // C++14
+ constexpr const_iterator lower_bound(const K& x) const; // C++14
- iterator upper_bound(const key_type& k);
- const_iterator upper_bound(const key_type& k) const;
+ constexpr iterator upper_bound(const key_type& k);
+ constexpr const_iterator upper_bound(const key_type& k) const;
template<typename K>
- iterator upper_bound(const K& x); // C++14
+ constexpr iterator upper_bound(const K& x); // C++14
template<typename K>
- const_iterator upper_bound(const K& x) const; // C++14
+ constexpr const_iterator upper_bound(const K& x) const; // C++14
- pair<iterator,iterator> equal_range(const key_type& k);
- pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+ constexpr pair<iterator,iterator> equal_range(const key_type& k);
+ constexpr pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
template<typename K>
- pair<iterator,iterator> equal_range(const K& x); // C++14
+ constexpr pair<iterator,iterator> equal_range(const K& x); // C++14
template<typename K>
- pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
+ constexpr pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14
};
template <class InputIterator,
@@ -411,7 +409,7 @@ public:
template <class... Args>
iterator emplace(Args&&... args);
template <class... Args>
- iterator emplace_hint(const_iterator position, Args&&... args);
+ iterator emplace_hint(const_iterator position, Args&&... args);
iterator insert(const value_type& v);
iterator insert( value_type&& v); // C++17
template <class P>
@@ -641,28 +639,37 @@ class __map_value_compare {
_LIBCPP_COMPRESSED_ELEMENT(_Compare, __comp_);
public:
- _LIBCPP_HIDE_FROM_ABI __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_value_compare()
+ _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)
: __comp_() {}
- _LIBCPP_HIDE_FROM_ABI __map_value_compare(_Compare __c) _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_value_compare(_Compare __c)
+ _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)
: __comp_(__c) {}
- _LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return __comp_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const _Compare& key_comp() const _NOEXCEPT { return __comp_; }
- _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const { return __comp_(__x.first, __y.first); }
- _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const { return __comp_(__x.first, __y); }
- _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const { return __comp_(__x, __y.first); }
- _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator()(const _CP& __x, const _CP& __y) const {
+ return __comp_(__x.first, __y.first);
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator()(const _CP& __x, const _Key& __y) const {
+ return __comp_(__x.first, __y);
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator()(const _Key& __x, const _CP& __y) const {
+ return __comp_(__x, __y.first);
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(__map_value_compare& __y)
+ _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {
using std::swap;
swap(__comp_, __y.__comp_);
}
# if _LIBCPP_STD_VER >= 14
template <typename _K2>
- _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator()(const _K2& __x, const _CP& __y) const {
return __comp_(__x, __y.first);
}
template <typename _K2>
- _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool operator()(const _CP& __x, const _K2& __y) const {
return __comp_(__x.first, __y);
}
# endif
@@ -678,11 +685,11 @@ template <class _MapValueT, class _Key, class _Compare>
struct __lazy_synth_three_way_comparator<__map_value_compare<_Key, _MapValueT, _Compare>, _MapValueT, _MapValueT> {
__lazy_synth_three_way_comparator<_Compare, _Key, _Key> __comp_;
- __lazy_synth_three_way_comparator(
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 __lazy_synth_three_way_comparator(
_LIBCPP_CTOR_LIFETIMEBOUND const __map_value_compare<_Key, _MapValueT, _Compare>& __comp)
: __comp_(__comp.key_comp()) {}
- _LIBCPP_HIDE_FROM_ABI auto
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto
operator()(_LIBCPP_LIFETIMEBOUND const _MapValueT& __lhs, _LIBCPP_LIFETIMEBOUND const _MapValueT& __rhs) const {
return __comp_(__lhs.first, __rhs.first);
}
@@ -692,11 +699,11 @@ template <class _MapValueT, class _Key, class _TransparentKey, class _Compare>
struct __lazy_synth_three_way_comparator<__map_value_compare<_Key, _MapValueT, _Compare>, _TransparentKey, _MapValueT> {
__lazy_synth_three_way_comparator<_Compare, _TransparentKey, _Key> __comp_;
- __lazy_synth_three_way_comparator(
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 __lazy_synth_three_way_comparator(
_LIBCPP_CTOR_LIFETIMEBOUND const __map_value_compare<_Key, _MapValueT, _Compare>& __comp)
: __comp_(__comp.key_comp()) {}
- _LIBCPP_HIDE_FROM_ABI auto
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 auto
operator()(_LIBCPP_LIFETIMEBOUND const _TransparentKey& __lhs, _LIBCPP_LIFETIMEBOUND const _MapValueT& __rhs) const {
return __comp_(__lhs, __rhs.first);
}
@@ -718,7 +725,7 @@ struct __lazy_synth_three_way_comparator<__map_value_compare<_Key, _MapValueT, _
# endif // _LIBCPP_STD_VER >= 14
template <class _Key, class _CP, class _Compare>
-inline _LIBCPP_HIDE_FROM_ABI void
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
swap(__map_value_compare<_Key, _CP, _Compare>& __x, __map_value_compare<_Key, _CP, _Compare>& __y)
_NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
__x.swap(__y);
@@ -779,37 +786,41 @@ public:
using reference = value_type&;
using pointer = typename _TreeIterator::pointer;
- _LIBCPP_HIDE_FROM_ABI __map_iterator() _NOEXCEPT {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_iterator() _NOEXCEPT {}
- _LIBCPP_HIDE_FROM_ABI __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
- _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__i_; }
- _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(*__i_); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reference operator*() const { return *__i_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pointer operator->() const {
+ return pointer_traits<pointer>::pointer_to(*__i_);
+ }
- _LIBCPP_HIDE_FROM_ABI __map_iterator& operator++() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_iterator& operator++() {
++__i_;
return *this;
}
- _LIBCPP_HIDE_FROM_ABI __map_iterator operator++(int) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_iterator operator++(int) {
__map_iterator __t(*this);
++(*this);
return __t;
}
- _LIBCPP_HIDE_FROM_ABI __map_iterator& operator--() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_iterator& operator--() {
--__i_;
return *this;
}
- _LIBCPP_HIDE_FROM_ABI __map_iterator operator--(int) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_iterator operator--(int) {
__map_iterator __t(*this);
--(*this);
return __t;
}
- friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __map_iterator& __x, const __map_iterator& __y) {
+ friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+ operator==(const __map_iterator& __x, const __map_iterator& __y) {
return __x.__i_ == __y.__i_;
}
- friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __map_iterator& __x, const __map_iterator& __y) {
+ friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+ operator!=(const __map_iterator& __x, const __map_iterator& __y) {
return __x.__i_ != __y.__i_;
}
@@ -834,7 +845,8 @@ struct __specialized_algorithm<_Alg, __iterator_pair<__map_iterator<_TreeIterato
using __iterator _LIBCPP_NODEBUG = __map_iterator<_TreeIterator>;
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void
+ operator()(__iterator __first, __iterator __last, _Args&&... __args) {
__base()(__first.__i_, __last.__i_, std::forward<_Args>(__args)...);
}
};
@@ -851,39 +863,43 @@ public:
using reference = const value_type&;
using pointer = typename _TreeIterator::pointer;
- _LIBCPP_HIDE_FROM_ABI __map_const_iterator() _NOEXCEPT {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_const_iterator() _NOEXCEPT {}
- _LIBCPP_HIDE_FROM_ABI __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
__map_const_iterator(__map_iterator< typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT : __i_(__i.__i_) {}
- _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__i_; }
- _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(*__i_); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reference operator*() const { return *__i_; }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pointer operator->() const {
+ return pointer_traits<pointer>::pointer_to(*__i_);
+ }
- _LIBCPP_HIDE_FROM_ABI __map_const_iterator& operator++() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_const_iterator& operator++() {
++__i_;
return *this;
}
- _LIBCPP_HIDE_FROM_ABI __map_const_iterator operator++(int) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_const_iterator operator++(int) {
__map_const_iterator __t(*this);
++(*this);
return __t;
}
- _LIBCPP_HIDE_FROM_ABI __map_const_iterator& operator--() {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_const_iterator& operator--() {
--__i_;
return *this;
}
- _LIBCPP_HIDE_FROM_ABI __map_const_iterator operator--(int) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __map_const_iterator operator--(int) {
__map_const_iterator __t(*this);
--(*this);
return __t;
}
- friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y) {
+ friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+ operator==(const __map_const_iterator& __x, const __map_const_iterator& __y) {
return __x.__i_ == __y.__i_;
}
- friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y) {
+ friend _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+ operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y) {
return __x.__i_ != __y.__i_;
}
@@ -910,7 +926,8 @@ struct __specialized_algorithm<
using __iterator _LIBCPP_NODEBUG = __map_const_iterator<_TreeIterator>;
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void
+ operator()(__iterator __first, __iterator __last, _Args&&... __args) {
__base()(__first.__i_, __last.__i_, std::forward<_Args>(__args)...);
}
};
@@ -940,10 +957,11 @@ public:
protected:
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) {}
public:
- _LIBCPP_HIDE_FROM_ABI bool operator()(const value_type& __x, const value_type& __y) const {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
+ operator()(const value_type& __x, const value_type& __y) const {
return comp(__x.first, __y.first);
}
};
@@ -979,26 +997,27 @@ public:
template <class _Key2, class _Value2, class _Comp2, class _Alloc2>
friend class multimap;
- _LIBCPP_HIDE_FROM_ABI map() _NOEXCEPT_(
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map() _NOEXCEPT_(
is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&
is_nothrow_copy_constructible<key_compare>::value)
: __tree_(__vc(key_compare())) {}
- _LIBCPP_HIDE_FROM_ABI explicit map(const key_compare& __comp) _NOEXCEPT_(
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit map(const key_compare& __comp) _NOEXCEPT_(
is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)
: __tree_(__vc(__comp)) {}
- _LIBCPP_HIDE_FROM_ABI explicit map(const key_compare& __comp, const allocator_type& __a)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit map(const key_compare& __comp, const allocator_type& __a)
: __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}
template <class _InputIterator>
- _LIBCPP_HIDE_FROM_ABI map(_InputIterator __f, _InputIterator __l, const key_compare& __comp = key_compare())
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
+ map(_InputIterator __f, _InputIterator __l, const key_compare& __comp = key_compare())
: __tree_(__vc(__comp)) {
insert(__f, __l);
}
template <class _InputIterator>
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
map(_InputIterator __f, _InputIterator __l, const key_compare& __comp, const allocator_type& __a)
: __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
insert(__f, __l);
@@ -1006,7 +1025,7 @@ public:
# if _LIBCPP_STD_VER >= 23
template <_ContainerCompatibleRange<value_type> _Range>
- _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
map(from_range_t,
_Range&& __range,
const key_compare& __comp = key_compare(),
@@ -1018,44 +1037,48 @@ public:
# if _LIBCPP_STD_VER >= 14
template <class _InputIterator>
- _LIBCPP_HIDE_FROM_ABI map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
+ _LIBCPP_HIDE_FROM_ABI
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
: map(__f, __l, key_compare(), __a) {}
# endif
# if _LIBCPP_STD_VER >= 23
template <_ContainerCompatibleRange<value_type> _Range>
- _LIBCPP_HIDE_FROM_ABI map(from_range_t, _Range&& __range, const allocator_type& __a)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(from_range_t, _Range&& __range, const allocator_type& __a)
: map(from_range, std::forward<_Range>(__range), key_compare(), __a) {}
# endif
- _LIBCPP_HIDE_FROM_ABI map(const map& __m) = default;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(const map& __m) = default;
- _LIBCPP_HIDE_FROM_ABI map& operator=(const map& __m) = default;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map& operator=(const map& __m) = default;
# ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI map(map&& __m) = default;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(map&& __m) = default;
- _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), __a) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(map&& __m, const allocator_type& __a)
+ : __tree_(std::move(__m.__tree_), __a) {}
- _LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) = default;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map& operator=(map&& __m) = default;
- _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
+ map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())
: __tree_(__vc(__comp)) {
insert(__il.begin(), __il.end());
}
- _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26
+ map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
: __tree_(__vc(__comp), typename __base::allocator_type(__a)) {
insert(__il.begin(), __il.end());
}
# if _LIBCPP_STD_VER >= 14
- _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const allocator_type& __a)
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(initializer_list<value_type> __il, const allocator_type& __a)
: map(__il, key_compare(), __a) {}
# endif
- _LIBCPP_HIDE_FROM_ABI map& operator=(initializer_list<value_type> __il) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map& operator=(initializer_list<value_type> __il) {
clear();
insert(__il.begin(), __il.end());
return *this;
@@ -1063,118 +1086,157 @@ public:
# endif // _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI explicit map(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 explicit map(const allocator_type& __a)
+ : __tree_(typename __base::allocator_type(__a)) {}
- _LIBCPP_HIDE_FROM_ABI map(const map& __m, const allocator_type& __alloc) : __tree_(__m.__tree_, __alloc) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(const map& __m, const allocator_type& __alloc)
+ : __tree_(__m.__tree_, __alloc) {}
- _LIBCPP_HIDE_FROM_ABI ~map() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 ~map() {
+ static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), "");
+ }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator begin() _NOEXCEPT {
+ return __tree_.begin();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator begin() const _NOEXCEPT {
+ return __tree_.begin();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator end() _NOEXCEPT {
+ return __tree_.end();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator end() const _NOEXCEPT {
+ return __tree_.end();
+ }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rbegin() _NOEXCEPT {
+ return reverse_iterator(end());
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator
+ rbegin() const _NOEXCEPT {
return const_reverse_iterator(end());
}
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 reverse_iterator rend() _NOEXCEPT {
+ return reverse_iterator(begin());
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator rend() const _NOEXCEPT {
return const_reverse_iterator(begin());
}
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cbegin() const _NOEXCEPT {
+ return begin();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator cend() const _NOEXCEPT {
+ return end();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator
+ crbegin() const _NOEXCEPT {
+ return rbegin();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_reverse_iterator crend() const _NOEXCEPT {
+ return rend();
+ }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool empty() const _NOEXCEPT {
+ return __tree_.size() == 0;
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type size() const _NOEXCEPT {
+ return __tree_.size();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type max_size() const _NOEXCEPT {
+ return __tree_.max_size();
+ }
- _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](const key_type& __k);
# ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& operator[](key_type&& __k);
# endif
template <class _Arg,
__enable_if_t<__is_transparently_comparable_v<_Compare, key_type, __remove_cvref_t<_Arg> >, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mapped_type& at(_Arg&& __arg) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(_Arg&& __arg) {
auto [_, __child] = __tree_.__find_equal(__arg);
if (__child == nullptr)
std::__throw_out_of_range("map::at: key not found");
- return static_cast<__node_pointer>(__child)->__get_value().second;
+ return std::__static_fancy_pointer_cast<__node_pointer>(__child)->__get_value().second;
}
template <class _Arg,
__enable_if_t<__is_transparently_comparable_v<_Compare, key_type, __remove_cvref_t<_Arg> >, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const mapped_type& at(_Arg&& __arg) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type& at(_Arg&& __arg) const {
auto [_, __child] = __tree_.__find_equal(__arg);
if (__child == nullptr)
std::__throw_out_of_range("map::at: key not found");
- return static_cast<__node_pointer>(__child)->__get_value().second;
+ return std::__static_fancy_pointer_cast<__node_pointer>(__child)->__get_value().second;
}
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 mapped_type& at(const key_type& __k);
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const mapped_type&
+ at(const key_type& __k) const;
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 allocator_type get_allocator() const _NOEXCEPT {
return allocator_type(__tree_.__alloc());
}
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 key_compare key_comp() const {
+ return __tree_.value_comp().key_comp();
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 value_compare value_comp() const {
return value_compare(__tree_.value_comp().key_comp());
}
# ifndef _LIBCPP_CXX03_LANG
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> emplace(_Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> emplace(_Args&&... __args) {
return __tree_.__emplace_unique(std::forward<_Args>(__args)...);
}
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator emplace_hint(const_iterator __p, _Args&&... __args) {
return __tree_.__emplace_hint_unique(__p.__i_, std::forward<_Args>(__args)...).first;
}
template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(_Pp&& __p) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert(_Pp&& __p) {
return __tree_.__emplace_unique(std::forward<_Pp>(__p));
}
template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __pos, _Pp&& __p) {
return __tree_.__emplace_hint_unique(__pos.__i_, std::forward<_Pp>(__p)).first;
}
# endif // _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__emplace_unique(__v); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert(const value_type& __v) {
+ return __tree_.__emplace_unique(__v);
+ }
- _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __p, const value_type& __v) {
return __tree_.__emplace_hint_unique(__p.__i_, __v).first;
}
# ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert(value_type&& __v) {
return __tree_.__emplace_unique(std::move(__v));
}
- _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __p, value_type&& __v) {
return __tree_.__emplace_hint_unique(__p.__i_, std::move(__v)).first;
}
- _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(initializer_list<value_type> __il) {
+ insert(__il.begin(), __il.end());
+ }
# endif
template <class _InputIterator>
- _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert(_InputIterator __first, _InputIterator __last) {
__tree_.__insert_range_unique(__first, __last);
}
# if _LIBCPP_STD_VER >= 23
template <_ContainerCompatibleRange<value_type> _Range>
- _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void insert_range(_Range&& __range) {
__tree_.__insert_range_unique(ranges::begin(__range), ranges::end(__range));
}
# endif
@@ -1182,13 +1244,15 @@ public:
# if _LIBCPP_STD_VER >= 17
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool>
+ try_emplace(const key_type& __k, _Args&&... __args) {
return __tree_.__emplace_unique(
std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple(std::forward<_Args>(__args)...));
}
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool>
+ try_emplace(key_type&& __k, _Args&&... __args) {
return __tree_.__emplace_unique(
std::piecewise_construct,
std::forward_as_tuple(std::move(__k)),
@@ -1196,7 +1260,8 @@ public:
}
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
+ try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) {
return __tree_
.__emplace_hint_unique(
__h.__i_,
@@ -1207,7 +1272,8 @@ public:
}
template <class... _Args>
- _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
+ try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) {
return __tree_
.__emplace_hint_unique(
__h.__i_,
@@ -1218,7 +1284,8 @@ public:
}
template <class _Vp>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool>
+ insert_or_assign(const key_type& __k, _Vp&& __v) {
auto __result = __tree_.__emplace_unique(__k, std::forward<_Vp>(__v));
auto& [__iter, __inserted] = __result;
if (!__inserted)
@@ -1227,7 +1294,7 @@ public:
}
template <class _Vp>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) {
auto __result = __tree_.__emplace_unique(std::move(__k), std::forward<_Vp>(__v));
auto& [__iter, __inserted] = __result;
if (!__inserted)
@@ -1236,7 +1303,8 @@ public:
}
template <class _Vp>
- _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
+ insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) {
auto [__r, __inserted] = __tree_.__emplace_hint_unique(__h.__i_, __k, std::forward<_Vp>(__v));
if (!__inserted)
@@ -1246,7 +1314,8 @@ public:
}
template <class _Vp>
- _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator
+ insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v) {
auto [__r, __inserted] = __tree_.__emplace_hint_unique(__h.__i_, std::move(__k), std::forward<_Vp>(__v));
if (!__inserted)
@@ -1257,39 +1326,45 @@ public:
# endif // _LIBCPP_STD_VER >= 17
- _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p.__i_); }
- _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __p) { return __tree_.erase(__p.__i_); }
- _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_unique(__k); }
- _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __p) {
+ return __tree_.erase(__p.__i_);
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(iterator __p) { return __tree_.erase(__p.__i_); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type erase(const key_type& __k) {
+ return __tree_.__erase_unique(__k);
+ }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator erase(const_iterator __f, const_iterator __l) {
return __tree_.erase(__f.__i_, __l.__i_);
}
- _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void clear() _NOEXCEPT { __tree_.clear(); }
# if _LIBCPP_STD_VER >= 17
- _LIBCPP_HIDE_FROM_ABI insert_return_type insert(node_type&& __nh) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 insert_return_type insert(node_type&& __nh) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to map::insert()");
return __tree_.template __node_handle_insert_unique< node_type, insert_return_type>(std::move(__nh));
}
- _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator insert(const_iterator __hint, node_type&& __nh) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to map::insert()");
return __tree_.template __node_handle_insert_unique<node_type>(__hint.__i_, std::move(__nh));
}
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 node_type extract(key_type const& __key) {
return __tree_.template __node_handle_extract<node_type>(__key);
}
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 node_type extract(const_iterator __it) {
return __tree_.template __node_handle_extract<node_type>(__it.__i_);
}
template <class _Compare2>
- _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+ merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
}
template <class _Compare2>
- _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
+ merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
__source.get_allocator() == get_allocator(), "merging container with incompatible allocator");
__tree_.__node_handle_merge_unique(__source.__tree_);
@@ -1308,50 +1383,59 @@ public:
}
# endif
- _LIBCPP_HIDE_FROM_ABI void swap(map& __m) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) { __tree_.swap(__m.__tree_); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void swap(map& __m) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) {
+ __tree_.swap(__m.__tree_);
+ }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const key_type& __k) {
+ return __tree_.find(__k);
+ }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const key_type& __k) const {
+ return __tree_.find(__k);
+ }
# if _LIBCPP_STD_VER >= 14
template <typename _K2,
class _Comp = _Compare,
enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator find(const _K2& __k) {
return __tree_.find(__k);
}
template <typename _K2,
class _Comp = _Compare,
enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator find(const _K2& __k) const {
return __tree_.find(__k);
}
# endif
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const key_type& __k) const {
return __tree_.__count_unique(__k);
}
# if _LIBCPP_STD_VER >= 14
template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 size_type count(const _K2& __k) const {
return __tree_.__count_multi(__k);
}
# endif
# if _LIBCPP_STD_VER >= 20
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const key_type& __k) const {
+ return find(__k) != end();
+ }
template <typename _K2,
class _Comp = _Compare,
enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool contains(const _K2& __k) const {
return find(__k) != end();
}
# endif // _LIBCPP_STD_VER >= 20
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const key_type& __k) {
return __tree_.__lower_bound_unique(__k);
}
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ lower_bound(const key_type& __k) const {
return __tree_.__lower_bound_unique(__k);
}
@@ -1361,23 +1445,25 @@ public:
template <typename _K2,
class _Comp = _Compare,
enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator lower_bound(const _K2& __k) {
return __tree_.__lower_bound_multi(__k);
}
template <typename _K2,
class _Comp = _Compare,
enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ lower_bound(const _K2& __k) const {
return __tree_.__lower_bound_multi(__k);
}
# endif
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const key_type& __k) {
return __tree_.__upper_bound_unique(__k);
}
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ upper_bound(const key_type& __k) const {
return __tree_.__upper_bound_unique(__k);
}
@@ -1385,30 +1471,35 @@ public:
template <typename _K2,
class _Comp = _Compare,
enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 iterator upper_bound(const _K2& __k) {
return __tree_.__upper_bound_multi(__k);
}
template <typename _K2,
class _Comp = _Compare,
enable_if_t<__is_transparent_v<_Comp> || __is_transparently_comparable_v<_Comp, key_type, _K2>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 const_iterator
+ upper_bound(const _K2& __k) const {
return __tree_.__upper_bound_multi(__k);
}
# endif
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {
+ [[__nodiscard__]]
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const key_type& __k) {
return __tree_.__equal_range_unique(__k);
}
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ equal_range(const key_type& __k) const {
return __tree_.__equal_range_unique(__k);
}
# if _LIBCPP_STD_VER >= 14
template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {
+ [[__nodiscard__]]
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<iterator, iterator> equal_range(const _K2& __k) {
return __tree_.__equal_range_multi(__k);
}
template <typename _K2, class _Comp = _Compare, enable_if_t<__is_transparent_v<_Comp>, int> = 0>
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 pair<const_iterator, const_iterator>
+ equal_range(const _K2& __k) const {
return __tree_.__equal_range_multi(__k);
}
# endif
@@ -1487,7 +1578,7 @@ struct __specialized_algorithm<_Algorithm::__for_each, __single_range<map<_Key,
static const bool __has_algorithm = true;
template <class _Map, class _Func, class _Proj>
- _LIBCPP_HIDE_FROM_ABI static auto operator()(_Map&& __map, _Func __func, _Proj __proj) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto operator()(_Map&& __map, _Func __func, _Proj __proj) {
auto [_, __func2] = __specialized_algorithm<_Algorithm::__for_each, __single_range<typename __map::__base>>()(
__map.__tree_, std::move(__func), std::move(__proj));
return std::make_pair(__map.end(), std::move(__func2));
@@ -1497,13 +1588,13 @@ struct __specialized_algorithm<_Algorithm::__for_each, __single_range<map<_Key,
# ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Tp, class _Compare, class _Allocator>
-_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
return __tree_.__emplace_unique(std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())
.first->second;
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
-_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) {
return __tree_
.__emplace_unique(std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())
.first->second;
@@ -1538,23 +1629,23 @@ _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
# endif // _LIBCPP_CXX03_LANG
template <class _Key, class _Tp, class _Compare, class _Allocator>
-_Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) {
auto [_, __child] = __tree_.__find_equal(__k);
if (__child == nullptr)
std::__throw_out_of_range("map::at: key not found");
- return static_cast<__node_pointer>(__child)->__get_value().second;
+ return std::__static_fancy_pointer_cast<__node_pointer>(__child)->__get_value().second;
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
-const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const {
+_LIBCPP_CONSTEXPR_SINCE_CXX26 const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const {
auto [_, __child] = __tree_.__find_equal(__k);
if (__child == nullptr)
std::__throw_out_of_range("map::at: key not found");
- return static_cast<__node_pointer>(__child)->__get_value().second;
+ return std::__static_fancy_pointer_cast<__node_pointer>(__child)->__get_value().second;
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI bool
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
}
@@ -1562,31 +1653,31 @@ operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp,
# if _LIBCPP_STD_VER <= 17
template <class _Key, class _Tp, class _Compare, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI bool
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
operator<(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI bool
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
return !(__x == __y);
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI bool
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
operator>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
return __y < __x;
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI bool
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
return !(__x < __y);
}
template <class _Key, class _Tp, class _Compare, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI bool
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 bool
operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
return !(__y < __x);
}
@@ -1594,7 +1685,7 @@ operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp,
# else // #if _LIBCPP_STD_VER <= 17
template <class _Key, class _Tp, class _Compare, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 __synth_three_way_result<pair<const _Key, _Tp>>
operator<=>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {
return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);
}
@@ -1602,7 +1693,7 @@ operator<=>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp
# endif // #if _LIBCPP_STD_VER <= 17
template <class _Key, class _Tp, class _Compare, class _Allocator>
-inline _LIBCPP_HIDE_FROM_ABI void
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void
swap(map<_Key, _Tp, _Compare, _Allocator>& __x, map<_Key, _Tp, _Compare, _Allocator>& __y)
_NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
__x.swap(__y);
@@ -1610,7 +1701,7 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x, map<_Key, _Tp, _Compare, _Alloca
# if _LIBCPP_STD_VER >= 20
template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
-inline _LIBCPP_HIDE_FROM_ABI typename map<_Key, _Tp, _Compare, _Allocator>::size_type
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 typename map<_Key, _Tp, _Compare, _Allocator>::size_type
erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
return std::__libcpp_erase_if_container(__c, __pred);
}
diff --git a/libcxx/include/version b/libcxx/include/version
index 471eb3c104b53..d4d29b4d31a72 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -78,6 +78,7 @@ __cpp_lib_constexpr_forward_list 202502L <forward_list>
__cpp_lib_constexpr_functional 201907L <functional>
__cpp_lib_constexpr_iterator 201811L <iterator>
__cpp_lib_constexpr_list 202502L <list>
+__cpp_lib_constexpr_map 202502L <map>
__cpp_lib_constexpr_memory 202202L <memory>
201811L // C++20
__cpp_lib_constexpr_new 202406L <new>
@@ -568,6 +569,7 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_constexpr_flat_set 202502L
# define __cpp_lib_constexpr_forward_list 202502L
# define __cpp_lib_constexpr_list 202502L
+# define __cpp_lib_constexpr_map 202502L
# if !defined(_LIBCPP_ABI_VCRUNTIME)
# define __cpp_lib_constexpr_new 202406L
# endif
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/for_each.associative.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/for_each.associative.pass.cpp
index 2bf7b261ed971..0fcd3ab27635a 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/for_each.associative.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/for_each.associative.pass.cpp
@@ -19,8 +19,10 @@
#include <map>
#include <set>
+#include "test_macros.h"
+
template <class Container, class Converter>
-void test_node_container(Converter conv) {
+TEST_CONSTEXPR_CXX26 void test_node_container(Converter conv) {
Container c;
using value_type = typename Container::value_type;
for (int i = 0; i != 10; ++i)
@@ -68,11 +70,25 @@ void test_node_container(Converter conv) {
}
}
-int main(int, char**) {
- test_node_container<std::set<int> >([](int i) { return i; });
- test_node_container<std::multiset<int> >([](int i) { return i; });
+TEST_CONSTEXPR_CXX26 bool test() {
+ // FIXME: remove when set is made constexpr
+ if (!TEST_IS_CONSTANT_EVALUATED)
+ test_node_container<std::set<int> >([](int i) { return i; });
+ // FIXME: remove when multiset is made constexpr
+ if (!TEST_IS_CONSTANT_EVALUATED)
+ test_node_container<std::multiset<int> >([](int i) { return i; });
test_node_container<std::map<int, int> >([](int i) { return std::make_pair(i, i); });
- test_node_container<std::multimap<int, int> >([](int i) { return std::make_pair(i, i); });
+ // FIXME: remove when multimap is made constexpr
+ if (!TEST_IS_CONSTANT_EVALUATED)
+ test_node_container<std::multimap<int, int> >([](int i) { return std::make_pair(i, i); });
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/ranges.for_each.associative.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/ranges.for_each.associative.pass.cpp
index 120308852b994..0a1bbe024cffa 100644
--- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/ranges.for_each.associative.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.foreach/ranges.for_each.associative.pass.cpp
@@ -25,8 +25,10 @@
#include <map>
#include <set>
+#include "test_macros.h"
+
template <class Container, class Converter>
-void test_node_container(Converter conv) {
+TEST_CONSTEXPR_CXX26 void test_node_container(Converter conv) {
using value_type = typename Container::value_type;
{ // Check that an empty container works
@@ -224,12 +226,12 @@ void test_invoke_set_like() {
}
template <template <class, class> class Container>
-void test_invoke_map_like() {
+TEST_CONSTEXPR_CXX26 void test_invoke_map_like() {
{ // check that std::invoke is used
struct S {
int i;
- void zero() { i = 0; }
+ TEST_CONSTEXPR_CXX26 void zero() { i = 0; }
};
{ // Iterator overload
@@ -249,17 +251,39 @@ void test_invoke_map_like() {
}
}
-int main(int, char**) {
- test_node_container<std::set<int> >([](int i) { return i; });
- test_node_container<std::multiset<int> >([](int i) { return i; });
+TEST_CONSTEXPR_CXX26 bool test() {
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ // FIXME: remove when set is made constexpr
+ test_node_container<std::set<int> >([](int i) { return i; });
+
+ // FIXME: remove when multiset is made constexpr
+ test_node_container<std::multiset<int> >([](int i) { return i; });
+
+ // FIXME: remove when multimap is made constexpr
+ test_node_container<std::multimap<int, int> >([](int i) { return std::make_pair(i, i); });
+ }
test_node_container<std::map<int, int> >([](int i) { return std::make_pair(i, i); });
- test_node_container<std::multimap<int, int> >([](int i) { return std::make_pair(i, i); });
- test_invoke_set_like<std::set>();
- test_invoke_set_like<std::multiset>();
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ // FIXME: remove when set is made constexpr
+ test_invoke_set_like<std::set>();
+
+ // FIXME: remove when multiset is made constexpr
+ test_invoke_set_like<std::multiset>();
+
+ // FIXME: remove when multimap is made constexpr
+ test_invoke_map_like<std::multimap>();
+ }
test_invoke_map_like<std::map>();
- test_invoke_map_like<std::multimap>();
+ 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/associative/from_range_associative_containers.h b/libcxx/test/std/containers/associative/from_range_associative_containers.h
index cb3646d738968..943b79f5211fc 100644
--- a/libcxx/test/std/containers/associative/from_range_associative_containers.h
+++ b/libcxx/test/std/containers/associative/from_range_associative_containers.h
@@ -60,7 +60,7 @@ template <template <class...> class Container,
class Comp,
class Alloc,
class ValueType = std::pair<const K, V>>
-void test_associative_map_with_input(std::vector<ValueType>&& input) {
+TEST_CONSTEXPR_CXX26 void test_associative_map_with_input(std::vector<ValueType>&& input) {
{ // (range)
auto in = wrap_input<Iter, Sent>(input);
Container<K, V> c(std::from_range, in);
@@ -103,7 +103,7 @@ void test_associative_map_with_input(std::vector<ValueType>&& input) {
}
template <template <class...> class Container, class K, class V, class Iter, class Sent, class Comp, class Alloc>
-void test_associative_map() {
+TEST_CONSTEXPR_CXX26 void test_associative_map() {
auto test_with_input = &test_associative_map_with_input<Container, K, V, Iter, Sent, Comp, Alloc>;
// Normal input.
@@ -115,7 +115,7 @@ void test_associative_map() {
}
template <template <class...> class Container>
-void test_associative_map_move_only() {
+TEST_CONSTEXPR_CXX26 void test_associative_map_move_only() {
std::pair<const int, MoveOnly> input[5];
std::ranges::subrange in(std::move_iterator{input}, std::move_iterator{input + 5});
@@ -123,8 +123,8 @@ void test_associative_map_move_only() {
}
template <template <class...> class Container>
-void test_map_exception_safety_throwing_copy() {
-#if !defined(TEST_HAS_NO_EXCEPTIONS)
+TEST_CONSTEXPR_CXX26 void test_map_exception_safety_throwing_copy() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(TEST_IS_CONSTANT_EVALUATED)
using K = int;
using V = ThrowingCopy<3>;
@@ -145,8 +145,8 @@ void test_map_exception_safety_throwing_copy() {
}
template <template <class...> class Container, class K, class V>
-void test_map_exception_safety_throwing_allocator() {
-#if !defined(TEST_HAS_NO_EXCEPTIONS)
+TEST_CONSTEXPR_CXX26 void test_map_exception_safety_throwing_allocator() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(TEST_IS_CONSTANT_EVALUATED)
using ValueType = std::pair<const K, V>;
ValueType in[] = {ValueType{K{1}, V{1}}};
@@ -189,7 +189,7 @@ constexpr bool test_set_constraints() {
}
template <template <class...> class Container, class T, class Iter, class Sent, class Comp, class Alloc>
-void test_associative_set_with_input(std::vector<T>&& input) {
+TEST_CONSTEXPR_CXX26 void test_associative_set_with_input(std::vector<T>&& input) {
{ // (range)
std::ranges::subrange in(Iter(input.data()), Sent(Iter(input.data() + input.size())));
Container<T> c(std::from_range, in);
@@ -232,7 +232,7 @@ void test_associative_set_with_input(std::vector<T>&& input) {
}
template <template <class...> class Container, class T, class Iter, class Sent, class Comp, class Alloc>
-void test_associative_set() {
+TEST_CONSTEXPR_CXX26 void test_associative_set() {
auto test_with_input = &test_associative_set_with_input<Container, T, Iter, Sent, Comp, Alloc>;
// Normal input.
diff --git a/libcxx/test/std/containers/associative/map/compare.pass.cpp b/libcxx/test/std/containers/associative/map/compare.pass.cpp
index cb7a64b0409fc..464446e4d9058 100644
--- a/libcxx/test/std/containers/associative/map/compare.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/compare.pass.cpp
@@ -10,7 +10,7 @@
// template <class Key, class T, class Compare = less<Key>,
// class Allocator = allocator<pair<const Key, T>>>
-// class map
+// class map // constexpr since C++26
// https://llvm.org/PR16538
// https://llvm.org/PR16549
@@ -23,11 +23,11 @@
struct Key {
template <typename T>
- Key(const T&) {}
- bool operator<(const Key&) const { return false; }
+ TEST_CONSTEXPR_CXX26 Key(const T&) {}
+ TEST_CONSTEXPR_CXX26 bool operator<(const Key&) const { return false; }
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::map<Key, int> MapT;
typedef MapT::iterator Iter;
typedef std::pair<Iter, bool> IterBool;
@@ -50,6 +50,13 @@ int main(int, char**) {
assert(!result2.second);
assert(map[Key(0)] == 42);
}
+ 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/associative/map/get_allocator.pass.cpp b/libcxx/test/std/containers/associative/map/get_allocator.pass.cpp
index 2dbd662d3b7ac..d52ce6a775c73 100644
--- a/libcxx/test/std/containers/associative/map/get_allocator.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/get_allocator.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// allocator_type get_allocator() const
+// allocator_type get_allocator() const // constexpr since C++26
#include <map>
#include <cassert>
@@ -19,7 +19,7 @@
#include "test_allocator.h"
#include "test_macros.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::pair<const int, std::string> ValueType;
{
std::allocator<ValueType> alloc;
@@ -31,6 +31,13 @@ int main(int, char**) {
const std::map<int, std::string, std::less<int>, other_allocator<ValueType> > m(alloc);
assert(m.get_allocator() == alloc);
}
+ 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/associative/map/incomplete_type.pass.cpp b/libcxx/test/std/containers/associative/map/incomplete_type.pass.cpp
index 6f9e38cf35f5c..939a23f240b52 100644
--- a/libcxx/test/std/containers/associative/map/incomplete_type.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/incomplete_type.pass.cpp
@@ -6,13 +6,15 @@
//
//===----------------------------------------------------------------------===//
-// <map>
+// <map> // constexpr since C++26
// Check that std::map and its iterators can be instantiated with an incomplete
// type.
#include <map>
+#include <cassert>
+
#include "min_allocator.h"
#include "test_macros.h"
@@ -26,11 +28,19 @@ struct A {
inline bool operator==(A const& L, A const& R) { return &L == &R; }
inline bool operator<(A const& L, A const& R) { return L.data < R.data; }
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
A a;
// Make sure that the allocator isn't rebound to and incomplete type
std::map<int, int, std::less<int>, complete_type_allocator<std::pair<const int, int> > > m;
+ 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/associative/map/map.access/at.pass.cpp b/libcxx/test/std/containers/associative/map/map.access/at.pass.cpp
index cabc9f7eb1066..7418d807e76cc 100644
--- a/libcxx/test/std/containers/associative/map/map.access/at.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.access/at.pass.cpp
@@ -10,8 +10,8 @@
// class map
-// mapped_type& at(const key_type& k);
-// const mapped_type& at(const key_type& k) const;
+// mapped_type& at(const key_type& k); // constexpr since C++26
+// const mapped_type& at(const key_type& k) const; // constexpr since C++26
#include <cassert>
#include <map>
@@ -20,7 +20,7 @@
#include "min_allocator.h"
#include "test_macros.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
V ar[] = {
@@ -42,11 +42,16 @@ int main(int, char**) {
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&) {
+
+ // throwing is not allowed during constant evaluation
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ try {
+ TEST_IGNORE_NODISCARD m.at(6);
+ assert(false);
+ } catch (std::out_of_range&) {
+ }
}
+
#endif
assert(m.at(7) == 7.5);
assert(m.at(8) == 8.5);
@@ -71,12 +76,16 @@ int main(int, char**) {
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&) {
+ // throwing is not allowed during constant evaluation
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ try {
+ TEST_IGNORE_NODISCARD m.at(6);
+ assert(false);
+ } catch (std::out_of_range&) {
+ }
}
#endif
+
assert(m.at(7) == 7.5);
assert(m.at(8) == 8.5);
assert(m.size() == 7);
@@ -103,10 +112,14 @@ int main(int, char**) {
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&) {
+
+ // throwing is not allowed during constant evaluation
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ try {
+ TEST_IGNORE_NODISCARD m.at(6);
+ assert(false);
+ } catch (std::out_of_range&) {
+ }
}
# endif
assert(m.at(7) == 7.5);
@@ -132,17 +145,28 @@ int main(int, char**) {
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&) {
+ // throwing is not allowed during constant evaluation
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ try {
+ TEST_IGNORE_NODISCARD m.at(6);
+ assert(false);
+ } catch (std::out_of_range&) {
+ }
}
+
# endif
assert(m.at(7) == 7.5);
assert(m.at(8) == 8.5);
assert(m.size() == 7);
}
#endif
+ 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/associative/map/map.access/empty.pass.cpp b/libcxx/test/std/containers/associative/map/map.access/empty.pass.cpp
index 21118eca69693..3b1e04eb5c484 100644
--- a/libcxx/test/std/containers/associative/map/map.access/empty.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.access/empty.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// bool empty() const;
+// bool empty() const; // constexpr since C++26
#include <map>
#include <cassert>
@@ -18,7 +18,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double> M;
M m;
@@ -39,6 +39,13 @@ int main(int, char**) {
assert(m.empty());
}
#endif
+ 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/associative/map/map.access/index_key.pass.cpp b/libcxx/test/std/containers/associative/map/map.access/index_key.pass.cpp
index 58610c69ed3dc..d2db33ffa4021 100644
--- a/libcxx/test/std/containers/associative/map/map.access/index_key.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.access/index_key.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// mapped_type& operator[](const key_type& k);
+// mapped_type& operator[](const key_type& k); // constexpr since C++26
#include <map>
#include <cassert>
@@ -23,7 +23,7 @@
# include "container_test_types.h"
#endif
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
V ar[] = {
@@ -74,6 +74,8 @@ int main(int, char**) {
assert(m[6] == 6.5);
assert(m.size() == 8);
}
+# ifndef TEST_IS_CONSTANT_EVALUATED
+ // static can't be constexpr
{
// Use "container_test_types.h" to check what arguments get passed
// to the allocator for operator[]
@@ -107,6 +109,7 @@ int main(int, char**) {
}
}
}
+# endif
#endif
#if TEST_STD_VER > 11
{
@@ -135,6 +138,13 @@ int main(int, char**) {
assert(m.size() == 8);
}
#endif
+ 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/associative/map/map.access/index_rv_key.pass.cpp b/libcxx/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
index d5d01b96a6988..6f25b54547c2e 100644
--- a/libcxx/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.access/index_rv_key.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// mapped_type& operator[](key_type&& k);
+// mapped_type& operator[](key_type&& k); // constexpr since C++26
#include <map>
#include <cassert>
@@ -23,7 +23,7 @@
#include "min_allocator.h"
#include "container_test_types.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
std::map<MoveOnly, double> m;
assert(m.size() == 0);
@@ -53,6 +53,8 @@ int main(int, char**) {
assert(m[6] == 6.5);
assert(m.size() == 2);
}
+#ifndef TEST_IS_CONSTANT_EVALUATED
+ // static can't be constexpr
{
// Use "container_test_types.h" to check what arguments get passed
// to the allocator for operator[]
@@ -76,5 +78,15 @@ int main(int, char**) {
}
}
+#endif
+ 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/associative/map/map.access/index_tuple.pass.cpp b/libcxx/test/std/containers/associative/map/map.access/index_tuple.pass.cpp
index 3f33cfd699151..3148fca2b0e9a 100644
--- a/libcxx/test/std/containers/associative/map/map.access/index_tuple.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.access/index_tuple.pass.cpp
@@ -12,16 +12,26 @@
// class map
-// mapped_type& operator[](const key_type& k);
+// mapped_type& operator[](const key_type& k); // constexpr since C++26
// https://llvm.org/PR16542
#include <map>
#include <tuple>
-int main(int, char**) {
+#include <cassert>
+#include "test_macros.h"
+
+TEST_CONSTEXPR_CXX26 bool test() {
std::map<std::tuple<int, int>, std::size_t> m;
m[std::make_tuple(2, 3)] = 7;
+ 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/associative/map/map.access/iterator.pass.cpp b/libcxx/test/std/containers/associative/map/map.access/iterator.pass.cpp
index bbad44c8edb30..e92a68e4d7072 100644
--- a/libcxx/test/std/containers/associative/map/map.access/iterator.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.access/iterator.pass.cpp
@@ -10,20 +10,20 @@
// class map
-// iterator begin();
-// const_iterator begin() const;
-// iterator end();
-// const_iterator end() const;
+// iterator begin(); // constexpr since C++26
+// const_iterator begin() const; // constexpr since C++26
+// iterator end(); // constexpr since C++26
+// const_iterator end() const; // constexpr since C++26
//
-// reverse_iterator rbegin();
-// const_reverse_iterator rbegin() const;
-// reverse_iterator rend();
-// const_reverse_iterator rend() const;
+// reverse_iterator rbegin(); // constexpr since C++26
+// const_reverse_iterator rbegin() const; // constexpr since C++26
+// reverse_iterator rend(); // constexpr since C++26
+// const_reverse_iterator rend() const; // constexpr since C++26
//
-// const_iterator cbegin() const;
-// const_iterator cend() const;
-// const_reverse_iterator crbegin() const;
-// const_reverse_iterator crend() const;
+// const_iterator cbegin() const; // constexpr since C++26
+// const_iterator cend() const; // constexpr since C++26
+// const_reverse_iterator crbegin() const; // constexpr since C++26
+// const_reverse_iterator crend() const; // constexpr since C++26
#include <map>
#include <cassert>
@@ -32,7 +32,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
V ar[] = {V(1, 1), V(1, 1.5), V(1, 2), V(2, 1), V(2, 1.5), V(2, 2), V(3, 1), V(3, 1.5),
@@ -156,6 +156,13 @@ int main(int, char**) {
assert(!(cii != ii1));
}
#endif
+ 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/associative/map/map.access/max_size.pass.cpp b/libcxx/test/std/containers/associative/map/map.access/max_size.pass.cpp
index 1a5d35c2579d8..27bd52b1c41d9 100644
--- a/libcxx/test/std/containers/associative/map/map.access/max_size.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.access/max_size.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// size_type max_size() const;
+// size_type max_size() const; // constexpr since C++26
#include <cassert>
#include <limits>
@@ -20,7 +20,7 @@
#include "test_allocator.h"
#include "test_macros.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::pair<const int, int> KV;
{
typedef limited_allocator<KV, 10> A;
@@ -44,6 +44,13 @@ int main(int, char**) {
assert(c.max_size() <= max_dist);
assert(c.max_size() <= alloc_max_size(c.get_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/associative/map/map.access/size.pass.cpp b/libcxx/test/std/containers/associative/map/map.access/size.pass.cpp
index 23914f6b8ed16..92507945e143e 100644
--- a/libcxx/test/std/containers/associative/map/map.access/size.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.access/size.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// size_type size() const;
+// size_type size() const; // constexpr since C++26
#include <map>
#include <cassert>
@@ -18,7 +18,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double> M;
M m;
@@ -55,6 +55,13 @@ int main(int, char**) {
assert(m.size() == 0);
}
#endif
+ 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/associative/map/map.cons/alloc.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/alloc.pass.cpp
index 52199204d7914..9b854659c38f9 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/alloc.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/alloc.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// explicit map(const allocator_type& a);
+// explicit map(const allocator_type& a); // constexpr since C++26
#include <map>
#include <cassert>
@@ -19,7 +19,7 @@
#include "test_allocator.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::less<int> C;
typedef test_allocator<std::pair<const int, double> > A;
@@ -46,6 +46,13 @@ int main(int, char**) {
assert(m.get_allocator() == A());
}
#endif
+ 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/associative/map/map.cons/assign_initializer_list.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
index f237c9b56deee..a0308e1d218d5 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/assign_initializer_list.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// map& operator=(initializer_list<value_type> il);
+// map& operator=(initializer_list<value_type> il); // constexpr since C++26
#include <map>
#include <cassert>
@@ -21,7 +21,7 @@
#include "min_allocator.h"
#include "test_allocator.h"
-void test_basic() {
+TEST_CONSTEXPR_CXX26 bool test_basic() {
{
typedef std::pair<const int, double> V;
std::map<int, double> m = {
@@ -46,9 +46,10 @@ void test_basic() {
assert(*std::next(m.begin()) == V(2, 1));
assert(*std::next(m.begin(), 2) == V(3, 1));
}
+ return true;
}
-void duplicate_keys_test() {
+TEST_CONSTEXPR_CXX26 bool duplicate_keys_test() {
test_allocator_statistics alloc_stats;
typedef std::map<int, int, std::less<int>, test_allocator<std::pair<const int, int> > > Map;
{
@@ -61,11 +62,19 @@ void duplicate_keys_test() {
assert(s.begin()->first == 4);
}
LIBCPP_ASSERT(alloc_stats.alloc_count == 0);
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
test_basic();
duplicate_keys_test();
+ 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/associative/map/map.cons/compare.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/compare.pass.cpp
index bd27a2f4ddeb9..52a79e149d686 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/compare.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/compare.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// explicit map(const key_compare& comp);
+// explicit map(const key_compare& comp); // constexpr since C++26
#include <map>
#include <cassert>
@@ -19,7 +19,7 @@
#include "../../../test_compare.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef test_less<int> C;
const std::map<int, double, C> m(C(3));
@@ -36,6 +36,13 @@ int main(int, char**) {
assert(m.key_comp() == C(3));
}
#endif
+ 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/associative/map/map.cons/compare_alloc.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp
index 20f6a08db6a36..867ec4fd3ea5f 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/compare_alloc.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// map(const key_compare& comp, const allocator_type& a);
+// map(const key_compare& comp, const allocator_type& a); // constexpr since C++26
#include <map>
#include <cassert>
@@ -20,7 +20,7 @@
#include "test_allocator.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef test_less<int> C;
typedef test_allocator<std::pair<const int, double> > A;
@@ -50,6 +50,13 @@ int main(int, char**) {
assert(m.get_allocator() == A{});
}
#endif
+ 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/associative/map/map.cons/copy.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/copy.pass.cpp
index f1696b003c131..3a5db9d6ec96e 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/copy.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/copy.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// map(const map& m);
+// map(const map& m); // constexpr since C++26
#include <cassert>
#include <map>
@@ -20,7 +20,7 @@
#include "test_allocator.h"
template <template <class> class Alloc>
-void test_alloc() {
+TEST_CONSTEXPR_CXX26 bool test_alloc() {
{ // Simple check
using V = std::pair<const int, int>;
using Map = std::map<int, int, std::less<int>, Alloc<V> >;
@@ -80,9 +80,10 @@ void test_alloc() {
assert(*std::next(orig.begin(), 4) == V(5, 0));
assert(std::next(orig.begin(), 5) == orig.end());
}
+ return true;
}
-void test() {
+TEST_CONSTEXPR_CXX26 bool test() {
test_alloc<std::allocator>();
test_alloc<min_allocator>(); // Make sure that fancy pointers work
@@ -131,10 +132,13 @@ void test() {
assert(orig.size() == 3);
assert(orig.get_allocator() == other_allocator<V>(10));
}
+ 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/associative/map/map.cons/copy_alloc.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp
index caa3490d44faf..7bbadbcda4b24 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// map(const map& m, const allocator_type& a);
+// map(const map& m, const allocator_type& a); // constexpr since C++26
#include <cassert>
#include <map>
@@ -21,7 +21,7 @@
#include "min_allocator.h"
template <class Alloc>
-void test_alloc(const Alloc& new_alloc) {
+TEST_CONSTEXPR_CXX26 bool test_alloc(const Alloc& new_alloc) {
{ // Simple check
using V = std::pair<const int, int>;
using Map = std::map<int, int, std::less<int>, Alloc>;
@@ -81,9 +81,10 @@ void test_alloc(const Alloc& new_alloc) {
assert(*std::next(orig.begin(), 4) == V(5, 0));
assert(std::next(orig.begin(), 5) == orig.end());
}
+ return true;
}
-void test() {
+TEST_CONSTEXPR_CXX26 bool test() {
test_alloc(std::allocator<std::pair<const int, int> >());
test_alloc(test_allocator<std::pair<const int, int> >(25)); // Make sure that the new allocator is actually used
test_alloc(min_allocator<std::pair<const int, int> >()); // Make sure that fancy pointers work
@@ -102,10 +103,14 @@ void test() {
assert(orig.size() == 3);
assert(orig.key_comp() == test_less<int>(3));
}
+
+ return true;
}
int main(int, char**) {
test();
-
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp
index 56c6cdd7e1e99..704cbc196651b 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/copy_assign.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// map& operator=(const map& m);
+// map& operator=(const map& m); // constexpr since C++26
#include <algorithm>
#include <cassert>
@@ -24,6 +24,41 @@
#include "test_allocator.h"
#include "min_allocator.h"
+#if TEST_STD_VER >= 11
+struct NonTrivial {
+ int i;
+ // TEST_CONSTEXPR_CXX26 NonTrivial() = default;
+ TEST_CONSTEXPR_CXX26 NonTrivial(int arg_i) : i(arg_i) {}
+ TEST_CONSTEXPR_CXX26 NonTrivial(const NonTrivial& other) : i(other.i) {}
+ TEST_CONSTEXPR_CXX26 NonTrivial(NonTrivial&& other) : i(other.i) {
+ // i = 0, means the object got moved from
+ other.i = 0;
+ }
+ TEST_CONSTEXPR_CXX26 NonTrivial& operator=(const NonTrivial& other) {
+ if (this != &other) {
+ i = other.i;
+ }
+ return *this;
+ }
+ TEST_CONSTEXPR_CXX26 NonTrivial& operator=(NonTrivial&& other) {
+ i = other.i;
+ // i = 0, means the object got moved from
+ other.i = 0;
+ return *this;
+ }
+
+ TEST_CONSTEXPR_CXX26 friend bool operator<(NonTrivial const& left, NonTrivial const& right) {
+ return left.i < right.i;
+ }
+ TEST_CONSTEXPR_CXX26 friend bool operator==(NonTrivial const& left, NonTrivial const& right) {
+ return left.i == right.i;
+ }
+};
+static_assert(!std::is_trivially_copy_assignable<NonTrivial>::value, "");
+static_assert(!std::is_trivially_default_constructible<NonTrivial>::value, "");
+
+#endif
+
template <class T>
class tracking_allocator {
std::vector<void*>* allocs_;
@@ -35,42 +70,43 @@ class tracking_allocator {
using value_type = T;
using propagate_on_container_copy_assignment = std::true_type;
- tracking_allocator(std::vector<void*>& allocs) : allocs_(&allocs) {}
+ TEST_CONSTEXPR_CXX26 tracking_allocator(std::vector<void*>& allocs) : allocs_(&allocs) {}
template <class U>
- tracking_allocator(const tracking_allocator<U>& other) : allocs_(other.allocs_) {}
+ TEST_CONSTEXPR_CXX26 tracking_allocator(const tracking_allocator<U>& other) : allocs_(other.allocs_) {}
- T* allocate(std::size_t n) {
+ TEST_CONSTEXPR_CXX26 T* allocate(std::size_t n) {
T* allocation = std::allocator<T>().allocate(n);
allocs_->push_back(allocation);
return allocation;
}
- void deallocate(T* ptr, std::size_t n) TEST_NOEXCEPT {
+ TEST_CONSTEXPR_CXX26 void deallocate(T* ptr, std::size_t n) TEST_NOEXCEPT {
auto res = std::remove(allocs_->begin(), allocs_->end(), ptr);
assert(res != allocs_->end() && "Trying to deallocate memory from
diff erent allocator?");
allocs_->erase(res);
std::allocator<T>().deallocate(ptr, n);
}
- friend bool operator==(const tracking_allocator& lhs, const tracking_allocator& rhs) {
+ TEST_CONSTEXPR_CXX26 friend bool operator==(const tracking_allocator& lhs, const tracking_allocator& rhs) {
return lhs.allocs_ == rhs.allocs_;
}
- friend bool operator!=(const tracking_allocator& lhs, const tracking_allocator& rhs) {
+ TEST_CONSTEXPR_CXX26 friend bool operator!=(const tracking_allocator& lhs, const tracking_allocator& rhs) {
return lhs.allocs_ != rhs.allocs_;
}
};
struct NoOp {
- void operator()() {}
+ TEST_CONSTEXPR_CXX26 void operator()() {}
};
template <class Alloc, class AllocatorInvariant = NoOp>
-void test_alloc(const Alloc& lhs_alloc = Alloc(),
- const Alloc& rhs_alloc = Alloc(),
- AllocatorInvariant check_alloc_invariant = NoOp()) {
- { // Test empty/non-empty map combinations
+TEST_CONSTEXPR_CXX26 bool
+test_alloc(const Alloc& lhs_alloc = Alloc(),
+ const Alloc& rhs_alloc = Alloc(),
+ AllocatorInvariant check_alloc_invariant = NoOp()) {
+ { // Test empty/non-empy map combinations
{ // assign from a non-empty container into an empty one
using V = std::pair<const int, int>;
using Map = std::map<int, int, std::less<int>, Alloc>;
@@ -242,10 +278,15 @@ void test_alloc(const Alloc& lhs_alloc = Alloc(),
}
}
check_alloc_invariant();
+ return true;
}
-void test() {
+TEST_CONSTEXPR_CXX26 bool test() {
test_alloc<std::allocator<std::pair<const int, int> > >();
+#if TEST_STD_VER >= 26
+ static_assert(test_alloc<std::allocator<std::pair<const int, int> > >());
+#endif
+
#if TEST_STD_VER >= 11
test_alloc<min_allocator<std::pair<const int, int> > >();
@@ -256,10 +297,10 @@ void test() {
std::vector<void*>* rhs_allocs_;
public:
- AssertEmpty(std::vector<void*>& lhs_allocs, std::vector<void*>& rhs_allocs)
+ TEST_CONSTEXPR_CXX26 AssertEmpty(std::vector<void*>& lhs_allocs, std::vector<void*>& rhs_allocs)
: lhs_allocs_(&lhs_allocs), rhs_allocs_(&rhs_allocs) {}
- void operator()() {
+ TEST_CONSTEXPR_CXX26 void operator()() {
assert(lhs_allocs_->empty());
assert(rhs_allocs_->empty());
}
@@ -270,6 +311,32 @@ void test() {
test_alloc<tracking_allocator<std::pair<const int, int> > >(
lhs_allocs, rhs_allocs, AssertEmpty(lhs_allocs, rhs_allocs));
}
+ {
+ // Test that non-trivial copies don't get moved.
+ {
+ using V = std::pair<const NonTrivial, NonTrivial>;
+ using Map = std::map<NonTrivial, NonTrivial, std::less<NonTrivial> >;
+
+ V arr[] = {V(1, 1), V(2, 3), V(3, 6)};
+
+ const Map orig(begin(arr), end(arr), std::less<NonTrivial>());
+ Map copy;
+ copy = orig;
+
+ assert(copy.size() == 3);
+ assert(*std::next(copy.begin(), 0) == V(1, 1));
+ assert(*std::next(copy.begin(), 1) == V(2, 3));
+ assert(*std::next(copy.begin(), 2) == V(3, 6));
+ assert(std::next(copy.begin(), 3) == copy.end());
+
+ // Check that orig is still what is expected
+ assert(orig.size() == 3);
+ assert(*std::next(orig.begin(), 0) == V(1, 1));
+ assert(*std::next(orig.begin(), 1) == V(2, 3));
+ assert(*std::next(orig.begin(), 2) == V(3, 6));
+ assert(std::next(orig.begin(), 3) == orig.end());
+ }
+ }
#endif
{ // Ensure that the comparator is copied
@@ -300,10 +367,13 @@ void test() {
out = in;
out.erase(std::next(out.begin(), 17), out.end());
}
+ return true;
}
int main(int, char**) {
test();
-
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.cons/deduct.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/deduct.pass.cpp
index 5cefb6f361a53..4273237e19803 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/deduct.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/deduct.pass.cpp
@@ -33,7 +33,7 @@
// template<ranges::input_range R, class Allocator>
// map(from_range_t, R&&, Allocator)
// -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23
-
+// since C++26
#include <algorithm> // std::equal
#include <array>
#include <cassert>
@@ -51,7 +51,7 @@
using P = std::pair<int, long>;
using PC = std::pair<const int, long>;
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
const P arr[] = {{1, 1L}, {2, 2L}, {1, 1L}, {INT_MAX, 1L}, {3, 1L}};
std::map m(std::begin(arr), std::end(arr));
@@ -212,6 +212,13 @@ int main(int, char**) {
#endif
AssociativeContainerDeductionGuidesSfinaeAway<std::map, std::map<int, long>>();
+ 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/associative/map/map.cons/deduct_const.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/deduct_const.pass.cpp
index dcc2d4510bcb6..b59470ea891a9 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/deduct_const.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/deduct_const.pass.cpp
@@ -39,7 +39,7 @@ using P = std::pair<int, long>;
using PC = std::pair<const int, long>;
using PCC = std::pair<const int, const long>;
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
const PCC arr[] = {{1, 1L}, {2, 2L}, {1, 1L}, {INT_MAX, 1L}, {3, 1L}};
std::map m(std::begin(arr), std::end(arr));
@@ -102,6 +102,13 @@ int main(int, char**) {
assert(std::equal(m.begin(), m.end(), std::begin(expected_m), std::end(expected_m)));
assert(m.get_allocator().get_id() == 45);
}
+ 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/associative/map/map.cons/default.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/default.pass.cpp
index 1b48370387a8f..1d8d2e35c749d 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/default.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/default.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// map();
+// map(); // constexpr since C++26
#include <map>
#include <cassert>
@@ -18,7 +18,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
std::map<int, double> m;
assert(m.empty());
@@ -50,6 +50,13 @@ int main(int, char**) {
assert(m.begin() == m.end());
}
#endif
+ 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/associative/map/map.cons/default_noexcept.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/default_noexcept.pass.cpp
index 1e43a893d66c1..e5fe293a45bc2 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/default_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/default_noexcept.pass.cpp
@@ -12,7 +12,7 @@
// noexcept(
// is_nothrow_default_constructible<allocator_type>::value &&
// is_nothrow_default_constructible<key_compare>::value &&
-// is_nothrow_copy_constructible<key_compare>::value);
+// is_nothrow_copy_constructible<key_compare>::value); // constexpr since C++26
// This tests a conforming extension
@@ -32,7 +32,7 @@ struct some_comp {
bool operator()(const T&, const T&) const { return false; }
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::pair<const MoveOnly, MoveOnly> V;
#if defined(_LIBCPP_VERSION)
{
@@ -52,6 +52,13 @@ int main(int, char**) {
typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>> C;
static_assert(!std::is_nothrow_default_constructible<C>::value, "");
}
+ 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/associative/map/map.cons/dtor_noexcept.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp
index c9f7f281391f5..10ef5d7152d5f 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/dtor_noexcept.pass.cpp
@@ -8,7 +8,7 @@
// <map>
-// ~map() // implied noexcept;
+// ~map() // implied noexcept; constexpr since C++26
// UNSUPPORTED: c++03
@@ -27,7 +27,7 @@ struct some_comp {
bool operator()(const T&, const T&) const noexcept { return false; }
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::pair<const MoveOnly, MoveOnly> V;
{
typedef std::map<MoveOnly, MoveOnly> C;
@@ -47,6 +47,13 @@ int main(int, char**) {
static_assert(!std::is_nothrow_destructible<C>::value, "");
}
#endif // _LIBCPP_VERSION
+ 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/associative/map/map.cons/from_range.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/from_range.pass.cpp
index dc06266064a8d..d8b4ed71b5389 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/from_range.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/from_range.pass.cpp
@@ -9,11 +9,11 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// template<container-compatible-range<value_type> R>
-// map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23
+// constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23, constexpr since C++26
//
// template<container-compatible-range<value_type> R>
-// map(from_range_t, R&& rg, const Allocator& a))
-// : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23
+// constexpr map(from_range_t, R&& rg, const Allocator& a))
+// : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23, constexpr since C++26
#include <array>
#include <map>
@@ -21,7 +21,7 @@
#include "../../from_range_associative_containers.h"
#include "test_macros.h"
-void test_duplicates() {
+TEST_CONSTEXPR_CXX26 void test_duplicates() {
using T = std::pair<const int, char>;
std::array input = {T{1, 'a'}, T{2, 'a'}, T{3, 'a'}, T{3, 'b'}, T{3, 'c'}, T{2, 'b'}, T{4, 'a'}};
@@ -30,7 +30,7 @@ void test_duplicates() {
assert(std::ranges::is_permutation(expected, c));
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
using T = std::pair<const int, int>;
for_all_iterators_and_allocators<T>([]<class Iter, class Sent, class Alloc>() {
test_associative_map<std::map, int, int, Iter, Sent, test_less<int>, Alloc>();
@@ -42,6 +42,13 @@ int main(int, char**) {
test_map_exception_safety_throwing_copy<std::map>();
test_map_exception_safety_throwing_allocator<std::map, int, int>();
+ 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/associative/map/map.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/initializer_list.pass.cpp
index b18dc5cf754a0..a8b426d324c4e 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/initializer_list.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// map(initializer_list<value_type> il);
+// map(initializer_list<value_type> il); // constexpr since C++26
#include <map>
#include <cassert>
@@ -20,7 +20,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
std::map<int, double> m = {{1, 1}, {1, 1.5}, {1, 2}, {2, 1}, {2, 1.5}, {2, 2}, {3, 1}, {3, 1.5}, {3, 2}};
@@ -40,6 +40,13 @@ int main(int, char**) {
assert(*std::next(m.begin()) == V(2, 1));
assert(*std::next(m.begin(), 2) == V(3, 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/associative/map/map.cons/initializer_list_compare.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/initializer_list_compare.pass.cpp
index 301384362bfe7..74380e5754b23 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/initializer_list_compare.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/initializer_list_compare.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// map(initializer_list<value_type> il, const key_compare& comp);
+// map(initializer_list<value_type> il, const key_compare& comp); // constexpr since C++26
#include <map>
#include <cassert>
@@ -20,7 +20,7 @@
#include "../../../test_compare.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
typedef test_less<int> C;
@@ -44,6 +44,13 @@ int main(int, char**) {
assert(*std::next(m.begin(), 2) == V(3, 1));
assert(m.key_comp() == C(3));
}
+ return true;
+}
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp
index da138ebd9ae61..f3f1b6909994a 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/initializer_list_compare_alloc.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);
+// map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a); // constexpr since C++26
#include <map>
#include <cassert>
@@ -21,7 +21,7 @@
#include "test_allocator.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
typedef test_less<int> C;
@@ -80,6 +80,13 @@ int main(int, char**) {
assert(m.key_comp() == C(3));
assert(m.get_allocator() == a);
}
+ 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/associative/map/map.cons/iter_iter.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/iter_iter.pass.cpp
index c8ed1413c3084..451c00276e744 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/iter_iter.pass.cpp
@@ -11,7 +11,7 @@
// class map
// template <class InputIterator>
-// map(InputIterator first, InputIterator last);
+// constexpr map(InputIterator first, InputIterator last); // constexpr since C++26
#include <map>
#include <cassert>
@@ -19,7 +19,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
V ar[] = {
@@ -63,6 +63,13 @@ int main(int, char**) {
assert(*std::next(m.begin(), 2) == V(3, 1));
}
#endif
+ 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/associative/map/map.cons/iter_iter_comp.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp.pass.cpp
index f8ecee04a528a..ba64f539bf728 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp.pass.cpp
@@ -11,7 +11,7 @@
// class map
// template <class InputIterator>
-// map(InputIterator first, InputIterator last, const key_compare& comp);
+// constexpr map(InputIterator first, InputIterator last, const key_compare& comp); // constexpr since C++26
#include <map>
#include <cassert>
@@ -20,7 +20,7 @@
#include "../../../test_compare.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
V ar[] = {
@@ -67,6 +67,13 @@ int main(int, char**) {
assert(*std::next(m.begin(), 2) == V(3, 1));
}
#endif
+ 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/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp
index 862b07bb11731..014f9c5960e5b 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp
@@ -11,8 +11,8 @@
// class map
// template <class InputIterator>
-// map(InputIterator first, InputIterator last,
-// const key_compare& comp, const allocator_type& a);
+// constexpr map(InputIterator first, InputIterator last,
+// const key_compare& comp, const allocator_type& a); // constexpr since C++26
#include <map>
#include <cassert>
@@ -22,7 +22,7 @@
#include "test_allocator.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
V ar[] = {
@@ -115,6 +115,13 @@ int main(int, char**) {
}
# endif
#endif
+ 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/associative/map/map.cons/move.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/move.pass.cpp
index d33ef527c91de..ebf94b65897bc 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/move.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/move.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// map(map&& m);
+// map(map&& m); // constexpr since C++26
#include <map>
#include <cassert>
@@ -22,7 +22,7 @@
#include "test_allocator.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::pair<const int, double> V;
{
typedef test_less<int> C;
@@ -114,6 +114,13 @@ int main(int, char**) {
assert(mo.size() == 0);
assert(std::distance(mo.begin(), mo.end()) == 0);
}
+ 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/associative/map/map.cons/move_alloc.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp
index 886a4fa714d89..169639f5afa78 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/move_alloc.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// map(map&& m, const allocator_type& a);
+// map(map&& m, const allocator_type& a); // constexpr since C++26
#include <map>
#include <cassert>
@@ -20,18 +20,20 @@
#include "test_macros.h"
#include "MoveOnly.h"
+#include "CopyConstructible.h"
#include "../../../test_compare.h"
#include "test_allocator.h"
#include "min_allocator.h"
#include "Counter.h"
-int main(int, char**) {
+template <typename TKeyType>
+TEST_CONSTEXPR_CXX26 bool test_move_alloc() {
{
- typedef std::pair<MoveOnly, MoveOnly> V;
- typedef std::pair<const MoveOnly, MoveOnly> VC;
- typedef test_less<MoveOnly> C;
+ typedef std::pair<TKeyType, MoveOnly> V;
+ typedef std::pair<const TKeyType, MoveOnly> VC;
+ typedef test_less<TKeyType> C;
typedef test_allocator<VC> A;
- typedef std::map<MoveOnly, MoveOnly, C, A> M;
+ typedef std::map<TKeyType, MoveOnly, C, A> M;
typedef std::move_iterator<V*> I;
V a1[] = {V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3)};
M m1(I(a1), I(a1 + sizeof(a1) / sizeof(a1[0])), C(5), A(7));
@@ -44,11 +46,11 @@ int main(int, char**) {
LIBCPP_ASSERT(m1.empty());
}
{
- typedef std::pair<MoveOnly, MoveOnly> V;
- typedef std::pair<const MoveOnly, MoveOnly> VC;
- typedef test_less<MoveOnly> C;
+ typedef std::pair<TKeyType, MoveOnly> V;
+ typedef std::pair<const TKeyType, MoveOnly> VC;
+ typedef test_less<TKeyType> C;
typedef test_allocator<VC> A;
- typedef std::map<MoveOnly, MoveOnly, C, A> M;
+ typedef std::map<TKeyType, MoveOnly, C, A> M;
typedef std::move_iterator<V*> I;
V a1[] = {V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3)};
M m1(I(a1), I(a1 + sizeof(a1) / sizeof(a1[0])), C(5), A(7));
@@ -61,11 +63,11 @@ int main(int, char**) {
LIBCPP_ASSERT(m1.empty());
}
{
- typedef std::pair<MoveOnly, MoveOnly> V;
- typedef std::pair<const MoveOnly, MoveOnly> VC;
- typedef test_less<MoveOnly> C;
+ typedef std::pair<TKeyType, MoveOnly> V;
+ typedef std::pair<const TKeyType, MoveOnly> VC;
+ typedef test_less<TKeyType> C;
typedef other_allocator<VC> A;
- typedef std::map<MoveOnly, MoveOnly, C, A> M;
+ typedef std::map<TKeyType, MoveOnly, C, A> M;
typedef std::move_iterator<V*> I;
V a1[] = {V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3)};
M m1(I(a1), I(a1 + sizeof(a1) / sizeof(a1[0])), C(5), A(7));
@@ -77,7 +79,7 @@ int main(int, char**) {
assert(m3.key_comp() == C(5));
LIBCPP_ASSERT(m1.empty());
}
- {
+ if (!TEST_IS_CONSTANT_EVALUATED) {
typedef Counter<int> T;
typedef std::pair<int, T> V;
typedef std::pair<const int, T> VC;
@@ -117,11 +119,11 @@ int main(int, char**) {
assert(Counter_base::gConstructed == 0);
}
{
- typedef std::pair<MoveOnly, MoveOnly> V;
- typedef std::pair<const MoveOnly, MoveOnly> VC;
- typedef test_less<MoveOnly> C;
+ typedef std::pair<TKeyType, MoveOnly> V;
+ typedef std::pair<const TKeyType, MoveOnly> VC;
+ typedef test_less<TKeyType> C;
typedef min_allocator<VC> A;
- typedef std::map<MoveOnly, MoveOnly, C, A> M;
+ typedef std::map<TKeyType, MoveOnly, C, A> M;
typedef std::move_iterator<V*> I;
V a1[] = {V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3)};
M m1(I(a1), I(a1 + sizeof(a1) / sizeof(a1[0])), C(5), A());
@@ -134,11 +136,11 @@ int main(int, char**) {
LIBCPP_ASSERT(m1.empty());
}
{
- typedef std::pair<MoveOnly, MoveOnly> V;
- typedef std::pair<const MoveOnly, MoveOnly> VC;
- typedef test_less<MoveOnly> C;
+ typedef std::pair<TKeyType, MoveOnly> V;
+ typedef std::pair<const TKeyType, MoveOnly> VC;
+ typedef test_less<TKeyType> C;
typedef explicit_allocator<VC> A;
- typedef std::map<MoveOnly, MoveOnly, C, A> M;
+ typedef std::map<TKeyType, MoveOnly, C, A> M;
typedef std::move_iterator<V*> I;
V a1[] = {V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3)};
M m1(I(a1), I(a1 + sizeof(a1) / sizeof(a1[0])), C(5), A{});
@@ -150,6 +152,18 @@ int main(int, char**) {
assert(m3.key_comp() == C(5));
LIBCPP_ASSERT(m1.empty());
}
+ return true;
+}
+
+int main(int, char**) {
+ test_move_alloc<MoveOnly>();
+ test_move_alloc<CopyConstructible>();
+
+#if TEST_STD_VER >= 26
+ // FIXME: It is not yet possible to replace a `const MoveOnly` key subobject during constant evaluation.
+ // static_assert(test_move_alloc<MoveOnly>());
+ static_assert(test_move_alloc<CopyConstructible>());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.cons/move_assign.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/move_assign.pass.cpp
index 94f991976d6ad..4fffb2fe04300 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/move_assign.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/move_assign.pass.cpp
@@ -12,24 +12,26 @@
// class map
-// map& operator=(map&& m);
+// map& operator=(map&& m); // constexpr since C++26
#include <map>
#include <cassert>
#include "test_macros.h"
#include "MoveOnly.h"
+#include "CopyConstructible.h"
#include "../../../test_compare.h"
#include "test_allocator.h"
#include "min_allocator.h"
-int main(int, char**) {
+template <typename TKeyType >
+TEST_CONSTEXPR_CXX26 bool test_move_assign() {
{
- typedef std::pair<MoveOnly, MoveOnly> V;
- typedef std::pair<const MoveOnly, MoveOnly> VC;
- typedef test_less<MoveOnly> C;
+ typedef std::pair<TKeyType, MoveOnly> V;
+ typedef std::pair<const TKeyType, MoveOnly> VC;
+ typedef test_less<TKeyType> C;
typedef test_allocator<VC> A;
- typedef std::map<MoveOnly, MoveOnly, C, A> M;
+ typedef std::map<TKeyType, MoveOnly, C, A> M;
typedef std::move_iterator<V*> I;
V a1[] = {V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3)};
M m1(I(a1), I(a1 + sizeof(a1) / sizeof(a1[0])), C(5), A(7));
@@ -43,11 +45,11 @@ int main(int, char**) {
assert(m1.empty());
}
{
- typedef std::pair<MoveOnly, MoveOnly> V;
- typedef std::pair<const MoveOnly, MoveOnly> VC;
- typedef test_less<MoveOnly> C;
+ typedef std::pair<TKeyType, MoveOnly> V;
+ typedef std::pair<const TKeyType, MoveOnly> VC;
+ typedef test_less<TKeyType> C;
typedef test_allocator<VC> A;
- typedef std::map<MoveOnly, MoveOnly, C, A> M;
+ typedef std::map<TKeyType, MoveOnly, C, A> M;
typedef std::move_iterator<V*> I;
V a1[] = {V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3)};
M m1(I(a1), I(a1 + sizeof(a1) / sizeof(a1[0])), C(5), A(7));
@@ -61,11 +63,11 @@ int main(int, char**) {
LIBCPP_ASSERT(m1.empty());
}
{
- typedef std::pair<MoveOnly, MoveOnly> V;
- typedef std::pair<const MoveOnly, MoveOnly> VC;
- typedef test_less<MoveOnly> C;
+ typedef std::pair<TKeyType, MoveOnly> V;
+ typedef std::pair<const TKeyType, MoveOnly> VC;
+ typedef test_less<TKeyType> C;
typedef other_allocator<VC> A;
- typedef std::map<MoveOnly, MoveOnly, C, A> M;
+ typedef std::map<TKeyType, MoveOnly, C, A> M;
typedef std::move_iterator<V*> I;
V a1[] = {V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3)};
M m1(I(a1), I(a1 + sizeof(a1) / sizeof(a1[0])), C(5), A(7));
@@ -79,11 +81,11 @@ int main(int, char**) {
assert(m1.empty());
}
{
- typedef std::pair<MoveOnly, MoveOnly> V;
- typedef std::pair<const MoveOnly, MoveOnly> VC;
- typedef test_less<MoveOnly> C;
+ typedef std::pair<TKeyType, MoveOnly> V;
+ typedef std::pair<const TKeyType, MoveOnly> VC;
+ typedef test_less<TKeyType> C;
typedef min_allocator<VC> A;
- typedef std::map<MoveOnly, MoveOnly, C, A> M;
+ typedef std::map<TKeyType, MoveOnly, C, A> M;
typedef std::move_iterator<V*> I;
V a1[] = {V(1, 1), V(1, 2), V(1, 3), V(2, 1), V(2, 2), V(2, 3), V(3, 1), V(3, 2), V(3, 3)};
M m1(I(a1), I(a1 + sizeof(a1) / sizeof(a1[0])), C(5), A());
@@ -96,6 +98,18 @@ int main(int, char**) {
assert(m3.key_comp() == C(5));
assert(m1.empty());
}
+ return true;
+}
+
+int main(int, char**) {
+ test_move_assign<MoveOnly>();
+ test_move_assign<CopyConstructible>();
+
+#if TEST_STD_VER >= 26
+ // FIXME: It is not yet possible to replace a `const MoveOnly` key subobject during constant evaluation.
+ // static_assert(test_move_assign<MoveOnly>());
+ static_assert(test_move_assign<CopyConstructible>());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.cons/move_noexcept.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/move_noexcept.pass.cpp
index 06316ccf0901a..ed58c0a9f849e 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/move_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/move_noexcept.pass.cpp
@@ -10,7 +10,7 @@
// map(map&&)
// noexcept(is_nothrow_move_constructible<allocator_type>::value &&
-// is_nothrow_move_constructible<key_compare>::value);
+// is_nothrow_move_constructible<key_compare>::value); // constexpr since C++26
// This tests a conforming extension
@@ -30,7 +30,7 @@ struct some_comp {
bool operator()(const T&, const T&) const { return false; }
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
#if defined(_LIBCPP_VERSION)
typedef std::pair<const MoveOnly, MoveOnly> V;
{
@@ -50,6 +50,12 @@ int main(int, char**) {
typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>> C;
static_assert(!std::is_nothrow_move_constructible<C>::value, "");
}
-
+ 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/associative/map/map.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp
index ccfd800cafde0..f47506f356269 100644
--- a/libcxx/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.erasure/erase_if.pass.cpp
@@ -11,7 +11,7 @@
// template <class Key, class T, class Compare, class Allocator, class Predicate>
// typename map<Key, T, Compare, Allocator>::size_type
-// erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
+// constexpr erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // constexpr since C++26
#include <map>
@@ -21,7 +21,7 @@
using Init = std::initializer_list<int>;
template <typename M>
-M make(Init vals) {
+TEST_CONSTEXPR_CXX26 M make(Init vals) {
M ret;
for (int v : vals)
ret[static_cast<typename M::key_type>(v)] = static_cast<typename M::mapped_type>(v + 10);
@@ -29,7 +29,7 @@ M make(Init vals) {
}
template <typename M, typename Pred>
-void test0(Init vals, Pred p, Init expected, std::size_t expected_erased_count) {
+TEST_CONSTEXPR_CXX26 void test0(Init vals, Pred p, Init expected, std::size_t expected_erased_count) {
M s = make<M>(vals);
ASSERT_SAME_TYPE(typename M::size_type, decltype(std::erase_if(s, p)));
assert(expected_erased_count == std::erase_if(s, p));
@@ -37,7 +37,7 @@ void test0(Init vals, Pred p, Init expected, std::size_t expected_erased_count)
}
template <typename S>
-void test() {
+TEST_CONSTEXPR_CXX26 bool test() {
auto is1 = [](auto v) { return v.first == 1; };
auto is2 = [](auto v) { return v.first == 2; };
auto is3 = [](auto v) { return v.first == 3; };
@@ -61,9 +61,12 @@ void test() {
test0<S>({1, 2, 3}, True, {}, 3);
test0<S>({1, 2, 3}, False, {1, 2, 3}, 0);
+
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26
+bool test_upper() {
test<std::map<int, int>>();
test<std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>>>();
test<std::map<int, int, std::less<int>, test_allocator<std::pair<const int, int>>>>();
@@ -71,5 +74,21 @@ int main(int, char**) {
test<std::map<long, short>>();
test<std::map<short, double>>();
+ return true;
+}
+
+int main(int, char**) {
+ test_upper();
+
+#if TEST_STD_VER >= 26
+# ifndef TEST_COMPILER_GCC
+ // FIXME: Fails with g++-15 with:
+ // clang-format off
+ // __tree:116:23: error: ''result_decl' not supported by dump_expr<expression error>' is not a constant expression
+ // clang-format on
+ static_assert(test_upper());
+# endif
+#endif
+
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.modifiers/clear.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/clear.pass.cpp
index 938f22eb880a6..4ca10b15564f5 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/clear.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/clear.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// void clear() noexcept;
+// void clear() noexcept; // constexpr since C++26
#include <map>
#include <cassert>
@@ -18,7 +18,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double> M;
typedef std::pair<int, double> P;
@@ -59,6 +59,13 @@ int main(int, char**) {
assert(m.size() == 0);
}
#endif
+ 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/associative/map/map.modifiers/emplace.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/emplace.pass.cpp
index 36b073c2b551e..ee6cbba6e50ab 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/emplace.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/emplace.pass.cpp
@@ -13,7 +13,7 @@
// class map
// template <class... Args>
-// pair<iterator, bool> emplace(Args&&... args);
+// constexpr pair<iterator, bool> emplace(Args&&... args); // constexpr since C++26
#include <map>
#include <cassert>
@@ -24,35 +24,38 @@
#include "DefaultOnly.h"
#include "min_allocator.h"
-int main(int, char**) {
- {
- typedef std::map<int, DefaultOnly> M;
- typedef std::pair<M::iterator, bool> R;
- M m;
+TEST_CONSTEXPR_CXX26 bool test() {
+ // DefaultOnly::count is static
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ {
+ typedef std::map<int, DefaultOnly> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ assert(DefaultOnly::count == 0);
+ R r = m.emplace();
+ assert(r.second);
+ assert(r.first == m.begin());
+ assert(m.size() == 1);
+ assert(m.begin()->first == 0);
+ assert(m.begin()->second == DefaultOnly());
+ assert(DefaultOnly::count == 1);
+ r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
+ assert(r.second);
+ assert(r.first == std::next(m.begin()));
+ assert(m.size() == 2);
+ assert(std::next(m.begin())->first == 1);
+ assert(std::next(m.begin())->second == DefaultOnly());
+ assert(DefaultOnly::count == 2);
+ r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
+ assert(!r.second);
+ assert(r.first == std::next(m.begin()));
+ assert(m.size() == 2);
+ assert(std::next(m.begin())->first == 1);
+ assert(std::next(m.begin())->second == DefaultOnly());
+ assert(DefaultOnly::count == 2);
+ }
assert(DefaultOnly::count == 0);
- R r = m.emplace();
- assert(r.second);
- assert(r.first == m.begin());
- assert(m.size() == 1);
- assert(m.begin()->first == 0);
- assert(m.begin()->second == DefaultOnly());
- assert(DefaultOnly::count == 1);
- r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
- assert(r.second);
- assert(r.first == std::next(m.begin()));
- assert(m.size() == 2);
- assert(std::next(m.begin())->first == 1);
- assert(std::next(m.begin())->second == DefaultOnly());
- assert(DefaultOnly::count == 2);
- r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
- assert(!r.second);
- assert(r.first == std::next(m.begin()));
- assert(m.size() == 2);
- assert(std::next(m.begin())->first == 1);
- assert(std::next(m.begin())->second == DefaultOnly());
- assert(DefaultOnly::count == 2);
}
- assert(DefaultOnly::count == 0);
{
typedef std::map<int, Emplaceable> M;
typedef std::pair<M::iterator, bool> R;
@@ -87,34 +90,38 @@ int main(int, char**) {
assert(m.begin()->first == 2);
assert(m.begin()->second == 3.5);
}
- {
- typedef std::map<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M;
- typedef std::pair<M::iterator, bool> R;
- M m;
+
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ {
+ typedef std::map<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M;
+ typedef std::pair<M::iterator, bool> R;
+ M m;
+ assert(DefaultOnly::count == 0);
+ R r = m.emplace();
+ assert(r.second);
+ assert(r.first == m.begin());
+ assert(m.size() == 1);
+ assert(m.begin()->first == 0);
+ assert(m.begin()->second == DefaultOnly());
+ assert(DefaultOnly::count == 1);
+ r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
+ assert(r.second);
+ assert(r.first == std::next(m.begin()));
+ assert(m.size() == 2);
+ assert(std::next(m.begin())->first == 1);
+ assert(std::next(m.begin())->second == DefaultOnly());
+ assert(DefaultOnly::count == 2);
+ r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
+ assert(!r.second);
+ assert(r.first == std::next(m.begin()));
+ assert(m.size() == 2);
+ assert(std::next(m.begin())->first == 1);
+ assert(std::next(m.begin())->second == DefaultOnly());
+ assert(DefaultOnly::count == 2);
+ }
assert(DefaultOnly::count == 0);
- R r = m.emplace();
- assert(r.second);
- assert(r.first == m.begin());
- assert(m.size() == 1);
- assert(m.begin()->first == 0);
- assert(m.begin()->second == DefaultOnly());
- assert(DefaultOnly::count == 1);
- r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
- assert(r.second);
- assert(r.first == std::next(m.begin()));
- assert(m.size() == 2);
- assert(std::next(m.begin())->first == 1);
- assert(std::next(m.begin())->second == DefaultOnly());
- assert(DefaultOnly::count == 2);
- r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
- assert(!r.second);
- assert(r.first == std::next(m.begin()));
- assert(m.size() == 2);
- assert(std::next(m.begin())->first == 1);
- assert(std::next(m.begin())->second == DefaultOnly());
- assert(DefaultOnly::count == 2);
}
- assert(DefaultOnly::count == 0);
+
{
typedef std::map<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
typedef std::pair<M::iterator, bool> R;
@@ -149,6 +156,13 @@ int main(int, char**) {
assert(m.begin()->first == 2);
assert(m.begin()->second == 3.5);
}
+ 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/associative/map/map.modifiers/emplace_hint.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/emplace_hint.pass.cpp
index 56d1c5c2b90ac..ee352166d8bac 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/emplace_hint.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/emplace_hint.pass.cpp
@@ -13,7 +13,7 @@
// class map
// template <class... Args>
-// iterator emplace_hint(const_iterator position, Args&&... args);
+// constexpr iterator emplace_hint(const_iterator position, Args&&... args); // constexpr since C++26
#include <map>
#include <cassert>
@@ -23,32 +23,36 @@
#include "DefaultOnly.h"
#include "min_allocator.h"
-int main(int, char**) {
- {
- typedef std::map<int, DefaultOnly> M;
- typedef M::iterator R;
- M m;
+TEST_CONSTEXPR_CXX26 bool test() {
+ // DefaultOnly::count is static
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ {
+ typedef std::map<int, DefaultOnly> M;
+ typedef M::iterator R;
+ M m;
+ assert(DefaultOnly::count == 0);
+ R r = m.emplace_hint(m.end());
+ assert(r == m.begin());
+ assert(m.size() == 1);
+ assert(m.begin()->first == 0);
+ assert(m.begin()->second == DefaultOnly());
+ assert(DefaultOnly::count == 1);
+ r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
+ assert(r == std::next(m.begin()));
+ assert(m.size() == 2);
+ assert(std::next(m.begin())->first == 1);
+ assert(std::next(m.begin())->second == DefaultOnly());
+ assert(DefaultOnly::count == 2);
+ r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
+ assert(r == std::next(m.begin()));
+ assert(m.size() == 2);
+ assert(std::next(m.begin())->first == 1);
+ assert(std::next(m.begin())->second == DefaultOnly());
+ assert(DefaultOnly::count == 2);
+ }
assert(DefaultOnly::count == 0);
- R r = m.emplace_hint(m.end());
- assert(r == m.begin());
- assert(m.size() == 1);
- assert(m.begin()->first == 0);
- assert(m.begin()->second == DefaultOnly());
- assert(DefaultOnly::count == 1);
- r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
- assert(r == std::next(m.begin()));
- assert(m.size() == 2);
- assert(std::next(m.begin())->first == 1);
- assert(std::next(m.begin())->second == DefaultOnly());
- assert(DefaultOnly::count == 2);
- r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
- assert(r == std::next(m.begin()));
- assert(m.size() == 2);
- assert(std::next(m.begin())->first == 1);
- assert(std::next(m.begin())->second == DefaultOnly());
- assert(DefaultOnly::count == 2);
}
- assert(DefaultOnly::count == 0);
+
{
typedef std::map<int, Emplaceable> M;
typedef M::iterator R;
@@ -79,31 +83,35 @@ int main(int, char**) {
assert(m.begin()->first == 2);
assert(m.begin()->second == 3.5);
}
- {
- typedef std::map<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M;
- typedef M::iterator R;
- M m;
+
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ {
+ typedef std::map<int, DefaultOnly, std::less<int>, min_allocator<std::pair<const int, DefaultOnly>>> M;
+ typedef M::iterator R;
+ M m;
+ assert(DefaultOnly::count == 0);
+ R r = m.emplace_hint(m.end());
+ assert(r == m.begin());
+ assert(m.size() == 1);
+ assert(m.begin()->first == 0);
+ assert(m.begin()->second == DefaultOnly());
+ assert(DefaultOnly::count == 1);
+ r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
+ assert(r == std::next(m.begin()));
+ assert(m.size() == 2);
+ assert(std::next(m.begin())->first == 1);
+ assert(std::next(m.begin())->second == DefaultOnly());
+ assert(DefaultOnly::count == 2);
+ r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
+ assert(r == std::next(m.begin()));
+ assert(m.size() == 2);
+ assert(std::next(m.begin())->first == 1);
+ assert(std::next(m.begin())->second == DefaultOnly());
+ assert(DefaultOnly::count == 2);
+ }
assert(DefaultOnly::count == 0);
- R r = m.emplace_hint(m.end());
- assert(r == m.begin());
- assert(m.size() == 1);
- assert(m.begin()->first == 0);
- assert(m.begin()->second == DefaultOnly());
- assert(DefaultOnly::count == 1);
- r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
- assert(r == std::next(m.begin()));
- assert(m.size() == 2);
- assert(std::next(m.begin())->first == 1);
- assert(std::next(m.begin())->second == DefaultOnly());
- assert(DefaultOnly::count == 2);
- r = m.emplace_hint(m.end(), std::piecewise_construct, std::forward_as_tuple(1), std::forward_as_tuple());
- assert(r == std::next(m.begin()));
- assert(m.size() == 2);
- assert(std::next(m.begin())->first == 1);
- assert(std::next(m.begin())->second == DefaultOnly());
- assert(DefaultOnly::count == 2);
}
- assert(DefaultOnly::count == 0);
+
{
typedef std::map<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
typedef M::iterator R;
@@ -134,6 +142,13 @@ int main(int, char**) {
assert(m.begin()->first == 2);
assert(m.begin()->second == 3.5);
}
+ 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/associative/map/map.modifiers/erase_iter.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/erase_iter.pass.cpp
index 9a0cf9bd21cee..341ff2b48cfa2 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/erase_iter.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/erase_iter.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// iterator erase(const_iterator position);
+// iterator erase(const_iterator position); // constexpr since C++26
#include <map>
#include <cassert>
@@ -20,12 +20,12 @@
struct TemplateConstructor {
template <typename T>
- TemplateConstructor(const T&) {}
+ TEST_CONSTEXPR_CXX26 TemplateConstructor(const T&) {}
};
bool operator<(const TemplateConstructor&, const TemplateConstructor&) { return false; }
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double> M;
typedef std::pair<int, double> P;
@@ -252,6 +252,13 @@ int main(int, char**) {
c.erase(it);
}
#endif
+ 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/associative/map/map.modifiers/erase_iter_iter.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp
index 671f114951fc4..f85b1649f704e 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/erase_iter_iter.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// iterator erase(const_iterator first, const_iterator last);
+// iterator erase(const_iterator first, const_iterator last); // constexpr since C++26
#include <map>
#include <cassert>
@@ -18,7 +18,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double> M;
typedef std::pair<int, double> P;
@@ -151,6 +151,13 @@ int main(int, char**) {
assert(i == m.end());
}
#endif
+ 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/associative/map/map.modifiers/erase_key.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/erase_key.pass.cpp
index f276467d97029..5f2cbb4d5b18e 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/erase_key.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/erase_key.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// size_type erase(const key_type& k);
+// size_type erase(const key_type& k); // constexpr since C++26
#include <map>
#include <cassert>
@@ -18,7 +18,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double> M;
typedef std::pair<int, double> P;
@@ -269,6 +269,13 @@ int main(int, char**) {
assert(s == 1);
}
#endif
+ 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/associative/map/map.modifiers/extract_iterator.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/extract_iterator.pass.cpp
index db360cb8fe701..f55fdcf32e367 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/extract_iterator.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/extract_iterator.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// node_type extract(const_iterator);
+// node_type extract(const_iterator); // constexpr since C++26
#include <map>
#include "test_macros.h"
@@ -20,7 +20,7 @@
#include "Counter.h"
template <class Container>
-void test(Container& c) {
+TEST_CONSTEXPR_CXX26 bool test(Container& c) {
std::size_t sz = c.size();
auto some_key = c.cbegin()->first;
@@ -29,17 +29,20 @@ void test(Container& c) {
auto key_value = first->first;
typename Container::node_type t = c.extract(first++);
--sz;
- assert(t.key() == key_value);
- t.key() = some_key;
- assert(t.key() == some_key);
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ assert(t.key() == key_value);
+ t.key() = some_key;
+ assert(t.key() == some_key);
+ }
assert(t.get_allocator() == c.get_allocator());
assert(sz == c.size());
}
assert(c.size() == 0);
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
using map_type = std::map<int, int>;
map_type m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
@@ -47,17 +50,24 @@ int main(int, char**) {
}
{
- std::map<Counter<int>, Counter<int>> m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
- assert(Counter_base::gConstructed == 12);
+ using min_alloc_map = std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>>;
+ min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
test(m);
- assert(Counter_base::gConstructed == 0);
}
+ return true;
+}
+int main(int, char**) {
{
- using min_alloc_map = std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>>;
- min_alloc_map m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ std::map<Counter<int>, Counter<int>> m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
+ assert(Counter_base::gConstructed == 12);
test(m);
+ assert(Counter_base::gConstructed == 0);
}
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.modifiers/extract_key.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/extract_key.pass.cpp
index 7ad9558c90c07..0e28fd5f59d43 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/extract_key.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/extract_key.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// node_type extract(key_type const&);
+// node_type extract(key_type const&); // constexpr since C++26
#include <map>
#include "test_macros.h"
@@ -20,7 +20,7 @@
#include "Counter.h"
template <class Container, class KeyTypeIter>
-void test(Container& c, KeyTypeIter first, KeyTypeIter last) {
+TEST_CONSTEXPR_CXX26 void test(Container& c, KeyTypeIter first, KeyTypeIter last) {
std::size_t sz = c.size();
assert((std::size_t)std::distance(first, last) == sz);
@@ -28,9 +28,12 @@ void test(Container& c, KeyTypeIter first, KeyTypeIter last) {
typename Container::node_type t = c.extract(*copy);
assert(!t.empty());
--sz;
- assert(t.key() == *copy);
- t.key() = *first; // We should be able to mutate key.
- assert(t.key() == *first);
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ // CWG1514: key() is not `constexpr`
+ assert(t.key() == *copy);
+ t.key() = *first; // We should be able to mutate key.
+ assert(t.key() == *first);
+ }
assert(t.get_allocator() == c.get_allocator());
assert(sz == c.size());
}
@@ -43,14 +46,14 @@ void test(Container& c, KeyTypeIter first, KeyTypeIter last) {
}
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
std::map<int, int> m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
int keys[] = {1, 2, 3, 4, 5, 6};
test(m, std::begin(keys), std::end(keys));
}
- {
+ if (!TEST_IS_CONSTANT_EVALUATED) {
std::map<Counter<int>, Counter<int>> m = {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}};
{
Counter<int> keys[] = {1, 2, 3, 4, 5, 6};
@@ -66,6 +69,13 @@ int main(int, char**) {
int keys[] = {1, 2, 3, 4, 5, 6};
test(m, std::begin(keys), std::end(keys));
}
+ 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/associative/map/map.modifiers/insert_cv.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_cv.pass.cpp
index e845461cfbf31..8705b0a5c1c7e 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_cv.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_cv.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// pair<iterator, bool> insert(const value_type& v);
+// pair<iterator, bool> insert(const value_type& v); // constexpr since C++26
#include <map>
#include <cassert>
@@ -19,7 +19,7 @@
#include "min_allocator.h"
template <class Container>
-void do_insert_cv_test() {
+TEST_CONSTEXPR_CXX26 bool do_insert_cv_test() {
typedef Container M;
typedef std::pair<typename M::iterator, bool> R;
typedef typename M::value_type VT;
@@ -56,9 +56,11 @@ void do_insert_cv_test() {
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3.5);
+
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
do_insert_cv_test<std::map<int, double> >();
#if TEST_STD_VER >= 11
{
@@ -66,6 +68,13 @@ int main(int, char**) {
do_insert_cv_test<M>();
}
#endif
+ 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/associative/map/map.modifiers/insert_initializer_list.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp
index 1f6e5c6371a11..0f5eb4e8b1766 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_initializer_list.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// void insert(initializer_list<value_type> il);
+// void insert(initializer_list<value_type> il); // constexpr since C++26
#include <map>
#include <cassert>
@@ -20,7 +20,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
std::map<int, double> m = {{1, 1}, {1, 1.5}, {1, 2}, {3, 1}, {3, 1.5}, {3, 2}};
@@ -49,6 +49,13 @@ int main(int, char**) {
assert(*std::next(m.begin()) == V(2, 1));
assert(*std::next(m.begin(), 2) == V(3, 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/associative/map/map.modifiers/insert_iter_cv.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp
index 5256ca2c8d451..c76f2277a2643 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_cv.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// iterator insert(const_iterator position, const value_type& v);
+// iterator insert(const_iterator position, const value_type& v); // constexpr since C++26
#include <map>
#include <cassert>
@@ -19,7 +19,7 @@
#include "min_allocator.h"
template <class Container>
-void do_insert_iter_cv_test() {
+TEST_CONSTEXPR_CXX26 bool do_insert_iter_cv_test() {
typedef Container M;
typedef typename M::iterator R;
typedef typename M::value_type VT;
@@ -52,9 +52,11 @@ void do_insert_iter_cv_test() {
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
+
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
do_insert_iter_cv_test<std::map<int, double> >();
#if TEST_STD_VER >= 11
{
@@ -62,6 +64,13 @@ int main(int, char**) {
do_insert_iter_cv_test<M>();
}
#endif
+ 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/associative/map/map.modifiers/insert_iter_iter.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp
index dfbeb33698e6c..e618ca875914f 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_iter.pass.cpp
@@ -11,7 +11,7 @@
// class map
// template <class InputIterator>
-// void insert(InputIterator first, InputIterator last);
+// constexpr void insert(InputIterator first, InputIterator last); // constexpr since C++26
#include <array>
#include <cassert>
@@ -21,7 +21,7 @@
#include "min_allocator.h"
template <class Iter, class Alloc>
-void test_alloc() {
+TEST_CONSTEXPR_CXX26 void test_alloc() {
{ // Check that an empty range works correctly
{ // Without elements in the container
using Map = std::map<int, int, std::less<int>, Alloc>;
@@ -188,13 +188,16 @@ void test_alloc() {
}
}
-void test() {
+TEST_CONSTEXPR_CXX26 bool test() {
test_alloc<cpp17_input_iterator<std::pair<const int, int>*>, std::allocator<std::pair<const int, int> > >();
test_alloc<cpp17_input_iterator<std::pair<const int, int>*>, min_allocator<std::pair<const int, int> > >();
+ 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/associative/map/map.modifiers/insert_iter_rv.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp
index 5d72bae39bad1..087e2d2495cf6 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_iter_rv.pass.cpp
@@ -13,7 +13,7 @@
// class map
// template <class P>
-// iterator insert(const_iterator position, P&& p);
+// constexpr iterator insert(const_iterator position, P&& p); // constexpr since C++26
#include <map>
#include <cassert>
@@ -23,7 +23,7 @@
#include "test_macros.h"
template <class Container, class Pair>
-void do_insert_iter_rv_test() {
+TEST_CONSTEXPR_CXX26 bool do_insert_iter_rv_test() {
typedef Container M;
typedef Pair P;
typedef typename M::iterator R;
@@ -51,8 +51,10 @@ void do_insert_iter_rv_test() {
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
+
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
do_insert_iter_rv_test<std::map<int, MoveOnly>, std::pair<int, MoveOnly>>();
do_insert_iter_rv_test<std::map<int, MoveOnly>, std::pair<const int, MoveOnly>>();
@@ -91,6 +93,13 @@ int main(int, char**) {
assert(r->first == 3);
assert(r->second == 3);
}
+ return true;
+}
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp
index 1875c3635d9d2..c48ffc8512f44 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// insert_return_type insert(node_type&&);
+// insert_return_type insert(node_type&&); // constexpr since C++26
#include <map>
#include <memory>
@@ -21,7 +21,7 @@
#include "min_allocator.h"
template <class Container, class T>
-void verify_insert_return_type(T&& t) {
+TEST_CONSTEXPR_CXX26 void verify_insert_return_type(T&& t) {
using verified_type = std::remove_cv_t<std::remove_reference_t<T>>;
static_assert(std::is_aggregate_v<verified_type>);
static_assert(std::is_same_v<verified_type, typename Container::insert_return_type>);
@@ -42,20 +42,21 @@ void verify_insert_return_type(T&& t) {
}
template <class Container>
-typename Container::node_type
-node_factory(typename Container::key_type const& key, typename Container::mapped_type const& mapped) {
- static Container c;
+TEST_CONSTEXPR_CXX26 typename Container::node_type
+node_factory(Container& c, typename Container::key_type const& key, typename Container::mapped_type const& mapped) {
auto p = c.insert({key, mapped});
assert(p.second);
return c.extract(p.first);
}
template <class Container>
-void test(Container& c) {
+TEST_CONSTEXPR_CXX26 void testContainer(Container& c) {
auto* nf = &node_factory<Container>;
+ Container c2;
+
for (int i = 0; i != 10; ++i) {
- typename Container::node_type node = nf(i, i + 1);
+ typename Container::node_type node = nf(c2, i, i + 1);
assert(!node.empty());
typename Container::insert_return_type irt = c.insert(std::move(node));
assert(node.empty());
@@ -78,13 +79,14 @@ void test(Container& c) {
}
{ // Insert duplicate node.
- typename Container::node_type dupl = nf(0, 42);
+ typename Container::node_type dupl = nf(c2, 0, 42);
auto irt = c.insert(std::move(dupl));
assert(dupl.empty());
assert(!irt.inserted);
assert(!irt.node.empty());
assert(irt.position == c.find(0));
- assert(irt.node.key() == 0 && irt.node.mapped() == 42);
+ if (!TEST_IS_CONSTANT_EVALUATED)
+ assert(irt.node.key() == 0 && irt.node.mapped() == 42);
verify_insert_return_type<Container>(irt);
}
@@ -96,11 +98,20 @@ void test(Container& c) {
}
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26
+bool test() {
std::map<int, int> m;
- test(m);
+ testContainer(m);
std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>> m2;
- test(m2);
+ testContainer(m2);
+ 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/associative/map/map.modifiers/insert_node_type_hint.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type_hint.pass.cpp
index f7db47173bc3b..257b36491d110 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type_hint.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_node_type_hint.pass.cpp
@@ -19,20 +19,21 @@
#include "min_allocator.h"
template <class Container>
-typename Container::node_type
-node_factory(typename Container::key_type const& key, typename Container::mapped_type const& mapped) {
- static Container c;
+TEST_CONSTEXPR_CXX26 typename Container::node_type
+node_factory(Container& c, typename Container::key_type const& key, typename Container::mapped_type const& mapped) {
auto p = c.insert({key, mapped});
assert(p.second);
return c.extract(p.first);
}
template <class Container>
-void test(Container& c) {
+TEST_CONSTEXPR_CXX26 void test(Container& c) {
auto* nf = &node_factory<Container>;
+ Container c2;
+
for (int i = 0; i != 10; ++i) {
- typename Container::node_type node = nf(i, i + 1);
+ typename Container::node_type node = nf(c2, i, i + 1);
assert(!node.empty());
std::size_t prev = c.size();
auto it = c.insert(c.end(), std::move(node));
@@ -50,11 +51,21 @@ void test(Container& c) {
}
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26
+bool test() {
std::map<int, int> m;
test(m);
std::map<int, int, std::less<int>, min_allocator<std::pair<const int, int>>> m2;
test(m2);
+ 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/associative/map/map.modifiers/insert_or_assign.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_or_assign.pass.cpp
index 22d4a19a0eb44..41c2b29807b33 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_or_assign.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_or_assign.pass.cpp
@@ -13,13 +13,13 @@
// class map
// template <class M>
-// pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17
+// constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17, constexpr since C++26
// template <class M>
-// pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17
+// constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17, constexpr since C++26
// template <class M>
-// iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17
+// constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17, constexpr since C++26
// template <class M>
-// iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17
+// constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17, constexpr since C++26
#include <map>
#include <cassert>
@@ -36,13 +36,13 @@ class Moveable {
double double_;
public:
- Moveable() : int_(0), double_(0) {}
- Moveable(int i, double d) : int_(i), double_(d) {}
- Moveable(Moveable&& x) : int_(x.int_), double_(x.double_) {
+ TEST_CONSTEXPR_CXX26 Moveable() : int_(0), double_(0) {}
+ TEST_CONSTEXPR_CXX26 Moveable(int i, double d) : int_(i), double_(d) {}
+ TEST_CONSTEXPR_CXX26 Moveable(Moveable&& x) : int_(x.int_), double_(x.double_) {
x.int_ = -1;
x.double_ = -1;
}
- Moveable& operator=(Moveable&& x) {
+ TEST_CONSTEXPR_CXX26 Moveable& operator=(Moveable&& x) {
int_ = x.int_;
x.int_ = -1;
double_ = x.double_;
@@ -50,14 +50,16 @@ class Moveable {
return *this;
}
- bool operator==(const Moveable& x) const { return int_ == x.int_ && double_ == x.double_; }
- bool operator<(const Moveable& x) const { return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_); }
+ TEST_CONSTEXPR_CXX26 bool operator==(const Moveable& x) const { return int_ == x.int_ && double_ == x.double_; }
+ TEST_CONSTEXPR_CXX26 bool operator<(const Moveable& x) const {
+ return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);
+ }
- int get() const { return int_; }
- bool moved() const { return int_ == -1; }
+ TEST_CONSTEXPR_CXX26 int get() const { return int_; }
+ TEST_CONSTEXPR_CXX26 bool moved() const { return int_ == -1; }
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{ // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
typedef std::map<int, Moveable> M;
typedef std::pair<M::iterator, bool> R;
@@ -290,6 +292,13 @@ int main(int, char**) {
assert(r->first.get() == 11); // key
assert(r->second.get() == 13); // value
}
+ 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/associative/map/map.modifiers/insert_range.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_range.pass.cpp
index 95d8897cea282..bb0fea0a605b4 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_range.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_range.pass.cpp
@@ -9,18 +9,19 @@
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// Some fields in the test case variables are deliberately not explicitly initialized, this silences a warning on GCC.
// ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-missing-field-initializers
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2147483647
// <map>
// template<container-compatible-range<value_type> R>
-// void insert_range(R&& rg); // C++23
+// constexpr void insert_range(R&& rg); // C++23, constexpr since C++26
#include <map>
#include "../../../insert_range_maps_sets.h"
#include "test_macros.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
// Note: we want to use a pair with non-const elements for input (an assignable type is a lot more convenient) but
// have to use the exact `value_type` of the map (that is, `pair<const K, V>`) for the allocator.
using Pair = std::pair<int, char>;
@@ -35,6 +36,13 @@ int main(int, char**) {
test_map_insert_range_exception_safety_throwing_copy<std::map>();
test_assoc_map_insert_range_exception_safety_throwing_allocator<std::map, int, int>();
+ 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/associative/map/map.modifiers/insert_rv.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_rv.pass.cpp
index 345bfde531cf9..d1e7140df50e9 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_rv.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_rv.pass.cpp
@@ -14,7 +14,7 @@
// pair<iterator, bool> insert( value_type&& v); // C++17 and later
// template <class P>
-// pair<iterator, bool> insert(P&& p);
+// constexpr pair<iterator, bool> insert(P&& p); // constexpr since C++26
#include <map>
#include <cassert>
@@ -24,7 +24,7 @@
#include "test_macros.h"
template <class Container, class Pair>
-void do_insert_rv_test() {
+TEST_CONSTEXPR_CXX26 bool do_insert_rv_test() {
typedef Container M;
typedef Pair P;
typedef std::pair<typename M::iterator, bool> R;
@@ -56,9 +56,11 @@ void do_insert_rv_test() {
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3);
+
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
do_insert_rv_test<std::map<int, MoveOnly>, std::pair<int, MoveOnly>>();
do_insert_rv_test<std::map<int, MoveOnly>, std::pair<const int, MoveOnly>>();
@@ -101,6 +103,13 @@ int main(int, char**) {
assert(r.first->first == 3);
assert(r.first->second == 3);
}
+ return true;
+}
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.modifiers/merge.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
index 3613acfa18c1d..c46234a8ff7fc 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
@@ -13,13 +13,13 @@
// class map
// template <class C2>
-// void merge(map<key_type, value_type, C2, allocator_type>& source);
+// constexpr void merge(map<key_type, value_type, C2, allocator_type>& source); // constexpr since C++26
// template <class C2>
-// void merge(map<key_type, value_type, C2, allocator_type>&& source);
+// constexpr void merge(map<key_type, value_type, C2, allocator_type>&& source); // constexpr since C++26
// template <class C2>
-// void merge(multimap<key_type, value_type, C2, allocator_type>& source);
+// constexpr void merge(multimap<key_type, value_type, C2, allocator_type>& source); // constexpr since C++26
// template <class C2>
-// void merge(multimap<key_type, value_type, C2, allocator_type>&& source);
+// constexpr void merge(multimap<key_type, value_type, C2, allocator_type>&& source); // constexpr since C++26
#include <map>
#include <cassert>
@@ -27,7 +27,7 @@
#include "Counter.h"
template <class Map>
-bool map_equal(const Map& map, Map other) {
+TEST_CONSTEXPR_CXX26 bool map_equal(const Map& map, Map other) {
return map == other;
}
@@ -46,7 +46,8 @@ struct throw_comparator {
};
#endif
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26
+bool test() {
{
std::map<int, int> src{{1, 0}, {3, 0}, {5, 0}};
std::map<int, int> dst{{2, 0}, {4, 0}, {5, 0}};
@@ -56,7 +57,7 @@ int main(int, char**) {
}
#ifndef TEST_HAS_NO_EXCEPTIONS
- {
+ if (!TEST_IS_CONSTANT_EVALUATED) {
bool do_throw = false;
typedef std::map<Counter<int>, int, throw_comparator> map_type;
map_type src({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw));
@@ -75,13 +76,14 @@ int main(int, char**) {
assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw))));
}
#endif
- assert(Counter_base::gConstructed == 0);
+ if (!TEST_IS_CONSTANT_EVALUATED)
+ assert(Counter_base::gConstructed == 0);
struct comparator {
comparator() = default;
bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const { return lhs < rhs; }
};
- {
+ if (!TEST_IS_CONSTANT_EVALUATED) {
typedef std::map<Counter<int>, int, std::less<Counter<int>>> first_map_type;
typedef std::map<Counter<int>, int, comparator> second_map_type;
typedef std::multimap<Counter<int>, int, comparator> third_map_type;
@@ -121,7 +123,8 @@ int main(int, char**) {
}
assert(Counter_base::gConstructed == 0);
}
- assert(Counter_base::gConstructed == 0);
+ if (!TEST_IS_CONSTANT_EVALUATED)
+ assert(Counter_base::gConstructed == 0);
{
std::map<int, int> first;
{
@@ -129,11 +132,20 @@ int main(int, char**) {
first.merge(second);
first.merge(std::move(second));
}
- {
+ if (!TEST_IS_CONSTANT_EVALUATED) {
std::multimap<int, int> second;
first.merge(second);
first.merge(std::move(second));
}
}
+ 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/associative/map/map.modifiers/try.emplace.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp
index a087704fb4daf..eb3fc9d793e07 100644
--- a/libcxx/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.modifiers/try.emplace.pass.cpp
@@ -13,13 +13,13 @@
// class map
// template <class... Args>
-// pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17
+// constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17, constexpr since C++26
// template <class... Args>
-// pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17
+// constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17, constexpr since C++26
// template <class... Args>
-// iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17
+// constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17, constexpr since C++26
// template <class... Args>
-// iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17
+// constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17, constexpr since C++26
#include <map>
#include <cassert>
@@ -36,13 +36,13 @@ class Moveable {
double double_;
public:
- Moveable() : int_(0), double_(0) {}
- Moveable(int i, double d) : int_(i), double_(d) {}
- Moveable(Moveable&& x) : int_(x.int_), double_(x.double_) {
+ TEST_CONSTEXPR_CXX26 Moveable() : int_(0), double_(0) {}
+ TEST_CONSTEXPR_CXX26 Moveable(int i, double d) : int_(i), double_(d) {}
+ TEST_CONSTEXPR_CXX26 Moveable(Moveable&& x) : int_(x.int_), double_(x.double_) {
x.int_ = -1;
x.double_ = -1;
}
- Moveable& operator=(Moveable&& x) {
+ TEST_CONSTEXPR_CXX26 Moveable& operator=(Moveable&& x) {
int_ = x.int_;
x.int_ = -1;
double_ = x.double_;
@@ -50,14 +50,16 @@ class Moveable {
return *this;
}
- bool operator==(const Moveable& x) const { return int_ == x.int_ && double_ == x.double_; }
- bool operator<(const Moveable& x) const { return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_); }
+ TEST_CONSTEXPR_CXX26 bool operator==(const Moveable& x) const { return int_ == x.int_ && double_ == x.double_; }
+ TEST_CONSTEXPR_CXX26 bool operator<(const Moveable& x) const {
+ return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);
+ }
- int get() const { return int_; }
- bool moved() const { return int_ == -1; }
+ TEST_CONSTEXPR_CXX26 int get() const { return int_; }
+ TEST_CONSTEXPR_CXX26 bool moved() const { return int_ == -1; }
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{ // pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
typedef std::map<int, Moveable> M;
typedef std::pair<M::iterator, bool> R;
@@ -92,10 +94,10 @@ int main(int, char**) {
assert(r.first->second.get() == 5); // value
Moveable mv3(-1, 3.0);
- r = m.try_emplace(117, std::move(mv2));
+ r = m.try_emplace(117, std::move(mv3));
assert(m.size() == 13);
assert(r.second); // was inserted
- assert(mv2.moved()); // was moved from
+ assert(mv3.moved()); // was moved from
assert(r.first->first == 117); // key
assert(r.first->second.get() == -1); // value
}
@@ -178,6 +180,13 @@ int main(int, char**) {
assert(r->first.get() == 3); // key
assert(r->second.get() == 4); // value
}
+ 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/associative/map/map.nonmember/compare.three_way.pass.cpp b/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.pass.cpp
index 0e1c57f123e58..fc31bd28bbe1f 100644
--- a/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.nonmember/compare.three_way.pass.cpp
@@ -12,9 +12,9 @@
// class map
// template<class Key, class T, class Compare, class Allocator>
-// synth-three-way-result<pair<const Key, T>>
+// constexpr synth-three-way-result<pair<const Key, T>>
// operator<=>(const map<Key, T, Compare, Allocator>& x,
-// const map<Key, T, Compare, Allocator>& y);
+// const map<Key, T, Compare, Allocator>& y); // constexpr since C++26
#include <cassert>
#include <map>
@@ -23,6 +23,9 @@
int main(int, char**) {
assert(test_ordered_map_container_spaceship<std::map>());
- // `std::map` is not constexpr, so no `static_assert` test here.
+#if TEST_STD_VER >= 26
+ static_assert(test_ordered_map_container_spaceship<std::map>());
+#endif
+
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.nonmember/op_compare.pass.cpp b/libcxx/test/std/containers/associative/map/map.nonmember/op_compare.pass.cpp
index 9e376f6a1862b..f576cc07603f6 100644
--- a/libcxx/test/std/containers/associative/map/map.nonmember/op_compare.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.nonmember/op_compare.pass.cpp
@@ -10,27 +10,27 @@
// template<class Key, class T, class Compare, class Alloc>
// bool operator==(const std::map<Key, T, Compare, Alloc>& lhs,
-// const std::map<Key, T, Compare, Alloc>& rhs);
+// const std::map<Key, T, Compare, Alloc>& rhs); // constexpr since C++26
//
// template<class Key, class T, class Compare, class Alloc>
// bool operator!=(const std::map<Key, T, Compare, Alloc>& lhs,
-// const std::map<Key, T, Compare, Alloc>& rhs);
+// const std::map<Key, T, Compare, Alloc>& rhs); // constexpr since C++26
//
// template<class Key, class T, class Compare, class Alloc>
// bool operator<(const std::map<Key, T, Compare, Alloc>& lhs,
-// const std::map<Key, T, Compare, Alloc>& rhs);
+// const std::map<Key, T, Compare, Alloc>& rhs); // constexpr since C++26
//
// template<class Key, class T, class Compare, class Alloc>
// bool operator>(const std::map<Key, T, Compare, Alloc>& lhs,
-// const std::map<Key, T, Compare, Alloc>& rhs);
+// const std::map<Key, T, Compare, Alloc>& rhs); // constexpr since C++26
//
// template<class Key, class T, class Compare, class Alloc>
// bool operator<=(const std::map<Key, T, Compare, Alloc>& lhs,
-// const std::map<Key, T, Compare, Alloc>& rhs);
+// const std::map<Key, T, Compare, Alloc>& rhs); // constexpr since C++26
//
// template<class Key, class T, class Compare, class Alloc>
// bool operator>=(const std::map<Key, T, Compare, Alloc>& lhs,
-// const std::map<Key, T, Compare, Alloc>& rhs);
+// const std::map<Key, T, Compare, Alloc>& rhs); // constexpr since C++26
#include <map>
#include <cassert>
@@ -38,7 +38,7 @@
#include "test_comparisons.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::map<int, std::string> map_type;
typedef map_type::value_type value_type;
{
@@ -77,5 +77,15 @@ int main(int, char**) {
const map_type &cm1 = m1, cm2 = m2;
assert(testComparisons(cm1, cm2, false, true));
}
+
+ 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/associative/map/map.observers/key_comp.pass.cpp b/libcxx/test/std/containers/associative/map/map.observers/key_comp.pass.cpp
index f0757ab47ee48..dcd7af29d5f18 100644
--- a/libcxx/test/std/containers/associative/map/map.observers/key_comp.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.observers/key_comp.pass.cpp
@@ -8,13 +8,15 @@
// <map>
-// key_compare key_comp() const;
+// key_compare key_comp() const; // constexpr since C++26
#include <map>
#include <cassert>
#include <string>
-int main(int, char**) {
+#include "test_macros.h"
+
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::map<int, std::string> map_type;
map_type m;
@@ -25,6 +27,13 @@ int main(int, char**) {
assert(cm.key_comp()(p1.first->first, p2.first->first));
assert(!cm.key_comp()(p2.first->first, p1.first->first));
+ 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/associative/map/map.observers/value_comp.pass.cpp b/libcxx/test/std/containers/associative/map/map.observers/value_comp.pass.cpp
index edd1cd3c5c271..32a10acafbd61 100644
--- a/libcxx/test/std/containers/associative/map/map.observers/value_comp.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.observers/value_comp.pass.cpp
@@ -8,13 +8,15 @@
// <map>
-// value_compare value_comp() const;
+// value_compare value_comp() const; // constexpr since C++26
#include <map>
#include <cassert>
#include <string>
-int main(int, char**) {
+#include "test_macros.h"
+
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::map<int, std::string> map_type;
map_type m;
@@ -25,6 +27,13 @@ int main(int, char**) {
assert(cm.value_comp()(*p1.first, *p2.first));
assert(!cm.value_comp()(*p2.first, *p1.first));
+ 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/associative/map/map.ops/contains.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/contains.pass.cpp
index 7191d4c5e835d..64ccb401e134c 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/contains.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/contains.pass.cpp
@@ -13,10 +13,12 @@
// <map>
-// bool contains(const key_type& x) const;
+// bool contains(const key_type& x) const; // constexpr since C++26
+
+#include "test_macros.h"
template <typename T, typename P, typename B, typename... Pairs>
-void test(B bad, Pairs... args) {
+TEST_CONSTEXPR_CXX26 bool test(B bad, Pairs... args) {
T map;
P pairs[] = {args...};
@@ -26,6 +28,8 @@ void test(B bad, Pairs... args) {
assert(map.contains(p.first));
assert(!map.contains(bad));
+
+ return true;
}
struct E {
@@ -34,7 +38,7 @@ struct E {
char c = 1;
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
test<std::map<char, int>, std::pair<char, int> >(
'e', std::make_pair('a', 10), std::make_pair('b', 11), std::make_pair('c', 12), std::make_pair('d', 13));
@@ -45,7 +49,8 @@ int main(int, char**) {
test<std::map<int, E>, std::pair<int, E> >(
-1, std::make_pair(1, E{}), std::make_pair(2, E{}), std::make_pair(3, E{}), std::make_pair(4, E{}));
}
- {
+ // FIXME: remove when multimap is made constexpr
+ if (!TEST_IS_CONSTANT_EVALUATED) {
test<std::multimap<char, int>, std::pair<char, int> >(
'e', std::make_pair('a', 10), std::make_pair('b', 11), std::make_pair('c', 12), std::make_pair('d', 13));
@@ -55,6 +60,13 @@ int main(int, char**) {
test<std::multimap<int, E>, std::pair<int, E> >(
-1, std::make_pair(1, E{}), std::make_pair(2, E{}), std::make_pair(3, E{}), std::make_pair(4, E{}));
}
+ 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/associative/map/map.ops/contains_transparent.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp
index f80f1a2714bfd..778bd312469a9 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/contains_transparent.pass.cpp
@@ -13,29 +13,46 @@
// <map>
-// template<class K> bool contains(const K& x) const; // C++20
+// template<class K> constexpr bool contains(const K& x) const; // C++20, constexpr since C++26
+
+#include "test_macros.h"
struct Comp {
using is_transparent = void;
- bool operator()(const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const { return lhs < rhs; }
+ TEST_CONSTEXPR_CXX26 bool operator()(const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const {
+ return lhs < rhs;
+ }
- bool operator()(const std::pair<int, int>& lhs, int rhs) const { return lhs.first < rhs; }
+ TEST_CONSTEXPR_CXX26 bool operator()(const std::pair<int, int>& lhs, int rhs) const { return lhs.first < rhs; }
- bool operator()(int lhs, const std::pair<int, int>& rhs) const { return lhs < rhs.first; }
+ TEST_CONSTEXPR_CXX26 bool operator()(int lhs, const std::pair<int, int>& rhs) const { return lhs < rhs.first; }
};
template <typename Container>
-void test() {
+TEST_CONSTEXPR_CXX26 bool test() {
Container s{{{2, 1}, 1}, {{1, 2}, 2}, {{1, 3}, 3}, {{1, 4}, 4}, {{2, 2}, 5}};
assert(s.contains(1));
assert(!s.contains(-1));
+
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
test<std::map<std::pair<int, int>, int, Comp> >();
- test<std::multimap<std::pair<int, int>, int, Comp> >();
+ // FIXME: remove when multimap is made constexpr
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ test<std::multimap<std::pair<int, int>, int, Comp> >();
+ }
+ 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/associative/map/map.ops/count.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/count.pass.cpp
index 9fa53ca05026c..7f7ef18a879d7 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/count.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/count.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// size_type count(const key_type& k) const;
+// size_type count(const key_type& k) const; // constexpr since C++26
#include <map>
#include <cassert>
@@ -23,12 +23,12 @@
#if TEST_STD_VER >= 11
template <class T>
struct FinalCompare final {
- bool operator()(const T& x, const T& y) const { return x < y; }
+ TEST_CONSTEXPR_CXX26 bool operator()(const T& x, const T& y) const { return x < y; }
};
#endif
template <class Map, class ArgType = typename Map::key_type>
-void test() {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef typename Map::value_type V;
typedef typename Map::size_type R;
@@ -45,9 +45,11 @@ void test() {
R r = m.count(ArgType(i));
assert(r == 1);
}
+
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
test<std::map<int, double> >();
#if TEST_STD_VER >= 11
typedef std::pair<const int, double> V;
@@ -85,5 +87,14 @@ int main(int, char**) {
}
}
#endif // TEST_STD_VER >= 14
+
+ 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/associative/map/map.ops/count0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp
index 62491e2bc4438..856f91fc18fee 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/count0.pass.cpp
@@ -12,7 +12,7 @@
// class map
-// size_type count(const key_type& k) const;
+// size_type count(const key_type& k) const; // constexpr since C++26
//
// The member function templates find, count, lower_bound, upper_bound, and
// equal_range shall not participate in overload resolution unless the
@@ -24,7 +24,7 @@
#include "test_macros.h"
#include "is_transparent.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double, transparent_less> M;
assert(M().count(C2Int{5}) == 0);
@@ -37,6 +37,13 @@ int main(int, char**) {
using M = std::map<int, double, transparent_less_nonempty>;
assert(M().count(C2Int{5}) == 0);
}
+ 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/associative/map/map.ops/count_transparent.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp
index fc097c1dc672c..1edfa1f471dd4 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp
@@ -13,27 +13,39 @@
// class map
// template<typename K>
-// size_type count(const K& x) const; // C++14
+// constexpr size_type count(const K& x) const; // C++14, constexpr since C++26
#include <cassert>
#include <map>
#include <utility>
+#include "test_macros.h"
+
struct Comp {
using is_transparent = void;
- bool operator()(const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const { return lhs < rhs; }
+ TEST_CONSTEXPR_CXX26 bool operator()(const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const {
+ return lhs < rhs;
+ }
- bool operator()(const std::pair<int, int>& lhs, int rhs) const { return lhs.first < rhs; }
+ TEST_CONSTEXPR_CXX26 bool operator()(const std::pair<int, int>& lhs, int rhs) const { return lhs.first < rhs; }
- bool operator()(int lhs, const std::pair<int, int>& rhs) const { return lhs < rhs.first; }
+ TEST_CONSTEXPR_CXX26 bool operator()(int lhs, const std::pair<int, int>& rhs) const { return lhs < rhs.first; }
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
std::map<std::pair<int, int>, int, Comp> s{{{2, 1}, 1}, {{1, 2}, 2}, {{1, 3}, 3}, {{1, 4}, 4}, {{2, 2}, 5}};
auto cnt = s.count(1);
assert(cnt == 3);
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.ops/equal_range.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/equal_range.pass.cpp
index 883cd379802e6..ad4877630e65f 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/equal_range.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/equal_range.pass.cpp
@@ -10,8 +10,8 @@
// class map
-// pair<iterator,iterator> equal_range(const key_type& k);
-// pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+// pair<iterator,iterator> equal_range(const key_type& k); // constexpr since C++26
+// pair<const_iterator,const_iterator> equal_range(const key_type& k) const; // constexpr since C++26
#include <map>
#include <cassert>
@@ -21,7 +21,7 @@
#include "private_constructor.h"
#include "is_transparent.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
typedef std::map<int, double> M;
@@ -436,6 +436,13 @@ int main(int, char**) {
assert(r.second == std::next(m.begin(), 8));
}
#endif
+ 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/associative/map/map.ops/equal_range0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
index 57ce9339f6323..62f473fc8616f 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/equal_range0.pass.cpp
@@ -12,8 +12,8 @@
// class map
-// pair<iterator,iterator> equal_range(const key_type& k);
-// pair<const_iterator,const_iterator> equal_range(const key_type& k) const;
+// pair<iterator,iterator> equal_range(const key_type& k); // constexpr since C++26
+// pair<const_iterator,const_iterator> equal_range(const key_type& k) const; // constexpr since C++26
//
// The member function templates find, count, lower_bound, upper_bound, and
// equal_range shall not participate in overload resolution unless the
@@ -25,7 +25,7 @@
#include "test_macros.h"
#include "is_transparent.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double, transparent_less> M;
typedef std::pair<typename M::iterator, typename M::iterator> P;
@@ -47,6 +47,13 @@ int main(int, char**) {
P result = example.equal_range(C2Int{5});
assert(result.first == result.second);
}
+ 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/associative/map/map.ops/equal_range_transparent.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp
index 2b651468887ea..fd69a7fc9a82a 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp
@@ -13,26 +13,29 @@
// class map
// template<typename K>
-// pair<iterator,iterator> equal_range(const K& x); // C++14
+// constexpr pair<iterator,iterator> equal_range(const K& x); // C++14, constexpr since C++26
// template<typename K>
-// pair<const_iterator,const_iterator> equal_range(const K& x) const;
-// // C++14
+// constexpr pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14, constexpr since C++26
#include <cassert>
#include <map>
#include <utility>
+#include "test_macros.h"
+
struct Comp {
using is_transparent = void;
- bool operator()(const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const { return lhs < rhs; }
+ TEST_CONSTEXPR_CXX26 bool operator()(const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const {
+ return lhs < rhs;
+ }
- bool operator()(const std::pair<int, int>& lhs, int rhs) const { return lhs.first < rhs; }
+ TEST_CONSTEXPR_CXX26 bool operator()(const std::pair<int, int>& lhs, int rhs) const { return lhs.first < rhs; }
- bool operator()(int lhs, const std::pair<int, int>& rhs) const { return lhs < rhs.first; }
+ TEST_CONSTEXPR_CXX26 bool operator()(int lhs, const std::pair<int, int>& rhs) const { return lhs < rhs.first; }
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
std::map<std::pair<int, int>, int, Comp> s{{{2, 1}, 1}, {{1, 2}, 2}, {{1, 3}, 3}, {{1, 4}, 4}, {{2, 2}, 5}};
auto er = s.equal_range(1);
@@ -44,6 +47,13 @@ int main(int, char**) {
}
assert(nels == 3);
+ return true;
+}
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.ops/find.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/find.pass.cpp
index b0e8b5ee8ba9e..6d4a84210f32d 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/find.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/find.pass.cpp
@@ -10,8 +10,8 @@
// class map
-// iterator find(const key_type& k);
-// const_iterator find(const key_type& k) const;
+// iterator find(const key_type& k); // constexpr since C++26
+// const_iterator find(const key_type& k) const; // constexpr since C++26
#include <map>
#include <cassert>
@@ -21,7 +21,7 @@
#include "private_constructor.h"
#include "is_transparent.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
typedef std::map<int, double> M;
@@ -95,6 +95,7 @@ int main(int, char**) {
{
typedef M::iterator R;
V ar[] = {V(5, 5), V(6, 6), V(7, 7), V(8, 8), V(9, 9), V(10, 10), V(11, 11), V(12, 12)};
+ (void)ar[0].second;
M m(ar, ar + sizeof(ar) / sizeof(ar[0]));
R r = m.find(5);
assert(r == m.begin());
@@ -222,5 +223,14 @@ int main(int, char**) {
assert(r == std::next(m.begin(), 8));
}
#endif
+
+ 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/associative/map/map.ops/find0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp
index 3f09d5608772d..a41dd3ef6960c 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/find0.pass.cpp
@@ -12,8 +12,8 @@
// class map
-// iterator find(const key_type& k);
-// const_iterator find(const key_type& k) const;
+// iterator find(const key_type& k); // constexpr since C++26
+// const_iterator find(const key_type& k) const; // constexpr since C++26
//
// The member function templates find, count, lower_bound, upper_bound, and
// equal_range shall not participate in overload resolution unless the
@@ -25,7 +25,7 @@
#include "test_macros.h"
#include "is_transparent.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double, transparent_less> M;
M example;
@@ -41,6 +41,13 @@ int main(int, char**) {
M example;
assert(example.find(C2Int{5}) == example.end());
}
+ return true;
+}
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.ops/lower_bound.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/lower_bound.pass.cpp
index 755ad36a3ba4d..5f61de3acd5d6 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/lower_bound.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/lower_bound.pass.cpp
@@ -10,8 +10,8 @@
// class map
-// iterator lower_bound(const key_type& k);
-// const_iterator lower_bound(const key_type& k) const;
+// iterator lower_bound(const key_type& k); // constexpr since C++26
+// const_iterator lower_bound(const key_type& k) const; // constexpr since C++26
#include <map>
#include <cassert>
@@ -21,7 +21,7 @@
#include "private_constructor.h"
#include "is_transparent.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
typedef std::map<int, double> M;
@@ -318,6 +318,13 @@ int main(int, char**) {
assert(r == std::next(m.begin(), 8));
}
#endif
+ 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/associative/map/map.ops/lower_bound0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
index 308a2ed1e3af0..677f2265b9603 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/lower_bound0.pass.cpp
@@ -12,8 +12,8 @@
// class map
-// iterator lower_bound(const key_type& k);
-// const_iterator lower_bound(const key_type& k) const;
+// iterator lower_bound(const key_type& k); // constexpr since C++26
+// const_iterator lower_bound(const key_type& k) const; // constexpr since C++26
//
// The member function templates find, count, lower_bound, upper_bound, and
// equal_range shall not participate in overload resolution unless the
@@ -25,7 +25,7 @@
#include "test_macros.h"
#include "is_transparent.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double, transparent_less> M;
M example;
@@ -41,6 +41,13 @@ int main(int, char**) {
M example;
assert(example.lower_bound(C2Int{5}) == example.end());
}
+ return true;
+}
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.ops/upper_bound.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/upper_bound.pass.cpp
index bd967e3dfb742..4602b4abf70a5 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/upper_bound.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/upper_bound.pass.cpp
@@ -10,8 +10,8 @@
// class map
-// iterator upper_bound(const key_type& k);
-// const_iterator upper_bound(const key_type& k) const;
+// iterator upper_bound(const key_type& k); // constexpr since C++26
+// const_iterator upper_bound(const key_type& k) const; // constexpr since C++26
#include <map>
#include <cassert>
@@ -20,7 +20,7 @@
#include "min_allocator.h"
#include "private_constructor.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::pair<const int, double> V;
typedef std::map<int, double> M;
@@ -281,6 +281,13 @@ int main(int, char**) {
assert(r == std::next(m.begin(), 8));
}
#endif
+ 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/associative/map/map.ops/upper_bound0.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
index 332b71a84e9fb..e664853227c8b 100644
--- a/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.ops/upper_bound0.pass.cpp
@@ -12,8 +12,8 @@
// class map
-// iterator upper_bound(const key_type& k);
-// const_iterator upper_bound(const key_type& k) const;
+// iterator upper_bound(const key_type& k); // constexpr since C++26
+// const_iterator upper_bound(const key_type& k) const; // constexpr since C++26
//
// The member function templates find, count, lower_bound, upper_bound, and
// equal_range shall not participate in overload resolution unless the
@@ -25,7 +25,7 @@
#include "test_macros.h"
#include "is_transparent.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double, transparent_less> M;
M example;
@@ -41,6 +41,12 @@ int main(int, char**) {
M example;
assert(example.upper_bound(C2Int{5}) == example.end());
}
-
+ return true;
+}
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 26
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/containers/associative/map/map.special/member_swap.pass.cpp b/libcxx/test/std/containers/associative/map/map.special/member_swap.pass.cpp
index ffb74f62b8877..442a58cbe3a37 100644
--- a/libcxx/test/std/containers/associative/map/map.special/member_swap.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.special/member_swap.pass.cpp
@@ -10,7 +10,7 @@
// class map
-// void swap(map& m);
+// void swap(map& m); // constexpr since C++26
#include <map>
#include <cassert>
@@ -18,7 +18,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::pair<const int, double> V;
{
typedef std::map<int, double> M;
@@ -108,6 +108,13 @@ int main(int, char**) {
}
}
#endif
+ 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/associative/map/map.special/non_member_swap.pass.cpp b/libcxx/test/std/containers/associative/map/map.special/non_member_swap.pass.cpp
index ba390acd128f5..5f6967e3e0b38 100644
--- a/libcxx/test/std/containers/associative/map/map.special/non_member_swap.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.special/non_member_swap.pass.cpp
@@ -11,8 +11,8 @@
// class map
// template <class Key, class T, class Compare, class Allocator>
-// void
-// swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y);
+// constexpr void
+// swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y); // constexpr since C++26
#include <map>
#include <cassert>
@@ -21,7 +21,7 @@
#include "../../../test_compare.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::pair<const int, double> V;
{
typedef std::map<int, double> M;
@@ -165,6 +165,13 @@ int main(int, char**) {
assert(m2.get_allocator() == A());
}
#endif
+ 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/associative/map/map.special/swap_noexcept.pass.cpp b/libcxx/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp
index 118158fd45ec3..8ede02a4f772d 100644
--- a/libcxx/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.special/swap_noexcept.pass.cpp
@@ -12,11 +12,11 @@
// void swap(map& c)
// noexcept(!allocator_type::propagate_on_container_swap::value ||
-// __is_nothrow_swappable<allocator_type>::value);
+// __is_nothrow_swappable<allocator_type>::value); // constexpr since C++26
//
// In C++17, the standard says that swap shall have:
// noexcept(allocator_traits<Allocator>::is_always_equal::value &&
-// noexcept(swap(declval<Compare&>(), declval<Compare&>())));
+// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); // constexpr since C++26
// This tests a conforming extension
@@ -86,7 +86,7 @@ struct some_alloc3 {
typedef std::false_type is_always_equal;
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::pair<const MoveOnly, MoveOnly> V;
{
typedef std::map<MoveOnly, MoveOnly> C;
@@ -131,6 +131,13 @@ int main(int, char**) {
}
# endif // _LIBCPP_VERSION
#endif
+ 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/associative/map/map.value_compare/invoke.pass.cpp b/libcxx/test/std/containers/associative/map/map.value_compare/invoke.pass.cpp
index 70fa972812cec..b5fa819bb2ca6 100644
--- a/libcxx/test/std/containers/associative/map/map.value_compare/invoke.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/map.value_compare/invoke.pass.cpp
@@ -10,24 +10,26 @@
// class value_compare
-// bool operator()( const value_type& lhs, const value_type& rhs ) const;
+// bool operator()( const value_type& lhs, const value_type& rhs ) const; // constexpr since C++26
#include <map>
#include <cassert>
#include <string>
#include <utility>
+#include "test_macros.h"
+
template <typename Map>
struct CallCompMember : Map::value_compare {
- CallCompMember(const typename Map::value_compare& vc) : Map::value_compare(vc) {}
+ TEST_CONSTEXPR_CXX26 CallCompMember(const typename Map::value_compare& vc) : Map::value_compare(vc) {}
typedef typename Map::value_type value_type;
- bool operator()(const value_type& value1, const value_type& value2) const {
+ TEST_CONSTEXPR_CXX26 bool operator()(const value_type& value1, const value_type& value2) const {
return this->comp(value1.first, value2.first);
}
};
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
typedef std::map<int, std::string> map_type;
map_type m;
@@ -42,6 +44,13 @@ int main(int, char**) {
assert(!vc(*p2.first, *p1.first));
assert(!call_comp(*p2.first, *p1.first));
+ 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/associative/map/types.pass.cpp b/libcxx/test/std/containers/associative/map/types.pass.cpp
index 7832ff3efd3a4..e69eb59081043 100644
--- a/libcxx/test/std/containers/associative/map/types.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/types.pass.cpp
@@ -34,7 +34,7 @@
#include "test_macros.h"
#include "min_allocator.h"
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
{
typedef std::map<int, double> C;
static_assert((std::is_same<C::key_type, int>::value), "");
@@ -66,6 +66,13 @@ int main(int, char**) {
static_assert((std::is_same<C::
diff erence_type, std::ptr
diff _t>::value), "");
}
#endif
+ 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.node/node_handle.pass.cpp b/libcxx/test/std/containers/container.node/node_handle.pass.cpp
index 3b1552cdaa5d4..c1477763e0afe 100644
--- a/libcxx/test/std/containers/container.node/node_handle.pass.cpp
+++ b/libcxx/test/std/containers/container.node/node_handle.pass.cpp
@@ -107,7 +107,7 @@ static_assert(
"");
template <class Container>
-void test_node_handle_operations() {
+TEST_CONSTEXPR_CXX26 bool test_node_handle_operations() {
Container c;
typename Container::node_type nt1, nt2 = c.extract(c.emplace().first);
@@ -117,10 +117,12 @@ void test_node_handle_operations() {
std::swap(nt1, nt2);
assert(nt1.get_allocator() == c.get_allocator());
assert(nt2.empty());
+
+ return true;
}
template <class Container>
-void test_node_handle_operations_multi() {
+TEST_CONSTEXPR_CXX26 bool test_node_handle_operations_multi() {
Container c;
typename Container::node_type nt1, nt2 = c.extract(c.emplace());
@@ -130,30 +132,50 @@ void test_node_handle_operations_multi() {
std::swap(nt1, nt2);
assert(nt1.get_allocator() == c.get_allocator());
assert(nt2.empty());
+
+ return true;
}
template <class>
-void test_typedef() {}
+TEST_CONSTEXPR_CXX26 bool test_typedef() {
+ return true;
+}
template <class Container>
-void test_insert_return_type() {
+TEST_CONSTEXPR_CXX26 bool test_insert_return_type() {
test_typedef<typename Container::insert_return_type>();
+ return true;
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX26 bool test() {
test_node_handle_operations<std::map<int, int>>();
- test_node_handle_operations_multi<std::multimap<int, int>>();
- test_node_handle_operations<std::set<int>>();
- test_node_handle_operations_multi<std::multiset<int>>();
- test_node_handle_operations<std::unordered_map<int, int>>();
- test_node_handle_operations_multi<std::unordered_multimap<int, int>>();
- test_node_handle_operations<std::unordered_set<int>>();
- test_node_handle_operations_multi<std::unordered_multiset<int>>();
+
+ // FIXME: update when other containers are made constexpr
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ test_node_handle_operations_multi<std::multimap<int, int>>();
+ test_node_handle_operations<std::set<int>>();
+ test_node_handle_operations_multi<std::multiset<int>>();
+ test_node_handle_operations<std::unordered_map<int, int>>();
+ test_node_handle_operations_multi<std::unordered_multimap<int, int>>();
+ test_node_handle_operations<std::unordered_set<int>>();
+ test_node_handle_operations_multi<std::unordered_multiset<int>>();
+ }
test_insert_return_type<std::map<int, int>>();
- test_insert_return_type<std::set<int>>();
- test_insert_return_type<std::unordered_map<int, int>>();
- test_insert_return_type<std::unordered_set<int>>();
+ // FIXME: update when other containers are made constexpr
+ if (!TEST_IS_CONSTANT_EVALUATED) {
+ test_insert_return_type<std::set<int>>();
+ test_insert_return_type<std::unordered_map<int, int>>();
+ test_insert_return_type<std::unordered_set<int>>();
+ }
+ 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/insert_range_maps_sets.h b/libcxx/test/std/containers/insert_range_maps_sets.h
index 6e344d8ad3b0f..9b14a70a68236 100644
--- a/libcxx/test/std/containers/insert_range_maps_sets.h
+++ b/libcxx/test/std/containers/insert_range_maps_sets.h
@@ -200,7 +200,7 @@ TestCaseMapSet<std::pair<K, V>> constexpr NElementsContainer_RangeWithDuplicates
{16, 'D'}}};
template <class Container, class T, class Iter, class Sent>
-void test_map_set_insert_range(bool allow_duplicates = false) {
+TEST_CONSTEXPR_CXX26 void test_map_set_insert_range(bool allow_duplicates = false) {
auto test = [&](const TestCaseMapSet<T>& test_case, bool check_multi = false) {
Container c(test_case.initial.begin(), test_case.initial.end());
auto in = wrap_input<Iter, Sent>(test_case.input);
@@ -259,13 +259,14 @@ void test_set_insert_range_move_only() {
}
template <template <class...> class Container>
-void test_map_insert_range_move_only() {
+TEST_CONSTEXPR_CXX26 bool test_map_insert_range_move_only() {
using Value = std::pair<const int, MoveOnly>;
Value input[5];
std::ranges::subrange in(std::move_iterator{input}, std::move_iterator{input + 5});
Container<int, MoveOnly> c;
c.insert_range(in);
+ return true;
}
// Exception safety.
@@ -290,8 +291,8 @@ void test_set_insert_range_exception_safety_throwing_copy() {
}
template <template <class...> class Container>
-void test_map_insert_range_exception_safety_throwing_copy() {
-#if !defined(TEST_HAS_NO_EXCEPTIONS)
+TEST_CONSTEXPR_CXX26 void test_map_insert_range_exception_safety_throwing_copy() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(TEST_IS_CONSTANT_EVALUATED)
using K = int;
using V = ThrowingCopy<3>;
@@ -351,8 +352,8 @@ void test_unord_set_insert_range_exception_safety_throwing_allocator() {
}
template <template <class...> class Container, class K, class V>
-void test_assoc_map_insert_range_exception_safety_throwing_allocator() {
-#if !defined(TEST_HAS_NO_EXCEPTIONS)
+TEST_CONSTEXPR_CXX26 void test_assoc_map_insert_range_exception_safety_throwing_allocator() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(TEST_IS_CONSTANT_EVALUATED)
using ValueType = std::pair<const K, V>;
ValueType in[] = {ValueType{K{1}, V{1}}};
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/map.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/map.version.compile.pass.cpp
index 3db3861c72b5c..794c2ee9ad086 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/map.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/map.version.compile.pass.cpp
@@ -32,6 +32,10 @@
# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_containers_ranges
# error "__cpp_lib_containers_ranges should not be defined before c++23"
# endif
@@ -74,6 +78,10 @@
# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_containers_ranges
# error "__cpp_lib_containers_ranges should not be defined before c++23"
# endif
@@ -122,6 +130,10 @@
# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_containers_ranges
# error "__cpp_lib_containers_ranges should not be defined before c++23"
# endif
@@ -179,6 +191,10 @@
# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_containers_ranges
# error "__cpp_lib_containers_ranges should not be defined before c++23"
# endif
@@ -248,6 +264,10 @@
# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifndef __cpp_lib_containers_ranges
# error "__cpp_lib_containers_ranges should be defined in c++23"
# endif
@@ -338,6 +358,13 @@
# endif
# endif
+# ifndef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should be defined in c++26"
+# endif
+# if __cpp_lib_constexpr_map != 202502L
+# error "__cpp_lib_constexpr_map should have the value 202502L in c++26"
+# endif
+
# ifndef __cpp_lib_containers_ranges
# error "__cpp_lib_containers_ranges should be defined in c++26"
# endif
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 2aa52a64c6cf0..20c16700ef76a 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -232,6 +232,10 @@
# error "__cpp_lib_constexpr_list should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_constexpr_memory
# error "__cpp_lib_constexpr_memory should not be defined before c++20"
# endif
@@ -1164,6 +1168,10 @@
# error "__cpp_lib_constexpr_list should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_constexpr_memory
# error "__cpp_lib_constexpr_memory should not be defined before c++20"
# endif
@@ -2198,6 +2206,10 @@
# error "__cpp_lib_constexpr_list should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifdef __cpp_lib_constexpr_memory
# error "__cpp_lib_constexpr_memory should not be defined before c++20"
# endif
@@ -3472,6 +3484,10 @@
# error "__cpp_lib_constexpr_list should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifndef __cpp_lib_constexpr_memory
# error "__cpp_lib_constexpr_memory should be defined in c++20"
# endif
@@ -4962,6 +4978,10 @@
# error "__cpp_lib_constexpr_list should not be defined before c++26"
# endif
+# ifdef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should not be defined before c++26"
+# endif
+
# ifndef __cpp_lib_constexpr_memory
# error "__cpp_lib_constexpr_memory should be defined in c++23"
# endif
@@ -6683,6 +6703,13 @@
# error "__cpp_lib_constexpr_list should have the value 202502L in c++26"
# endif
+# ifndef __cpp_lib_constexpr_map
+# error "__cpp_lib_constexpr_map should be defined in c++26"
+# endif
+# if __cpp_lib_constexpr_map != 202502L
+# error "__cpp_lib_constexpr_map should have the value 202502L in c++26"
+# endif
+
# ifndef __cpp_lib_constexpr_memory
# error "__cpp_lib_constexpr_memory should be defined in c++26"
# endif
diff --git a/libcxx/test/support/CopyConstructible.h b/libcxx/test/support/CopyConstructible.h
new file mode 100644
index 0000000000000..d42981de739dd
--- /dev/null
+++ b/libcxx/test/support/CopyConstructible.h
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef COPYCONSTRUCTIBLE_H
+#define COPYCONSTRUCTIBLE_H
+
+#include "test_macros.h"
+
+#include <cstddef>
+#include <functional>
+#include <type_traits>
+
+class CopyConstructible {
+ int data_;
+
+public:
+ TEST_CONSTEXPR CopyConstructible(int data = 1) : data_(data) {}
+
+ CopyConstructible(const CopyConstructible&) = default;
+ CopyConstructible& operator=(const CopyConstructible&) = default;
+
+ TEST_CONSTEXPR_CXX14 CopyConstructible(CopyConstructible&& x) TEST_NOEXCEPT : data_(x.data_) { x.data_ = 0; }
+ TEST_CONSTEXPR_CXX14 CopyConstructible& operator=(CopyConstructible&& x) {
+ data_ = x.data_;
+ x.data_ = 0;
+ return *this;
+ }
+
+ TEST_CONSTEXPR int get() const { return data_; }
+
+ friend TEST_CONSTEXPR bool operator==(const CopyConstructible& x, const CopyConstructible& y) {
+ return x.data_ == y.data_;
+ }
+ friend TEST_CONSTEXPR bool operator!=(const CopyConstructible& x, const CopyConstructible& y) {
+ return x.data_ != y.data_;
+ }
+ friend TEST_CONSTEXPR bool operator<(const CopyConstructible& x, const CopyConstructible& y) {
+ return x.data_ < y.data_;
+ }
+ friend TEST_CONSTEXPR bool operator<=(const CopyConstructible& x, const CopyConstructible& y) {
+ return x.data_ <= y.data_;
+ }
+ friend TEST_CONSTEXPR bool operator>(const CopyConstructible& x, const CopyConstructible& y) {
+ return x.data_ > y.data_;
+ }
+ friend TEST_CONSTEXPR bool operator>=(const CopyConstructible& x, const CopyConstructible& y) {
+ return x.data_ >= y.data_;
+ }
+
+#if TEST_STD_VER > 17
+ friend constexpr auto operator<=>(const CopyConstructible&, const CopyConstructible&) = default;
+#endif // TEST_STD_VER > 17
+
+ TEST_CONSTEXPR_CXX14 CopyConstructible operator+(const CopyConstructible& x) const {
+ return CopyConstructible(data_ + x.data_);
+ }
+ TEST_CONSTEXPR_CXX14 CopyConstructible operator*(const CopyConstructible& x) const {
+ return CopyConstructible(data_ * x.data_);
+ }
+
+ template <class T>
+ friend void operator,(CopyConstructible const&, T) = delete;
+
+ template <class T>
+ friend void operator,(T, CopyConstructible const&) = delete;
+};
+static_assert(std::is_copy_constructible<CopyConstructible>::value, "Needs to be copy-constructible");
+
+#endif
diff --git a/libcxx/test/support/is_transparent.h b/libcxx/test/support/is_transparent.h
index 9d3791d68a865..846f8fa4d06dd 100644
--- a/libcxx/test/support/is_transparent.h
+++ b/libcxx/test/support/is_transparent.h
@@ -81,16 +81,17 @@ struct transparent_less_not_a_type
};
struct C2Int { // comparable to int
- C2Int() : i_(0) {}
- C2Int(int i): i_(i) {}
- int get () const { return i_; }
+ TEST_CONSTEXPR_CXX26 C2Int() : i_(0) {}
+ TEST_CONSTEXPR_CXX26 C2Int(int i) : i_(i) {}
+ TEST_CONSTEXPR_CXX26 int get() const { return i_; }
+
private:
int i_;
};
-bool operator <(int rhs, const C2Int& lhs) { return rhs < lhs.get(); }
-bool operator <(const C2Int& rhs, const C2Int& lhs) { return rhs.get() < lhs.get(); }
-bool operator <(const C2Int& rhs, int lhs) { return rhs.get() < lhs; }
+ TEST_CONSTEXPR_CXX26 bool operator<(int rhs, const C2Int& lhs) { return rhs < lhs.get(); }
+ TEST_CONSTEXPR_CXX26 bool operator<(const C2Int& rhs, const C2Int& lhs) { return rhs.get() < lhs.get(); }
+ TEST_CONSTEXPR_CXX26 bool operator<(const C2Int& rhs, int lhs) { return rhs.get() < lhs; }
#endif // TEST_STD_VER > 11
diff --git a/libcxx/test/support/private_constructor.h b/libcxx/test/support/private_constructor.h
index 24f540c6a7fdc..c7ed288c4032e 100644
--- a/libcxx/test/support/private_constructor.h
+++ b/libcxx/test/support/private_constructor.h
@@ -9,18 +9,22 @@
#ifndef TEST_SUPPORT_PRIVATE_CONSTRUCTOR_H
#define TEST_SUPPORT_PRIVATE_CONSTRUCTOR_H
+#include "test_macros.h"
+
struct PrivateConstructor {
+ TEST_CONSTEXPR_CXX26 PrivateConstructor static make(int v) { return PrivateConstructor(v); }
+ TEST_CONSTEXPR_CXX26 int get() const { return val; }
- PrivateConstructor static make ( int v ) { return PrivateConstructor(v); }
- int get () const { return val; }
private:
- PrivateConstructor ( int v ) : val(v) {}
- int val;
+ TEST_CONSTEXPR_CXX26 PrivateConstructor(int v) : val(v) {}
+ int val;
};
-bool operator < ( const PrivateConstructor &lhs, const PrivateConstructor &rhs ) { return lhs.get() < rhs.get(); }
+ TEST_CONSTEXPR_CXX26 bool operator<(const PrivateConstructor& lhs, const PrivateConstructor& rhs) {
+ return lhs.get() < rhs.get();
+ }
-bool operator < ( const PrivateConstructor &lhs, int rhs ) { return lhs.get() < rhs; }
-bool operator < ( int lhs, const PrivateConstructor &rhs ) { return lhs < rhs.get(); }
+ TEST_CONSTEXPR_CXX26 bool operator<(const PrivateConstructor& lhs, int rhs) { return lhs.get() < rhs; }
+ TEST_CONSTEXPR_CXX26 bool operator<(int lhs, const PrivateConstructor& rhs) { return lhs < rhs.get(); }
#endif // TEST_SUPPORT_PRIVATE_CONSTRUCTOR_H
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 050dab93bea29..d8fb575b97b2f 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -405,6 +405,11 @@ def add_version_header(tc):
"values": {"c++26": 202502},
"headers": ["list"],
},
+ {
+ "name": "__cpp_lib_constexpr_map",
+ "values": {"c++26": 202502},
+ "headers": ["map"],
+ },
{
"name": "__cpp_lib_constexpr_memory",
"values": {"c++20": 201811, "c++23": 202202},
More information about the libcxx-commits
mailing list