From d0e62e436d52f8cba641c6abbf682ad270c3d094 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Sat, 1 Mar 2025 12:37:25 -0500 Subject: [PATCH 1/5] Make list constexpr as part of P3372R3 --- libcxx/docs/FeatureTestMacroTable.rst | 2 + libcxx/include/list | 552 +++++++++------ libcxx/include/version | 2 + .../sequences/list/compare.pass.cpp | 24 +- .../sequences/list/compare.three_way.pass.cpp | 6 +- .../sequences/list/get_allocator.pass.cpp | 13 +- .../sequences/list/incomplete_type.pass.cpp | 13 +- .../sequences/list/iterators.pass.cpp | 27 +- .../list/list.capacity/empty.pass.cpp | 13 +- .../list/list.capacity/max_size.pass.cpp | 13 +- .../list/list.capacity/resize_size.pass.cpp | 63 +- .../list.capacity/resize_size_value.pass.cpp | 13 +- .../list/list.capacity/size.pass.cpp | 13 +- .../list/list.cons/assign_copy.pass.cpp | 13 +- .../assign_initializer_list.pass.cpp | 13 +- .../list/list.cons/assign_move.pass.cpp | 13 +- .../sequences/list/list.cons/copy.pass.cpp | 13 +- .../list/list.cons/copy_alloc.pass.cpp | 13 +- .../sequences/list/list.cons/default.pass.cpp | 13 +- .../list.cons/default_stack_alloc.pass.cpp | 13 +- .../list/list.cons/from_range.pass.cpp | 20 +- .../list/list.cons/initializer_list.pass.cpp | 13 +- .../list.cons/initializer_list_alloc.pass.cpp | 13 +- .../list/list.cons/input_iterator.pass.cpp | 31 +- .../sequences/list/list.cons/move.pass.cpp | 13 +- .../list/list.cons/move_alloc.pass.cpp | 13 +- .../op_equal_initializer_list.pass.cpp | 13 +- .../list/list.cons/size_type.pass.cpp | 40 +- .../list/list.cons/size_value_alloc.pass.cpp | 13 +- .../list/list.erasure/erase.pass.cpp | 27 +- .../list/list.erasure/erase_if.pass.cpp | 27 +- .../list/list.modifiers/append_range.pass.cpp | 20 +- .../list/list.modifiers/assign_range.pass.cpp | 20 +- .../list/list.modifiers/clear.pass.cpp | 13 +- .../list/list.modifiers/emplace.pass.cpp | 19 +- .../list/list.modifiers/emplace_back.pass.cpp | 19 +- .../list.modifiers/emplace_front.pass.cpp | 19 +- .../list/list.modifiers/erase_iter.pass.cpp | 13 +- .../list.modifiers/erase_iter_iter.pass.cpp | 13 +- .../insert_iter_initializer_list.pass.cpp | 13 +- .../insert_iter_iter_iter.pass.cpp | 59 +- .../insert_iter_rvalue.pass.cpp | 13 +- .../insert_iter_size_value.pass.cpp | 33 +- .../list.modifiers/insert_iter_value.pass.cpp | 33 +- .../list/list.modifiers/insert_range.pass.cpp | 23 +- .../list/list.modifiers/pop_back.pass.cpp | 13 +- .../list/list.modifiers/pop_front.pass.cpp | 13 +- .../list.modifiers/prepend_range.pass.cpp | 20 +- .../list/list.modifiers/push_back.pass.cpp | 13 +- .../list.modifiers/push_back_rvalue.pass.cpp | 13 +- .../list/list.modifiers/push_front.pass.cpp | 13 +- .../list.modifiers/push_front_rvalue.pass.cpp | 13 +- .../sequences/list/list.ops/merge.pass.cpp | 13 +- .../list/list.ops/merge_comp.pass.cpp | 13 +- .../sequences/list/list.ops/remove.pass.cpp | 25 +- .../list/list.ops/remove_if.pass.cpp | 25 +- .../sequences/list/list.ops/reverse.pass.cpp | 13 +- .../sequences/list/list.ops/sort.pass.cpp | 19 +- .../list/list.ops/sort_comp.pass.cpp | 57 +- .../list/list.ops/splice_pos_list.pass.cpp | 13 +- .../list.ops/splice_pos_list_iter.pass.cpp | 13 +- .../splice_pos_list_iter_iter.pass.cpp | 13 +- .../sequences/list/list.ops/unique.pass.cpp | 13 +- .../list/list.ops/unique_pred.pass.cpp | 23 +- .../sequences/list/list.special/swap.pass.cpp | 13 +- .../list/list.special/swap_noexcept.pass.cpp | 13 +- libcxx/test/support/min_allocator.h | 647 +++++++++--------- .../generate_feature_test_macro_components.py | 5 + 68 files changed, 1550 insertions(+), 844 deletions(-) diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 3e6fd643f620c..5ebc9bb7dcda2 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -422,6 +422,8 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_forward_list`` ``202502L`` ---------------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_list`` ``202502L`` + ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_new`` ``202406L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_constexpr_queue`` ``202502L`` diff --git a/libcxx/include/list b/libcxx/include/list index 98610f59ed74a..ee846f7aa5fcf 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -297,14 +297,20 @@ struct __list_node_base { __base_pointer __prev_; __base_pointer __next_; - _LIBCPP_HIDE_FROM_ABI __list_node_base() : __prev_(__self()), __next_(__self()) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_node_base() : __prev_(__self()), __next_(__self()) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit __list_node_base(__base_pointer __prev, __base_pointer __next) : __prev_(__prev), __next_(__next) {} - _LIBCPP_HIDE_FROM_ABI __base_pointer __self() { return pointer_traits<__base_pointer>::pointer_to(*this); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer __self() { + return pointer_traits<__base_pointer>::pointer_to(*this); + } - _LIBCPP_HIDE_FROM_ABI __node_pointer __as_node() { return static_cast<__node_pointer>(__self()); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __node_pointer __as_node() { + return pointer_traits<__node_pointer>::pointer_to( + *static_cast::element_type*>(this)); + } }; template @@ -319,7 +325,7 @@ private: }; public: - _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; } # else private: @@ -332,10 +338,14 @@ public: typedef __list_node_base<_Tp, _VoidPtr> __base; typedef typename __base::__base_pointer __base_pointer; - _LIBCPP_HIDE_FROM_ABI explicit __list_node(__base_pointer __prev, __base_pointer __next) : __base(__prev, __next) {} - _LIBCPP_HIDE_FROM_ABI ~__list_node() {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit __list_node(__base_pointer __prev, __base_pointer __next) + : __base(__prev, __next) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI ~__list_node() {} - _LIBCPP_HIDE_FROM_ABI __base_pointer __as_link() { return __base::__self(); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer __as_link() { + return pointer_traits<__base_pointer>::pointer_to( + *static_cast::element_type*>(this)); + } }; template > @@ -352,7 +362,8 @@ class __list_iterator { __base_pointer __ptr_; - _LIBCPP_HIDE_FROM_ABI explicit __list_iterator(__base_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit __list_iterator(__base_pointer __p) _NOEXCEPT + : __ptr_(__p) {} template friend class list; @@ -368,37 +379,41 @@ public: typedef __rebind_pointer_t<_VoidPtr, value_type> pointer; typedef typename pointer_traits::difference_type difference_type; - _LIBCPP_HIDE_FROM_ABI __list_iterator() _NOEXCEPT : __ptr_(nullptr) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_iterator() _NOEXCEPT : __ptr_(nullptr) {} - _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __ptr_->__as_node()->__get_value(); } - _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference operator*() const { + return __ptr_->__as_node()->__get_value(); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits::pointer_to(__ptr_->__as_node()->__get_value()); } - _LIBCPP_HIDE_FROM_ABI __list_iterator& operator++() { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_iterator& operator++() { __ptr_ = __ptr_->__next_; return *this; } - _LIBCPP_HIDE_FROM_ABI __list_iterator operator++(int) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_iterator operator++(int) { __list_iterator __t(*this); ++(*this); return __t; } - _LIBCPP_HIDE_FROM_ABI __list_iterator& operator--() { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_iterator& operator--() { __ptr_ = __ptr_->__prev_; return *this; } - _LIBCPP_HIDE_FROM_ABI __list_iterator operator--(int) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_iterator operator--(int) { __list_iterator __t(*this); --(*this); return __t; } - friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __list_iterator& __x, const __list_iterator& __y) { + friend _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool + operator==(const __list_iterator& __x, const __list_iterator& __y) { return __x.__ptr_ == __y.__ptr_; } - friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __list_iterator& __x, const __list_iterator& __y) { + friend _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool + operator!=(const __list_iterator& __x, const __list_iterator& __y) { return !(__x == __y); } }; @@ -410,7 +425,8 @@ class __list_const_iterator { __base_pointer __ptr_; - _LIBCPP_HIDE_FROM_ABI explicit __list_const_iterator(__base_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit __list_const_iterator(__base_pointer __p) _NOEXCEPT + : __ptr_(__p) {} template friend class list; @@ -424,39 +440,43 @@ public: typedef __rebind_pointer_t<_VoidPtr, const value_type> pointer; typedef typename pointer_traits::difference_type difference_type; - _LIBCPP_HIDE_FROM_ABI __list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {} - _LIBCPP_HIDE_FROM_ABI __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT - : __ptr_(__p.__ptr_) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI + __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT : __ptr_(__p.__ptr_) {} - _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __ptr_->__as_node()->__get_value(); } - _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference operator*() const { + return __ptr_->__as_node()->__get_value(); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits::pointer_to(__ptr_->__as_node()->__get_value()); } - _LIBCPP_HIDE_FROM_ABI __list_const_iterator& operator++() { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_const_iterator& operator++() { __ptr_ = __ptr_->__next_; return *this; } - _LIBCPP_HIDE_FROM_ABI __list_const_iterator operator++(int) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_const_iterator operator++(int) { __list_const_iterator __t(*this); ++(*this); return __t; } - _LIBCPP_HIDE_FROM_ABI __list_const_iterator& operator--() { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_const_iterator& operator--() { __ptr_ = __ptr_->__prev_; return *this; } - _LIBCPP_HIDE_FROM_ABI __list_const_iterator operator--(int) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_const_iterator operator--(int) { __list_const_iterator __t(*this); --(*this); return __t; } - friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y) { + friend _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool + operator==(const __list_const_iterator& __x, const __list_const_iterator& __y) { return __x.__ptr_ == __y.__ptr_; } - friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y) { + friend _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool + operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y) { return !(__x == __y); } }; @@ -497,43 +517,49 @@ protected: __node_base __end_; _LIBCPP_COMPRESSED_PAIR(size_type, __size_, __node_allocator, __node_alloc_); - _LIBCPP_HIDE_FROM_ABI __base_pointer __end_as_link() const _NOEXCEPT { - return const_cast<__node_base&>(__end_).__self(); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer __end_as_link() const _NOEXCEPT { + return pointer_traits<__base_pointer>::pointer_to(const_cast<__node_base&>(__end_)); } - _LIBCPP_HIDE_FROM_ABI size_type __node_alloc_max_size() const _NOEXCEPT { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type __node_alloc_max_size() const _NOEXCEPT { return __node_alloc_traits::max_size(__node_alloc_); } - _LIBCPP_HIDE_FROM_ABI static void __unlink_nodes(__base_pointer __f, __base_pointer __l) _NOEXCEPT; + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI static void + __unlink_nodes(__base_pointer __f, __base_pointer __l) _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI __list_imp() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value); - _LIBCPP_HIDE_FROM_ABI __list_imp(const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI __list_imp(const __node_allocator& __a); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_imp() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_imp(const allocator_type& __a); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_imp(const __node_allocator& __a); # ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI __list_imp(__node_allocator&& __a) _NOEXCEPT; + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __list_imp(__node_allocator&& __a) _NOEXCEPT; # endif - _LIBCPP_HIDE_FROM_ABI ~__list_imp(); - _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __size_ == 0; } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI ~__list_imp(); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __size_ == 0; } - _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__end_.__next_); } - _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return const_iterator(__end_.__next_); } - _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(__end_as_link()); } - _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return const_iterator(__end_as_link()); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return iterator(__end_.__next_); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { + return const_iterator(__end_.__next_); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return iterator(__end_as_link()); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { + return const_iterator(__end_as_link()); + } - _LIBCPP_HIDE_FROM_ABI void swap(__list_imp& __c) + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(__list_imp& __c) # if _LIBCPP_STD_VER >= 14 _NOEXCEPT; # else _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v); # endif - _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __list_imp& __c) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __list_imp& __c) { __copy_assign_alloc( __c, integral_constant()); } - _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp& __c) + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp& __c) _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_move_assignment::value || is_nothrow_move_assignable<__node_allocator>::value) { __move_assign_alloc( @@ -541,7 +567,8 @@ protected: } template - _LIBCPP_HIDE_FROM_ABI __node_pointer __create_node(__base_pointer __prev, __base_pointer __next, _Args&&... __args) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __node_pointer + __create_node(__base_pointer __prev, __base_pointer __next, _Args&&... __args) { __allocation_guard<__node_allocator> __guard(__node_alloc_, 1); // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value // held inside the node, since we need to use the allocator's construct() method for that. @@ -557,7 +584,7 @@ protected: return __guard.__release_ptr(); } - _LIBCPP_HIDE_FROM_ABI void __delete_node(__node_pointer __node) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __delete_node(__node_pointer __node) { // For the same reason as above, we use the allocator's destroy() method for the value_type, // but not for the node itself. __node_alloc_traits::destroy(__node_alloc_, std::addressof(__node->__get_value())); @@ -566,54 +593,57 @@ protected: } private: - _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __list_imp& __c, true_type) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __list_imp& __c, true_type) { if (__node_alloc_ != __c.__node_alloc_) clear(); __node_alloc_ = __c.__node_alloc_; } - _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __list_imp&, false_type) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __list_imp&, false_type) {} - _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp& __c, true_type) + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp& __c, true_type) _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) { __node_alloc_ = std::move(__c.__node_alloc_); } - _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp&, false_type) _NOEXCEPT {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__list_imp&, false_type) _NOEXCEPT {} }; // Unlink nodes [__f, __l] template -inline void __list_imp<_Tp, _Alloc>::__unlink_nodes(__base_pointer __f, __base_pointer __l) _NOEXCEPT { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline void +__list_imp<_Tp, _Alloc>::__unlink_nodes(__base_pointer __f, __base_pointer __l) _NOEXCEPT { __f->__prev_->__next_ = __l->__next_; __l->__next_->__prev_ = __f->__prev_; } template -inline __list_imp<_Tp, _Alloc>::__list_imp() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline __list_imp<_Tp, _Alloc>::__list_imp() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) : __size_(0) {} template -inline __list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a) +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline __list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a) : __size_(0), __node_alloc_(__node_allocator(__a)) {} template -inline __list_imp<_Tp, _Alloc>::__list_imp(const __node_allocator& __a) : __size_(0), __node_alloc_(__a) {} +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline __list_imp<_Tp, _Alloc>::__list_imp(const __node_allocator& __a) + : __size_(0), __node_alloc_(__a) {} # ifndef _LIBCPP_CXX03_LANG template -inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT : __size_(0), __node_alloc_(std::move(__a)) {} # endif template -__list_imp<_Tp, _Alloc>::~__list_imp() { +_LIBCPP_CONSTEXPR_SINCE_CXX26 __list_imp<_Tp, _Alloc>::~__list_imp() { clear(); } template -void __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT { if (!empty()) { __base_pointer __f = __end_.__next_; __base_pointer __l = __end_as_link(); @@ -628,7 +658,7 @@ void __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT { } template -void __list_imp<_Tp, _Alloc>::swap(__list_imp& __c) +_LIBCPP_CONSTEXPR_SINCE_CXX26 void __list_imp<_Tp, _Alloc>::swap(__list_imp& __c) # if _LIBCPP_STD_VER >= 14 _NOEXCEPT # else @@ -686,170 +716,204 @@ public: typedef void __remove_return_type; # endif - _LIBCPP_HIDE_FROM_ABI list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {} - _LIBCPP_HIDE_FROM_ABI explicit list(const allocator_type& __a) : __base(__a) {} - _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list() + _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(const allocator_type& __a) : __base(__a) {} + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n); # if _LIBCPP_STD_VER >= 14 - _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n, const allocator_type& __a); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n, const allocator_type& __a); # endif - _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x); template <__enable_if_t<__is_allocator<_Alloc>::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x, const allocator_type& __a) : __base(__a) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI + list(size_type __n, const value_type& __x, const allocator_type& __a) + : __base(__a) { for (; __n > 0; --__n) push_back(__x); } template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l); template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l, const allocator_type& __a); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l, const allocator_type& __a); # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI list(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI + list(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) : __base(__a) { prepend_range(std::forward<_Range>(__range)); } # endif - _LIBCPP_HIDE_FROM_ABI list(const list& __c); - _LIBCPP_HIDE_FROM_ABI list(const list& __c, const __type_identity_t& __a); - _LIBCPP_HIDE_FROM_ABI list& operator=(const list& __c); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(const list& __c); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI + list(const list& __c, const __type_identity_t& __a); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list& operator=(const list& __c); # ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI list(initializer_list __il); - _LIBCPP_HIDE_FROM_ABI list(initializer_list __il, const allocator_type& __a); - - _LIBCPP_HIDE_FROM_ABI list(list&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); - _LIBCPP_HIDE_FROM_ABI list(list&& __c, const __type_identity_t& __a); - _LIBCPP_HIDE_FROM_ABI list& operator=(list&& __c) noexcept( + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(initializer_list __il); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI + list(initializer_list __il, const allocator_type& __a); + + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(list&& __c) + _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(list&& __c, const __type_identity_t& __a); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list& operator=(list&& __c) noexcept( (__node_alloc_traits::propagate_on_container_move_assignment::value && is_nothrow_move_assignable<__node_allocator>::value) || allocator_traits::is_always_equal::value); - _LIBCPP_HIDE_FROM_ABI list& operator=(initializer_list __il) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list& operator=(initializer_list __il) { assign(__il.begin(), __il.end()); return *this; } - _LIBCPP_HIDE_FROM_ABI void assign(initializer_list __il) { assign(__il.begin(), __il.end()); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(initializer_list __il) { + assign(__il.begin(), __il.end()); + } # endif // _LIBCPP_CXX03_LANG template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI void assign(_InpIter __f, _InpIter __l); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(_InpIter __f, _InpIter __l); # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI void assign_range(_Range&& __range) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign_range(_Range&& __range) { __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); } # endif - _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __x); - _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT; + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return this->__size_; } - [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __base::empty(); } - _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return this->__size_; } + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { + return __base::empty(); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return std::min(this->__node_alloc_max_size(), numeric_limits::max()); } - _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __base::begin(); } - _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __base::begin(); } - _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __base::end(); } - _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __base::end(); } - _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return __base::begin(); } - _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __base::end(); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __base::begin(); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __base::begin(); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __base::end(); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __base::end(); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { + return __base::begin(); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return __base::end(); } - _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(end()); } - _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(begin()); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { + return reverse_iterator(end()); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { + return const_reverse_iterator(end()); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { + return reverse_iterator(begin()); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { + return const_reverse_iterator(begin()); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { + return const_reverse_iterator(end()); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { + return const_reverse_iterator(begin()); + } - _LIBCPP_HIDE_FROM_ABI reference front() { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference front() { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list"); return __base::__end_.__next_->__as_node()->__get_value(); } - _LIBCPP_HIDE_FROM_ABI const_reference front() const { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference front() const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list"); return __base::__end_.__next_->__as_node()->__get_value(); } - _LIBCPP_HIDE_FROM_ABI reference back() { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI reference back() { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list"); return __base::__end_.__prev_->__as_node()->__get_value(); } - _LIBCPP_HIDE_FROM_ABI const_reference back() const { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI const_reference back() const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list"); return __base::__end_.__prev_->__as_node()->__get_value(); } # ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x); - _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x); # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI void prepend_range(_Range&& __range) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void prepend_range(_Range&& __range) { insert_range(begin(), std::forward<_Range>(__range)); } template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI void append_range(_Range&& __range) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void append_range(_Range&& __range) { insert_range(end(), std::forward<_Range>(__range)); } # endif template + _LIBCPP_CONSTEXPR_SINCE_CXX26 # if _LIBCPP_STD_VER >= 17 - _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); + _LIBCPP_HIDE_FROM_ABI reference + emplace_front(_Args&&... __args); # else - _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); + _LIBCPP_HIDE_FROM_ABI void + emplace_front(_Args&&... __args); # endif template + _LIBCPP_CONSTEXPR_SINCE_CXX26 # if _LIBCPP_STD_VER >= 17 - _LIBCPP_HIDE_FROM_ABI reference emplace_back(_Args&&... __args); + _LIBCPP_HIDE_FROM_ABI reference + emplace_back(_Args&&... __args); # else - _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args); + _LIBCPP_HIDE_FROM_ABI void + emplace_back(_Args&&... __args); # endif template - _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __x); - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, initializer_list __il) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator + insert(const_iterator __p, initializer_list __il) { return insert(__p, __il.begin(), __il.end()); } # endif // _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __x); - _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __x); # ifndef _LIBCPP_CXX03_LANG template - _LIBCPP_HIDE_FROM_ABI void __emplace_back(_Arg&& __arg) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __emplace_back(_Arg&& __arg) { emplace_back(std::forward<_Arg>(__arg)); } # else _LIBCPP_HIDE_FROM_ABI void __emplace_back(value_type const& __arg) { push_back(__arg); } # endif - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __x); - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator + insert(const_iterator __p, size_type __n, const value_type& __x); template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InpIter __f, _InpIter __l); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InpIter __f, _InpIter __l); # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange<_Tp> _Range> - _LIBCPP_HIDE_FROM_ABI iterator insert_range(const_iterator __position, _Range&& __range) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator + insert_range(const_iterator __position, _Range&& __range) { return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); } # endif - _LIBCPP_HIDE_FROM_ABI void swap(list& __c) + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void swap(list& __c) # if _LIBCPP_STD_VER >= 14 _NOEXCEPT # else @@ -858,72 +922,80 @@ public: { __base::swap(__c); } - _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __base::clear(); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __base::clear(); } - _LIBCPP_HIDE_FROM_ABI void pop_front(); - _LIBCPP_HIDE_FROM_ABI void pop_back(); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void pop_front(); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void pop_back(); - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); - _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); - _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __x); - _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c); # ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list&& __c) { splice(__p, __c); } - _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list&& __c, const_iterator __i) { splice(__p, __c, __i); } - _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list&& __c) { splice(__p, __c); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list&& __c, const_iterator __i) { + splice(__p, __c, __i); + } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void + splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l) { splice(__p, __c, __f, __l); } # endif - _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c, const_iterator __i); - _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c, const_iterator __i); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void + splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l); - _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __x); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __x); template - _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Pred __pred); - _LIBCPP_HIDE_FROM_ABI __remove_return_type unique() { return unique(__equal_to()); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Pred __pred); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __remove_return_type unique() { return unique(__equal_to()); } template - _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPred __binary_pred); - _LIBCPP_HIDE_FROM_ABI void merge(list& __c); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPred __binary_pred); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void merge(list& __c); # ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI void merge(list&& __c) { merge(__c); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void merge(list&& __c) { merge(__c); } template - _LIBCPP_HIDE_FROM_ABI void merge(list&& __c, _Comp __comp) { + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void merge(list&& __c, _Comp __comp) { merge(__c, __comp); } # endif template - _LIBCPP_HIDE_FROM_ABI void merge(list& __c, _Comp __comp); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void merge(list& __c, _Comp __comp); - _LIBCPP_HIDE_FROM_ABI void sort(); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void sort(); template - _LIBCPP_HIDE_FROM_ABI void sort(_Comp __comp); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void sort(_Comp __comp); - _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT; + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI bool __invariants() const; + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI bool __invariants() const; private: template - _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __f, _Sentinel __l); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel(_Iterator __f, _Sentinel __l); template - _LIBCPP_HIDE_FROM_ABI iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); - - _LIBCPP_HIDE_FROM_ABI static void __link_nodes(__base_pointer __p, __base_pointer __f, __base_pointer __l); - _LIBCPP_HIDE_FROM_ABI void __link_nodes_at_front(__base_pointer __f, __base_pointer __l); - _LIBCPP_HIDE_FROM_ABI void __link_nodes_at_back(__base_pointer __f, __base_pointer __l); - _LIBCPP_HIDE_FROM_ABI iterator __iterator(size_type __n); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator + __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); + + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI static void + __link_nodes(__base_pointer __p, __base_pointer __f, __base_pointer __l); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void + __link_nodes_at_front(__base_pointer __f, __base_pointer __l); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __link_nodes_at_back(__base_pointer __f, __base_pointer __l); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI iterator __iterator(size_type __n); // TODO: Make this _LIBCPP_HIDE_FROM_ABI template - _LIBCPP_HIDDEN static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDDEN static iterator + __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp); - _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, true_type) + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, true_type) _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value); - _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, false_type); + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, false_type); }; # if _LIBCPP_STD_VER >= 17 @@ -949,7 +1021,8 @@ list(from_range_t, _Range&&, _Alloc = _Alloc()) -> list -inline void list<_Tp, _Alloc>::__link_nodes(__base_pointer __p, __base_pointer __f, __base_pointer __l) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline void +list<_Tp, _Alloc>::__link_nodes(__base_pointer __p, __base_pointer __f, __base_pointer __l) { __p->__prev_->__next_ = __f; __f->__prev_ = __p->__prev_; __p->__prev_ = __l; @@ -958,7 +1031,8 @@ inline void list<_Tp, _Alloc>::__link_nodes(__base_pointer __p, __base_pointer _ // Link in nodes [__f, __l] at the front of the list template -inline void list<_Tp, _Alloc>::__link_nodes_at_front(__base_pointer __f, __base_pointer __l) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline void +list<_Tp, _Alloc>::__link_nodes_at_front(__base_pointer __f, __base_pointer __l) { __f->__prev_ = __base::__end_as_link(); __l->__next_ = __base::__end_.__next_; __l->__next_->__prev_ = __l; @@ -967,7 +1041,8 @@ inline void list<_Tp, _Alloc>::__link_nodes_at_front(__base_pointer __f, __base_ // Link in nodes [__f, __l] at the back of the list template -inline void list<_Tp, _Alloc>::__link_nodes_at_back(__base_pointer __f, __base_pointer __l) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline void +list<_Tp, _Alloc>::__link_nodes_at_back(__base_pointer __f, __base_pointer __l) { __l->__next_ = __base::__end_as_link(); __f->__prev_ = __base::__end_.__prev_; __f->__prev_->__next_ = __f; @@ -975,12 +1050,12 @@ inline void list<_Tp, _Alloc>::__link_nodes_at_back(__base_pointer __f, __base_p } template -inline typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::__iterator(size_type __n) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::__iterator(size_type __n) { return __n <= this->__size_ / 2 ? std::next(begin(), __n) : std::prev(end(), this->__size_ - __n); } template -list<_Tp, _Alloc>::list(size_type __n) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(size_type __n) { for (; __n > 0; --__n) # ifndef _LIBCPP_CXX03_LANG emplace_back(); @@ -991,41 +1066,43 @@ list<_Tp, _Alloc>::list(size_type __n) { # if _LIBCPP_STD_VER >= 14 template -list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : __base(__a) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : __base(__a) { for (; __n > 0; --__n) emplace_back(); } # endif template -list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) { for (; __n > 0; --__n) push_back(__x); } template template ::value, int> > -list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l) { for (; __f != __l; ++__f) __emplace_back(*__f); } template template ::value, int> > -list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a) : __base(__a) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a) + : __base(__a) { for (; __f != __l; ++__f) __emplace_back(*__f); } template -list<_Tp, _Alloc>::list(const list& __c) +_LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(const list& __c) : __base(__node_alloc_traits::select_on_container_copy_construction(__c.__node_alloc_)) { for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) push_back(*__i); } template -list<_Tp, _Alloc>::list(const list& __c, const __type_identity_t& __a) : __base(__a) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(const list& __c, const __type_identity_t& __a) + : __base(__a) { for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) push_back(*__i); } @@ -1033,25 +1110,28 @@ list<_Tp, _Alloc>::list(const list& __c, const __type_identity_t # ifndef _LIBCPP_CXX03_LANG template -list<_Tp, _Alloc>::list(initializer_list __il, const allocator_type& __a) : __base(__a) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(initializer_list __il, const allocator_type& __a) + : __base(__a) { for (typename initializer_list::const_iterator __i = __il.begin(), __e = __il.end(); __i != __e; ++__i) push_back(*__i); } template -list<_Tp, _Alloc>::list(initializer_list __il) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(initializer_list __il) { for (typename initializer_list::const_iterator __i = __il.begin(), __e = __il.end(); __i != __e; ++__i) push_back(*__i); } template -inline list<_Tp, _Alloc>::list(list&& __c) noexcept(is_nothrow_move_constructible<__node_allocator>::value) +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline list<_Tp, _Alloc>::list(list&& __c) noexcept( + is_nothrow_move_constructible<__node_allocator>::value) : __base(std::move(__c.__node_alloc_)) { splice(end(), __c); } template -inline list<_Tp, _Alloc>::list(list&& __c, const __type_identity_t& __a) : __base(__a) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline list<_Tp, _Alloc>::list(list&& __c, const __type_identity_t& __a) + : __base(__a) { if (__a == __c.get_allocator()) splice(end(), __c); else { @@ -1061,7 +1141,7 @@ inline list<_Tp, _Alloc>::list(list&& __c, const __type_identity_t -inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(list&& __c) noexcept( +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(list&& __c) noexcept( (__node_alloc_traits::propagate_on_container_move_assignment::value && is_nothrow_move_assignable<__node_allocator>::value) || allocator_traits::is_always_equal::value) { @@ -1070,7 +1150,7 @@ inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(list&& __c) noexcept( } template -void list<_Tp, _Alloc>::__move_assign(list& __c, false_type) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::__move_assign(list& __c, false_type) { if (this->__node_alloc_ != __c.__node_alloc_) { typedef move_iterator _Ip; assign(_Ip(__c.begin()), _Ip(__c.end())); @@ -1079,8 +1159,8 @@ void list<_Tp, _Alloc>::__move_assign(list& __c, false_type) { } template -void list<_Tp, _Alloc>::__move_assign(list& __c, - true_type) noexcept(is_nothrow_move_assignable<__node_allocator>::value) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void +list<_Tp, _Alloc>::__move_assign(list& __c, true_type) noexcept(is_nothrow_move_assignable<__node_allocator>::value) { clear(); __base::__move_assign_alloc(__c); splice(end(), __c); @@ -1089,7 +1169,7 @@ void list<_Tp, _Alloc>::__move_assign(list& __c, # endif // _LIBCPP_CXX03_LANG template -inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list& __c) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list& __c) { if (this != std::addressof(__c)) { __base::__copy_assign_alloc(__c); assign(__c.begin(), __c.end()); @@ -1099,13 +1179,14 @@ inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list& __c) { template template ::value, int> > -void list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l) { __assign_with_sentinel(__f, __l); } template template -_LIBCPP_HIDE_FROM_ABI void list<_Tp, _Alloc>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void +list<_Tp, _Alloc>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { iterator __i = begin(); iterator __e = end(); for (; __f != __l && __i != __e; ++__f, (void)++__i) @@ -1117,7 +1198,7 @@ _LIBCPP_HIDE_FROM_ABI void list<_Tp, _Alloc>::__assign_with_sentinel(_Iterator _ } template -void list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) { iterator __i = begin(); iterator __e = end(); for (; __n > 0 && __i != __e; --__n, (void)++__i) @@ -1129,12 +1210,13 @@ void list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) { } template -inline _Alloc list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _Alloc list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT { return allocator_type(this->__node_alloc_); } template -typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) { __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, __x); __link_nodes(__p.__ptr_, __node->__as_link(), __node->__as_link()); ++this->__size_; @@ -1142,7 +1224,7 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __ } template -typename list<_Tp, _Alloc>::iterator +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x) { iterator __r(__p.__ptr_); if (__n > 0) { @@ -1178,13 +1260,14 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _ template template ::value, int> > -typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l) { return __insert_with_sentinel(__p, __f, __l); } template template -_LIBCPP_HIDE_FROM_ABI typename list<_Tp, _Alloc>::iterator +_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { iterator __r(__p.__ptr_); if (__f != __l) { @@ -1219,7 +1302,7 @@ list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Se } template -void list<_Tp, _Alloc>::push_front(const value_type& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::push_front(const value_type& __x) { __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, __x); __base_pointer __nl = __node->__as_link(); __link_nodes_at_front(__nl, __nl); @@ -1227,7 +1310,7 @@ void list<_Tp, _Alloc>::push_front(const value_type& __x) { } template -void list<_Tp, _Alloc>::push_back(const value_type& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::push_back(const value_type& __x) { __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, __x); __base_pointer __nl = __node->__as_link(); __link_nodes_at_back(__nl, __nl); @@ -1237,7 +1320,7 @@ void list<_Tp, _Alloc>::push_back(const value_type& __x) { # ifndef _LIBCPP_CXX03_LANG template -void list<_Tp, _Alloc>::push_front(value_type&& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::push_front(value_type&& __x) { __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::move(__x)); __base_pointer __nl = __node->__as_link(); __link_nodes_at_front(__nl, __nl); @@ -1245,7 +1328,7 @@ void list<_Tp, _Alloc>::push_front(value_type&& __x) { } template -void list<_Tp, _Alloc>::push_back(value_type&& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::push_back(value_type&& __x) { __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::move(__x)); __base_pointer __nl = __node->__as_link(); __link_nodes_at_back(__nl, __nl); @@ -1254,12 +1337,13 @@ void list<_Tp, _Alloc>::push_back(value_type&& __x) { template template +_LIBCPP_CONSTEXPR_SINCE_CXX26 # if _LIBCPP_STD_VER >= 17 -typename list<_Tp, _Alloc>::reference + typename list<_Tp, _Alloc>::reference # else -void + void # endif -list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { + list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::forward<_Args>(__args)...); __base_pointer __nl = __node->__as_link(); @@ -1272,12 +1356,13 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { template template +_LIBCPP_CONSTEXPR_SINCE_CXX26 # if _LIBCPP_STD_VER >= 17 -typename list<_Tp, _Alloc>::reference + typename list<_Tp, _Alloc>::reference # else -void + void # endif -list<_Tp, _Alloc>::emplace_back(_Args&&... __args) { + list<_Tp, _Alloc>::emplace_back(_Args&&... __args) { __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::forward<_Args>(__args)...); __base_pointer __nl = __node->__as_link(); @@ -1290,7 +1375,8 @@ list<_Tp, _Alloc>::emplace_back(_Args&&... __args) { template template -typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) { __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::forward<_Args>(__args)...); __base_pointer __nl = __node->__as_link(); @@ -1300,7 +1386,8 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::emplace(const_iterator _ } template -typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) { __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::move(__x)); __base_pointer __nl = __node->__as_link(); __link_nodes(__p.__ptr_, __nl, __nl); @@ -1311,7 +1398,7 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __ # endif // _LIBCPP_CXX03_LANG template -void list<_Tp, _Alloc>::pop_front() { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::pop_front() { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_front() called with empty list"); __base_pointer __n = __base::__end_.__next_; __base::__unlink_nodes(__n, __n); @@ -1320,7 +1407,7 @@ void list<_Tp, _Alloc>::pop_front() { } template -void list<_Tp, _Alloc>::pop_back() { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::pop_back() { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_back() called on an empty list"); __base_pointer __n = __base::__end_.__prev_; __base::__unlink_nodes(__n, __n); @@ -1329,7 +1416,7 @@ void list<_Tp, _Alloc>::pop_back() { } template -typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __p) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __p) { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(), "list::erase(iterator) called with a non-dereferenceable iterator"); __base_pointer __n = __p.__ptr_; __base_pointer __r = __n->__next_; @@ -1340,7 +1427,8 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __p } template -typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::iterator +list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) { if (__f != __l) { __base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_); while (__f != __l) { @@ -1354,7 +1442,7 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __f } template -void list<_Tp, _Alloc>::resize(size_type __n) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::resize(size_type __n) { if (__n < this->__size_) erase(__iterator(__n), end()); else if (__n > this->__size_) { @@ -1389,7 +1477,7 @@ void list<_Tp, _Alloc>::resize(size_type __n) { } template -void list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) { if (__n < this->__size_) erase(__iterator(__n), end()); else if (__n > this->__size_) { @@ -1425,7 +1513,7 @@ void list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) { } template -void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) { _LIBCPP_ASSERT_VALID_INPUT_RANGE( this != std::addressof(__c), "list::splice(iterator, list) called with this == &list"); if (!__c.empty()) { @@ -1439,7 +1527,7 @@ void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) { } template -void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) { if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_) { __base_pointer __f = __i.__ptr_; __base::__unlink_nodes(__f, __f); @@ -1450,7 +1538,8 @@ void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i } template -void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void +list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l) { if (__f != __l) { __base_pointer __first = __f.__ptr_; --__l; @@ -1466,7 +1555,8 @@ void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f } template -typename list<_Tp, _Alloc>::__remove_return_type list<_Tp, _Alloc>::remove(const value_type& __x) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::__remove_return_type +list<_Tp, _Alloc>::remove(const value_type& __x) { list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing for (const_iterator __i = begin(), __e = end(); __i != __e;) { if (*__i == __x) { @@ -1486,7 +1576,8 @@ typename list<_Tp, _Alloc>::__remove_return_type list<_Tp, _Alloc>::remove(const template template -typename list<_Tp, _Alloc>::__remove_return_type list<_Tp, _Alloc>::remove_if(_Pred __pred) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::__remove_return_type +list<_Tp, _Alloc>::remove_if(_Pred __pred) { list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing for (iterator __i = begin(), __e = end(); __i != __e;) { if (__pred(*__i)) { @@ -1506,7 +1597,8 @@ typename list<_Tp, _Alloc>::__remove_return_type list<_Tp, _Alloc>::remove_if(_P template template -typename list<_Tp, _Alloc>::__remove_return_type list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::__remove_return_type +list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred) { list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing for (iterator __i = begin(), __e = end(); __i != __e;) { iterator __j = std::next(__i); @@ -1522,13 +1614,13 @@ typename list<_Tp, _Alloc>::__remove_return_type list<_Tp, _Alloc>::unique(_Bina } template -inline void list<_Tp, _Alloc>::merge(list& __c) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline void list<_Tp, _Alloc>::merge(list& __c) { merge(__c, __less<>()); } template template -void list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) { if (this != std::addressof(__c)) { iterator __f1 = begin(); iterator __e1 = end(); @@ -1557,19 +1649,19 @@ void list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) { } template -inline void list<_Tp, _Alloc>::sort() { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline void list<_Tp, _Alloc>::sort() { sort(__less<>()); } template template -inline void list<_Tp, _Alloc>::sort(_Comp __comp) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline void list<_Tp, _Alloc>::sort(_Comp __comp) { __sort(begin(), end(), this->__size_, __comp); } template template -typename list<_Tp, _Alloc>::iterator +_LIBCPP_CONSTEXPR_SINCE_CXX26 typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp) { switch (__n) { case 0: @@ -1623,7 +1715,7 @@ list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __ } template -void list<_Tp, _Alloc>::reverse() _NOEXCEPT { +_LIBCPP_CONSTEXPR_SINCE_CXX26 void list<_Tp, _Alloc>::reverse() _NOEXCEPT { if (this->__size_ > 1) { iterator __e = end(); for (iterator __i = begin(); __i.__ptr_ != __e.__ptr_;) { @@ -1635,46 +1727,52 @@ void list<_Tp, _Alloc>::reverse() _NOEXCEPT { } template -bool list<_Tp, _Alloc>::__invariants() const { +_LIBCPP_CONSTEXPR_SINCE_CXX26 bool list<_Tp, _Alloc>::__invariants() const { return size() == std::distance(begin(), end()); } template -inline _LIBCPP_HIDE_FROM_ABI bool operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI bool +operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); } # if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI bool operator<(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI bool +operator<(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } template -inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI bool +operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return !(__x == __y); } template -inline _LIBCPP_HIDE_FROM_ABI bool operator>(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI bool +operator>(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return __y < __x; } template -inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI bool +operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return !(__x < __y); } template -inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI bool +operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return !(__y < __x); } # else // _LIBCPP_STD_VER <= 17 template -_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> +_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> operator<=>(const list<_Tp, _Allocator>& __x, const list<_Tp, _Allocator>& __y) { return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); } @@ -1682,20 +1780,20 @@ operator<=>(const list<_Tp, _Allocator>& __x, const list<_Tp, _Allocator>& __y) # endif // _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI void swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI void swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { __x.swap(__y); } # if _LIBCPP_STD_VER >= 20 template -inline _LIBCPP_HIDE_FROM_ABI typename list<_Tp, _Allocator>::size_type +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI typename list<_Tp, _Allocator>::size_type erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) { return __c.remove_if(__pred); } template -inline _LIBCPP_HIDE_FROM_ABI typename list<_Tp, _Allocator>::size_type +_LIBCPP_CONSTEXPR_SINCE_CXX26 inline _LIBCPP_HIDE_FROM_ABI typename list<_Tp, _Allocator>::size_type erase(list<_Tp, _Allocator>& __c, const _Up& __v) { return std::erase_if(__c, [&](const auto& __elem) -> bool { return __elem == __v; }); } diff --git a/libcxx/include/version b/libcxx/include/version index 87c4ede9a7e59..7154cab923356 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -71,6 +71,7 @@ __cpp_lib_constexpr_dynamic_alloc 201907L __cpp_lib_constexpr_forward_list 202502L __cpp_lib_constexpr_functional 201907L __cpp_lib_constexpr_iterator 201811L +__cpp_lib_constexpr_list 202502L __cpp_lib_constexpr_memory 202202L 201811L // C++20 __cpp_lib_constexpr_new 202406L @@ -545,6 +546,7 @@ __cpp_lib_void_t 201411L # undef __cpp_lib_constexpr_algorithms # define __cpp_lib_constexpr_algorithms 202306L # define __cpp_lib_constexpr_forward_list 202502L +# define __cpp_lib_constexpr_list 202502L # if !defined(_LIBCPP_ABI_VCRUNTIME) # define __cpp_lib_constexpr_new 202406L # endif diff --git a/libcxx/test/std/containers/sequences/list/compare.pass.cpp b/libcxx/test/std/containers/sequences/list/compare.pass.cpp index ce00f57733bf9..9705fd9161987 100644 --- a/libcxx/test/std/containers/sequences/list/compare.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/compare.pass.cpp @@ -10,34 +10,34 @@ // template< class T, class Alloc > // bool operator==( const std::list& lhs, -// const std::list& rhs ); +// const std::list& rhs ); // constexpr since C++26 // template< class T, class Alloc > // bool operator!=( const std::list& lhs, -// const std::list& rhs ); +// const std::list& rhs ); // constexpr since C++26 // template< class T, class Alloc > // bool operator<( const std::list& lhs, -// const std::list& rhs ); +// const std::list& rhs ); // constexpr since C++26 // template< class T, class Alloc > // bool operator<=( const std::list& lhs, -// const std::list& rhs ); +// const std::list& rhs ); // constexpr since C++26 // template< class T, class Alloc > // bool operator>( const std::list& lhs, -// const std::list& rhs ); +// const std::list& rhs ); // constexpr since C++26 // template< class T, class Alloc > // bool operator>=( const std::list& lhs, -// const std::list& rhs ); +// const std::list& rhs ); // constexpr since C++26 #include #include #include "test_comparisons.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { const std::list l1, l2; assert(testComparisons(l1, l2, true, false)); @@ -113,5 +113,15 @@ int main(int, char**) { const std::list l2(items2, items2 + 2); assert(testComparisons(l1, l2, false, false)); } + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/compare.three_way.pass.cpp b/libcxx/test/std/containers/sequences/list/compare.three_way.pass.cpp index 059fba3c26268..7a23a653c0aa8 100644 --- a/libcxx/test/std/containers/sequences/list/compare.three_way.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/compare.three_way.pass.cpp @@ -11,7 +11,7 @@ // template constexpr // synth-three-way-result -// operator<=>(const list& x, const list& y); +// operator<=>(const list& x, const list& y); // constexpr since C++26 #include #include @@ -20,6 +20,8 @@ int main(int, char**) { assert(test_sequence_container_spaceship()); - // `std::list` is not constexpr, so no `static_assert` test here. +#if TEST_STD_VER >= 26 + static_assert(test_sequence_container_spaceship()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/get_allocator.pass.cpp b/libcxx/test/std/containers/sequences/list/get_allocator.pass.cpp index f1002f2ca8113..9d724673d31e8 100644 --- a/libcxx/test/std/containers/sequences/list/get_allocator.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/get_allocator.pass.cpp @@ -10,7 +10,7 @@ // class list -// allocator_type get_allocator() const +// allocator_type get_allocator() const // constexpr since C++26 #include #include @@ -18,7 +18,7 @@ #include "test_allocator.h" #include "test_macros.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::allocator alloc; const std::list l(alloc); @@ -30,5 +30,14 @@ int main(int, char**) { assert(l.get_allocator() == alloc); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/incomplete_type.pass.cpp b/libcxx/test/std/containers/sequences/list/incomplete_type.pass.cpp index 1802e53ecf387..ac8a76097d0ab 100644 --- a/libcxx/test/std/containers/sequences/list/incomplete_type.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/incomplete_type.pass.cpp @@ -12,6 +12,7 @@ // type. #include +#include #include "test_macros.h" @@ -23,8 +24,18 @@ struct A { std::list::const_reverse_iterator crit; }; -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { A a; + (void)a; + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/iterators.pass.cpp b/libcxx/test/std/containers/sequences/list/iterators.pass.cpp index deaae31f2d27c..b41a1899f2ff1 100644 --- a/libcxx/test/std/containers/sequences/list/iterators.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/iterators.pass.cpp @@ -8,12 +8,12 @@ // -// iterator begin(); -// iterator end(); -// const_iterator begin() const; -// const_iterator end() const; -// const_iterator cbegin() const; -// const_iterator cend() const; +// iterator begin(); // constexpr since C++26 +// iterator end(); // constexpr since C++26 +// const_iterator begin() const; // constexpr since C++26 +// const_iterator end() const; // constexpr since C++26 +// const_iterator cbegin() const; // constexpr since C++26 +// const_iterator cend() const; // constexpr since C++26 #include #include @@ -27,7 +27,7 @@ struct A { int second; }; -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { typedef int T; typedef std::list C; @@ -74,6 +74,8 @@ int main(int, char**) { typedef std::list C; C::iterator i; C::const_iterator j; + (void)i; + (void)j; } #if TEST_STD_VER >= 11 { @@ -122,6 +124,8 @@ int main(int, char**) { typedef std::list> C; C::iterator i; C::const_iterator j; + (void)i; + (void)j; } { typedef A T; @@ -150,5 +154,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.capacity/empty.pass.cpp b/libcxx/test/std/containers/sequences/list/list.capacity/empty.pass.cpp index 50ca23ff9c56c..f368d8e700bb6 100644 --- a/libcxx/test/std/containers/sequences/list/list.capacity/empty.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.capacity/empty.pass.cpp @@ -10,7 +10,7 @@ // class list -// bool empty() const noexcept; +// bool empty() const noexcept; // constexpr since C++26 #include #include @@ -18,7 +18,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { typedef std::list C; C c; @@ -42,5 +42,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp b/libcxx/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp index 74c2ccfb14421..1f956b33e4822 100644 --- a/libcxx/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp @@ -8,7 +8,7 @@ // -// size_type max_size() const noexcept +// size_type max_size() const noexcept // constexpr since C++26 #include #include @@ -18,7 +18,7 @@ #include "test_allocator.h" #include "test_macros.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { typedef limited_allocator A; typedef std::list C; @@ -42,5 +42,14 @@ int main(int, char**) { assert(c.max_size() <= alloc_max_size(c.get_allocator())); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp b/libcxx/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp index 754d931646cc6..32049b22881b9 100644 --- a/libcxx/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp @@ -8,15 +8,17 @@ // -// void resize(size_type sz); +// void resize(size_type sz); // constexpr since C++26 #include #include +#include + #include "test_macros.h" #include "DefaultOnly.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l(5, 2); l.resize(2); @@ -33,17 +35,31 @@ int main(int, char**) { assert(l.back() == 0); } #if TEST_STD_VER >= 11 - { - std::list l(10); - l.resize(5); - assert(l.size() == 5); - assert(std::distance(l.begin(), l.end()) == 5); - } - { - std::list l(10); - l.resize(20); - assert(l.size() == 20); - assert(std::distance(l.begin(), l.end()) == 20); + if (!std::is_constant_evaluated()) { + { + std::list l(10); + l.resize(5); + assert(l.size() == 5); + assert(std::distance(l.begin(), l.end()) == 5); + } + { + std::list l(10); + l.resize(20); + assert(l.size() == 20); + assert(std::distance(l.begin(), l.end()) == 20); + } + { + std::list> l(10); + l.resize(5); + assert(l.size() == 5); + assert(std::distance(l.begin(), l.end()) == 5); + } + { + std::list> l(10); + l.resize(20); + assert(l.size() == 20); + assert(std::distance(l.begin(), l.end()) == 20); + } } { std::list> l(5, 2); @@ -60,18 +76,15 @@ int main(int, char**) { assert(l.front() == 2); assert(l.back() == 0); } - { - std::list> l(10); - l.resize(5); - assert(l.size() == 5); - assert(std::distance(l.begin(), l.end()) == 5); - } - { - std::list> l(10); - l.resize(20); - assert(l.size() == 20); - assert(std::distance(l.begin(), l.end()) == 20); - } +#endif + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); #endif return 0; diff --git a/libcxx/test/std/containers/sequences/list/list.capacity/resize_size_value.pass.cpp b/libcxx/test/std/containers/sequences/list/list.capacity/resize_size_value.pass.cpp index 95fccddeca540..a93ec224bd6da 100644 --- a/libcxx/test/std/containers/sequences/list/list.capacity/resize_size_value.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.capacity/resize_size_value.pass.cpp @@ -8,7 +8,7 @@ // -// void resize(size_type sz, const value_type& x); +// void resize(size_type sz, const value_type& x); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "DefaultOnly.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l(5, 2); l.resize(2, 3.5); @@ -50,5 +50,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.capacity/size.pass.cpp b/libcxx/test/std/containers/sequences/list/list.capacity/size.pass.cpp index 930331205a9a5..8aecfcaea0270 100644 --- a/libcxx/test/std/containers/sequences/list/list.capacity/size.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.capacity/size.pass.cpp @@ -10,7 +10,7 @@ // class list -// size_type size() const noexcept; +// size_type size() const noexcept; // constexpr since C++26 #include #include @@ -18,7 +18,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { typedef std::list C; C c; @@ -58,5 +58,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/assign_copy.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/assign_copy.pass.cpp index ca468d870998e..912975d55e1d7 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/assign_copy.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/assign_copy.pass.cpp @@ -8,7 +8,7 @@ // -// list& operator=(const list& c); +// list& operator=(const list& c); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list > l(3, 2, test_allocator(5)); std::list > l2(l, test_allocator(3)); @@ -41,5 +41,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp index d4c1120df6226..07b25f189a111 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/assign_initializer_list.pass.cpp @@ -10,7 +10,7 @@ // -// void assign(initializer_list il); +// void assign(initializer_list il); // constexpr since C++26 #include #include @@ -18,7 +18,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list d; d.assign({3, 4, 5, 6}); @@ -40,5 +40,14 @@ int main(int, char**) { assert(*i++ == 6); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/assign_move.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/assign_move.pass.cpp index 87faaaac2b210..aa199b05ed45c 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/assign_move.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/assign_move.pass.cpp @@ -10,7 +10,7 @@ // -// list& operator=(list&& c); +// list& operator=(list&& c); // constexpr since C++26 #include #include @@ -19,7 +19,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list > l(test_allocator(5)); std::list > lo(test_allocator(5)); @@ -79,5 +79,14 @@ int main(int, char**) { assert(it == l2.begin()); // Iterators remain valid } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/copy.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/copy.pass.cpp index de52da0fefabf..a3e510d4d6ebf 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/copy.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/copy.pass.cpp @@ -8,7 +8,7 @@ // -// list(const list& c); +// list(const list& c); // constexpr since C++26 #include #include @@ -18,7 +18,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l(3, 2); std::list l2 = l; @@ -50,5 +50,14 @@ 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/sequences/list/list.cons/copy_alloc.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/copy_alloc.pass.cpp index 0d6c6f431f09d..5da17a9c9b592 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/copy_alloc.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/copy_alloc.pass.cpp @@ -8,7 +8,7 @@ // -// list(const list& c, const allocator_type& a); +// list(const list& c, const allocator_type& a); // constexpr since C++26 #include #include @@ -17,7 +17,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list > l(3, 2, test_allocator(5)); std::list > l2(l, test_allocator(3)); @@ -39,5 +39,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/default.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/default.pass.cpp index 0cfd8f1e9c594..1256433659c61 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/default.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/default.pass.cpp @@ -8,7 +8,7 @@ // -// explicit list(const Alloc& = Alloc()); +// explicit list(const Alloc& = Alloc()); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "DefaultOnly.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l; assert(l.size() == 0); @@ -65,5 +65,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp index e31a58d7b9a5c..3a78d0e0e0d5e 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/default_stack_alloc.pass.cpp @@ -8,7 +8,7 @@ // -// explicit list(const Alloc& = Alloc()); +// explicit list(const Alloc& = Alloc()); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l; assert(l.size() == 0); @@ -45,5 +45,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/from_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/from_range.pass.cpp index cc5ed5729b57b..60a4764725679 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/from_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/from_range.pass.cpp @@ -9,14 +9,15 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // template R> -// list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 +// list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23; constexpr since C++26 #include +#include #include "../../from_range_sequence_containers.h" #include "test_macros.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { for_all_iterators_and_allocators([]() { test_sequence_container([](const auto&) { // No additional validation to do. @@ -26,8 +27,19 @@ int main(int, char**) { static_assert(test_constraints()); - test_exception_safety_throwing_copy(); - test_exception_safety_throwing_allocator(); + if (!std::is_constant_evaluated()) { + test_exception_safety_throwing_copy(); + test_exception_safety_throwing_allocator(); + } + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/initializer_list.pass.cpp index 3ba90d1337e94..9e3a71ed3bd1c 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/initializer_list.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/initializer_list.pass.cpp @@ -10,7 +10,7 @@ // -// list(initializer_list il); +// list(initializer_list il); // constexpr since C++26 #include #include @@ -18,7 +18,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list d = {3, 4, 5, 6}; assert(d.size() == 4); @@ -38,5 +38,14 @@ int main(int, char**) { assert(*i++ == 6); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp index e4779eb5a6401..1b6b1e19c6eba 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/initializer_list_alloc.pass.cpp @@ -10,7 +10,7 @@ // -// list(initializer_list il, const Allocator& a = allocator_type()); +// list(initializer_list il, const Allocator& a = allocator_type()); // constexpr since C++26 #include #include @@ -19,7 +19,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list> d({3, 4, 5, 6}, test_allocator(3)); assert(d.get_allocator() == test_allocator(3)); @@ -41,5 +41,14 @@ int main(int, char**) { assert(*i++ == 6); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp index c99069f92f51d..e24d123c37318 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp @@ -9,10 +9,11 @@ // // template -// list(InputIterator first, InputIterator last, const Allocator& = Allocator()); +// list(InputIterator first, InputIterator last, const Allocator& = Allocator()); // constexpr since C++26 #include #include + #include "test_macros.h" #include "test_iterators.h" #include "test_allocator.h" @@ -22,7 +23,7 @@ # include "container_test_types.h" #endif -void basic_test() { +TEST_CONSTEXPR_CXX26 void basic_test() { { int a[] = {0, 1, 2, 3}; std::list l( @@ -81,7 +82,7 @@ void basic_test() { #endif } -void test_emplacable_concept() { +TEST_CONSTEXPR_CXX26 void test_emplacable_concept() { #if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; @@ -126,7 +127,7 @@ void test_emplacable_concept() { #endif } -void test_emplacable_concept_with_alloc() { +TEST_CONSTEXPR_CXX26 void test_emplacable_concept_with_alloc() { #if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; @@ -173,7 +174,7 @@ void test_emplacable_concept_with_alloc() { #endif } -void test_ctor_under_alloc() { +TEST_CONSTEXPR_CXX26 void test_ctor_under_alloc() { #if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; @@ -204,7 +205,7 @@ void test_ctor_under_alloc() { #endif } -void test_ctor_under_alloc_with_alloc() { +TEST_CONSTEXPR_CXX26 void test_ctor_under_alloc_with_alloc() { #if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; @@ -239,12 +240,24 @@ void test_ctor_under_alloc_with_alloc() { #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { basic_test(); test_emplacable_concept(); test_emplacable_concept_with_alloc(); - test_ctor_under_alloc(); - test_ctor_under_alloc_with_alloc(); + + if (!TEST_IS_CONSTANT_EVALUATED) { + test_ctor_under_alloc(); + test_ctor_under_alloc_with_alloc(); + } + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/move.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/move.pass.cpp index 6703390f10b94..cae2886cf08b8 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/move.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/move.pass.cpp @@ -10,7 +10,7 @@ // -// list(list&& c); +// list(list&& c); // constexpr since C++26 #include #include @@ -19,7 +19,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list > l(test_allocator(5)); std::list > lo(test_allocator(5)); @@ -63,5 +63,14 @@ int main(int, char**) { assert(it == l2.begin()); // Iterators remain valid } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/move_alloc.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/move_alloc.pass.cpp index f6a1f2c33a63a..dee0282c99780 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/move_alloc.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/move_alloc.pass.cpp @@ -10,7 +10,7 @@ // -// list(list&& c, const allocator_type& a); +// list(list&& c, const allocator_type& a); // constexpr since C++26 #include #include @@ -19,7 +19,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list > l(test_allocator(5)); std::list > lo(test_allocator(5)); @@ -69,5 +69,14 @@ int main(int, char**) { assert(l2.get_allocator() == min_allocator()); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp index a9ab30b82640c..d7679931ee71f 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/op_equal_initializer_list.pass.cpp @@ -10,14 +10,14 @@ // -// list& operator=(initializer_list il); +// list& operator=(initializer_list il); // constexpr since C++26 #include #include #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list d; d = {3, 4, 5, 6}; @@ -39,5 +39,14 @@ int main(int, char**) { assert(*i++ == 6); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp index 937a86a27e058..f9c3b8c2a96c4 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp @@ -8,18 +8,20 @@ // -// explicit list(size_type n); +// explicit list(size_type n); // constexpr since C++26 #include #include #include +#include + #include "test_macros.h" #include "DefaultOnly.h" #include "test_allocator.h" #include "min_allocator.h" template -void test3(unsigned n, Allocator const& alloc = Allocator()) { +TEST_CONSTEXPR_CXX26 void test1(unsigned n, Allocator const& alloc = Allocator()) { #if TEST_STD_VER > 11 typedef std::list C; { @@ -34,7 +36,7 @@ void test3(unsigned n, Allocator const& alloc = Allocator()) { #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l(3); assert(l.size() == 3); @@ -70,15 +72,10 @@ int main(int, char**) { assert(*i == 0); ++i; assert(*i == 0); - test3>(3); + test1>(3); } #endif #if TEST_STD_VER >= 11 - { - std::list l(3); - assert(l.size() == 3); - assert(std::distance(l.begin(), l.end()) == 3); - } { std::list> l(3); assert(l.size() == 3); @@ -90,12 +87,29 @@ int main(int, char**) { ++i; assert(*i == 0); } - { - std::list> l(3); - assert(l.size() == 3); - assert(std::distance(l.begin(), l.end()) == 3); + + if (!std::is_constant_evaluated()) { + { + std::list l(3); + assert(l.size() == 3); + assert(std::distance(l.begin(), l.end()) == 3); + } + { + std::list> l(3); + assert(l.size() == 3); + assert(std::distance(l.begin(), l.end()) == 3); + } } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp index ff7982ce147d5..42700c3ed6582 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/size_value_alloc.pass.cpp @@ -8,7 +8,7 @@ // -// list(size_type n, const T& value, const Allocator& = Allocator()); +// list(size_type n, const T& value, const Allocator& = Allocator()); // constexpr since C++26 #include #include @@ -17,7 +17,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l(3, 2); assert(l.size() == 3); @@ -77,5 +77,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.erasure/erase.pass.cpp b/libcxx/test/std/containers/sequences/list/list.erasure/erase.pass.cpp index 77f9f89560375..babd4b2758e6a 100644 --- a/libcxx/test/std/containers/sequences/list/list.erasure/erase.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.erasure/erase.pass.cpp @@ -11,7 +11,7 @@ // template // typename list::size_type -// erase(list& c, const U& value); +// erase(list& c, const U& value); // constexpr since C++26 #include #include @@ -21,14 +21,14 @@ #include "min_allocator.h" template -void test0(S s, U val, S expected, std::size_t expected_erased_count) { +TEST_CONSTEXPR_CXX26 void test0(S s, U val, S expected, std::size_t expected_erased_count) { ASSERT_SAME_TYPE(typename S::size_type, decltype(std::erase(s, val))); assert(expected_erased_count == std::erase(s, val)); assert(s == expected); } template -void test() { +TEST_CONSTEXPR_CXX26 void test1() { test0(S(), 1, S(), 0); test0(S({1}), 1, S(), 1); @@ -62,13 +62,22 @@ void test() { test0(S({1, 2, 1}), opt(3), S({1, 2, 1}), 0); } -int main(int, char**) { - test>(); - test>>(); - test>>(); +TEST_CONSTEXPR_CXX26 bool test() { + test1>(); + test1>>(); + test1>>(); + + test1>(); + test1>(); - test>(); - test>(); + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp b/libcxx/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp index 5352a2f454f80..e396330bc68c4 100644 --- a/libcxx/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.erasure/erase_if.pass.cpp @@ -11,7 +11,7 @@ // template // typename list::size_type -// erase_if(list& c, Predicate pred); +// erase_if(list& c, Predicate pred); // constexpr since C++26 #include @@ -20,14 +20,14 @@ #include "min_allocator.h" template -void test0(S s, Pred p, S expected, std::size_t expected_erased_count) { +TEST_CONSTEXPR_CXX26 void test0(S s, Pred p, S expected, std::size_t expected_erased_count) { ASSERT_SAME_TYPE(typename S::size_type, decltype(std::erase_if(s, p))); assert(expected_erased_count == std::erase_if(s, p)); assert(s == expected); } template -void test() { +TEST_CONSTEXPR_CXX26 void test1() { auto is1 = [](auto v) { return v == 1; }; auto is2 = [](auto v) { return v == 2; }; auto is3 = [](auto v) { return v == 3; }; @@ -64,13 +64,22 @@ void test() { test0(S({1, 2, 3}), False, S({1, 2, 3}), 0); } -int main(int, char**) { - test>(); - test>>(); - test>>(); +TEST_CONSTEXPR_CXX26 bool test() { + test1>(); + test1>>(); + test1>>(); + + test1>(); + test1>(); - test>(); - test>(); + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/append_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/append_range.pass.cpp index 46a99cb548447..66b72415f3b26 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/append_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/append_range.pass.cpp @@ -9,9 +9,10 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // template R> -// constexpr void append_range(R&& rg); // C++23 +// constexpr void append_range(R&& rg); // C++23; constexpr since C++26 #include +#include #include "../../insert_range_sequence_containers.h" #include "test_macros.h" @@ -21,7 +22,7 @@ // {empty/one-element/full} container); // - appending move-only elements; // - an exception is thrown when copying the elements or when allocating new elements. -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { static_assert(test_constraints_append_range()); for_all_iterators_and_allocators([]() { @@ -31,8 +32,19 @@ int main(int, char**) { }); test_sequence_append_range_move_only(); - test_append_range_exception_safety_throwing_copy(); - test_append_range_exception_safety_throwing_allocator(); + if (!std::is_constant_evaluated()) { + test_append_range_exception_safety_throwing_copy(); + test_append_range_exception_safety_throwing_allocator(); + } + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/assign_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/assign_range.pass.cpp index d745786b6815d..92a835e1c91bd 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/assign_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/assign_range.pass.cpp @@ -9,9 +9,10 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // template R> -// constexpr void assign_range(R&& rg); // C++23 +// constexpr void assign_range(R&& rg); // C++23; constexpr since C++26 #include +#include #include "../../insert_range_sequence_containers.h" #include "test_macros.h" @@ -21,7 +22,7 @@ // {empty/one-element/full} container); // - assigning move-only elements; // - an exception is thrown when copying the elements or when allocating new elements. -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { static_assert(test_constraints_assign_range()); for_all_iterators_and_allocators([]() { @@ -31,8 +32,19 @@ int main(int, char**) { }); test_sequence_assign_range_move_only(); - test_assign_range_exception_safety_throwing_copy(); - test_assign_range_exception_safety_throwing_allocator(); + if (!std::is_constant_evaluated()) { + test_assign_range_exception_safety_throwing_copy(); + test_assign_range_exception_safety_throwing_allocator(); + } + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp index 5931fd62d037c..0b38ae05bd684 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/clear.pass.cpp @@ -8,7 +8,7 @@ // -// void clear() noexcept; +// void clear() noexcept; // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a[] = {1, 2, 3}; std::list c(a, a + 3); @@ -34,5 +34,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/emplace.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/emplace.pass.cpp index 2f83aa0d317b5..9bd7a151d20e1 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/emplace.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/emplace.pass.cpp @@ -10,7 +10,7 @@ // -// template void emplace(const_iterator p, Args&&... args); +// template void emplace(const_iterator p, Args&&... args); // constexpr since C++26 #include #include @@ -26,13 +26,13 @@ class A { A& operator=(const A&); public: - A(int i, double d) : i_(i), d_(d) {} + TEST_CONSTEXPR_CXX20 A(int i, double d) : i_(i), d_(d) {} - int geti() const { return i_; } - double getd() const { return d_; } + TEST_CONSTEXPR int geti() const { return i_; } + TEST_CONSTEXPR double getd() const { return d_; } }; -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list c; c.emplace(c.cbegin(), 2, 3.5); @@ -60,5 +60,14 @@ int main(int, char**) { assert(c.back().getd() == 4.5); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/emplace_back.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/emplace_back.pass.cpp index 900f8b83d3e69..5f84c4c7c05ab 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/emplace_back.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/emplace_back.pass.cpp @@ -10,7 +10,7 @@ // -// template reference emplace_back(Args&&... args); +// template reference emplace_back(Args&&... args); // constexpr since C++26 // return type is 'reference' in C++17; 'void' before #include @@ -27,13 +27,13 @@ class A { A& operator=(const A&); public: - A(int i, double d) : i_(i), d_(d) {} + TEST_CONSTEXPR_CXX20 A(int i, double d) : i_(i), d_(d) {} - int geti() const { return i_; } - double getd() const { return d_; } + TEST_CONSTEXPR int geti() const { return i_; } + TEST_CONSTEXPR double getd() const { return d_; } }; -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list c; #if TEST_STD_VER > 14 @@ -83,5 +83,14 @@ int main(int, char**) { assert(c.back().getd() == 4.5); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/emplace_front.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/emplace_front.pass.cpp index 665f5077bd429..95474b52dbd00 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/emplace_front.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/emplace_front.pass.cpp @@ -10,7 +10,7 @@ // -// template reference emplace_front(Args&&... args); +// template reference emplace_front(Args&&... args); // constexpr since C++26 // return type is 'reference' in C++17; 'void' before #include @@ -27,13 +27,13 @@ class A { A& operator=(const A&); public: - A(int i, double d) : i_(i), d_(d) {} + TEST_CONSTEXPR_CXX20 A(int i, double d) : i_(i), d_(d) {} - int geti() const { return i_; } - double getd() const { return d_; } + TEST_CONSTEXPR int geti() const { return i_; } + TEST_CONSTEXPR double getd() const { return d_; } }; -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list c; #if TEST_STD_VER > 14 @@ -84,5 +84,14 @@ int main(int, char**) { assert(c.back().getd() == 3.5); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/erase_iter.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/erase_iter.pass.cpp index ba139b4367d73..79dae11a82631 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/erase_iter.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/erase_iter.pass.cpp @@ -8,7 +8,7 @@ // -// iterator erase(const_iterator position); +// iterator erase(const_iterator position); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {1, 2, 3}; std::list l1(a1, a1 + 3); @@ -62,5 +62,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp index cc8d537032d04..fa6f8139ff756 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/erase_iter_iter.pass.cpp @@ -8,7 +8,7 @@ // -// iterator erase(const_iterator first, const_iterator last); +// iterator erase(const_iterator first, const_iterator last); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { int a1[] = {1, 2, 3}; { std::list l1(a1, a1 + 3); @@ -81,5 +81,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp index 8bd01c940d958..4475d27a7e737 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_initializer_list.pass.cpp @@ -10,7 +10,7 @@ // -// iterator insert(const_iterator p, initializer_list il); +// iterator insert(const_iterator p, initializer_list il); // constexpr since C++26 #include #include @@ -18,7 +18,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list d(10, 1); std::list::iterator i = d.insert(std::next(d.cbegin(), 2), {3, 4, 5, 6}); @@ -62,5 +62,14 @@ int main(int, char**) { assert(*i++ == 1); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp index bab125ca62094..27db218511aaf 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_iter_iter.pass.cpp @@ -9,7 +9,7 @@ // // template -// iterator insert(const_iterator position, Iter first, Iter last); +// iterator insert(const_iterator position, Iter first, Iter last); // constexpr since C++26 #include #include @@ -21,7 +21,7 @@ #include "count_new.h" template -void test() { +TEST_CONSTEXPR_CXX26 void test() { int a1[] = {1, 2, 3}; List l1; typename List::iterator i = l1.insert(l1.begin(), a1, a1 + 3); @@ -53,36 +53,47 @@ void test() { assert(*i == 3); #if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(DISABLE_NEW_COUNT) - globalMemCounter.throw_after = 2; - int save_count = globalMemCounter.outstanding_new; - try { - i = l1.insert(i, a2, a2 + 3); - assert(false); - } catch (...) { + if (!TEST_IS_CONSTANT_EVALUATED) { + globalMemCounter.throw_after = 2; + int save_count = globalMemCounter.outstanding_new; + try { + i = l1.insert(i, a2, a2 + 3); + assert(false); + } catch (...) { + } + assert(globalMemCounter.checkOutstandingNewEq(save_count)); + assert(l1.size() == 6); + assert(std::distance(l1.begin(), l1.end()) == 6); + i = l1.begin(); + assert(*i == 1); + ++i; + assert(*i == 2); + ++i; + assert(*i == 4); + ++i; + assert(*i == 5); + ++i; + assert(*i == 6); + ++i; + assert(*i == 3); } - assert(globalMemCounter.checkOutstandingNewEq(save_count)); - assert(l1.size() == 6); - assert(std::distance(l1.begin(), l1.end()) == 6); - i = l1.begin(); - assert(*i == 1); - ++i; - assert(*i == 2); - ++i; - assert(*i == 4); - ++i; - assert(*i == 5); - ++i; - assert(*i == 6); - ++i; - assert(*i == 3); #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { test >(); #if TEST_STD_VER >= 11 test>>(); #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp index 8bb513208eb7f..7d7b2f158a602 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_rvalue.pass.cpp @@ -10,7 +10,7 @@ // -// iterator insert(const_iterator position, value_type&& x); +// iterator insert(const_iterator position, value_type&& x); // constexpr since C++26 #include #include @@ -19,7 +19,7 @@ #include "MoveOnly.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l1; l1.insert(l1.cend(), MoveOnly(1)); @@ -41,5 +41,14 @@ int main(int, char**) { assert(l1.back() == MoveOnly(1)); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp index 32ee7a73406dc..1056d997f9d85 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_size_value.pass.cpp @@ -8,7 +8,7 @@ // -// iterator insert(const_iterator position, size_type n, const value_type& x); +// iterator insert(const_iterator position, size_type n, const value_type& x); // constexpr since C++26 // UNSUPPORTED: sanitizer-new-delete @@ -21,7 +21,7 @@ #include "test_macros.h" template -void test() { +TEST_CONSTEXPR_CXX26 void test() { int a1[] = {1, 2, 3}; int a2[] = {1, 4, 4, 4, 4, 4, 2, 3}; List l1(a1, a1 + 3); @@ -29,23 +29,34 @@ void test() { assert(i == std::next(l1.begin())); assert(l1 == List(a2, a2 + 8)); #ifndef TEST_HAS_NO_EXCEPTIONS - globalMemCounter.throw_after = 4; - int save_count = globalMemCounter.outstanding_new; - try { - i = l1.insert(i, 5, 5); - assert(false); - } catch (...) { + if (!TEST_IS_CONSTANT_EVALUATED) { + globalMemCounter.throw_after = 4; + int save_count = globalMemCounter.outstanding_new; + try { + i = l1.insert(i, 5, 5); + assert(false); + } catch (...) { + } + assert(globalMemCounter.checkOutstandingNewEq(save_count)); + assert(l1 == List(a2, a2 + 8)); } - assert(globalMemCounter.checkOutstandingNewEq(save_count)); - assert(l1 == List(a2, a2 + 8)); #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { test >(); #if TEST_STD_VER >= 11 test>>(); #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp index 129fe05cb39d2..615bb5bb2b42e 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_iter_value.pass.cpp @@ -8,7 +8,7 @@ // -// iterator insert(const_iterator position, const value_type& x); +// iterator insert(const_iterator position, const value_type& x); // constexpr since C++26 #include #include @@ -19,7 +19,7 @@ #include "count_new.h" template -void test() { +TEST_CONSTEXPR_CXX26 void test() { int a1[] = {1, 2, 3}; int a2[] = {1, 4, 2, 3}; List l1(a1, a1 + 3); @@ -30,23 +30,34 @@ void test() { assert(l1 == List(a2, a2 + 4)); #if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(DISABLE_NEW_COUNT) - globalMemCounter.throw_after = 0; - int save_count = globalMemCounter.outstanding_new; - try { - i = l1.insert(i, 5); - assert(false); - } catch (...) { + if (!TEST_IS_CONSTANT_EVALUATED) { + globalMemCounter.throw_after = 0; + int save_count = globalMemCounter.outstanding_new; + try { + i = l1.insert(i, 5); + assert(false); + } catch (...) { + } + assert(globalMemCounter.checkOutstandingNewEq(save_count)); + assert(l1 == List(a2, a2 + 4)); } - assert(globalMemCounter.checkOutstandingNewEq(save_count)); - assert(l1 == List(a2, a2 + 4)); #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { test >(); #if TEST_STD_VER >= 11 test>>(); #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_range.pass.cpp index eb3937eb8f9e7..370d7ab1aee64 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_range.pass.cpp @@ -6,12 +6,16 @@ // //===----------------------------------------------------------------------===// +// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=20000000 +// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-ops-limit): -fconstexpr-ops-limit=80000000 + // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // template R> -// constexpr iterator insert_range(const_iterator position, R&& rg); // C++23 +// constexpr iterator insert_range(const_iterator position, R&& rg); // C++23; constexpr since C++26 #include +#include #include "../../insert_range_sequence_containers.h" #include "test_macros.h" @@ -21,7 +25,7 @@ // {empty/one-element/full} container at the {beginning/middle/end}); // - inserting move-only elements; // - an exception is thrown when copying the elements or when allocating new elements. -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { static_assert(test_constraints_insert_range()); for_all_iterators_and_allocators([]() { @@ -31,8 +35,19 @@ int main(int, char**) { }); test_sequence_insert_range_move_only(); - test_insert_range_exception_safety_throwing_copy(); - test_insert_range_exception_safety_throwing_allocator(); + if (!std::is_constant_evaluated()) { + test_insert_range_exception_safety_throwing_copy(); + test_insert_range_exception_safety_throwing_allocator(); + } + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/pop_back.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/pop_back.pass.cpp index aaa225b147767..5bbac428d8d5e 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/pop_back.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/pop_back.pass.cpp @@ -8,7 +8,7 @@ // -// void pop_back(); +// void pop_back(); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a[] = {1, 2, 3}; std::list c(a, a + 3); @@ -40,5 +40,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/pop_front.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/pop_front.pass.cpp index 33b8ff35c524c..74b6a1cc319b7 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/pop_front.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/pop_front.pass.cpp @@ -8,7 +8,7 @@ // -// void pop_front(); +// void pop_front(); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a[] = {1, 2, 3}; std::list c(a, a + 3); @@ -40,5 +40,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/prepend_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/prepend_range.pass.cpp index d5e4d4fabb761..b978166564583 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/prepend_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/prepend_range.pass.cpp @@ -9,9 +9,10 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // template R> -// constexpr void prepend_range(R&& rg); // C++23 +// constexpr void prepend_range(R&& rg); // C++23; constexpr since C++26 #include +#include #include "../../insert_range_sequence_containers.h" #include "test_macros.h" @@ -21,7 +22,7 @@ // {empty/one-element/full} container); // - prepending move-only elements; // - an exception is thrown when copying the elements or when allocating new elements. -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { static_assert(test_constraints_prepend_range()); for_all_iterators_and_allocators([]() { @@ -31,8 +32,19 @@ int main(int, char**) { }); test_sequence_prepend_range_move_only(); - test_prepend_range_exception_safety_throwing_copy(); - test_prepend_range_exception_safety_throwing_allocator(); + if (!std::is_constant_evaluated()) { + test_prepend_range_exception_safety_throwing_copy(); + test_prepend_range_exception_safety_throwing_allocator(); + } + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/push_back.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/push_back.pass.cpp index 582f4a200ac26..3ac9a60e7901c 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/push_back.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/push_back.pass.cpp @@ -8,7 +8,7 @@ // -// void push_back(const value_type& x); +// void push_back(const value_type& x); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list c; for (int i = 0; i < 5; ++i) @@ -34,5 +34,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp index 6a31d81d694f3..011aa015d843e 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp @@ -10,7 +10,7 @@ // -// void push_back(value_type&& x); +// void push_back(value_type&& x); // constexpr since C++26// constexpr since C++26 #include #include @@ -19,7 +19,7 @@ #include "MoveOnly.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l1; l1.push_back(MoveOnly(1)); @@ -41,5 +41,14 @@ int main(int, char**) { assert(l1.back() == MoveOnly(2)); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/push_front.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/push_front.pass.cpp index 3b5f74a217a2f..7ec18e8418225 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/push_front.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/push_front.pass.cpp @@ -8,7 +8,7 @@ // -// void push_front(const value_type& x); +// void push_front(const value_type& x); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list c; for (int i = 0; i < 5; ++i) @@ -34,5 +34,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp index 0d41b8fd8553d..930b6af5f2431 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/push_front_rvalue.pass.cpp @@ -10,7 +10,7 @@ // -// void push_front(value_type&& x); +// void push_front(value_type&& x); // constexpr since C++26 #include #include @@ -19,7 +19,7 @@ #include "MoveOnly.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { std::list l1; l1.push_front(MoveOnly(1)); @@ -41,5 +41,14 @@ int main(int, char**) { assert(l1.back() == MoveOnly(1)); } + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/merge.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/merge.pass.cpp index 7f82f65fd493b..19ea940cb2a08 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/merge.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/merge.pass.cpp @@ -8,7 +8,7 @@ // -// void merge(list& x); +// void merge(list& x); // constexpr since C++26 // If (addressof(x) == this) does nothing; otherwise ... #include @@ -17,7 +17,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; @@ -49,5 +49,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp index 13241909c6e5b..974700926db6c 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/merge_comp.pass.cpp @@ -8,7 +8,7 @@ // -// template void merge(list& x, Compare comp); +// template void merge(list& x, Compare comp); // constexpr since C++26 // If (addressof(x) == this) does nothing; otherwise ... #include @@ -18,7 +18,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {10, 9, 7, 3, 1}; int a2[] = {11, 8, 6, 5, 4, 2, 0}; @@ -49,5 +49,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/remove.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/remove.pass.cpp index 238ea9b69ea2e..9bf677b8745c6 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/remove.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/remove.pass.cpp @@ -9,7 +9,7 @@ // // void remove(const value_type& value); // pre-c++20 -// size_type remove(const value_type& value); // c++20 and later +// size_type remove(const value_type& value); // c++20 and later; constexpr since C++26 #include #include @@ -18,22 +18,22 @@ #include "min_allocator.h" struct S { - S(int i) : i_(new int(i)) {} - S(const S& rhs) : i_(new int(*rhs.i_)) {} - S& operator=(const S& rhs) { + TEST_CONSTEXPR_CXX20 S(int i) : i_(new int(i)) {} + TEST_CONSTEXPR_CXX20 S(const S& rhs) : i_(new int(*rhs.i_)) {} + TEST_CONSTEXPR_CXX14 S& operator=(const S& rhs) { *i_ = *rhs.i_; return *this; } - ~S() { + TEST_CONSTEXPR_CXX20 ~S() { delete i_; i_ = NULL; } - bool operator==(const S& rhs) const { return *i_ == *rhs.i_; } - int get() const { return *i_; } + TEST_CONSTEXPR bool operator==(const S& rhs) const { return *i_ == *rhs.i_; } + TEST_CONSTEXPR int get() const { return *i_; } int* i_; }; -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {1, 2, 3, 4}; int a2[] = {1, 2, 4}; @@ -101,5 +101,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/remove_if.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/remove_if.pass.cpp index 510cb361142b4..c7ee09530ed9c 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/remove_if.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/remove_if.pass.cpp @@ -9,7 +9,7 @@ // // template void remove_if(Pred pred); // before C++20 -// template size_type remove_if(Pred pred); // c++20 and later +// template size_type remove_if(Pred pred); // c++20 and later; constexpr since C++26 #include #include @@ -19,22 +19,22 @@ #include "min_allocator.h" #include "counting_predicates.h" -bool even(int i) { return i % 2 == 0; } +TEST_CONSTEXPR bool even(int i) { return i % 2 == 0; } -bool g(int i) { return i < 3; } +TEST_CONSTEXPR bool g(int i) { return i < 3; } struct PredLWG526 { - PredLWG526(int i) : i_(i) {} - ~PredLWG526() { i_ = -32767; } - bool operator()(const PredLWG526& p) const { return p.i_ == i_; } + TEST_CONSTEXPR_CXX20 PredLWG526(int i) : i_(i) {} + TEST_CONSTEXPR_CXX20 ~PredLWG526() { i_ = -32767; } + TEST_CONSTEXPR bool operator()(const PredLWG526& p) const { return p.i_ == i_; } - bool operator==(int i) const { return i == i_; } + TEST_CONSTEXPR bool operator==(int i) const { return i == i_; } int i_; }; typedef unary_counting_predicate Predicate; -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {1, 2, 3, 4}; int a2[] = {3, 4}; @@ -92,5 +92,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/reverse.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/reverse.pass.cpp index 5b91ad0224be6..43e894f5e83a9 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/reverse.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/reverse.pass.cpp @@ -8,7 +8,7 @@ // -// void reverse(); +// void reverse(); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; int a2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; @@ -34,5 +34,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/sort.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/sort.pass.cpp index 892419f6ac964..34ead09110a38 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/sort.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/sort.pass.cpp @@ -8,7 +8,7 @@ // -// void sort(); +// void sort(); // constexpr since C++26 #include #include @@ -58,7 +58,7 @@ void test_stable(int N) { } } -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9}; int a2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; @@ -76,8 +76,19 @@ int main(int, char**) { } #endif - for (int i = 0; i < 40; ++i) - test_stable(i); + if (!TEST_IS_CONSTANT_EVALUATED) { + for (int i = 0; i < 40; ++i) + test_stable(i); + } + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/sort_comp.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/sort_comp.pass.cpp index 4997022819919..a24f187f4b4ef 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/sort_comp.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/sort_comp.pass.cpp @@ -8,7 +8,7 @@ // -// template sort(Compare comp); +// template sort(Compare comp); // constexpr since C++26 #include #include @@ -76,7 +76,7 @@ void test_stable(int N) { } } -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9}; int a2[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; @@ -85,37 +85,48 @@ int main(int, char**) { assert(c1 == std::list(a2, a2 + sizeof(a2) / sizeof(a2[0]))); } + if (!TEST_IS_CONSTANT_EVALUATED) { // Test with throwing comparison; make sure that nothing is lost. // This is (sort of) LWG #2824 #ifndef TEST_HAS_NO_EXCEPTIONS - { - int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9}; - const int sz = sizeof(a1) / sizeof(a1[0]); - for (int i = 0; i < 10; ++i) { - std::list c1(a1, a1 + sz); - try { - throwingLess comp(i); - c1.sort(std::cref(comp)); - } catch (int) { + { + int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9}; + const int sz = sizeof(a1) / sizeof(a1[0]); + for (int i = 0; i < 10; ++i) { + std::list c1(a1, a1 + sz); + try { + throwingLess comp(i); + c1.sort(std::cref(comp)); + } catch (int) { + } + assert((c1.size() == sz)); + assert((std::is_permutation(c1.begin(), c1.end(), a1))); } - assert((c1.size() == sz)); - assert((std::is_permutation(c1.begin(), c1.end(), a1))); } - } #endif #if TEST_STD_VER >= 11 - { - int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9}; - int a2[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; - std::list> c1(a1, a1 + sizeof(a1) / sizeof(a1[0])); - c1.sort(std::greater()); - assert((c1 == std::list>(a2, a2 + sizeof(a2) / sizeof(a2[0])))); - } + { + int a1[] = {4, 8, 1, 0, 5, 7, 2, 3, 6, 11, 10, 9}; + int a2[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; + std::list> c1(a1, a1 + sizeof(a1) / sizeof(a1[0])); + c1.sort(std::greater()); + assert((c1 == std::list>(a2, a2 + sizeof(a2) / sizeof(a2[0])))); + } #endif - for (int i = 0; i < 40; ++i) - test_stable(i); + for (int i = 0; i < 40; ++i) + test_stable(i); + } + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list.pass.cpp index 4b40876e3bb7d..0f1cfefab34e7 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list.pass.cpp @@ -8,7 +8,7 @@ // -// void splice(const_iterator position, list& x); +// void splice(const_iterator position, list& x); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { int a1[] = {1, 2, 3}; int a2[] = {4, 5, 6}; { @@ -780,5 +780,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp index db71fe17a06eb..38dce58dc3904 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list_iter.pass.cpp @@ -8,7 +8,7 @@ // -// void splice(const_iterator position, list& x, iterator i); +// void splice(const_iterator position, list& x, iterator i); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { int a1[] = {1, 2, 3}; int a2[] = {4, 5, 6}; { @@ -334,5 +334,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp index b77b6a26440d5..8fca21c81c66d 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/splice_pos_list_iter_iter.pass.cpp @@ -8,7 +8,7 @@ // -// void splice(const_iterator position, list& x, iterator first, iterator last); +// void splice(const_iterator position, list& x, iterator first, iterator last); // constexpr since C++26 #include #include @@ -16,7 +16,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { int a1[] = {1, 2, 3}; int a2[] = {4, 5, 6}; { @@ -214,5 +214,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/unique.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/unique.pass.cpp index c08e348218f95..c2fa54f425534 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/unique.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/unique.pass.cpp @@ -9,7 +9,7 @@ // // void unique(); // before C++20 -// size_type unique(); // C++20 and later +// size_type unique(); // C++20 and later; constexpr since C++26 #include #include @@ -17,7 +17,7 @@ #include "test_macros.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3}; int a2[] = {2, 1, 4, 3}; @@ -46,5 +46,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.ops/unique_pred.pass.cpp b/libcxx/test/std/containers/sequences/list/list.ops/unique_pred.pass.cpp index 1d3a8e0c426aa..830e54a3288d0 100644 --- a/libcxx/test/std/containers/sequences/list/list.ops/unique_pred.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.ops/unique_pred.pass.cpp @@ -9,7 +9,7 @@ // // template void unique(BinaryPred pred); // before C++20 -// template size_type unique(BinaryPred pred); // C++20 and later +// template size_type unique(BinaryPred pred); // C++20 and later; constexpr since C++26 #include #include @@ -18,18 +18,18 @@ #include "test_macros.h" #include "min_allocator.h" -bool g(int x, int y) { return x == y; } +TEST_CONSTEXPR bool g(int x, int y) { return x == y; } struct PredLWG526 { - PredLWG526(int i) : i_(i) {} - ~PredLWG526() { i_ = -32767; } - bool operator()(const PredLWG526& lhs, const PredLWG526& rhs) const { return lhs.i_ == rhs.i_; } + TEST_CONSTEXPR_CXX20 PredLWG526(int i) : i_(i) {} + TEST_CONSTEXPR_CXX20 ~PredLWG526() { i_ = -32767; } + TEST_CONSTEXPR bool operator()(const PredLWG526& lhs, const PredLWG526& rhs) const { return lhs.i_ == rhs.i_; } - bool operator==(int i) const { return i == i_; } + TEST_CONSTEXPR bool operator==(int i) const { return i == i_; } int i_; }; -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {2, 1, 1, 4, 4, 4, 4, 3, 3}; int a2[] = {2, 1, 4, 3}; @@ -75,5 +75,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.special/swap.pass.cpp b/libcxx/test/std/containers/sequences/list/list.special/swap.pass.cpp index 1e9c71131d80a..32efddb06920c 100644 --- a/libcxx/test/std/containers/sequences/list/list.special/swap.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.special/swap.pass.cpp @@ -9,7 +9,7 @@ // // template -// void swap(list& x, list& y); +// void swap(list& x, list& y); // constexpr since C++26 #include #include @@ -17,7 +17,7 @@ #include "test_allocator.h" #include "min_allocator.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { int a1[] = {1, 3, 7, 9, 10}; int a2[] = {0, 2, 4, 5, 6, 8, 11}; @@ -133,5 +133,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp b/libcxx/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp index a4b1622a04bee..037c7d07c4cb8 100644 --- a/libcxx/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp @@ -12,7 +12,7 @@ // void swap(list& c) // noexcept(!allocator_type::propagate_on_container_swap::value || -// __is_nothrow_swappable::value); +// __is_nothrow_swappable::value); // constexpr since C++26 // // In C++17, the standard says that swap shall have: // noexcept(allocator_traits::is_always_equal::value); @@ -52,7 +52,7 @@ struct some_alloc2 { typedef std::true_type is_always_equal; }; -int main(int, char**) { +TEST_CONSTEXPR_CXX26 bool test() { { typedef std::list C; static_assert(noexcept(swap(std::declval(), std::declval())), ""); @@ -84,5 +84,14 @@ int main(int, char**) { } #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 26 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/support/min_allocator.h b/libcxx/test/support/min_allocator.h index 3b7d12af24ce0..16775649f55cf 100644 --- a/libcxx/test/support/min_allocator.h +++ b/libcxx/test/support/min_allocator.h @@ -22,384 +22,381 @@ #include "test_macros.h" template -class bare_allocator -{ +class bare_allocator { public: - typedef T value_type; + typedef T value_type; - bare_allocator() TEST_NOEXCEPT {} + bare_allocator() TEST_NOEXCEPT {} - template - bare_allocator(bare_allocator) TEST_NOEXCEPT {} + template + bare_allocator(bare_allocator) TEST_NOEXCEPT {} - T* allocate(std::size_t n) - { - return static_cast(::operator new(n*sizeof(T))); - } + T* allocate(std::size_t n) { return static_cast(::operator new(n * sizeof(T))); } - void deallocate(T* p, std::size_t) - { - return ::operator delete(static_cast(p)); - } + void deallocate(T* p, std::size_t) { return ::operator delete(static_cast(p)); } - friend bool operator==(bare_allocator, bare_allocator) {return true;} - friend bool operator!=(bare_allocator x, bare_allocator y) {return !(x == y);} + friend bool operator==(bare_allocator, bare_allocator) { return true; } + friend bool operator!=(bare_allocator x, bare_allocator y) { return !(x == y); } }; - template -class no_default_allocator -{ +class no_default_allocator { #if TEST_STD_VER >= 11 - no_default_allocator() = delete; + no_default_allocator() = delete; #else - no_default_allocator(); + no_default_allocator(); #endif - struct construct_tag {}; - explicit no_default_allocator(construct_tag) {} + struct construct_tag {}; + TEST_CONSTEXPR_CXX20 explicit no_default_allocator(construct_tag) {} public: - static no_default_allocator create() { - construct_tag tag; - return no_default_allocator(tag); - } + TEST_CONSTEXPR_CXX20 static no_default_allocator create() { + construct_tag tag; + return no_default_allocator(tag); + } public: - typedef T value_type; + typedef T value_type; - template - no_default_allocator(no_default_allocator) TEST_NOEXCEPT {} + template + TEST_CONSTEXPR_CXX20 no_default_allocator(no_default_allocator) TEST_NOEXCEPT {} - T* allocate(std::size_t n) - { - return static_cast(::operator new(n*sizeof(T))); - } + TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) { return static_cast(std::allocator().allocate(n)); } - void deallocate(T* p, std::size_t) - { - return ::operator delete(static_cast(p)); - } + TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t n) { std::allocator().deallocate(p, n); } - friend bool operator==(no_default_allocator, no_default_allocator) {return true;} - friend bool operator!=(no_default_allocator x, no_default_allocator y) {return !(x == y);} + friend TEST_CONSTEXPR bool operator==(no_default_allocator, no_default_allocator) { return true; } + friend TEST_CONSTEXPR bool operator!=(no_default_allocator x, no_default_allocator y) { return !(x == y); } }; struct malloc_allocator_base { - static std::size_t outstanding_bytes; - static std::size_t alloc_count; - static std::size_t dealloc_count; - static bool disable_default_constructor; - - static std::size_t outstanding_alloc() { - assert(alloc_count >= dealloc_count); - return (alloc_count - dealloc_count); - } - - static void reset() { - assert(outstanding_alloc() == 0); - disable_default_constructor = false; - outstanding_bytes = 0; - alloc_count = 0; - dealloc_count = 0; - } + static std::size_t outstanding_bytes; + static std::size_t alloc_count; + static std::size_t dealloc_count; + static bool disable_default_constructor; + + static std::size_t outstanding_alloc() { + assert(alloc_count >= dealloc_count); + return (alloc_count - dealloc_count); + } + + static void reset() { + assert(outstanding_alloc() == 0); + disable_default_constructor = false; + outstanding_bytes = 0; + alloc_count = 0; + dealloc_count = 0; + } }; -size_t malloc_allocator_base::outstanding_bytes = 0; -size_t malloc_allocator_base::alloc_count = 0; -size_t malloc_allocator_base::dealloc_count = 0; +size_t malloc_allocator_base::outstanding_bytes = 0; +size_t malloc_allocator_base::alloc_count = 0; +size_t malloc_allocator_base::dealloc_count = 0; bool malloc_allocator_base::disable_default_constructor = false; - template -class malloc_allocator : public malloc_allocator_base -{ +class malloc_allocator : public malloc_allocator_base { public: - typedef T value_type; - - malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); } - - template - malloc_allocator(malloc_allocator) TEST_NOEXCEPT {} - - T* allocate(std::size_t n) - { - const std::size_t nbytes = n*sizeof(T); - ++alloc_count; - outstanding_bytes += nbytes; - return static_cast(std::malloc(nbytes)); - } - - void deallocate(T* p, std::size_t n) - { - const std::size_t nbytes = n*sizeof(T); - ++dealloc_count; - outstanding_bytes -= nbytes; - std::free(static_cast(p)); - } - - friend bool operator==(malloc_allocator, malloc_allocator) {return true;} - friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);} + typedef T value_type; + + malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); } + + template + malloc_allocator(malloc_allocator) TEST_NOEXCEPT {} + + T* allocate(std::size_t n) { + const std::size_t nbytes = n * sizeof(T); + ++alloc_count; + outstanding_bytes += nbytes; + return static_cast(std::malloc(nbytes)); + } + + void deallocate(T* p, std::size_t n) { + const std::size_t nbytes = n * sizeof(T); + ++dealloc_count; + outstanding_bytes -= nbytes; + std::free(static_cast(p)); + } + + friend bool operator==(malloc_allocator, malloc_allocator) { return true; } + friend bool operator!=(malloc_allocator x, malloc_allocator y) { return !(x == y); } }; template -struct cpp03_allocator : bare_allocator -{ - typedef T value_type; - typedef value_type* pointer; - - static bool construct_called; - - // Returned value is not used but it's not prohibited. - pointer construct(pointer p, const value_type& val) - { - ::new(p) value_type(val); - construct_called = true; - return p; - } - - std::size_t max_size() const - { - return UINT_MAX / sizeof(T); - } +struct cpp03_allocator : bare_allocator { + typedef T value_type; + typedef value_type* pointer; + + static bool construct_called; + + // Returned value is not used but it's not prohibited. + pointer construct(pointer p, const value_type& val) { + ::new (p) value_type(val); + construct_called = true; + return p; + } + + std::size_t max_size() const { return UINT_MAX / sizeof(T); } }; -template bool cpp03_allocator::construct_called = false; +template +bool cpp03_allocator::construct_called = false; template -struct cpp03_overload_allocator : bare_allocator -{ - typedef T value_type; - typedef value_type* pointer; - - static bool construct_called; - - void construct(pointer p, const value_type& val) - { - construct(p, val, std::is_class()); - } - void construct(pointer p, const value_type& val, std::true_type) - { - ::new(p) value_type(val); - construct_called = true; - } - void construct(pointer p, const value_type& val, std::false_type) - { - ::new(p) value_type(val); - construct_called = true; - } - - std::size_t max_size() const - { - return UINT_MAX / sizeof(T); - } +struct cpp03_overload_allocator : bare_allocator { + typedef T value_type; + typedef value_type* pointer; + + static bool construct_called; + + void construct(pointer p, const value_type& val) { construct(p, val, std::is_class()); } + void construct(pointer p, const value_type& val, std::true_type) { + ::new (p) value_type(val); + construct_called = true; + } + void construct(pointer p, const value_type& val, std::false_type) { + ::new (p) value_type(val); + construct_called = true; + } + + std::size_t max_size() const { return UINT_MAX / sizeof(T); } }; -template bool cpp03_overload_allocator::construct_called = false; +template +bool cpp03_overload_allocator::construct_called = false; -template > class min_pointer; -template class min_pointer; -template class min_pointer; -template class min_pointer; -template class min_allocator; +template > +class min_pointer; +template +class min_pointer; +template +class min_pointer; +template +class min_pointer; +template +class min_allocator; template -class min_pointer -{ - const void* ptr_; +class min_pointer { + const void* ptr_; + public: - min_pointer() TEST_NOEXCEPT = default; - min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} - template - min_pointer(min_pointer p) TEST_NOEXCEPT : ptr_(p.ptr_) {} + min_pointer() TEST_NOEXCEPT = default; + min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} + template + min_pointer(min_pointer p) TEST_NOEXCEPT : ptr_(p.ptr_) {} - explicit operator bool() const {return ptr_ != nullptr;} + explicit operator bool() const { return ptr_ != nullptr; } - friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} - friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} - template friend class min_pointer; + friend bool operator==(min_pointer x, min_pointer y) { return x.ptr_ == y.ptr_; } + friend bool operator!=(min_pointer x, min_pointer y) { return !(x == y); } + template + friend class min_pointer; }; template -class min_pointer -{ - void* ptr_; +class min_pointer { + void* ptr_; + public: - min_pointer() TEST_NOEXCEPT = default; - TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} - template ::value - >::type - > - TEST_CONSTEXPR_CXX14 min_pointer(min_pointer p) TEST_NOEXCEPT : ptr_(p.ptr_) {} - - TEST_CONSTEXPR_CXX14 explicit operator bool() const {return ptr_ != nullptr;} - - TEST_CONSTEXPR_CXX14 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} - TEST_CONSTEXPR_CXX14 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} - template friend class min_pointer; + min_pointer() TEST_NOEXCEPT = default; + TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} + template ::value >::type > + TEST_CONSTEXPR_CXX14 min_pointer(min_pointer p) TEST_NOEXCEPT : ptr_(p.ptr_) {} + + TEST_CONSTEXPR_CXX14 explicit operator bool() const { return ptr_ != nullptr; } + + TEST_CONSTEXPR_CXX14 friend bool operator==(min_pointer x, min_pointer y) { return x.ptr_ == y.ptr_; } + TEST_CONSTEXPR_CXX14 friend bool operator!=(min_pointer x, min_pointer y) { return !(x == y); } + template + friend class min_pointer; }; template -class min_pointer -{ - T* ptr_; +class min_pointer { + T* ptr_; + + TEST_CONSTEXPR_CXX14 explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {} - TEST_CONSTEXPR_CXX14 explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {} public: - min_pointer() TEST_NOEXCEPT = default; - TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} - TEST_CONSTEXPR_CXX14 explicit min_pointer(min_pointer p) TEST_NOEXCEPT : ptr_(static_cast(p.ptr_)) {} - - TEST_CONSTEXPR_CXX14 explicit operator bool() const {return ptr_ != nullptr;} - - typedef std::ptrdiff_t difference_type; - typedef T& reference; - typedef T* pointer; - typedef T value_type; - typedef std::random_access_iterator_tag iterator_category; - - TEST_CONSTEXPR_CXX14 reference operator*() const {return *ptr_;} - TEST_CONSTEXPR_CXX14 pointer operator->() const {return ptr_;} - - TEST_CONSTEXPR_CXX14 min_pointer& operator++() {++ptr_; return *this;} - TEST_CONSTEXPR_CXX14 min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;} - - TEST_CONSTEXPR_CXX14 min_pointer& operator--() {--ptr_; return *this;} - TEST_CONSTEXPR_CXX14 min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;} - - TEST_CONSTEXPR_CXX14 min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;} - TEST_CONSTEXPR_CXX14 min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;} - - TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n) const - { - min_pointer tmp(*this); - tmp += n; - return tmp; - } - - friend TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n, min_pointer x) - { - return x + n; - } - - TEST_CONSTEXPR_CXX14 min_pointer operator-(difference_type n) const - { - min_pointer tmp(*this); - tmp -= n; - return tmp; - } - - friend TEST_CONSTEXPR_CXX14 difference_type operator-(min_pointer x, min_pointer y) - { - return x.ptr_ - y.ptr_; - } - - TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return ptr_[n];} - - friend TEST_CONSTEXPR_CXX14 bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;} - friend TEST_CONSTEXPR_CXX14 bool operator> (min_pointer x, min_pointer y) {return y < x;} - friend TEST_CONSTEXPR_CXX14 bool operator<=(min_pointer x, min_pointer y) {return !(y < x);} - friend TEST_CONSTEXPR_CXX14 bool operator>=(min_pointer x, min_pointer y) {return !(x < y);} - - static TEST_CONSTEXPR_CXX14 min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));} - - friend TEST_CONSTEXPR_CXX14 bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} - friend TEST_CONSTEXPR_CXX14 bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} - template friend class min_pointer; - template friend class min_allocator; + min_pointer() TEST_NOEXCEPT = default; + TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} + TEST_CONSTEXPR_CXX14 explicit min_pointer(min_pointer p) TEST_NOEXCEPT : ptr_(static_cast(p.ptr_)) {} + + TEST_CONSTEXPR_CXX14 explicit operator bool() const { return ptr_ != nullptr; } + + typedef std::ptrdiff_t difference_type; + typedef T& reference; + typedef T* pointer; + typedef T value_type; + typedef std::random_access_iterator_tag iterator_category; + + TEST_CONSTEXPR_CXX14 reference operator*() const { return *ptr_; } + TEST_CONSTEXPR_CXX14 pointer operator->() const { return ptr_; } + + TEST_CONSTEXPR_CXX14 min_pointer& operator++() { + ++ptr_; + return *this; + } + TEST_CONSTEXPR_CXX14 min_pointer operator++(int) { + min_pointer tmp(*this); + ++ptr_; + return tmp; + } + + TEST_CONSTEXPR_CXX14 min_pointer& operator--() { + --ptr_; + return *this; + } + TEST_CONSTEXPR_CXX14 min_pointer operator--(int) { + min_pointer tmp(*this); + --ptr_; + return tmp; + } + + TEST_CONSTEXPR_CXX14 min_pointer& operator+=(difference_type n) { + ptr_ += n; + return *this; + } + TEST_CONSTEXPR_CXX14 min_pointer& operator-=(difference_type n) { + ptr_ -= n; + return *this; + } + + TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n) const { + min_pointer tmp(*this); + tmp += n; + return tmp; + } + + friend TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n, min_pointer x) { return x + n; } + + TEST_CONSTEXPR_CXX14 min_pointer operator-(difference_type n) const { + min_pointer tmp(*this); + tmp -= n; + return tmp; + } + + friend TEST_CONSTEXPR_CXX14 difference_type operator-(min_pointer x, min_pointer y) { return x.ptr_ - y.ptr_; } + + TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const { return ptr_[n]; } + + friend TEST_CONSTEXPR_CXX14 bool operator<(min_pointer x, min_pointer y) { return x.ptr_ < y.ptr_; } + friend TEST_CONSTEXPR_CXX14 bool operator>(min_pointer x, min_pointer y) { return y < x; } + friend TEST_CONSTEXPR_CXX14 bool operator<=(min_pointer x, min_pointer y) { return !(y < x); } + friend TEST_CONSTEXPR_CXX14 bool operator>=(min_pointer x, min_pointer y) { return !(x < y); } + + static TEST_CONSTEXPR_CXX14 min_pointer pointer_to(T& t) { return min_pointer(std::addressof(t)); } + + friend TEST_CONSTEXPR_CXX14 bool operator==(min_pointer x, min_pointer y) { return x.ptr_ == y.ptr_; } + friend TEST_CONSTEXPR_CXX14 bool operator!=(min_pointer x, min_pointer y) { return !(x == y); } + template + friend class min_pointer; + template + friend class min_allocator; }; template -class min_pointer -{ - const T* ptr_; +class min_pointer { + const T* ptr_; + + TEST_CONSTEXPR_CXX14 explicit min_pointer(const T* p) : ptr_(p) {} - TEST_CONSTEXPR_CXX14 explicit min_pointer(const T* p) : ptr_(p) {} public: - min_pointer() TEST_NOEXCEPT = default; - TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) : ptr_(nullptr) {} - TEST_CONSTEXPR_CXX14 min_pointer(min_pointer p) : ptr_(p.ptr_) {} - TEST_CONSTEXPR_CXX14 explicit min_pointer(min_pointer p) : ptr_(static_cast(p.ptr_)) {} - - TEST_CONSTEXPR_CXX14 explicit operator bool() const {return ptr_ != nullptr;} - - typedef std::ptrdiff_t difference_type; - typedef const T& reference; - typedef const T* pointer; - typedef const T value_type; - typedef std::random_access_iterator_tag iterator_category; - - TEST_CONSTEXPR_CXX14 reference operator*() const {return *ptr_;} - TEST_CONSTEXPR_CXX14 pointer operator->() const {return ptr_;} - - TEST_CONSTEXPR_CXX14 min_pointer& operator++() {++ptr_; return *this;} - TEST_CONSTEXPR_CXX14 min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;} - - TEST_CONSTEXPR_CXX14 min_pointer& operator--() {--ptr_; return *this;} - TEST_CONSTEXPR_CXX14 min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;} - - TEST_CONSTEXPR_CXX14 min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;} - TEST_CONSTEXPR_CXX14 min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;} - - TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n) const - { - min_pointer tmp(*this); - tmp += n; - return tmp; - } - - friend TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n, min_pointer x) - { - return x + n; - } - - TEST_CONSTEXPR_CXX14 min_pointer operator-(difference_type n) const - { - min_pointer tmp(*this); - tmp -= n; - return tmp; - } - - friend TEST_CONSTEXPR_CXX14 difference_type operator-(min_pointer x, min_pointer y) - { - return x.ptr_ - y.ptr_; - } - - TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return ptr_[n];} - - friend TEST_CONSTEXPR_CXX14 bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;} - friend TEST_CONSTEXPR_CXX14 bool operator> (min_pointer x, min_pointer y) {return y < x;} - friend TEST_CONSTEXPR_CXX14 bool operator<=(min_pointer x, min_pointer y) {return !(y < x);} - friend TEST_CONSTEXPR_CXX14 bool operator>=(min_pointer x, min_pointer y) {return !(x < y);} - - static TEST_CONSTEXPR_CXX14 min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));} - - friend TEST_CONSTEXPR_CXX14 bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} - friend TEST_CONSTEXPR_CXX14 bool operator!=(min_pointer x, min_pointer y) {return x.ptr_ != y.ptr_;} - friend TEST_CONSTEXPR_CXX14 bool operator==(min_pointer x, std::nullptr_t) {return x.ptr_ == nullptr;} - friend TEST_CONSTEXPR_CXX14 bool operator!=(min_pointer x, std::nullptr_t) {return x.ptr_ != nullptr;} - friend TEST_CONSTEXPR_CXX14 bool operator==(std::nullptr_t, min_pointer x) {return x.ptr_ == nullptr;} - friend TEST_CONSTEXPR_CXX14 bool operator!=(std::nullptr_t, min_pointer x) {return x.ptr_ != nullptr;} - template friend class min_pointer; + min_pointer() TEST_NOEXCEPT = default; + TEST_CONSTEXPR_CXX14 min_pointer(std::nullptr_t) : ptr_(nullptr) {} + TEST_CONSTEXPR_CXX14 min_pointer(min_pointer p) : ptr_(p.ptr_) {} + TEST_CONSTEXPR_CXX14 explicit min_pointer(min_pointer p) : ptr_(static_cast(p.ptr_)) {} + + TEST_CONSTEXPR_CXX14 explicit operator bool() const { return ptr_ != nullptr; } + + typedef std::ptrdiff_t difference_type; + typedef const T& reference; + typedef const T* pointer; + typedef const T value_type; + typedef std::random_access_iterator_tag iterator_category; + + TEST_CONSTEXPR_CXX14 reference operator*() const { return *ptr_; } + TEST_CONSTEXPR_CXX14 pointer operator->() const { return ptr_; } + + TEST_CONSTEXPR_CXX14 min_pointer& operator++() { + ++ptr_; + return *this; + } + TEST_CONSTEXPR_CXX14 min_pointer operator++(int) { + min_pointer tmp(*this); + ++ptr_; + return tmp; + } + + TEST_CONSTEXPR_CXX14 min_pointer& operator--() { + --ptr_; + return *this; + } + TEST_CONSTEXPR_CXX14 min_pointer operator--(int) { + min_pointer tmp(*this); + --ptr_; + return tmp; + } + + TEST_CONSTEXPR_CXX14 min_pointer& operator+=(difference_type n) { + ptr_ += n; + return *this; + } + TEST_CONSTEXPR_CXX14 min_pointer& operator-=(difference_type n) { + ptr_ -= n; + return *this; + } + + TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n) const { + min_pointer tmp(*this); + tmp += n; + return tmp; + } + + friend TEST_CONSTEXPR_CXX14 min_pointer operator+(difference_type n, min_pointer x) { return x + n; } + + TEST_CONSTEXPR_CXX14 min_pointer operator-(difference_type n) const { + min_pointer tmp(*this); + tmp -= n; + return tmp; + } + + friend TEST_CONSTEXPR_CXX14 difference_type operator-(min_pointer x, min_pointer y) { return x.ptr_ - y.ptr_; } + + TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const { return ptr_[n]; } + + friend TEST_CONSTEXPR_CXX14 bool operator<(min_pointer x, min_pointer y) { return x.ptr_ < y.ptr_; } + friend TEST_CONSTEXPR_CXX14 bool operator>(min_pointer x, min_pointer y) { return y < x; } + friend TEST_CONSTEXPR_CXX14 bool operator<=(min_pointer x, min_pointer y) { return !(y < x); } + friend TEST_CONSTEXPR_CXX14 bool operator>=(min_pointer x, min_pointer y) { return !(x < y); } + + static TEST_CONSTEXPR_CXX14 min_pointer pointer_to(const T& t) { return min_pointer(std::addressof(t)); } + + friend TEST_CONSTEXPR_CXX14 bool operator==(min_pointer x, min_pointer y) { return x.ptr_ == y.ptr_; } + friend TEST_CONSTEXPR_CXX14 bool operator!=(min_pointer x, min_pointer y) { return x.ptr_ != y.ptr_; } + friend TEST_CONSTEXPR_CXX14 bool operator==(min_pointer x, std::nullptr_t) { return x.ptr_ == nullptr; } + friend TEST_CONSTEXPR_CXX14 bool operator!=(min_pointer x, std::nullptr_t) { return x.ptr_ != nullptr; } + friend TEST_CONSTEXPR_CXX14 bool operator==(std::nullptr_t, min_pointer x) { return x.ptr_ == nullptr; } + friend TEST_CONSTEXPR_CXX14 bool operator!=(std::nullptr_t, min_pointer x) { return x.ptr_ != nullptr; } + template + friend class min_pointer; }; template -class min_allocator -{ +class min_allocator { public: - typedef T value_type; - typedef min_pointer pointer; + typedef T value_type; + typedef min_pointer pointer; - min_allocator() = default; - template - TEST_CONSTEXPR_CXX20 min_allocator(min_allocator) {} + min_allocator() = default; + template + TEST_CONSTEXPR_CXX20 min_allocator(min_allocator) {} - TEST_CONSTEXPR_CXX20 pointer allocate(std::size_t n) { return pointer(std::allocator().allocate(n)); } + TEST_CONSTEXPR_CXX20 pointer allocate(std::size_t n) { return pointer(std::allocator().allocate(n)); } - TEST_CONSTEXPR_CXX20 void deallocate(pointer p, std::size_t n) { std::allocator().deallocate(p.ptr_, n); } + TEST_CONSTEXPR_CXX20 void deallocate(pointer p, std::size_t n) { std::allocator().deallocate(p.ptr_, n); } - TEST_CONSTEXPR_CXX20 friend bool operator==(min_allocator, min_allocator) {return true;} - TEST_CONSTEXPR_CXX20 friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);} + TEST_CONSTEXPR_CXX20 friend bool operator==(min_allocator, min_allocator) { return true; } + TEST_CONSTEXPR_CXX20 friend bool operator!=(min_allocator x, min_allocator y) { return !(x == y); } }; template @@ -427,25 +424,19 @@ template class explicit_allocator { public: - typedef T value_type; + typedef T value_type; - TEST_CONSTEXPR_CXX20 explicit_allocator() TEST_NOEXCEPT {} + TEST_CONSTEXPR_CXX20 explicit_allocator() TEST_NOEXCEPT {} - template - TEST_CONSTEXPR_CXX20 explicit explicit_allocator(explicit_allocator) TEST_NOEXCEPT {} + template + TEST_CONSTEXPR_CXX20 explicit explicit_allocator(explicit_allocator) TEST_NOEXCEPT {} - TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) - { - return static_cast(std::allocator().allocate(n)); - } + TEST_CONSTEXPR_CXX20 T* allocate(std::size_t n) { return static_cast(std::allocator().allocate(n)); } - TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t n) - { - std::allocator().deallocate(p, n); - } + TEST_CONSTEXPR_CXX20 void deallocate(T* p, std::size_t n) { std::allocator().deallocate(p, n); } - TEST_CONSTEXPR_CXX20 friend bool operator==(explicit_allocator, explicit_allocator) {return true;} - TEST_CONSTEXPR_CXX20 friend bool operator!=(explicit_allocator x, explicit_allocator y) {return !(x == y);} + TEST_CONSTEXPR_CXX20 friend bool operator==(explicit_allocator, explicit_allocator) { return true; } + TEST_CONSTEXPR_CXX20 friend bool operator!=(explicit_allocator x, explicit_allocator y) { return !(x == y); } }; template diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index b59c7fdaf0a3d..de06b9dd1bee7 100644 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -372,6 +372,11 @@ def add_version_header(tc): "values": {"c++20": 201811}, "headers": ["iterator"], }, + { + "name": "__cpp_lib_constexpr_list", + "values": {"c++26": 202502}, + "headers": ["list"], + }, { "name": "__cpp_lib_constexpr_memory", "values": {"c++20": 201811, "c++23": 202202}, From fbc01d01f36f68369893f917bf01e64ad5952bc6 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Wed, 5 Mar 2025 22:42:09 -0500 Subject: [PATCH 2/5] Fix gcc constexpr evaluation failure --- libcxx/include/list | 2 +- .../sequences/list/list.capacity/resize_size.pass.cpp | 3 +-- .../sequences/list/list.cons/input_iterator.pass.cpp | 4 ++-- .../containers/sequences/list/list.cons/size_type.pass.cpp | 3 +-- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/libcxx/include/list b/libcxx/include/list index ee846f7aa5fcf..2896231203d9b 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -344,7 +344,7 @@ public: _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer __as_link() { return pointer_traits<__base_pointer>::pointer_to( - *static_cast::element_type*>(this)); + *static_cast::element_type*>(std::addressof(*this))); } }; diff --git a/libcxx/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp b/libcxx/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp index 32049b22881b9..f694d9ab26504 100644 --- a/libcxx/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp @@ -12,7 +12,6 @@ #include #include -#include #include "test_macros.h" #include "DefaultOnly.h" @@ -35,7 +34,7 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(l.back() == 0); } #if TEST_STD_VER >= 11 - if (!std::is_constant_evaluated()) { + if (!TEST_IS_CONSTANT_EVALUATED) { { std::list l(10); l.resize(5); diff --git a/libcxx/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp index e24d123c37318..d92307283098d 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/input_iterator.pass.cpp @@ -174,7 +174,7 @@ TEST_CONSTEXPR_CXX26 void test_emplacable_concept_with_alloc() { #endif } -TEST_CONSTEXPR_CXX26 void test_ctor_under_alloc() { +void test_ctor_under_alloc() { #if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; @@ -205,7 +205,7 @@ TEST_CONSTEXPR_CXX26 void test_ctor_under_alloc() { #endif } -TEST_CONSTEXPR_CXX26 void test_ctor_under_alloc_with_alloc() { +void test_ctor_under_alloc_with_alloc() { #if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; diff --git a/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp index f9c3b8c2a96c4..55371e8354a9e 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include "test_macros.h" #include "DefaultOnly.h" @@ -88,7 +87,7 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(*i == 0); } - if (!std::is_constant_evaluated()) { + if (!TEST_IS_CONSTANT_EVALUATED) { { std::list l(3); assert(l.size() == 3); From 885aff2706691fbf8181909f5cbd3f2258ef0c37 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Thu, 8 May 2025 11:47:55 -0400 Subject: [PATCH 3/5] Rebase onto main to resolve conflicts --- .../list.version.compile.pass.cpp | 27 +++++++++++++++++++ .../version.version.compile.pass.cpp | 27 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/list.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/list.version.compile.pass.cpp index 9fd638087fcea..d10c61c0e9cf4 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/list.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/list.version.compile.pass.cpp @@ -24,6 +24,10 @@ # error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -54,6 +58,10 @@ # error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -87,6 +95,10 @@ # error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -126,6 +138,10 @@ # error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++20" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -171,6 +187,10 @@ # error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++23" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -219,6 +239,13 @@ # error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++26" # endif +# ifndef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list should be defined in c++26" +# endif +# if __cpp_lib_constexpr_list != 202502L +# error "__cpp_lib_constexpr_list 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 a13edacd1e46a..e4fe9f994e2e0 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 @@ -208,6 +208,10 @@ # error "__cpp_lib_constexpr_iterator should not be defined before c++20" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -1100,6 +1104,10 @@ # error "__cpp_lib_constexpr_iterator should not be defined before c++20" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -2094,6 +2102,10 @@ # error "__cpp_lib_constexpr_iterator should not be defined before c++20" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -3334,6 +3346,10 @@ # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -4790,6 +4806,10 @@ # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++23" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list 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 @@ -6468,6 +6488,13 @@ # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++26" # endif +# ifndef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list should be defined in c++26" +# endif +# if __cpp_lib_constexpr_list != 202502L +# error "__cpp_lib_constexpr_list 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 From 7950727b60ed3cd2bded824a36d5284655031d76 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Wed, 11 Jun 2025 09:59:13 -0400 Subject: [PATCH 4/5] Address ldionne's comments --- libcxx/include/list | 5 +---- .../containers/sequences/list/list.cons/from_range.pass.cpp | 2 +- .../sequences/list/list.modifiers/append_range.pass.cpp | 2 +- .../sequences/list/list.modifiers/assign_range.pass.cpp | 2 +- .../sequences/list/list.modifiers/insert_range.pass.cpp | 2 +- .../sequences/list/list.modifiers/prepend_range.pass.cpp | 2 +- .../sequences/list/list.modifiers/push_back_rvalue.pass.cpp | 2 +- 7 files changed, 7 insertions(+), 10 deletions(-) diff --git a/libcxx/include/list b/libcxx/include/list index 2896231203d9b..fd9f305ab4acb 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -342,10 +342,7 @@ public: : __base(__prev, __next) {} _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI ~__list_node() {} - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer __as_link() { - return pointer_traits<__base_pointer>::pointer_to( - *static_cast::element_type*>(std::addressof(*this))); - } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer __as_link() { return __base::__self(); } }; template > diff --git a/libcxx/test/std/containers/sequences/list/list.cons/from_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/from_range.pass.cpp index 60a4764725679..311c72d815d13 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/from_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/from_range.pass.cpp @@ -27,7 +27,7 @@ TEST_CONSTEXPR_CXX26 bool test() { static_assert(test_constraints()); - if (!std::is_constant_evaluated()) { + if (!TEST_IS_CONSTANT_EVALUATED) { test_exception_safety_throwing_copy(); test_exception_safety_throwing_allocator(); } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/append_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/append_range.pass.cpp index 66b72415f3b26..4b47a8738e525 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/append_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/append_range.pass.cpp @@ -32,7 +32,7 @@ TEST_CONSTEXPR_CXX26 bool test() { }); test_sequence_append_range_move_only(); - if (!std::is_constant_evaluated()) { + if (!TEST_IS_CONSTANT_EVALUATED) { test_append_range_exception_safety_throwing_copy(); test_append_range_exception_safety_throwing_allocator(); } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/assign_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/assign_range.pass.cpp index 92a835e1c91bd..83a12879a041e 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/assign_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/assign_range.pass.cpp @@ -32,7 +32,7 @@ TEST_CONSTEXPR_CXX26 bool test() { }); test_sequence_assign_range_move_only(); - if (!std::is_constant_evaluated()) { + if (!TEST_IS_CONSTANT_EVALUATED) { test_assign_range_exception_safety_throwing_copy(); test_assign_range_exception_safety_throwing_allocator(); } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_range.pass.cpp index 370d7ab1aee64..5908d40d0cc90 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/insert_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/insert_range.pass.cpp @@ -35,7 +35,7 @@ TEST_CONSTEXPR_CXX26 bool test() { }); test_sequence_insert_range_move_only(); - if (!std::is_constant_evaluated()) { + if (!TEST_IS_CONSTANT_EVALUATED) { test_insert_range_exception_safety_throwing_copy(); test_insert_range_exception_safety_throwing_allocator(); } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/prepend_range.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/prepend_range.pass.cpp index b978166564583..41f7061c09d28 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/prepend_range.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/prepend_range.pass.cpp @@ -32,7 +32,7 @@ TEST_CONSTEXPR_CXX26 bool test() { }); test_sequence_prepend_range_move_only(); - if (!std::is_constant_evaluated()) { + if (!TEST_IS_CONSTANT_EVALUATED) { test_prepend_range_exception_safety_throwing_copy(); test_prepend_range_exception_safety_throwing_allocator(); } diff --git a/libcxx/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp b/libcxx/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp index 011aa015d843e..764dd7da18328 100644 --- a/libcxx/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp @@ -10,7 +10,7 @@ // -// void push_back(value_type&& x); // constexpr since C++26// constexpr since C++26 +// void push_back(value_type&& x); // constexpr since C++26 #include #include From 46164d8fa33dfb4af24569b01466c9de82aad944 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Mon, 16 Jun 2025 09:23:04 -0400 Subject: [PATCH 5/5] Fix __as_link() --- libcxx/include/list | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libcxx/include/list b/libcxx/include/list index fd9f305ab4acb..2896231203d9b 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -342,7 +342,10 @@ public: : __base(__prev, __next) {} _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI ~__list_node() {} - _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer __as_link() { return __base::__self(); } + _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer __as_link() { + return pointer_traits<__base_pointer>::pointer_to( + *static_cast::element_type*>(std::addressof(*this))); + } }; template >