-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[libc++] Make list constexpr as part of P3372R3 #129799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
8c3656b
to
b535bbe
Compare
@llvm/pr-subscribers-libcxx Author: Peng Liu (winner245) ChangesFixes #128659. Patch is 188.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/129799.diff 73 Files Affected:
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index dcf9838edd74b..6cc5cef2211a7 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -416,6 +416,8 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_bitset`` ``202306L``
---------------------------------------------------------- -----------------
+ ``__cpp_lib_constexpr_list`` ``202502L``
+ ---------------------------------------------------------- -----------------
``__cpp_lib_constexpr_new`` ``202406L``
---------------------------------------------------------- -----------------
``__cpp_lib_constrained_equality`` *unimplemented*
diff --git a/libcxx/include/__memory/allocation_guard.h b/libcxx/include/__memory/allocation_guard.h
index 66edcd92ed618..2fc485f4ed0ed 100644
--- a/libcxx/include/__memory/allocation_guard.h
+++ b/libcxx/include/__memory/allocation_guard.h
@@ -49,24 +49,26 @@ struct __allocation_guard {
using _Size _LIBCPP_NODEBUG = typename allocator_traits<_Alloc>::size_type;
template <class _AllocT> // we perform the allocator conversion inside the constructor
- _LIBCPP_HIDE_FROM_ABI explicit __allocation_guard(_AllocT __alloc, _Size __n)
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit __allocation_guard(_AllocT __alloc, _Size __n)
: __alloc_(std::move(__alloc)),
__n_(__n),
__ptr_(allocator_traits<_Alloc>::allocate(__alloc_, __n_)) // initialization order is important
{}
- _LIBCPP_HIDE_FROM_ABI ~__allocation_guard() _NOEXCEPT { __destroy(); }
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI ~__allocation_guard() _NOEXCEPT { __destroy(); }
- _LIBCPP_HIDE_FROM_ABI __allocation_guard(const __allocation_guard&) = delete;
- _LIBCPP_HIDE_FROM_ABI __allocation_guard(__allocation_guard&& __other) _NOEXCEPT
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __allocation_guard(const __allocation_guard&) = delete;
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __allocation_guard(__allocation_guard&& __other) _NOEXCEPT
: __alloc_(std::move(__other.__alloc_)),
__n_(__other.__n_),
__ptr_(__other.__ptr_) {
__other.__ptr_ = nullptr;
}
- _LIBCPP_HIDE_FROM_ABI __allocation_guard& operator=(const __allocation_guard& __other) = delete;
- _LIBCPP_HIDE_FROM_ABI __allocation_guard& operator=(__allocation_guard&& __other) _NOEXCEPT {
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __allocation_guard&
+ operator=(const __allocation_guard& __other) = delete;
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __allocation_guard&
+ operator=(__allocation_guard&& __other) _NOEXCEPT {
if (std::addressof(__other) != this) {
__destroy();
@@ -79,17 +81,17 @@ struct __allocation_guard {
return *this;
}
- _LIBCPP_HIDE_FROM_ABI _Pointer
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI _Pointer
__release_ptr() _NOEXCEPT { // not called __release() because it's a keyword in objective-c++
_Pointer __tmp = __ptr_;
__ptr_ = nullptr;
return __tmp;
}
- _LIBCPP_HIDE_FROM_ABI _Pointer __get() const _NOEXCEPT { return __ptr_; }
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI _Pointer __get() const _NOEXCEPT { return __ptr_; }
private:
- _LIBCPP_HIDE_FROM_ABI void __destroy() _NOEXCEPT {
+ _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI void __destroy() _NOEXCEPT {
if (__ptr_ != nullptr) {
allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_);
}
diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h
index afe3d1bf8a2de..9626922ca3c2f 100644
--- a/libcxx/include/__memory/pointer_traits.h
+++ b/libcxx/include/__memory/pointer_traits.h
@@ -302,6 +302,14 @@ concept __resettable_smart_pointer_with_args = requires(_Smart __s, _Pointer __p
#endif
+template <class _PtrTo, class _PtrFrom>
+_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI _PtrTo __static_fancy_pointer_cast(const _PtrFrom& __p) {
+ using __ptr_traits = pointer_traits<_PtrTo>;
+ using __element_type = typename __ptr_traits::element_type;
+ return __p ? __ptr_traits::pointer_to(*static_cast<__element_type*>(std::addressof(*__p)))
+ : static_cast<_PtrTo>(nullptr);
+}
+
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
diff --git a/libcxx/include/list b/libcxx/include/list
index 1285174f1c384..e6ecce38dc023 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -287,10 +287,14 @@ struct __list_node_pointer_traits {
"_LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB macro to silence this diagnostic.");
# endif
- static _LIBCPP_HIDE_FROM_ABI __base_pointer __unsafe_link_pointer_cast(__base_pointer __p) { return __p; }
+ static _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer
+ __unsafe_link_pointer_cast(__base_pointer __p) {
+ return __p;
+ }
- static _LIBCPP_HIDE_FROM_ABI __base_pointer __unsafe_link_pointer_cast(__node_pointer __p) {
- return static_cast<__base_pointer>(static_cast<_VoidPtr>(__p));
+ static _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __base_pointer
+ __unsafe_link_pointer_cast(__node_pointer __p) {
+ return std::__static_fancy_pointer_cast<__base_pointer>(__p);
}
};
@@ -303,14 +307,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<typename pointer_traits<__node_pointer>::element_type*>(this));
+ }
};
template <class _Tp, class _VoidPtr>
@@ -325,7 +335,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:
@@ -338,10 +348,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<typename pointer_traits<__base_pointer>::element_type*>(std::addressof(*this)));
+ }
};
template <class _Tp, class _Alloc = allocator<_Tp> >
@@ -358,7 +372,8 @@ class _LIBCPP_TEMPLATE_VIS __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 <class, class>
friend class list;
@@ -374,37 +389,41 @@ public:
typedef __rebind_pointer_t<_VoidPtr, value_type> pointer;
typedef typename pointer_traits<pointer>::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>::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);
}
};
@@ -416,7 +435,8 @@ class _LIBCPP_TEMPLATE_VIS __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 <class, class>
friend class list;
@@ -430,39 +450,43 @@ public:
typedef __rebind_pointer_t<_VoidPtr, const value_type> pointer;
typedef typename pointer_traits<pointer>::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>::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);
}
};
@@ -503,43 +527,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 __node_pointer_traits::__unsafe_link_pointer_cast(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<allocator_type>);
# 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<bool, __node_alloc_traits::propagate_on_container_copy_assignment::value>());
}
- _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(
@@ -547,7 +577,8 @@ protected:
}
template <class... _Args>
- _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.
@@ -563,7 +594,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()));
@@ -572,54 +603,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 <class _Tp, class _Alloc>
-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 <class _Tp, class _Alloc>
-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 <class _Tp, class _Alloc>
-...
[truncated]
|
d39dabf
to
3e721b8
Compare
3e721b8
to
9694e9c
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
libcxx/test/std/containers/sequences/list/list.capacity/resize_size.pass.cpp
Show resolved
Hide resolved
test_ctor_under_alloc(); | ||
test_ctor_under_alloc_with_alloc(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's special with those that doesn't work inside constexpr
? Is there no way to tweak the tests so they work at compile-time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main challenge I faced to make these tests constexpr is that they both call a function getConstructController
, which defines a local static variable.
// getConstructController - Return the global allocator construction controller.
inline ConstructController* getConstructController() {
static ConstructController c;
return &c;
}
According to my test (https://godbolt.org/z/c51735h3T), this function call cannot be made constexpr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ideal outcome here might be to pass this static data as an argument to the various "controller" types and create the object as a local variable in the function instead. I don't know if that's feasible though. I think this is reasonable for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still find it challenging to make these two tests constexpr
, because the AllocatorConstructController
type must use a singleton pattern (as the test-types, test-allocator and test need to share the same controller), meaning that the controller object must be a static
variable. Whether it is a local static (https://godbolt.org/z/8eYxoj9or) or class static (https://godbolt.org/z/xnzh693WK) variable, I found it not possible to achieve a constexpr implementation.
libcxx/test/std/containers/sequences/list/list.modifiers/append_range.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/containers/sequences/list/list.modifiers/push_back_rvalue.pass.cpp
Outdated
Show resolved
Hide resolved
2dfa51a
to
64e31c6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM modulo the remaining comments and rebasing onto main
.
test_ctor_under_alloc(); | ||
test_ctor_under_alloc_with_alloc(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ideal outcome here might be to pass this static data as an argument to the various "controller" types and create the object as a local variable in the function instead. I don't know if that's feasible though. I think this is reasonable for now.
@@ -31,8 +32,19 @@ int main(int, char**) { | |||
}); | |||
test_sequence_prepend_range_move_only<std::list>(); | |||
|
|||
test_prepend_range_exception_safety_throwing_copy<std::list>(); | |||
test_prepend_range_exception_safety_throwing_allocator<std::list, int>(); | |||
if (!std::is_constant_evaluated()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should also be !TEST_IS_CONSTANT_EVALUATED
. Please make a pass throughout the patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've done a grep search in the entire patch, and modified all 5 usages to be !TEST_IS_CONSTANT_EVALUATED
.
64e31c6
to
428d378
Compare
428d378
to
75abeb6
Compare
This patch makes
std::list
constexpr as part of P3372R3.Fixes #128659.