diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -310,6 +310,8 @@ ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_cmath`` *unimplemented* ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_memory`` ``202202L`` + ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_typeinfo`` *unimplemented* ------------------------------------------------- ----------------- ``__cpp_lib_invoke_r`` *unimplemented* diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -38,6 +38,7 @@ Implemented Papers ------------------ - P2499R0 - ``string_view`` range constructor should be ``explicit`` +- P2273R3 - Making ``std::unique_ptr`` constexpr Improvements and New Features ----------------------------- diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv --- a/libcxx/docs/Status/Cxx2bPapers.csv +++ b/libcxx/docs/Status/Cxx2bPapers.csv @@ -44,7 +44,7 @@ "`P1206R7 `__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","","" "`P1413R3 `__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","","" "`P2255R3 `__","LWG","A type trait to detect reference binding to temporary","February 2022","","" -"`P2273R3 `__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","","" +"`P2273R3 `__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Complete|","16.0" "`P2387R3 `__","LWG","Pipe support for user-defined range adaptors","February 2022","","" "`P2440R1 `__","LWG","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","February 2022","","" "`P2441R2 `__","LWG","``views::join_view``","February 2022","","" diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -849,6 +849,12 @@ # define _LIBCPP_CONSTEXPR_AFTER_CXX17 # endif +# if _LIBCPP_STD_VER > 20 +# define _LIBCPP_CONSTEXPR_CXX23 constexpr +# else +# define _LIBCPP_CONSTEXPR_CXX23 +# endif + # if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC) # define _LIBCPP_NODISCARD [[nodiscard]] # elif defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG) diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -40,12 +40,12 @@ _LIBCPP_INLINE_VISIBILITY default_delete() {} #endif template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 default_delete(const default_delete<_Up>&, typename enable_if::value>::type* = 0) _NOEXCEPT {} - _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT { static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type"); static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type"); delete __ptr; @@ -67,12 +67,12 @@ #endif template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {} template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename _EnableIfConvertible<_Up>::type operator()(_Up* __ptr) const _NOEXCEPT { static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type"); @@ -177,18 +177,18 @@ template > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} template > > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {} template > > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, _VSTD::move(__d)) { static_assert(!is_reference::value, @@ -200,7 +200,7 @@ _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { } @@ -209,7 +209,7 @@ class = _EnableIfMoveConvertible, _Up>, class = _EnableIfDeleterConvertible<_Ep> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {} @@ -223,7 +223,7 @@ : __ptr_(__p.release(), __value_init_tag()) {} #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); @@ -234,7 +234,7 @@ class = _EnableIfMoveConvertible, _Up>, class = _EnableIfDeleterAssignable<_Ep> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter()); @@ -258,49 +258,49 @@ unique_ptr& operator=(unique_ptr const&) = delete; #endif - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 ~unique_ptr() { reset(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { reset(); return *this; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename add_lvalue_reference<_Tp>::type operator*() const { return *__ptr_.first(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_.first(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 pointer release() _NOEXCEPT { pointer __t = __ptr_.first(); __ptr_.first() = pointer(); return __t; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT { pointer __tmp = __ptr_.first(); __ptr_.first() = __p; @@ -308,7 +308,7 @@ __ptr_.second()(__tmp); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } @@ -400,27 +400,27 @@ template , class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 explicit unique_ptr(_Pp __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} template >, class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {} template > > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(nullptr, __d) {} template >, class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, _VSTD::move(__d)) { static_assert(!is_reference::value, @@ -429,7 +429,7 @@ template > > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(nullptr, _VSTD::move(__d)) { static_assert(!is_reference::value, @@ -442,12 +442,12 @@ _LIBCPP_INLINE_VISIBILITY unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); @@ -458,7 +458,7 @@ class = _EnableIfMoveConvertible, _Up>, class = _EnableIfDeleterConvertible<_Ep> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) { } @@ -467,7 +467,7 @@ class = _EnableIfMoveConvertible, _Up>, class = _EnableIfDeleterAssignable<_Ep> > - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { reset(__u.release()); @@ -480,40 +480,40 @@ unique_ptr& operator=(unique_ptr const&) = delete; #endif public: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 ~unique_ptr() { reset(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { reset(); return *this; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename add_lvalue_reference<_Tp>::type operator[](size_t __i) const { return __ptr_.first()[__i]; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 pointer release() _NOEXCEPT { pointer __t = __ptr_.first(); __ptr_.first() = pointer(); @@ -521,7 +521,7 @@ } template - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename enable_if< _CheckArrayPointerConversion<_Pp>::value >::type @@ -532,7 +532,7 @@ __ptr_.second()(__tmp); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT { pointer __tmp = __ptr_.first(); __ptr_.first() = nullptr; @@ -540,7 +540,7 @@ __ptr_.second()(__tmp); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } @@ -548,7 +548,7 @@ }; template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename enable_if< __is_swappable<_Dp>::value, void @@ -556,7 +556,7 @@ swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);} template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();} @@ -607,7 +607,7 @@ #endif template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { @@ -641,7 +641,7 @@ #endif // _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { @@ -650,7 +650,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { @@ -659,7 +659,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { @@ -667,7 +667,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { @@ -675,7 +675,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { @@ -683,7 +683,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { @@ -691,7 +691,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { @@ -699,7 +699,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { @@ -709,7 +709,7 @@ #if _LIBCPP_STD_VER > 17 template requires three_way_comparable::pointer> -_LIBCPP_HIDE_FROM_ABI +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_CXX23 compare_three_way_result_t::pointer> operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { return compare_three_way()(__x.get(), static_cast::pointer>(nullptr)); @@ -737,7 +737,7 @@ }; template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename __unique_if<_Tp>::__unique_single make_unique(_Args&&... __args) { @@ -745,7 +745,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound make_unique(size_t __n) { diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -406,16 +406,17 @@ struct default_delete { constexpr default_delete() noexcept = default; - template default_delete(const default_delete&) noexcept; + template constexpr default_delete(const default_delete&) noexcept; // constexpr since C++23 - void operator()(T*) const noexcept; + constexpr void operator()(T*) const noexcept; // constexpr since C++23 }; template struct default_delete { constexpr default_delete() noexcept = default; - void operator()(T*) const noexcept; + template constexpr default_delete(const default_delete &) noexcept; // constexpr since C++23 + constexpr void operator()(T*) const noexcept; // constexpr since C++23 template void operator()(U*) const = delete; }; @@ -429,36 +430,37 @@ // constructors constexpr unique_ptr() noexcept; - explicit unique_ptr(pointer p) noexcept; - unique_ptr(pointer p, see below d1) noexcept; - unique_ptr(pointer p, see below d2) noexcept; - unique_ptr(unique_ptr&& u) noexcept; - unique_ptr(nullptr_t) noexcept : unique_ptr() { } + constexpr explicit unique_ptr(pointer p) noexcept; // constexpr since C++23 + constexpr unique_ptr(pointer p, see below d1) noexcept; // constexpr since C++23 + constexpr unique_ptr(pointer p, see below d2) noexcept; // constexpr since C++23 + constexpr unique_ptr(unique_ptr&& u) noexcept; // constexpr since C++23 + constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } template - unique_ptr(unique_ptr&& u) noexcept; + constexpr unique_ptr(unique_ptr&& u) noexcept; // constexpr since C++23 template - unique_ptr(auto_ptr&& u) noexcept; // removed in C++17 + unique_ptr(auto_ptr&& u) noexcept; // removed in C++17 // destructor - ~unique_ptr(); + constexpr ~unique_ptr(); // constexpr since C++23 // assignment - unique_ptr& operator=(unique_ptr&& u) noexcept; - template unique_ptr& operator=(unique_ptr&& u) noexcept; - unique_ptr& operator=(nullptr_t) noexcept; + constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; // constexpr since C++23 + template + constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; // constexpr since C++23 + constexpr unique_ptr& operator=(nullptr_t) noexcept; // constexpr since C++23 // observers - typename add_lvalue_reference::type operator*() const; - pointer operator->() const noexcept; - pointer get() const noexcept; - deleter_type& get_deleter() noexcept; - const deleter_type& get_deleter() const noexcept; - explicit operator bool() const noexcept; + typename constexpr add_lvalue_reference::type operator*() const; // constexpr since C++23 + constexpr pointer operator->() const noexcept; // constexpr since C++23 + constexpr pointer get() const noexcept; // constexpr since C++23 + constexpr deleter_type& get_deleter() noexcept; // constexpr since C++23 + constexpr const deleter_type& get_deleter() const noexcept; // constexpr since C++23 + constexpr explicit operator bool() const noexcept; // constexpr since C++23 // modifiers - pointer release() noexcept; - void reset(pointer p = pointer()) noexcept; - void swap(unique_ptr& u) noexcept; + constexpr pointer release() noexcept; // constexpr since C++23 + constexpr void reset(pointer p = pointer()) noexcept; // constexpr since C++23 + constexpr void swap(unique_ptr& u) noexcept; // constexpr since C++23 }; template @@ -471,41 +473,41 @@ // constructors constexpr unique_ptr() noexcept; - explicit unique_ptr(pointer p) noexcept; - unique_ptr(pointer p, see below d) noexcept; - unique_ptr(pointer p, see below d) noexcept; - unique_ptr(unique_ptr&& u) noexcept; - unique_ptr(nullptr_t) noexcept : unique_ptr() { } + constexpr explicit unique_ptr(pointer p) noexcept; // constexpr since C++23 + constexpr unique_ptr(pointer p, see below d) noexcept; // constexpr since C++23 + constexpr unique_ptr(pointer p, see below d) noexcept; // constexpr since C++23 + constexpr unique_ptr(unique_ptr&& u) noexcept; // constexpr since C++23 + constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } // constexpr since C++23 // destructor - ~unique_ptr(); + constexpr ~unique_ptr(); // constexpr since C++23 // assignment - unique_ptr& operator=(unique_ptr&& u) noexcept; - unique_ptr& operator=(nullptr_t) noexcept; + constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; // constexpr since C++23 + constexpr unique_ptr& operator=(nullptr_t) noexcept; // constexpr since C++23 // observers - T& operator[](size_t i) const; - pointer get() const noexcept; - deleter_type& get_deleter() noexcept; - const deleter_type& get_deleter() const noexcept; - explicit operator bool() const noexcept; + constexpr T& operator[](size_t i) const; // constexpr since C++23 + constexpr pointer get() const noexcept; // constexpr since C++23 + constexpr deleter_type& get_deleter() noexcept; // constexpr since C++23 + constexpr const deleter_type& get_deleter() const noexcept; // constexpr since C++23 + constexpr explicit operator bool() const noexcept; // constexpr since C++23 // modifiers - pointer release() noexcept; - void reset(pointer p = pointer()) noexcept; - void reset(nullptr_t) noexcept; + constexpr pointer release() noexcept; // constexpr since C++23 + constexpr void reset(pointer p = pointer()) noexcept; // constexpr since C++23 + constexpr void reset(nullptr_t) noexcept; // constexpr since C++23 template void reset(U) = delete; - void swap(unique_ptr& u) noexcept; + constexpr void swap(unique_ptr& u) noexcept; // constexpr since C++23 }; template - void swap(unique_ptr& x, unique_ptr& y) noexcept; + constexpr void swap(unique_ptr& x, unique_ptr& y) noexcept; // constexpr since C++23 template - bool operator==(const unique_ptr& x, const unique_ptr& y); + constexpr bool operator==(const unique_ptr& x, const unique_ptr& y); // constexpr since C++23 template - bool operator!=(const unique_ptr& x, const unique_ptr& y); // removed in C++20 + bool operator!=(const unique_ptr& x, const unique_ptr& y); // removed in C++20 template bool operator<(const unique_ptr& x, const unique_ptr& y); template @@ -522,34 +524,34 @@ operator<=>(const unique_ptr& x, const unique_ptr& y); // C++20 template - bool operator==(const unique_ptr& x, nullptr_t) noexcept; + constexpr bool operator==(const unique_ptr& x, nullptr_t) noexcept; // constexpr since C++23 template - bool operator==(nullptr_t, const unique_ptr& y) noexcept; // removed in C++20 + bool operator==(nullptr_t, const unique_ptr& y) noexcept; // removed in C++20 template - bool operator!=(const unique_ptr& x, nullptr_t) noexcept; // removed in C++20 + bool operator!=(const unique_ptr& x, nullptr_t) noexcept; // removed in C++20 template - bool operator!=(nullptr_t, const unique_ptr& y) noexcept; // removed in C++20 + bool operator!=(nullptr_t, const unique_ptr& y) noexcept; // removed in C++20 template - bool operator<(const unique_ptr& x, nullptr_t); + constexpr bool operator<(const unique_ptr& x, nullptr_t); // constexpr since C++23 template - bool operator<(nullptr_t, const unique_ptr& y); + constexpr bool operator<(nullptr_t, const unique_ptr& y); // constexpr since C++23 template - bool operator<=(const unique_ptr& x, nullptr_t); + constexpr bool operator<=(const unique_ptr& x, nullptr_t); // constexpr since C++23 template - bool operator<=(nullptr_t, const unique_ptr& y); + constexpr bool operator<=(nullptr_t, const unique_ptr& y); // constexpr since C++23 template - bool operator>(const unique_ptr& x, nullptr_t); + constexpr bool operator>(const unique_ptr& x, nullptr_t); // constexpr since C++23 template - bool operator>(nullptr_t, const unique_ptr& y); + constexpr bool operator>(nullptr_t, const unique_ptr& y); // constexpr since C++23 template - bool operator>=(const unique_ptr& x, nullptr_t); + constexpr bool operator>=(const unique_ptr& x, nullptr_t); // constexpr since C++23 template - bool operator>=(nullptr_t, const unique_ptr& y); + constexpr bool operator>=(nullptr_t, const unique_ptr& y); // constexpr since C++23 template requires three_way_comparable::pointer> compare_three_way_result_t::pointer> - operator<=>(const unique_ptr& x, nullptr_t); // C++20 + constexpr operator<=>(const unique_ptr& x, nullptr_t); // C++20, constexpr since C++23 class bad_weak_ptr : public std::exception @@ -557,8 +559,10 @@ bad_weak_ptr() noexcept; }; -template unique_ptr make_unique(Args&&... args); // C++14 -template unique_ptr make_unique(size_t n); // C++14 +template +constexpr unique_ptr make_unique(Args&&... args); // C++14, constexpr since C++23 +template +constexpr unique_ptr make_unique(size_t n); // C++14, constexpr since C++23 template unspecified make_unique(Args&&...) = delete; // C++14, T == U[N] template diff --git a/libcxx/include/version b/libcxx/include/version --- a/libcxx/include/version +++ b/libcxx/include/version @@ -61,7 +61,8 @@ __cpp_lib_constexpr_dynamic_alloc 201907L __cpp_lib_constexpr_functional 201907L __cpp_lib_constexpr_iterator 201811L -__cpp_lib_constexpr_memory 201811L +__cpp_lib_constexpr_memory 202202L + 201811L // C++20 __cpp_lib_constexpr_numeric 201911L __cpp_lib_constexpr_string 201907L __cpp_lib_constexpr_string_view 201811L @@ -383,6 +384,8 @@ // # define __cpp_lib_bind_back 202202L # define __cpp_lib_byteswap 202110L // # define __cpp_lib_constexpr_cmath 202202L +# undef __cpp_lib_constexpr_memory +# define __cpp_lib_constexpr_memory 202202L // # define __cpp_lib_constexpr_typeinfo 202106L // # define __cpp_lib_invoke_r 202106L # define __cpp_lib_is_scoped_enum 202011L diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp @@ -23,6 +23,7 @@ __cpp_lib_atomic_value_initialization 201911L [C++20] __cpp_lib_constexpr_dynamic_alloc 201907L [C++20] __cpp_lib_constexpr_memory 201811L [C++20] + 202202L [C++2b] __cpp_lib_enable_shared_from_this 201603L [C++17] __cpp_lib_make_unique 201304L [C++14] __cpp_lib_out_ptr 202106L [C++2b] @@ -454,8 +455,8 @@ # ifndef __cpp_lib_constexpr_memory # error "__cpp_lib_constexpr_memory should be defined in c++2b" # endif -# if __cpp_lib_constexpr_memory != 201811L -# error "__cpp_lib_constexpr_memory should have the value 201811L in c++2b" +# if __cpp_lib_constexpr_memory != 202202L +# error "__cpp_lib_constexpr_memory should have the value 202202L in c++2b" # endif # ifndef __cpp_lib_enable_shared_from_this 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 --- 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 @@ -58,6 +58,7 @@ __cpp_lib_constexpr_functional 201907L [C++20] __cpp_lib_constexpr_iterator 201811L [C++20] __cpp_lib_constexpr_memory 201811L [C++20] + 202202L [C++2b] __cpp_lib_constexpr_numeric 201911L [C++20] __cpp_lib_constexpr_string 201907L [C++20] __cpp_lib_constexpr_string_view 201811L [C++20] @@ -3915,8 +3916,8 @@ # ifndef __cpp_lib_constexpr_memory # error "__cpp_lib_constexpr_memory should be defined in c++2b" # endif -# if __cpp_lib_constexpr_memory != 201811L -# error "__cpp_lib_constexpr_memory should have the value 201811L in c++2b" +# if __cpp_lib_constexpr_memory != 202202L +# error "__cpp_lib_constexpr_memory should have the value 202202L in c++2b" # endif # ifndef __cpp_lib_constexpr_numeric diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/constexpr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/constexpr.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/constexpr.pass.cpp @@ -0,0 +1,142 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +#include "test_macros.h" + +using namespace std; + +#if TEST_STD_VER >= 23 + +struct Dummy { + constexpr int test() const { + return 10; + } +}; + +TEST_CONSTEXPR_CXX23 bool test() { + // [memory.syn] + { + // FIXME no make_unique_for_overwrite support + //auto p1 = make_unique(42); + //auto p2 = make_unique_for_overwrite(); + //swap(p1, p2); + //assert(p1 == p1); + //assert(p1 != p2); + + //auto p3 = make_unique(10); + //auto p4 = make_unique_for_overwrite(4); + //swap(p3, p4); + //assert(p3 == p3); + //assert(p3 != p4); + + auto p5 = unique_ptr{nullptr}; + assert(p5 == nullptr); + assert(nullptr == p5); + assert(!(p5 != nullptr)); + assert(!(nullptr != p5)); + assert(!(p5 < nullptr)); + assert(!(nullptr < p5)); + assert(p5 <= nullptr); + assert(nullptr <= p5); + assert(!(p5 > nullptr)); + assert(!(nullptr > p5)); + assert(p5 >= nullptr); + assert(nullptr >= p5); + assert((p5 <=> nullptr) == strong_ordering::equal); + assert((nullptr <=> p5) == strong_ordering::equal); + } + + // changes in [unique.ptr.dltr.dflt] and [unique.ptr.dltr.dflt1] + // will be tested via destructors and copy assign/constructors + + // [unique.ptr.single.general] + { + // constructors + auto p1 = unique_ptr{new int{}}; + auto d1 = default_delete{}; + auto p2 = unique_ptr{new int{}, d1}; + auto p3 = unique_ptr{new int{}, default_delete{}}; + auto p4 = move(p3); + auto p5 = unique_ptr{nullptr}; + auto p6 = unique_ptr&>{new int{}, d1}; + auto p7 = unique_ptr{move(p6)}; + + // assignment + p3 = move(p4); + auto p8 = unique_ptr&>{new int{}, d1}; + p7 = move(p8); + p1 = nullptr; + + // observers + assert(*p2 == 0); + auto p9 = unique_ptr{new Dummy}; + assert(p9->test() == 10); + assert(p2.get() != nullptr); + [[maybe_unused]] auto& d2 = p2.get_deleter(); + [[maybe_unused]] auto& d3 = as_const(p2).get_deleter(); + auto b1 = static_cast(p2); + assert(b1); + + // modifiers + p1.reset(); + p1.reset(new int{}); + auto manual_delete = p2.release(); + delete manual_delete; + p5.swap(p1); + } + + // [unique.ptr.runtime.general] + { + // constructors + auto p1 = unique_ptr{new int[5]}; + auto d1 = default_delete{}; + auto p2 = unique_ptr{new int[5], d1}; + auto p3 = unique_ptr{new int[5], default_delete{}}; + auto p4 = move(p1); + auto p5 = unique_ptr&>{new int[5], d1}; + auto p6 = unique_ptr{move(p5)}; + + // assignment + p1 = move(p4); + auto p7 = unique_ptr&>{new int[5], d1}; + p6 = move(p7); + p4 = nullptr; + + // observers + p1[0] = 50; + assert(p1[0] == 50); + assert(p1.get() != nullptr); + [[maybe_unused]] auto& d2 = p1.get_deleter(); + [[maybe_unused]] auto& d3 = as_const(p1).get_deleter(); + auto b1 = static_cast(p1); + assert(b1); + + // modifiers + auto manual_delete = p1.release(); + delete[] manual_delete; + p1.reset(new int[3]); + p1.reset(nullptr); + p1.reset(); + p1.swap(p4); + } + + return true; +} + +static_assert(test()); + +#endif // TEST_STD_VER >= 23 + +int main() {} // COMPILE-ONLY diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp @@ -36,7 +36,7 @@ struct NonDefaultDeleter { NonDefaultDeleter() = delete; - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; #endif @@ -51,9 +51,9 @@ { // the constructor does not participate in overload resolution when // the deleter is not default constructible using Del = CDeleter; - using U1 = std::unique_ptr; - using U2 = std::unique_ptr; - using U3 = std::unique_ptr; + using U1 = std::unique_ptr; + using U2 = std::unique_ptr; + using U3 = std::unique_ptr; static_assert(!std::is_default_constructible::value, ""); static_assert(!std::is_default_constructible::value, ""); static_assert(!std::is_default_constructible::value, ""); @@ -62,7 +62,7 @@ } template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { #if TEST_STD_VER >= 11 { using U1 = std::unique_ptr; @@ -87,6 +87,8 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 0); } + + return true; } DEFINE_AND_RUN_IS_INCOMPLETE_TEST({ @@ -101,10 +103,16 @@ { test_sfinae(); test_basic(); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); +#endif } { test_sfinae(); test_basic(); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); +#endif } return 0; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp @@ -23,7 +23,7 @@ #include "unique_ptr_test_helper.h" template -void test_pointer_ctor() { +TEST_CONSTEXPR_CXX23 bool test_pointer_ctor() { { std::unique_ptr p(0); assert(p.get() == 0); @@ -33,10 +33,12 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 0); } + + return true; } template -void test_pointer_deleter_ctor() { +TEST_CONSTEXPR_CXX23 bool test_pointer_deleter_ctor() { { std::default_delete d; std::unique_ptr p(0, d); @@ -59,16 +61,25 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 5); } + + return true; } int main(int, char**) { { // test_pointer_ctor(); test_pointer_deleter_ctor(); +#if TEST_STD_VER >= 23 + static_assert(test_pointer_deleter_ctor()); +#endif } { test_pointer_ctor(); test_pointer_deleter_ctor(); +#if TEST_STD_VER >= 23 + static_assert(test_pointer_ctor()); + static_assert(test_pointer_deleter_ctor()); +#endif } return 0; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp @@ -18,7 +18,6 @@ #include "test_macros.h" #include "unique_ptr_test_helper.h" - #if TEST_STD_VER >= 11 TEST_CONSTINIT std::unique_ptr global_static_unique_ptr_single(nullptr); TEST_CONSTINIT std::unique_ptr global_static_unique_ptr_runtime(nullptr); @@ -30,15 +29,13 @@ #endif template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { #if TEST_STD_VER >= 11 { using U1 = std::unique_ptr; using U2 = std::unique_ptr >; - static_assert(std::is_nothrow_constructible::value, - ""); - static_assert(std::is_nothrow_constructible::value, - ""); + static_assert(std::is_nothrow_constructible::value, ""); + static_assert(std::is_nothrow_constructible::value, ""); } #endif { @@ -55,10 +52,12 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 0); } + + return true; } template -void test_sfinae() { +TEST_CONSTEXPR_CXX23 bool test_sfinae() { #if TEST_STD_VER >= 11 { // the constructor does not participate in overload resolution when // the deleter is a pointer type @@ -68,30 +67,26 @@ { // the constructor does not participate in overload resolution when // the deleter is not default constructible using Del = CDeleter; - using U1 = std::unique_ptr; - using U2 = std::unique_ptr; - using U3 = std::unique_ptr; + using U1 = std::unique_ptr; + using U2 = std::unique_ptr; + using U3 = std::unique_ptr; static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); } #endif + + return true; } DEFINE_AND_RUN_IS_INCOMPLETE_TEST({ { doIncompleteTypeTest(0, nullptr); } checkNumIncompleteTypeAlive(0); - { - doIncompleteTypeTest >(0, - nullptr); - } + { doIncompleteTypeTest >(0, nullptr); } checkNumIncompleteTypeAlive(0); { doIncompleteTypeTest(0, nullptr); } checkNumIncompleteTypeAlive(0); - { - doIncompleteTypeTest >( - 0, nullptr); - } + { doIncompleteTypeTest >(0, nullptr); } checkNumIncompleteTypeAlive(0); }) @@ -99,10 +94,18 @@ { test_basic(); test_sfinae(); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_sfinae()); +#endif } { test_basic(); test_sfinae(); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_sfinae()); +#endif } return 0; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp @@ -24,15 +24,15 @@ Deleter& operator=(Deleter&); public: - Deleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {} - int state() const { return state_; } + TEST_CONSTEXPR_CXX23 int state() const { return state_; } - void operator()(void*) { ++state_; } + TEST_CONSTEXPR_CXX23 void operator()(void*) { ++state_; } }; template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { Deleter d; assert(d.state() == 0); { @@ -41,11 +41,17 @@ assert(&p.get_deleter() == &d); } assert(d.state() == 0); + + return true; } int main(int, char**) { test_basic(); test_basic(); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_basic()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp @@ -13,16 +13,28 @@ // test reset against resetting self #include +#include #include "test_macros.h" struct A { std::unique_ptr ptr_; - A() : ptr_(this) {} - void reset() { ptr_.reset(); } + TEST_CONSTEXPR_CXX23 A() : ptr_(this) {} + TEST_CONSTEXPR_CXX23 void reset() { ptr_.reset(); } }; -int main(int, char**) { (new A)->reset(); +TEST_CONSTEXPR_CXX23 bool test() { + (new A)->reset(); + + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp @@ -17,9 +17,17 @@ #include "test_macros.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { std::unique_ptr p(new int(3)); assert(*p == 3); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp @@ -19,7 +19,7 @@ #include "unique_ptr_test_helper.h" template -void doTest(UPtr& p, bool ExpectTrue) { +TEST_CONSTEXPR_CXX23 void doTest(UPtr& p, bool ExpectTrue) { if (p) assert(ExpectTrue); else @@ -32,7 +32,7 @@ } template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { typedef typename std::conditional::type VT; typedef std::unique_ptr U; { @@ -57,11 +57,17 @@ doTest(p, false); doTest(cp, false); } + + return true; } int main(int, char**) { test_basic(); test_basic(); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_basic()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp @@ -19,7 +19,7 @@ #include "unique_ptr_test_helper.h" template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { typedef typename std::conditional::type VT; typedef const VT CVT; { @@ -42,11 +42,17 @@ assert(s.get() == p); assert(sc.get() == s.get()); } + + return true; } int main(int, char**) { test_basic(); test_basic(); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_basic()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp @@ -17,16 +17,16 @@ #include "test_macros.h" struct Deleter { - Deleter() {} + TEST_CONSTEXPR_CXX23 Deleter() {} - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} - int test() { return 5; } - int test() const { return 6; } + TEST_CONSTEXPR_CXX23 int test() { return 5; } + TEST_CONSTEXPR_CXX23 int test() const { return 6; } }; template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { typedef typename std::conditional::type VT; { std::unique_ptr p; @@ -56,11 +56,17 @@ assert(p.get_deleter().test() == 5); assert(cp.get_deleter().test() == 5); } + + return true; } int main(int, char**) { test_basic(); test_basic(); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_basic()); +#endif return 0; -} +} \ No newline at end of file diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp @@ -20,12 +20,21 @@ struct A { int i_; - A() : i_(7) {} + TEST_CONSTEXPR_CXX23 A() : i_(7) {} }; -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { std::unique_ptr p(new A); assert(p->i_ == 7); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp @@ -17,31 +17,39 @@ class foo { public: - foo () : val_(3) {} - int get () const { return val_; } + TEST_CONSTEXPR_CXX23 foo() : val_(3) {} + TEST_CONSTEXPR_CXX23 int get() const { return val_; } + private: - int val_; - }; + int val_; +}; -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX23 bool test() { + { auto p1 = std::make_unique(5); - for ( int i = 0; i < 5; ++i ) - assert ( p1[i] == 0 ); - } + for (int i = 0; i < 5; ++i) + assert(p1[i] == 0); + } - { + { auto p2 = std::make_unique(5); - for ( int i = 0; i < 5; ++i ) - assert ( p2[i].size () == 0 ); - } + for (int i = 0; i < 5; ++i) + assert(p2[i].size() == 0); + } - { + { auto p3 = std::make_unique(7); - for ( int i = 0; i < 7; ++i ) - assert ( p3[i].get () == 3 ); - } + for (int i = 0; i < 7; ++i) + assert(p3[i].get() == 3); + } + + return true; +} +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp @@ -13,23 +13,30 @@ #include "test_macros.h" -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX23 bool test() { + { std::unique_ptr p1 = std::make_unique(1); - assert ( *p1 == 1 ); - p1 = std::make_unique (); - assert ( *p1 == 0 ); - } + assert(*p1 == 1); + p1 = std::make_unique(); + assert(*p1 == 0); + } - { - std::unique_ptr p2 = std::make_unique ( "Meow!" ); - assert ( *p2 == "Meow!" ); - p2 = std::make_unique (); - assert ( *p2 == "" ); - p2 = std::make_unique ( 6, 'z' ); - assert ( *p2 == "zzzzzz" ); - } + { + std::unique_ptr p2 = std::make_unique("Meow!"); + assert(*p2 == "Meow!"); + p2 = std::make_unique(); + assert(*p2 == ""); + p2 = std::make_unique(6, 'z'); + assert(*p2 == "zzzzzz"); + } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp @@ -11,7 +11,7 @@ // default_delete[] // template -// default_delete(const default_delete&); +// constexpr default_delete(const default_delete&); // constexpr since C++23 // // This constructor shall not participate in overload resolution unless // U(*)[] is convertible to T(*)[]. @@ -21,11 +21,17 @@ #include "test_macros.h" -int main(int, char**) -{ - std::default_delete d1; - std::default_delete d2 = d1; - ((void)d2); +TEST_CONSTEXPR_CXX23 bool test() { + std::default_delete d1; + std::default_delete d2 = d1; + ((void)d2); - return 0; + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp @@ -8,69 +8,74 @@ // -// shared_ptr +// unique_ptr // template -// bool operator==(const unique_ptr& x, nullptr_t) noexcept; +// constexpr bool operator==(const unique_ptr& x, nullptr_t) noexcept; // constexpr since C++23 // template -// bool operator==(nullptr_t, const unique_ptr& y) noexcept; +// bool operator==(nullptr_t, const unique_ptr& y) noexcept; // removed in C++20 // template -// bool operator!=(const unique_ptr& x, nullptr_t) noexcept; +// bool operator!=(const unique_ptr& x, nullptr_t) noexcept; // removed in C++20 // template -// bool operator!=(nullptr_t, const unique_ptr& y) noexcept; +// bool operator!=(nullptr_t, const unique_ptr& y) noexcept; // removed in C++20 // template -// bool operator<(const unique_ptr& x, nullptr_t); +// constexpr bool operator<(const unique_ptr& x, nullptr_t); // constexpr since C++23 // template -// bool operator<(nullptr_t, const unique_ptr& y); +// constexpr bool operator<(nullptr_t, const unique_ptr& y); // constexpr since C++23 // template -// bool operator<=(const unique_ptr& x, nullptr_t); +// constexpr bool operator<=(const unique_ptr& x, nullptr_t); // constexpr since C++23 // template -// bool operator<=(nullptr_t, const unique_ptr& y); +// constexpr bool operator<=(nullptr_t, const unique_ptr& y); // constexpr since C++23 // template -// bool operator>(const unique_ptr& x, nullptr_t); +// constexpr bool operator>(const unique_ptr& x, nullptr_t); // constexpr since C++23 // template -// bool operator>(nullptr_t, const unique_ptr& y); +// constexpr bool operator>(nullptr_t, const unique_ptr& y); // constexpr since C++23 // template -// bool operator>=(const unique_ptr& x, nullptr_t); +// constexpr bool operator>=(const unique_ptr& x, nullptr_t); // constexpr since C++23 // template -// bool operator>=(nullptr_t, const unique_ptr& y); +// constexpr bool operator>=(nullptr_t, const unique_ptr& y); // constexpr since C++23 // template // requires three_­way_­comparable::pointer> // constexpr compare_three_way_result_t::pointer> -// operator<=>(const unique_ptr& x, nullptr_t); // C++20 +// operator<=>(const unique_ptr& x, nullptr_t); // C++20 #include #include +#include #include "test_macros.h" #include "test_comparisons.h" -int main(int, char**) -{ - AssertEqualityAreNoexcept, nullptr_t>(); - AssertEqualityAreNoexcept >(); - AssertComparisonsReturnBool, nullptr_t>(); - AssertComparisonsReturnBool >(); +TEST_CONSTEXPR_CXX23 bool test() { + if (!TEST_IS_CONSTANT_EVALUATED) { + AssertEqualityAreNoexcept, nullptr_t>(); + AssertEqualityAreNoexcept >(); + AssertComparisonsReturnBool, nullptr_t>(); + AssertComparisonsReturnBool >(); #if TEST_STD_VER > 17 - AssertOrderReturn, nullptr_t>(); - AssertOrderReturn>(); + AssertOrderReturn, nullptr_t>(); + AssertOrderReturn>(); #endif + } const std::unique_ptr p1(new int(1)); assert(!(p1 == nullptr)); assert(!(nullptr == p1)); - assert(!(p1 < nullptr)); - assert((nullptr < p1)); - assert(!(p1 <= nullptr)); - assert((nullptr <= p1)); - assert((p1 > nullptr)); - assert(!(nullptr > p1)); - assert((p1 >= nullptr)); - assert(!(nullptr >= p1)); + // A pointer to allocated storage and a nullptr can't be compared at compile-time + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(!(p1 < nullptr)); + assert((nullptr < p1)); + assert(!(p1 <= nullptr)); + assert((nullptr <= p1)); + assert((p1 > nullptr)); + assert(!(nullptr > p1)); + assert((p1 >= nullptr)); + assert(!(nullptr >= p1)); #if TEST_STD_VER > 17 - assert((nullptr <=> p1) == std::strong_ordering::less); - assert((p1 <=> nullptr) == std::strong_ordering::greater); + assert((nullptr <=> p1) == std::strong_ordering::less); + assert((p1 <=> nullptr) == std::strong_ordering::greater); #endif + } const std::unique_ptr p2; assert((p2 == nullptr)); @@ -87,5 +92,14 @@ assert((nullptr <=> p2) == std::strong_ordering::equivalent); #endif + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/support/deleter_types.h b/libcxx/test/support/deleter_types.h --- a/libcxx/test/support/deleter_types.h +++ b/libcxx/test/support/deleter_types.h @@ -25,441 +25,440 @@ #if TEST_STD_VER >= 11 template -class Deleter -{ - int state_; +class Deleter { + int state_; - Deleter(const Deleter&); - Deleter& operator=(const Deleter&); + Deleter(const Deleter&); + Deleter& operator=(const Deleter&); public: - Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} - Deleter& operator=(Deleter&& r) - { - state_ = r.state_; - r.state_ = 0; - return *this; - } - - - Deleter() : state_(0) {} - explicit Deleter(int s) : state_(s) {} - ~Deleter() {assert(state_ >= 0); state_ = -1;} - - template - Deleter(Deleter&& d, - typename std::enable_if::value>::type* = 0) - : state_(d.state()) {d.set_state(0);} + TEST_CONSTEXPR_CXX23 Deleter(Deleter&& r) : state_(r.state_) { r.state_ = 0; } + TEST_CONSTEXPR_CXX23 Deleter& operator=(Deleter&& r) { + state_ = r.state_; + r.state_ = 0; + return *this; + } + + TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit Deleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~Deleter() { + assert(state_ >= 0); + state_ = -1; + } + + template + TEST_CONSTEXPR_CXX23 Deleter(Deleter&& d, typename std::enable_if::value>::type* = 0) + : state_(d.state()) { + d.set_state(0); + } private: - template - Deleter(const Deleter& d, - typename std::enable_if::value>::type* = 0); + template + Deleter(const Deleter& d, typename std::enable_if::value>::type* = 0); + public: - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; template -class Deleter -{ - int state_; +class Deleter { + int state_; - Deleter(const Deleter&); - Deleter& operator=(const Deleter&); + Deleter(const Deleter&); + Deleter& operator=(const Deleter&); public: - - Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} - Deleter& operator=(Deleter&& r) - { - state_ = r.state_; - r.state_ = 0; - return *this; - } - - Deleter() : state_(0) {} - explicit Deleter(int s) : state_(s) {} - ~Deleter() {assert(state_ >= 0); state_ = -1;} - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 Deleter(Deleter&& r) : state_(r.state_) { r.state_ = 0; } + TEST_CONSTEXPR_CXX23 Deleter& operator=(Deleter&& r) { + state_ = r.state_; + r.state_ = 0; + return *this; + } + + TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit Deleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~Deleter() { + assert(state_ >= 0); + state_ = -1; + } + + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } + + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; #else // TEST_STD_VER < 11 template -class Deleter -{ - mutable int state_; +class Deleter { + mutable int state_; public: - Deleter() : state_(0) {} - explicit Deleter(int s) : state_(s) {} + Deleter() : state_(0) {} + explicit Deleter(int s) : state_(s) {} - Deleter(Deleter const & other) : state_(other.state_) { - other.state_ = 0; - } - Deleter& operator=(Deleter const& other) { - state_ = other.state_; - other.state_ = 0; - return *this; - } + Deleter(Deleter const& other) : state_(other.state_) { other.state_ = 0; } + Deleter& operator=(Deleter const& other) { + state_ = other.state_; + other.state_ = 0; + return *this; + } - ~Deleter() {assert(state_ >= 0); state_ = -1;} + ~Deleter() { + assert(state_ >= 0); + state_ = -1; + } - template - Deleter(Deleter d, - typename std::enable_if::value>::type* = 0) - : state_(d.state()) {} + template + Deleter(Deleter d, typename std::enable_if::value>::type* = 0) : state_(d.state()) {} public: - int state() const {return state_;} - void set_state(int i) {state_ = i;} + int state() const { return state_; } + void set_state(int i) { state_ = i; } - void operator()(T* p) {delete p;} + void operator()(T* p) { delete p; } }; template -class Deleter -{ - mutable int state_; +class Deleter { + mutable int state_; public: - - Deleter(Deleter const& other) : state_(other.state_) { - other.state_ = 0; - } - Deleter& operator=(Deleter const& other) { - state_ = other.state_; - other.state_ = 0; - return *this; - } - - Deleter() : state_(0) {} - explicit Deleter(int s) : state_(s) {} - ~Deleter() {assert(state_ >= 0); state_ = -1;} - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {delete [] p;} + Deleter(Deleter const& other) : state_(other.state_) { other.state_ = 0; } + Deleter& operator=(Deleter const& other) { + state_ = other.state_; + other.state_ = 0; + return *this; + } + + Deleter() : state_(0) {} + explicit Deleter(int s) : state_(s) {} + ~Deleter() { + assert(state_ >= 0); + state_ = -1; + } + + int state() const { return state_; } + void set_state(int i) { state_ = i; } + + void operator()(T* p) { delete[] p; } }; #endif template -void -swap(Deleter& x, Deleter& y) -{ - Deleter t(std::move(x)); - x = std::move(y); - y = std::move(t); +TEST_CONSTEXPR_CXX23 void swap(Deleter& x, Deleter& y) { + Deleter t(std::move(x)); + x = std::move(y); + y = std::move(t); } - template -class CDeleter -{ - int state_; +class CDeleter { + int state_; public: + TEST_CONSTEXPR_CXX23 CDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit CDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~CDeleter() { + assert(state_ >= 0); + state_ = -1; + } - CDeleter() : state_(0) {} - explicit CDeleter(int s) : state_(s) {} - ~CDeleter() {assert(state_ >= 0); state_ = -1;} - - template - CDeleter(const CDeleter& d) - : state_(d.state()) {} + template + TEST_CONSTEXPR_CXX23 CDeleter(const CDeleter& d) : state_(d.state()) {} - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; template -class CDeleter -{ - int state_; +class CDeleter { + int state_; public: + TEST_CONSTEXPR_CXX23 CDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit CDeleter(int s) : state_(s) {} + template + TEST_CONSTEXPR_CXX23 CDeleter(const CDeleter& d) : state_(d.state()) {} - CDeleter() : state_(0) {} - explicit CDeleter(int s) : state_(s) {} - template - CDeleter(const CDeleter& d) - : state_(d.state()) {} - - ~CDeleter() {assert(state_ >= 0); state_ = -1;} + TEST_CONSTEXPR_CXX23 ~CDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; template -void -swap(CDeleter& x, CDeleter& y) -{ - CDeleter t(std::move(x)); - x = std::move(y); - y = std::move(t); +TEST_CONSTEXPR_CXX23 void swap(CDeleter& x, CDeleter& y) { + CDeleter t(std::move(x)); + x = std::move(y); + y = std::move(t); } // Non-copyable deleter template -class NCDeleter -{ - int state_; - NCDeleter(NCDeleter const&); - NCDeleter& operator=(NCDeleter const&); -public: +class NCDeleter { + int state_; + NCDeleter(NCDeleter const&); + NCDeleter& operator=(NCDeleter const&); - NCDeleter() : state_(0) {} - explicit NCDeleter(int s) : state_(s) {} - ~NCDeleter() {assert(state_ >= 0); state_ = -1;} +public: + TEST_CONSTEXPR_CXX23 NCDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit NCDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~NCDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; - template -class NCDeleter -{ - int state_; - NCDeleter(NCDeleter const&); - NCDeleter& operator=(NCDeleter const&); -public: +class NCDeleter { + int state_; + NCDeleter(NCDeleter const&); + NCDeleter& operator=(NCDeleter const&); - NCDeleter() : state_(0) {} - explicit NCDeleter(int s) : state_(s) {} - ~NCDeleter() {assert(state_ >= 0); state_ = -1;} +public: + TEST_CONSTEXPR_CXX23 NCDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit NCDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~NCDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; - // Non-copyable deleter template -class NCConstDeleter -{ - int state_; - NCConstDeleter(NCConstDeleter const&); - NCConstDeleter& operator=(NCConstDeleter const&); -public: +class NCConstDeleter { + int state_; + NCConstDeleter(NCConstDeleter const&); + NCConstDeleter& operator=(NCConstDeleter const&); - NCConstDeleter() : state_(0) {} - explicit NCConstDeleter(int s) : state_(s) {} - ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;} +public: + TEST_CONSTEXPR_CXX23 NCConstDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit NCConstDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~NCConstDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) const {delete p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) const { delete p; } }; - template -class NCConstDeleter -{ - int state_; - NCConstDeleter(NCConstDeleter const&); - NCConstDeleter& operator=(NCConstDeleter const&); -public: +class NCConstDeleter { + int state_; + NCConstDeleter(NCConstDeleter const&); + NCConstDeleter& operator=(NCConstDeleter const&); - NCConstDeleter() : state_(0) {} - explicit NCConstDeleter(int s) : state_(s) {} - ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;} +public: + TEST_CONSTEXPR_CXX23 NCConstDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit NCConstDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~NCConstDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) const {delete [] p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) const { delete[] p; } }; - // Non-copyable deleter template -class CopyDeleter -{ - int state_; -public: +class CopyDeleter { + int state_; - CopyDeleter() : state_(0) {} - explicit CopyDeleter(int s) : state_(s) {} - ~CopyDeleter() {assert(state_ >= 0); state_ = -1;} - - CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} - CopyDeleter& operator=(CopyDeleter const& other) { - state_ = other.state_; - return *this; - } - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {delete p;} +public: + TEST_CONSTEXPR_CXX23 CopyDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit CopyDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~CopyDeleter() { + assert(state_ >= 0); + state_ = -1; + } + + TEST_CONSTEXPR_CXX23 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} + TEST_CONSTEXPR_CXX23 CopyDeleter& operator=(CopyDeleter const& other) { + state_ = other.state_; + return *this; + } + + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } + + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; - template -class CopyDeleter -{ - int state_; +class CopyDeleter { + int state_; public: - - CopyDeleter() : state_(0) {} - explicit CopyDeleter(int s) : state_(s) {} - ~CopyDeleter() {assert(state_ >= 0); state_ = -1;} - - CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} - CopyDeleter& operator=(CopyDeleter const& other) { - state_ = other.state_; - return *this; - } - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 CopyDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit CopyDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~CopyDeleter() { + assert(state_ >= 0); + state_ = -1; + } + + TEST_CONSTEXPR_CXX23 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} + TEST_CONSTEXPR_CXX23 CopyDeleter& operator=(CopyDeleter const& other) { + state_ = other.state_; + return *this; + } + + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } + + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; - -struct test_deleter_base -{ - static int count; - static int dealloc_count; +struct test_deleter_base { + static int count; + static int dealloc_count; }; -int test_deleter_base::count = 0; +int test_deleter_base::count = 0; int test_deleter_base::dealloc_count = 0; template -class test_deleter - : public test_deleter_base -{ - int state_; +class test_deleter : public test_deleter_base { + int state_; public: - - test_deleter() : state_(0) {++count;} - explicit test_deleter(int s) : state_(s) {++count;} - test_deleter(const test_deleter& d) - : state_(d.state_) {++count;} - ~test_deleter() {assert(state_ >= 0); --count; state_ = -1;} - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {assert(state_ >= 0); ++dealloc_count; delete p;} + test_deleter() : state_(0) { ++count; } + explicit test_deleter(int s) : state_(s) { ++count; } + test_deleter(const test_deleter& d) : state_(d.state_) { ++count; } + ~test_deleter() { + assert(state_ >= 0); + --count; + state_ = -1; + } + + int state() const { return state_; } + void set_state(int i) { state_ = i; } + + void operator()(T* p) { + assert(state_ >= 0); + ++dealloc_count; + delete p; + } #if TEST_STD_VER >= 11 - test_deleter* operator&() const = delete; + test_deleter* operator&() const = delete; #else + private: test_deleter* operator&() const; #endif }; template -void -swap(test_deleter& x, test_deleter& y) -{ - test_deleter t(std::move(x)); - x = std::move(y); - y = std::move(t); +void swap(test_deleter& x, test_deleter& y) { + test_deleter t(std::move(x)); + x = std::move(y); + y = std::move(t); } #if TEST_STD_VER >= 11 template -class PointerDeleter -{ - PointerDeleter(const PointerDeleter&); - PointerDeleter& operator=(const PointerDeleter&); +class PointerDeleter { + PointerDeleter(const PointerDeleter&); + PointerDeleter& operator=(const PointerDeleter&); public: - typedef min_pointer> pointer; + typedef min_pointer> pointer; - PointerDeleter() = default; - PointerDeleter(PointerDeleter&&) = default; - PointerDeleter& operator=(PointerDeleter&&) = default; - explicit PointerDeleter(int) {} + TEST_CONSTEXPR_CXX23 PointerDeleter() = default; + TEST_CONSTEXPR_CXX23 PointerDeleter(PointerDeleter&&) = default; + TEST_CONSTEXPR_CXX23 PointerDeleter& operator=(PointerDeleter&&) = default; + TEST_CONSTEXPR_CXX23 explicit PointerDeleter(int) {} - template - PointerDeleter(PointerDeleter&&, - typename std::enable_if::value>::type* = 0) - {} + template + TEST_CONSTEXPR_CXX23 + PointerDeleter(PointerDeleter&&, typename std::enable_if::value>::type* = 0) {} - void operator()(pointer p) { if (p) { delete std::addressof(*p); }} + TEST_CONSTEXPR_CXX23 void operator()(pointer p) { + if (p) { + delete std::addressof(*p); + } + } private: - template - PointerDeleter(const PointerDeleter&, - typename std::enable_if::value>::type* = 0); + template + PointerDeleter(const PointerDeleter&, typename std::enable_if::value>::type* = 0); }; - template -class PointerDeleter -{ - PointerDeleter(const PointerDeleter&); - PointerDeleter& operator=(const PointerDeleter&); +class PointerDeleter { + PointerDeleter(const PointerDeleter&); + PointerDeleter& operator=(const PointerDeleter&); public: - typedef min_pointer > pointer; + typedef min_pointer > pointer; - PointerDeleter() = default; - PointerDeleter(PointerDeleter&&) = default; - PointerDeleter& operator=(PointerDeleter&&) = default; - explicit PointerDeleter(int) {} + TEST_CONSTEXPR_CXX23 PointerDeleter() = default; + TEST_CONSTEXPR_CXX23 PointerDeleter(PointerDeleter&&) = default; + TEST_CONSTEXPR_CXX23 PointerDeleter& operator=(PointerDeleter&&) = default; + TEST_CONSTEXPR_CXX23 explicit PointerDeleter(int) {} - template - PointerDeleter(PointerDeleter&&, - typename std::enable_if::value>::type* = 0) - {} + template + TEST_CONSTEXPR_CXX23 + PointerDeleter(PointerDeleter&&, typename std::enable_if::value>::type* = 0) {} - void operator()(pointer p) { if (p) { delete [] std::addressof(*p); }} + TEST_CONSTEXPR_CXX23 void operator()(pointer p) { + if (p) { + delete[] std::addressof(*p); + } + } private: - template - PointerDeleter(const PointerDeleter&, - typename std::enable_if::value>::type* = 0); + template + PointerDeleter(const PointerDeleter&, typename std::enable_if::value>::type* = 0); }; #endif // TEST_STD_VER >= 11 template -class DefaultCtorDeleter -{ - int state_; +class DefaultCtorDeleter { + int state_; public: - int state() const {return state_;} - void operator()(T* p) {delete p;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; template -class DefaultCtorDeleter -{ - int state_; +class DefaultCtorDeleter { + int state_; public: - int state() const {return state_;} - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; #endif // SUPPORT_DELETER_TYPES_H diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -166,6 +166,12 @@ # define TEST_CONSTEXPR_CXX20 #endif +#if TEST_STD_VER >= 23 +# define TEST_CONSTEXPR_CXX23 constexpr +#else +# define TEST_CONSTEXPR_CXX23 +#endif + #define TEST_ALIGNAS_TYPE(...) TEST_ALIGNAS(TEST_ALIGNOF(__VA_ARGS__)) #if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) \ diff --git a/libcxx/test/support/unique_ptr_test_helper.h b/libcxx/test/support/unique_ptr_test_helper.h --- a/libcxx/test/support/unique_ptr_test_helper.h +++ b/libcxx/test/support/unique_ptr_test_helper.h @@ -34,15 +34,13 @@ int B::count = 0; template -typename std::enable_if::value, T*>::type -newValue(int num_elements) { +TEST_CONSTEXPR_CXX23 typename std::enable_if::value, T*>::type newValue(int num_elements) { assert(num_elements == 1); return new T; } template -typename std::enable_if::value, - typename std::remove_all_extents::type*>::type +TEST_CONSTEXPR_CXX23 typename std::enable_if::value, typename std::remove_all_extents::type*>::type newValue(int num_elements) { typedef typename std::remove_all_extents::type VT; assert(num_elements >= 1); @@ -57,33 +55,34 @@ IncompleteType* getNewIncompleteArray(int size); #if TEST_STD_VER >= 11 -template +template struct args_is_this_type : std::false_type {}; template struct args_is_this_type : std::is_same::type> {}; #endif -template > +template > struct StoresIncomplete { - static_assert((std::is_same::value || - std::is_same::value), ""); + static_assert( + (std::is_same::value || std::is_same::value), ""); std::unique_ptr m_ptr; #if TEST_STD_VER >= 11 StoresIncomplete(StoresIncomplete const&) = delete; - StoresIncomplete(StoresIncomplete&&) = default; + StoresIncomplete(StoresIncomplete&&) = default; - template + template StoresIncomplete(Args&&... args) : m_ptr(std::forward(args)...) { static_assert(!args_is_this_type::value, ""); } #else + private: StoresIncomplete(); StoresIncomplete(StoresIncomplete const&); + public: #endif @@ -94,8 +93,7 @@ }; #if TEST_STD_VER >= 11 -template , class... Args> +template , class... Args> void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) { checkNumIncompleteTypeAlive(expect_alive); { @@ -110,38 +108,34 @@ } #endif -#define INCOMPLETE_TEST_EPILOGUE() \ - int is_incomplete_test_anchor = is_incomplete_test(); \ - \ - struct IncompleteType { \ - static int count; \ - IncompleteType() { ++count; } \ - ~IncompleteType() { --count; } \ - }; \ - \ - int IncompleteType::count = 0; \ - \ - void checkNumIncompleteTypeAlive(int i) { \ - assert(IncompleteType::count == i); \ - } \ - int getNumIncompleteTypeAlive() { return IncompleteType::count; } \ - IncompleteType* getNewIncomplete() { return new IncompleteType; } \ - IncompleteType* getNewIncompleteArray(int size) { \ - return new IncompleteType[size]; \ - } \ - \ - template \ +#define INCOMPLETE_TEST_EPILOGUE() \ + int is_incomplete_test_anchor = is_incomplete_test(); \ + \ + struct IncompleteType { \ + static int count; \ + IncompleteType() { ++count; } \ + ~IncompleteType() { --count; } \ + }; \ + \ + int IncompleteType::count = 0; \ + \ + void checkNumIncompleteTypeAlive(int i) { assert(IncompleteType::count == i); } \ + int getNumIncompleteTypeAlive() { return IncompleteType::count; } \ + IncompleteType* getNewIncomplete() { return new IncompleteType; } \ + IncompleteType* getNewIncompleteArray(int size) { return new IncompleteType[size]; } \ + \ + template \ StoresIncomplete::~StoresIncomplete() {} # #if TEST_STD_VER >= 11 -#define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ - static int is_incomplete_test() { __VA_ARGS__ return 0; } \ - INCOMPLETE_TEST_EPILOGUE() +# define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ + static int is_incomplete_test() { __VA_ARGS__ return 0; } \ + INCOMPLETE_TEST_EPILOGUE() #else -#define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ - static int is_incomplete_test() { return 0; } \ - INCOMPLETE_TEST_EPILOGUE() +# define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ + static int is_incomplete_test() { return 0; } \ + INCOMPLETE_TEST_EPILOGUE() #endif #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -238,7 +238,7 @@ "headers": ["iterator"], }, { "name": "__cpp_lib_constexpr_memory", - "values": { "c++20": 201811 }, + "values": { "c++20": 201811, "c++2b": 202202 }, "headers": ["memory"], }, { "name": "__cpp_lib_constexpr_numeric",