Index: libcxx/docs/FeatureTestMacroTable.rst =================================================================== --- libcxx/docs/FeatureTestMacroTable.rst +++ libcxx/docs/FeatureTestMacroTable.rst @@ -312,6 +312,8 @@ ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_cmath`` *unimplemented* ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_memory`` ``202202L`` + ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_typeinfo`` *unimplemented* ------------------------------------------------- ----------------- ``__cpp_lib_forward_like`` ``202207L`` Index: libcxx/docs/ReleaseNotes.rst =================================================================== --- libcxx/docs/ReleaseNotes.rst +++ libcxx/docs/ReleaseNotes.rst @@ -40,6 +40,7 @@ - P2499R0 - ``string_view`` range constructor should be ``explicit`` - P2417R2 - A more constexpr bitset - P2445R1 - ``std::forward_like`` +- P2273R3 - Making ``std::unique_ptr`` constexpr Improvements and New Features ----------------------------- Index: libcxx/docs/Status/Cxx2b.rst =================================================================== --- libcxx/docs/Status/Cxx2b.rst +++ libcxx/docs/Status/Cxx2b.rst @@ -37,6 +37,10 @@ :header-rows: 1 :widths: auto +.. note:: + + .. [#note-P2273] P2273: ``make_unique_for_overwrite`` isn't done yet since `P1020` hasn't been implemented yet. + .. _issues-status-cxx2b: Library Working Group Issues Status Index: libcxx/docs/Status/Cxx2bPapers.csv =================================================================== --- libcxx/docs/Status/Cxx2bPapers.csv +++ 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","|Partial| [#note-P2273]_","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","","" Index: libcxx/include/__memory/unique_ptr.h =================================================================== --- libcxx/include/__memory/unique_ptr.h +++ libcxx/include/__memory/unique_ptr.h @@ -40,12 +40,10 @@ _LIBCPP_INLINE_VISIBILITY default_delete() {} #endif template - _LIBCPP_INLINE_VISIBILITY - default_delete(const default_delete<_Up>&, - typename enable_if::value>::type* = - 0) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_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_SINCE_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,13 +65,11 @@ #endif template - _LIBCPP_INLINE_VISIBILITY - default_delete(const default_delete<_Up[]>&, - typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 + default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {} template - _LIBCPP_INLINE_VISIBILITY - typename _EnableIfConvertible<_Up>::type + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename _EnableIfConvertible<_Up>::type operator()(_Up* __ptr) const _NOEXCEPT { static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type"); delete[] __ptr; @@ -175,22 +171,17 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} - template > - _LIBCPP_INLINE_VISIBILITY - explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} + template > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT + : __ptr_(__p, __value_init_tag()) {} - template > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT + template > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {} - template > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT - : __ptr_(__p, _VSTD::move(__d)) { + template > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 + unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, _VSTD::move(__d)) { static_assert(!is_reference::value, "rvalue deleter bound to reference"); } @@ -200,17 +191,14 @@ _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete; - _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr&& __u) _NOEXCEPT - : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT + : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) {} - template , _Up>, - class = _EnableIfDeleterConvertible<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT + template , _Up>, + class = _EnableIfDeleterConvertible<_Ep> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {} #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) @@ -223,19 +211,17 @@ : __ptr_(__p.release(), __value_init_tag()) {} #endif - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); return *this; } - template , _Up>, - class = _EnableIfDeleterAssignable<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { + template , _Up>, + class = _EnableIfDeleterAssignable<_Ep> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter()); return *this; @@ -258,58 +244,44 @@ unique_ptr& operator=(unique_ptr const&) = delete; #endif - _LIBCPP_INLINE_VISIBILITY - ~unique_ptr() { reset(); } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(nullptr_t) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { reset(); return *this; } - _LIBCPP_INLINE_VISIBILITY - typename add_lvalue_reference<_Tp>::type - operator*() const { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename add_lvalue_reference<_Tp>::type operator*() const { return *__ptr_.first(); } - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_.first(); } - _LIBCPP_INLINE_VISIBILITY - pointer get() const _NOEXCEPT { - return __ptr_.first(); - } - _LIBCPP_INLINE_VISIBILITY - deleter_type& get_deleter() _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY - const deleter_type& get_deleter() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY - explicit operator bool() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; } - _LIBCPP_INLINE_VISIBILITY - pointer release() _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT { pointer __t = __ptr_.first(); __ptr_.first() = pointer(); return __t; } - _LIBCPP_INLINE_VISIBILITY - void reset(pointer __p = pointer()) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(pointer __p = pointer()) _NOEXCEPT { pointer __tmp = __ptr_.first(); __ptr_.first() = __p; if (__tmp) __ptr_.second()(__tmp); } - _LIBCPP_INLINE_VISIBILITY - void swap(unique_ptr& __u) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } }; @@ -397,40 +369,36 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} - template , - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - explicit unique_ptr(_Pp __p) _NOEXCEPT + template , + class = _EnableIfPointerConvertible<_Pp> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} - template >, - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT + template >, + class = _EnableIfPointerConvertible<_Pp> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {} - template > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT + template > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(nullptr, __d) {} - template >, - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT + template >, + class = _EnableIfPointerConvertible<_Pp> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, _VSTD::move(__d)) { static_assert(!is_reference::value, "rvalue deleter bound to reference"); } - template > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT + template > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(nullptr, _VSTD::move(__d)) { static_assert(!is_reference::value, "rvalue deleter bound to reference"); @@ -442,34 +410,27 @@ _LIBCPP_INLINE_VISIBILITY unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete; - _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr&& __u) _NOEXCEPT - : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT + : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) {} - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); return *this; } - template , _Up>, - class = _EnableIfDeleterConvertible<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT - : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) { - } + template , _Up>, + class = _EnableIfDeleterConvertible<_Ep> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT + : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {} - template , _Up>, - class = _EnableIfDeleterAssignable<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr& - operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { + template , _Up>, + class = _EnableIfDeleterAssignable<_Ep> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter()); return *this; @@ -480,85 +441,70 @@ unique_ptr& operator=(unique_ptr const&) = delete; #endif public: - _LIBCPP_INLINE_VISIBILITY - ~unique_ptr() { reset(); } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); } - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(nullptr_t) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { reset(); return *this; } - _LIBCPP_INLINE_VISIBILITY - typename add_lvalue_reference<_Tp>::type + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename add_lvalue_reference<_Tp>::type operator[](size_t __i) const { return __ptr_.first()[__i]; } - _LIBCPP_INLINE_VISIBILITY - pointer get() const _NOEXCEPT { - return __ptr_.first(); - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } - _LIBCPP_INLINE_VISIBILITY - deleter_type& get_deleter() _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY - const deleter_type& get_deleter() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY - explicit operator bool() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; } - _LIBCPP_INLINE_VISIBILITY - pointer release() _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer release() _NOEXCEPT { pointer __t = __ptr_.first(); __ptr_.first() = pointer(); return __t; } template - _LIBCPP_INLINE_VISIBILITY - typename enable_if< - _CheckArrayPointerConversion<_Pp>::value - >::type - reset(_Pp __p) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 + typename enable_if< _CheckArrayPointerConversion<_Pp>::value >::type + reset(_Pp __p) _NOEXCEPT { pointer __tmp = __ptr_.first(); __ptr_.first() = __p; if (__tmp) __ptr_.second()(__tmp); } - _LIBCPP_INLINE_VISIBILITY - void reset(nullptr_t = nullptr) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void reset(nullptr_t = nullptr) _NOEXCEPT { pointer __tmp = __ptr_.first(); __ptr_.first() = nullptr; if (__tmp) __ptr_.second()(__tmp); } - _LIBCPP_INLINE_VISIBILITY - void swap(unique_ptr& __u) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } - }; template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if< - __is_swappable<_Dp>::value, - void ->::type -swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 + typename enable_if< __is_swappable<_Dp>::value, void >::type + swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT { + __x.swap(__y); +} template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { + return __x.get() == __y.get(); +} #if _LIBCPP_STD_VER <= 17 template @@ -607,11 +553,9 @@ #endif template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT -{ - return !__x; +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { + return !__x; } #if _LIBCPP_STD_VER <= 17 @@ -641,76 +585,60 @@ #endif // _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) -{ - typedef typename unique_ptr<_T1, _D1>::pointer _P1; - return less<_P1>()(__x.get(), nullptr); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { + typedef typename unique_ptr<_T1, _D1>::pointer _P1; + return less<_P1>()(__x.get(), nullptr); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) -{ - typedef typename unique_ptr<_T1, _D1>::pointer _P1; - return less<_P1>()(nullptr, __x.get()); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { + typedef typename unique_ptr<_T1, _D1>::pointer _P1; + return less<_P1>()(nullptr, __x.get()); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) -{ - return nullptr < __x; +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { + return nullptr < __x; } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) -{ - return __x < nullptr; +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { + return __x < nullptr; } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) -{ - return !(nullptr < __x); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { + return !(nullptr < __x); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) -{ - return !(__x < nullptr); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { + return !(__x < nullptr); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) -{ - return !(__x < nullptr); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { + return !(__x < nullptr); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) -{ - return !(nullptr < __x); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool +operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { + return !(nullptr < __x); } #if _LIBCPP_STD_VER > 17 template -requires three_way_comparable::pointer> -_LIBCPP_HIDE_FROM_ABI -compare_three_way_result_t::pointer> + requires three_way_comparable< + typename unique_ptr<_T1, _D1>::pointer> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_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)); } @@ -736,21 +664,17 @@ typedef void __unique_array_known_bound; }; -template -inline _LIBCPP_INLINE_VISIBILITY -typename __unique_if<_Tp>::__unique_single -make_unique(_Args&&... __args) -{ - return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...)); +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_single +make_unique(_Args&&... __args) { + return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...)); } -template -inline _LIBCPP_INLINE_VISIBILITY -typename __unique_if<_Tp>::__unique_array_unknown_bound -make_unique(size_t __n) -{ - typedef typename remove_extent<_Tp>::type _Up; - return unique_ptr<_Tp>(new _Up[__n]()); +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound +make_unique(size_t __n) { + typedef typename remove_extent<_Tp>::type _Up; + return unique_ptr<_Tp>(new _Up[__n]()); } template Index: libcxx/include/memory =================================================================== --- libcxx/include/memory +++ 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,45 @@ // 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 + template + constexpr unique_ptr(unique_ptr && u) noexcept; // constexpr since C++23 + constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } // 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 + 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 - 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 +528,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 +563,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 Index: libcxx/include/version =================================================================== --- libcxx/include/version +++ libcxx/include/version @@ -62,7 +62,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 @@ -384,6 +385,8 @@ # define __cpp_lib_byteswap 202110L # define __cpp_lib_constexpr_bitset 202207L // # 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_forward_like 202207L // # define __cpp_lib_invoke_r 202106L Index: libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp +++ 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] @@ -448,8 +449,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 Index: libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -59,6 +59,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] @@ -3950,8 +3951,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 Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp @@ -31,7 +31,7 @@ }; template -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional::type VT; { typedef std::unique_ptr P; @@ -54,9 +54,18 @@ #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_basic(); test_basic(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp @@ -33,34 +33,40 @@ }; template -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 5 : 1; { std::unique_ptr s1(newValue(expect_alive)); A* p = s1.get(); std::unique_ptr s2(newValue(expect_alive)); - assert(A::count == (expect_alive * 2)); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == (expect_alive * 2)); s2 = std::move(s1); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); assert(s2.get() == p); assert(s1.get() == 0); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { std::unique_ptr > s1(newValue(expect_alive), Deleter(5)); A* p = s1.get(); std::unique_ptr > s2(newValue(expect_alive)); - assert(A::count == (expect_alive * 2)); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == (expect_alive * 2)); s2 = std::move(s1); assert(s2.get() == p); assert(s1.get() == 0); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); assert(s2.get_deleter().state() == 5); assert(s1.get_deleter().state() == 0); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { CDeleter d1(5); std::unique_ptr&> s1(newValue(expect_alive), d1); @@ -70,23 +76,27 @@ s2 = std::move(s1); assert(s2.get() == p); assert(s1.get() == 0); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); assert(d1.state() == 5); assert(d2.state() == 5); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { std::unique_ptr s(newValue(expect_alive)); A* p = s.get(); s = std::move(s); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); assert(s.get() == p); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } template -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { typedef typename std::conditional::type VT; { typedef std::unique_ptr U; @@ -118,8 +128,7 @@ } } - -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_basic(); test_sfinae(); @@ -129,5 +138,14 @@ test_sfinae(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp @@ -23,21 +23,20 @@ template struct GenericDeleter { - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; template struct GenericConvertingDeleter { - template - GenericConvertingDeleter(GenericConvertingDeleter) {} + TEST_CONSTEXPR_CXX23 GenericConvertingDeleter(GenericConvertingDeleter) {} template - GenericConvertingDeleter& operator=(GenericConvertingDeleter const&) { + TEST_CONSTEXPR_CXX23 GenericConvertingDeleter& operator=(GenericConvertingDeleter const&) { return *this; } - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; template @@ -156,9 +155,9 @@ template struct AssignDeleter { - AssignDeleter() = default; - AssignDeleter(AssignDeleter const&) = default; - AssignDeleter(AssignDeleter&&) = default; + TEST_CONSTEXPR_CXX23 AssignDeleter() = default; + TEST_CONSTEXPR_CXX23 AssignDeleter(AssignDeleter const&) = default; + TEST_CONSTEXPR_CXX23 AssignDeleter(AssignDeleter&&) = default; AssignDeleter& operator=(AssignDeleter const&) = delete; AssignDeleter& operator=(AssignDeleter &&) = delete; @@ -166,34 +165,34 @@ template AssignDeleter& operator=(T&&) && = delete; template AssignDeleter& operator=(T&&) const && = delete; - template ::value && !AssignIsConst - >::type> - AssignDeleter& operator=(T&&) & { return *this; } + template ::value && !AssignIsConst >::type> + TEST_CONSTEXPR_CXX23 AssignDeleter& operator=(T&&) & { + return *this; + } - template ::value && AssignIsConst - >::type> - const AssignDeleter& operator=(T&&) const & { return *this; } + template ::value && AssignIsConst >::type> + TEST_CONSTEXPR_CXX23 const AssignDeleter& operator=(T&&) const& { + return *this; + } template - void operator()(T) const {} + TEST_CONSTEXPR_CXX23 void operator()(T) const {} }; template - void doDeleterTest() { - using U1 = std::unique_ptr; - using U2 = std::unique_ptr; - static_assert(std::is_nothrow_assignable::value, ""); - typename std::decay::type ddest; - typename std::decay::type dsource; - U1 u1(nullptr, ddest); - U2 u2(nullptr, dsource); - u1 = std::move(u2); +TEST_CONSTEXPR_CXX23 void doDeleterTest() { + using U1 = std::unique_ptr; + using U2 = std::unique_ptr; + static_assert(std::is_nothrow_assignable::value, ""); + typename std::decay::type ddest; + typename std::decay::type dsource; + U1 u1(nullptr, ddest); + U2 u2(nullptr, dsource); + u1 = std::move(u2); } template -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { typedef typename std::conditional::type VT; { // Test that different non-reference deleter types are allowed so long @@ -281,9 +280,8 @@ } } - template -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { typedef typename std::conditional::type VT; { typedef std::unique_ptr APtr; @@ -405,17 +403,28 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_sfinae(); test_noexcept(); - test_deleter_value_category(); + if (!TEST_IS_CONSTANT_EVALUATED) + test_deleter_value_category(); } { test_sfinae(); test_noexcept(); - test_deleter_value_category(); + if (!TEST_IS_CONSTANT_EVALUATED) + test_deleter_value_category(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp @@ -23,55 +23,58 @@ #include "unique_ptr_test_helper.h" template -void testAssign(APtr& aptr, BPtr& bptr) { +TEST_CONSTEXPR_CXX23 void testAssign(APtr& aptr, BPtr& bptr) { A* p = bptr.get(); - assert(A::count == 2); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 2); aptr = std::move(bptr); assert(aptr.get() == p); assert(bptr.get() == 0); - assert(A::count == 1); - assert(B::count == 1); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 1); + assert(B::count == 1); + } } template -void checkDeleter(LHS& lhs, RHS& rhs, int LHSState, int RHSState) { +TEST_CONSTEXPR_CXX23 void checkDeleter(LHS& lhs, RHS& rhs, int LHSState, int RHSState) { assert(lhs.get_deleter().state() == LHSState); assert(rhs.get_deleter().state() == RHSState); } template struct NCConvertingDeleter { - NCConvertingDeleter() = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; - NCConvertingDeleter(NCConvertingDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default; template - NCConvertingDeleter(NCConvertingDeleter&&) {} + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) {} - void operator()(T*) const {} + TEST_CONSTEXPR_CXX23 void operator()(T*) const {} }; template struct NCConvertingDeleter { - NCConvertingDeleter() = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; - NCConvertingDeleter(NCConvertingDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default; template - NCConvertingDeleter(NCConvertingDeleter&&) {} + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) {} - void operator()(T*) const {} + TEST_CONSTEXPR_CXX23 void operator()(T*) const {} }; struct NCGenericDeleter { - NCGenericDeleter() = default; + TEST_CONSTEXPR_CXX23 NCGenericDeleter() = default; NCGenericDeleter(NCGenericDeleter const&) = delete; - NCGenericDeleter(NCGenericDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCGenericDeleter(NCGenericDeleter&&) = default; - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { using DA = NCConvertingDeleter; // non-copyable deleters using DB = NCConvertingDeleter; using UA = std::unique_ptr; @@ -114,15 +117,17 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_sfinae(); { std::unique_ptr bptr(new B); std::unique_ptr aptr(new A); testAssign(aptr, bptr); } - assert(A::count == 0); - assert(B::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); + } { Deleter del(42); std::unique_ptr > bptr(new B, std::move(del)); @@ -130,8 +135,10 @@ testAssign(aptr, bptr); checkDeleter(aptr, bptr, 42, 0); } - assert(A::count == 0); - assert(B::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); + } { CDeleter adel(6); CDeleter bdel(42); @@ -140,8 +147,19 @@ testAssign(aptr, bptr); checkDeleter(aptr, bptr, 42, 42); } - assert(A::count == 0); - assert(B::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); + } + + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp @@ -20,22 +20,34 @@ // test assignment from null template -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 5 : 1; { std::unique_ptr s2(newValue(expect_alive)); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); s2 = NULL; - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); assert(s2.get() == 0); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_basic(); test_basic(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp @@ -21,22 +21,34 @@ // test assignment from null template -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 5 : 1; { std::unique_ptr s2(newValue(expect_alive)); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); s2 = nullptr; - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); assert(s2.get() == 0); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_basic(); test_basic(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp @@ -15,9 +15,9 @@ // The following constructors should not be selected by class template argument // deduction: // -// explicit unique_ptr(pointer p) -// unique_ptr(pointer p, const D& d) noexcept -// unique_ptr(pointer p, remove_reference_t&& d) noexcept +// constexpr explicit unique_ptr(pointer p) // constexpr since C++23 +// constexpr unique_ptr(pointer p, const D& d) noexcept // constexpr since C++23 +// constexpr unique_ptr(pointer p, remove_reference_t&& d) noexcept // constexpr since C++23 #include Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp @@ -36,12 +36,12 @@ struct NonDefaultDeleter { NonDefaultDeleter() = delete; - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; #endif template -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { #if TEST_STD_VER >= 11 { // the constructor does not participate in overload resolution when // the deleter is a pointer type @@ -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({ @@ -97,7 +99,7 @@ doIncompleteTypeTest >(0); }) -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_sfinae(); test_basic(); @@ -107,5 +109,14 @@ test_basic(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp @@ -38,12 +38,12 @@ // 'sink' should accept the unique_ptr by value. (C-1,2,4) template -std::unique_ptr source1() { +TEST_CONSTEXPR_CXX23 std::unique_ptr source1() { return std::unique_ptr(newValue(1)); } template -std::unique_ptr > source2() { +TEST_CONSTEXPR_CXX23 std::unique_ptr > source2() { return std::unique_ptr >(newValue(1), Deleter(5)); } @@ -54,12 +54,12 @@ } template -void sink1(std::unique_ptr p) { +TEST_CONSTEXPR_CXX23 void sink1(std::unique_ptr p) { assert(p.get() != nullptr); } template -void sink2(std::unique_ptr > p) { +TEST_CONSTEXPR_CXX23 void sink2(std::unique_ptr > p) { assert(p.get() != nullptr); assert(p.get_deleter().state() == 5); } @@ -72,7 +72,7 @@ } template -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { typedef std::unique_ptr U; { // Ensure unique_ptr is non-copyable static_assert((!std::is_constructible::value), ""); @@ -81,7 +81,7 @@ } template -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 5 : 1; { @@ -91,9 +91,11 @@ APtr s2 = std::move(s); assert(s2.get() == p); assert(s.get() == 0); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { typedef Deleter MoveDel; typedef std::unique_ptr APtr; @@ -105,11 +107,13 @@ APtr s2 = std::move(s); assert(s2.get() == p); assert(s.get() == 0); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); assert(s2.get_deleter().state() == 5); assert(s.get_deleter().state() == 0); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { typedef NCDeleter NonCopyDel; typedef std::unique_ptr APtr; @@ -120,25 +124,28 @@ APtr s2 = std::move(s); assert(s2.get() == p); assert(s.get() == 0); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); d.set_state(6); assert(s2.get_deleter().state() == d.state()); assert(s.get_deleter().state() == d.state()); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { sink1(source1()); - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); sink2(source2()); - assert(A::count == 0); - sink3(source3()); - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } template -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { #if TEST_STD_VER >= 11 { typedef std::unique_ptr U; @@ -159,7 +166,7 @@ #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_basic(); test_sfinae(); @@ -171,5 +178,23 @@ test_noexcept(); } + return true; +} + +template +void test_sink3() { + typedef typename std::conditional::type VT; + sink3(source3()); + assert(A::count == 0); +} + +int main(int, char**) { + test_sink3(); + test_sink3(); + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp @@ -23,14 +23,14 @@ template struct GenericDeleter { - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; template struct GenericConvertingDeleter { template - GenericConvertingDeleter(GenericConvertingDeleter) {} - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 GenericConvertingDeleter(GenericConvertingDeleter) {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; template @@ -50,37 +50,35 @@ template struct TrackingDeleter { - TrackingDeleter() : arg_type(&makeArgumentID<>()) {} + TEST_CONSTEXPR_CXX23 TrackingDeleter() : arg_type(&makeArgumentID<>()) {} - TrackingDeleter(TrackingDeleter const&) - : arg_type(&makeArgumentID()) {} + TEST_CONSTEXPR_CXX23 TrackingDeleter(TrackingDeleter const&) : arg_type(&makeArgumentID()) {} - TrackingDeleter(TrackingDeleter&&) - : arg_type(&makeArgumentID()) {} + TEST_CONSTEXPR_CXX23 TrackingDeleter(TrackingDeleter&&) : arg_type(&makeArgumentID()) {} template > - TrackingDeleter(T&&) : arg_type(&makeArgumentID()) {} + TEST_CONSTEXPR_CXX23 TrackingDeleter(T&&) : arg_type(&makeArgumentID()) {} - TrackingDeleter& operator=(TrackingDeleter const&) { + TEST_CONSTEXPR_CXX23 TrackingDeleter& operator=(TrackingDeleter const&) { arg_type = &makeArgumentID(); return *this; } - TrackingDeleter& operator=(TrackingDeleter &&) { + TEST_CONSTEXPR_CXX23 TrackingDeleter& operator=(TrackingDeleter&&) { arg_type = &makeArgumentID(); return *this; } template > - TrackingDeleter& operator=(T&&) { + TEST_CONSTEXPR_CXX23 TrackingDeleter& operator=(T&&) { arg_type = &makeArgumentID(); return *this; } - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} public: - TypeID const* reset() const { + TEST_CONSTEXPR_CXX23 TypeID const* reset() const { TypeID const* tmp = arg_type; arg_type = nullptr; return tmp; @@ -95,9 +93,8 @@ return d.arg_type && *d.arg_type == makeArgumentID(); } - template -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { typedef typename std::conditional::type VT; { // Test that different non-reference deleter types are allowed so long @@ -144,9 +141,8 @@ } } - template -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { typedef typename std::conditional::type VT; { typedef std::unique_ptr APtr; @@ -170,9 +166,8 @@ } } - template -void test_deleter_value_category() { +TEST_CONSTEXPR_CXX23 void test_deleter_value_category() { typedef typename std::conditional::type VT; using TD1 = TrackingDeleter<1>; using TD2 = TrackingDeleter<2>; @@ -203,18 +198,28 @@ } } - -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_sfinae(); test_noexcept(); - test_deleter_value_category(); + if (!TEST_IS_CONSTANT_EVALUATED) + test_deleter_value_category(); } { test_sfinae(); test_noexcept(); - test_deleter_value_category(); + if (!TEST_IS_CONSTANT_EVALUATED) + test_deleter_value_category(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp @@ -33,7 +33,7 @@ void operator()(void*) const {} }; -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { { // Disallow copying using U1 = std::unique_ptr >; using U2 = std::unique_ptr >; @@ -77,9 +77,17 @@ } } +TEST_CONSTEXPR_CXX23 bool test() { + test_sfinae(); + + return true; +} int main(int, char**) { - test_sfinae(); + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp @@ -29,7 +29,7 @@ // Explicit version template -void checkReferenceDeleter(LHS& lhs, RHS& rhs) { +TEST_CONSTEXPR_CXX23 void checkReferenceDeleter(LHS& lhs, RHS& rhs) { typedef typename LHS::deleter_type NewDel; static_assert(std::is_reference::value, ""); rhs.get_deleter().set_state(42); @@ -41,57 +41,61 @@ } template -void checkDeleter(LHS& lhs, RHS& rhs, int LHSVal, int RHSVal) { +TEST_CONSTEXPR_CXX23 void checkDeleter(LHS& lhs, RHS& rhs, int LHSVal, int RHSVal) { assert(lhs.get_deleter().state() == LHSVal); assert(rhs.get_deleter().state() == RHSVal); } template -void checkCtor(LHS& lhs, RHS& rhs, A* RHSVal) { +TEST_CONSTEXPR_CXX23 void checkCtor(LHS& lhs, RHS& rhs, A* RHSVal) { assert(lhs.get() == RHSVal); assert(rhs.get() == nullptr); - assert(A::count == 1); - assert(B::count == 1); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 1); + assert(B::count == 1); + } } -void checkNoneAlive() { - assert(A::count == 0); - assert(B::count == 0); +TEST_CONSTEXPR_CXX23 void checkNoneAlive() { + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); + } } template struct NCConvertingDeleter { - NCConvertingDeleter() = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; - NCConvertingDeleter(NCConvertingDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default; template - NCConvertingDeleter(NCConvertingDeleter&&) {} + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) {} - void operator()(T*) const {} + TEST_CONSTEXPR_CXX23 void operator()(T*) const {} }; template struct NCConvertingDeleter { - NCConvertingDeleter() = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; - NCConvertingDeleter(NCConvertingDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default; template - NCConvertingDeleter(NCConvertingDeleter&&) {} + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) {} - void operator()(T*) const {} + TEST_CONSTEXPR_CXX23 void operator()(T*) const {} }; struct NCGenericDeleter { - NCGenericDeleter() = default; + TEST_CONSTEXPR_CXX23 NCGenericDeleter() = default; NCGenericDeleter(NCGenericDeleter const&) = delete; - NCGenericDeleter(NCGenericDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCGenericDeleter(NCGenericDeleter&&) = default; - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { using DA = NCConvertingDeleter; // non-copyable deleters using DB = NCConvertingDeleter; using UA = std::unique_ptr; @@ -134,7 +138,7 @@ } } -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { { typedef std::unique_ptr APtr; typedef std::unique_ptr BPtr; @@ -157,7 +161,7 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_sfinae(); test_noexcept(); @@ -245,5 +249,14 @@ checkNoneAlive(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp +++ 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 void test_pointer_ctor() { { std::unique_ptr p(0); assert(p.get() == 0); @@ -36,7 +36,7 @@ } template -void test_pointer_deleter_ctor() { +TEST_CONSTEXPR_CXX23 void test_pointer_deleter_ctor() { { std::default_delete d; std::unique_ptr p(0, d); @@ -61,7 +61,7 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { // test_pointer_ctor(); test_pointer_deleter_ctor(); @@ -71,5 +71,14 @@ test_pointer_deleter_ctor(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp @@ -10,7 +10,7 @@ // unique_ptr -// unique_ptr(nullptr_t); +// constexpr unique_ptr(nullptr_t); // constexpr since C++23 #include #include @@ -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 void 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 { @@ -58,7 +55,7 @@ } template -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { #if TEST_STD_VER >= 11 { // the constructor does not participate in overload resolution when // the deleter is a pointer type @@ -68,9 +65,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_constructible::value, ""); static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); @@ -81,21 +78,15 @@ 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); }) -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_basic(); test_sfinae(); @@ -105,5 +96,14 @@ test_sfinae(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp @@ -37,7 +37,7 @@ // unique_ptr(pointer) ctor should only require default Deleter ctor template -void test_pointer() { +TEST_CONSTEXPR_CXX23 void test_pointer() { typedef typename std::conditional::type ValueT; const int expect_alive = IsArray ? 5 : 1; #if TEST_STD_VER >= 11 @@ -56,49 +56,66 @@ #endif { A* p = newValue(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); + std::unique_ptr s(p); assert(s.get() == p); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { A* p = newValue(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); + std::unique_ptr > s(p); assert(s.get() == p); assert(s.get_deleter().state() == 0); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { A* p = newValue(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); + std::unique_ptr > s(p); assert(s.get() == p); assert(s.get_deleter().state() == 0); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } -void test_derived() { +TEST_CONSTEXPR_CXX23 void test_derived() { { B* p = new B; - assert(A::count == 1); - assert(B::count == 1); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 1); + assert(B::count == 1); + } std::unique_ptr s(p); assert(s.get() == p); } - assert(A::count == 0); - assert(B::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); + } { B* p = new B; - assert(A::count == 1); - assert(B::count == 1); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 1); + assert(B::count == 1); + } std::unique_ptr > s(p); assert(s.get() == p); assert(s.get_deleter().state() == 0); } - assert(A::count == 0); - assert(B::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); + } } #if TEST_STD_VER >= 11 @@ -113,7 +130,7 @@ #endif template -void test_sfinae() { +void TEST_CONSTEXPR_CXX23 test_sfinae() { #if TEST_STD_VER >= 11 { // the constructor does not participate in overload resolution when // the deleter is a pointer type @@ -133,7 +150,7 @@ #endif } -static void test_sfinae_runtime() { +static TEST_CONSTEXPR_CXX23 void test_sfinae_runtime() { #if TEST_STD_VER >= 11 { // the constructor does not participate in overload resolution when // a base <-> derived conversion would occur. @@ -164,7 +181,7 @@ checkNumIncompleteTypeAlive(0); }) -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_pointer(); test_derived(); @@ -176,5 +193,14 @@ test_sfinae_runtime(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp @@ -34,25 +34,25 @@ #if TEST_STD_VER >= 11 struct DeleterBase { - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; struct CopyOnlyDeleter : DeleterBase { - CopyOnlyDeleter() = default; - CopyOnlyDeleter(CopyOnlyDeleter const&) = default; + TEST_CONSTEXPR_CXX23 CopyOnlyDeleter() = default; + TEST_CONSTEXPR_CXX23 CopyOnlyDeleter(CopyOnlyDeleter const&) = default; CopyOnlyDeleter(CopyOnlyDeleter&&) = delete; }; struct MoveOnlyDeleter : DeleterBase { - MoveOnlyDeleter() = default; - MoveOnlyDeleter(MoveOnlyDeleter&&) = default; + TEST_CONSTEXPR_CXX23 MoveOnlyDeleter() = default; + TEST_CONSTEXPR_CXX23 MoveOnlyDeleter(MoveOnlyDeleter&&) = default; }; struct NoCopyMoveDeleter : DeleterBase { - NoCopyMoveDeleter() = default; + TEST_CONSTEXPR_CXX23 NoCopyMoveDeleter() = default; NoCopyMoveDeleter(NoCopyMoveDeleter const&) = delete; }; #endif template -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { #if TEST_STD_VER >= 11 typedef typename std::conditional::type VT; { @@ -102,7 +102,7 @@ } template -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { #if TEST_STD_VER >= 11 typedef typename std::conditional::type VT; { @@ -133,7 +133,7 @@ #endif } -void test_sfinae_runtime() { +TEST_CONSTEXPR_CXX23 void test_sfinae_runtime() { #if TEST_STD_VER >= 11 { using D = CopyOnlyDeleter; @@ -204,20 +204,23 @@ } template -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 5 : 1; { // MoveConstructible deleter (C-1) A* p = newValue(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); std::unique_ptr > s(p, Deleter(5)); assert(s.get() == p); assert(s.get_deleter().state() == 5); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { // CopyConstructible deleter (C-2) A* p = newValue(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); CopyDeleter d(5); std::unique_ptr > s(p, d); assert(s.get() == p); @@ -225,10 +228,12 @@ d.set_state(6); assert(s.get_deleter().state() == 5); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { // Reference deleter (C-3) A* p = newValue(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); NCDeleter d(5); std::unique_ptr&> s(p, d); assert(s.get() == p); @@ -237,59 +242,70 @@ d.set_state(6); assert(s.get_deleter().state() == 6); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { // Const Reference deleter (C-4) A* p = newValue(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); NCConstDeleter d(5); std::unique_ptr const&> s(p, d); assert(s.get() == p); assert(s.get_deleter().state() == 5); assert(&s.get_deleter() == &d); } - assert(A::count == 0); - { // Void and function pointers (C-6,7) - typedef typename std::conditional::type VT2; - my_free_called = false; - { - int i = 0; - std::unique_ptr s(&i, my_free); - assert(s.get() == &i); - assert(s.get_deleter() == my_free); - assert(!my_free_called); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + { // Void and function pointers (C-6,7) + typedef typename std::conditional::type VT2; + my_free_called = false; + { + int i = 0; + std::unique_ptr s(&i, my_free); + assert(s.get() == &i); + assert(s.get_deleter() == my_free); + assert(!my_free_called); + } + assert(my_free_called); } - assert(my_free_called); } } -void test_basic_single() { - assert(A::count == 0); - assert(B::count == 0); +TEST_CONSTEXPR_CXX23 void test_basic_single() { + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); + } { // Derived pointers (C-5) B* p = new B; - assert(A::count == 1); - assert(B::count == 1); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 1); + assert(B::count == 1); + } std::unique_ptr > s(p, Deleter(5)); assert(s.get() == p); assert(s.get_deleter().state() == 5); } - assert(A::count == 0); - assert(B::count == 0); - { // Void and function pointers (C-6,7) - my_free_called = false; - { - int i = 0; - std::unique_ptr s(&i, my_free); - assert(s.get() == &i); - assert(s.get_deleter() == my_free); - assert(!my_free_called); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); + + { // Void and function pointers (C-6,7) + my_free_called = false; + { + int i = 0; + std::unique_ptr s(&i, my_free); + assert(s.get() == &i); + assert(s.get_deleter() == my_free); + assert(!my_free_called); + } + assert(my_free_called); } - assert(my_free_called); } } template -void test_nullptr() { +TEST_CONSTEXPR_CXX23 void test_nullptr() { #if TEST_STD_VER >= 11 typedef typename std::conditional::type VT; { @@ -309,7 +325,7 @@ #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_basic(); test_nullptr(); @@ -325,5 +341,14 @@ test_noexcept(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp +++ 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 void test_basic() { Deleter d; assert(d.state() == 0); { @@ -43,9 +43,18 @@ assert(d.state() == 0); } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_basic(); test_basic(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp @@ -19,7 +19,7 @@ #include "unique_ptr_test_helper.h" template -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 3 : 1; #if TEST_STD_VER >= 11 @@ -31,10 +31,12 @@ #endif { std::unique_ptr p(newValue(expect_alive)); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); A* ap = p.get(); A* a = p.release(); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); assert(p.get() == nullptr); assert(ap == a); assert(a != nullptr); @@ -44,14 +46,25 @@ else delete a; - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_basic(); test_basic(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp @@ -19,90 +19,106 @@ #include "unique_ptr_test_helper.h" template -void test_reset_pointer() { +TEST_CONSTEXPR_CXX23 void test_reset_pointer() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 3 : 1; #if TEST_STD_VER >= 11 { using U = std::unique_ptr; - U u; ((void)u); + U u; + ((void)u); ASSERT_NOEXCEPT(u.reset((A*)nullptr)); } #endif { std::unique_ptr p(newValue(expect_alive)); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); A* i = p.get(); assert(i != nullptr); A* new_value = newValue(expect_alive); - assert(A::count == (expect_alive * 2)); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == (expect_alive * 2)); p.reset(new_value); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); assert(p.get() == new_value); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { std::unique_ptr p(newValue(expect_alive)); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); const A* i = p.get(); assert(i != nullptr); A* new_value = newValue(expect_alive); - assert(A::count == (expect_alive * 2)); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == (expect_alive * 2)); p.reset(new_value); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); assert(p.get() == new_value); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } template -void test_reset_nullptr() { +TEST_CONSTEXPR_CXX23 void test_reset_nullptr() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 3 : 1; #if TEST_STD_VER >= 11 { using U = std::unique_ptr; - U u; ((void)u); + U u; + ((void)u); ASSERT_NOEXCEPT(u.reset(nullptr)); } #endif { std::unique_ptr p(newValue(expect_alive)); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); A* i = p.get(); assert(i != nullptr); p.reset(nullptr); - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); assert(p.get() == nullptr); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } - template -void test_reset_no_arg() { +TEST_CONSTEXPR_CXX23 void test_reset_no_arg() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 3 : 1; #if TEST_STD_VER >= 11 { using U = std::unique_ptr; - U u; ((void)u); + U u; + ((void)u); ASSERT_NOEXCEPT(u.reset()); } #endif { std::unique_ptr p(newValue(expect_alive)); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); A* i = p.get(); assert(i != nullptr); p.reset(); - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); assert(p.get() == nullptr); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_reset_pointer(); test_reset_nullptr(); @@ -114,5 +130,14 @@ test_reset_no_arg(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp @@ -18,31 +18,52 @@ #include "test_macros.h" #include "unique_ptr_test_helper.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { std::unique_ptr p(new A); - assert(A::count == 1); - assert(B::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 1); + assert(B::count == 0); + } A* i = p.get(); assert(i != nullptr); p.reset(new B); - assert(A::count == 1); - assert(B::count == 1); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 1); + assert(B::count == 1); + } + } + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); } - assert(A::count == 0); - assert(B::count == 0); { std::unique_ptr p(new B); - assert(A::count == 1); - assert(B::count == 1); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 1); + assert(B::count == 1); + } A* i = p.get(); assert(i != nullptr); p.reset(new B); - assert(A::count == 1); - assert(B::count == 1); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 1); + assert(B::count == 1); + } + } + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(A::count == 0); + assert(B::count == 0); } - assert(A::count == 0); - assert(B::count == 0); + + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp @@ -19,10 +19,21 @@ 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; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp @@ -21,25 +21,34 @@ struct TT { int state_; static int count; - TT() : state_(-1) { ++count; } - explicit TT(int i) : state_(i) { ++count; } - TT(const TT& a) : state_(a.state_) { ++count; } - TT& operator=(const TT& a) { + TEST_CONSTEXPR_CXX23 TT() : state_(-1) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 explicit TT(int i) : state_(i) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 TT(const TT& a) : state_(a.state_) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 TT& operator=(const TT& a) { state_ = a.state_; return *this; } - ~TT() { --count; } - - friend bool operator==(const TT& x, const TT& y) { - return x.state_ == y.state_; + TEST_CONSTEXPR_CXX23 ~TT() { + if (!TEST_IS_CONSTANT_EVALUATED) + --count; } + + friend TEST_CONSTEXPR_CXX23 bool operator==(const TT& x, const TT& y) { return x.state_ == y.state_; } }; int TT::count = 0; template -typename std::remove_all_extents::type* newValueInit(int size, - int new_value) { +TEST_CONSTEXPR_CXX23 typename std::remove_all_extents::type* newValueInit(int size, int new_value) { typedef typename std::remove_all_extents::type VT; VT* p = newValue(size); for (int i = 0; i < size; ++i) @@ -48,7 +57,7 @@ } template -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional::type VT; const int expect_alive = IsArray ? 5 : 1; #if TEST_STD_VER >= 11 @@ -76,14 +85,25 @@ assert(s2.get() == p1); assert(*s2.get() == TT(1)); assert(s2.get_deleter().state() == 1); - assert(TT::count == (expect_alive * 2)); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(TT::count == (expect_alive * 2)); } - assert(TT::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(TT::count == 0); } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_basic(); test_basic(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp @@ -17,9 +17,18 @@ #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; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp @@ -10,7 +10,7 @@ // unique_ptr -// test op*() +// test constexpr explicit operator bool() const noexcept; // constexpr since C++23 #include #include @@ -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 void test_basic() { typedef typename std::conditional::type VT; typedef std::unique_ptr U; { @@ -59,9 +59,18 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_basic(); test_basic(); - return 0; + return true; } + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + + return 0; +} \ No newline at end of file Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp +++ 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 void test_basic() { typedef typename std::conditional::type VT; typedef const VT CVT; { @@ -44,9 +44,18 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_basic(); test_basic(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp +++ 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 void test_basic() { typedef typename std::conditional::type VT; { std::unique_ptr p; @@ -58,9 +58,18 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_basic(); test_basic(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp +++ 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; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp @@ -22,12 +22,16 @@ static int next_; public: - A() : state_(++next_) {} - int get() const { return state_; } + TEST_CONSTEXPR_CXX23 A() : state_(0) { + if (!TEST_IS_CONSTANT_EVALUATED) + state_ = ++next_; + } + + TEST_CONSTEXPR_CXX23 int get() const { return state_; } - friend bool operator==(const A& x, int y) { return x.state_ == y; } + friend TEST_CONSTEXPR_CXX23 bool operator==(const A& x, int y) { return x.state_ == y; } - A& operator=(int i) { + TEST_CONSTEXPR_CXX23 A& operator=(int i) { state_ = i; return *this; } @@ -35,11 +39,13 @@ int A::next_ = 0; -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { std::unique_ptr p(new A[3]); - assert(p[0] == 1); - assert(p[1] == 2); - assert(p[2] == 3); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(p[0] == 1); + assert(p[1] == 2); + assert(p[2] == 3); + } p[0] = 3; p[1] = 2; p[2] = 1; @@ -47,5 +53,14 @@ assert(p[1] == 2); assert(p[2] == 1); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp @@ -17,31 +17,40 @@ 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; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp @@ -13,23 +13,31 @@ #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; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp @@ -41,5 +41,6 @@ assert(p != nullptr); } #endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp @@ -10,42 +10,38 @@ // default_delete +// convert constructor + #include #include #include "test_macros.h" +#include "unique_ptr_test_helper.h" -struct A -{ - static int count; - A() {++count;} - A(const A&) {++count;} - virtual ~A() {--count;} -}; - -int A::count = 0; - -struct B - : public A -{ - static int count; - B() {++count;} - B(const B& other) : A(other) {++count;} - virtual ~B() {--count;} -}; - -int B::count = 0; - -int main(int, char**) -{ - std::default_delete d2; - std::default_delete d1 = d2; - A* p = new B; +TEST_CONSTEXPR_CXX23 bool test() { + std::default_delete d2; + std::default_delete d1 = d2; + A* p = new B; + if (!TEST_IS_CONSTANT_EVALUATED) { assert(A::count == 1); assert(B::count == 1); - d1(p); + } + + d1(p); + + if (!TEST_IS_CONSTANT_EVALUATED) { assert(A::count == 0); assert(B::count == 0); + } + + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp @@ -14,24 +14,27 @@ #include #include "test_macros.h" +#include "unique_ptr_test_helper.h" -struct A -{ - static int count; - A() {++count;} - A(const A&) {++count;} - ~A() {--count;} -}; +TEST_CONSTEXPR_CXX23 bool test() { + std::default_delete d; + A* p = new A; + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 1); -int A::count = 0; + d(p); -int main(int, char**) -{ - std::default_delete d; - A* p = new A; - assert(A::count == 1); - d(p); + if (!TEST_IS_CONSTANT_EVALUATED) assert(A::count == 0); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp +++ 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,19 @@ #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 true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp @@ -16,24 +16,27 @@ #include #include "test_macros.h" +#include "unique_ptr_test_helper.h" -struct A -{ - static int count; - A() {++count;} - A(const A&) {++count;} - ~A() {--count;} -}; +TEST_CONSTEXPR_CXX23 bool test() { + std::default_delete d; + A* p = new A[3]; + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 3); -int A::count = 0; + d(p); -int main(int, char**) -{ - std::default_delete d; - A* p = new A[3]; - assert(A::count == 3); - d(p); + if (!TEST_IS_CONSTANT_EVALUATED) assert(A::count == 0); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp @@ -0,0 +1,13 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// Includes Microsoft's test that tests the entire header. + +#include "test.cpp" Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp =================================================================== --- /dev/null +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp @@ -0,0 +1,128 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +#include "test_macros.h" + +using namespace std; + +struct Dummy { + constexpr int test() const { return 10; } +}; + +constexpr 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 = std::move(p3); + auto p5 = unique_ptr{nullptr}; + auto p6 = unique_ptr&>{new int{}, d1}; + auto p7 = unique_ptr{std::move(p6)}; + + // assignment + p3 = std::move(p4); + auto p8 = unique_ptr&>{new int{}, d1}; + p7 = std::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 = std::move(p1); + auto p5 = unique_ptr&>{new int[5], d1}; + auto p6 = unique_ptr{std::move(p5)}; + + // assignment + p1 = std::move(p4); + auto p7 = unique_ptr&>{new int[5], d1}; + p6 = std::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()); + +int main() {} // COMPILE-ONLY Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp @@ -47,26 +47,9 @@ #include "test_macros.h" #include "deleter_types.h" #include "test_comparisons.h" +#include "unique_ptr_test_helper.h" -struct A { - static int count; - A() { ++count; } - A(const A&) { ++count; } - virtual ~A() { --count; } -}; - -int A::count = 0; - -struct B : public A { - static int count; - B() { ++count; } - B(const B& other) : A(other) { ++count; } - virtual ~B() { --count; } -}; - -int B::count = 0; - -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { AssertComparisonsReturnBool >(); #if TEST_STD_VER > 17 AssertOrderReturn>(); @@ -81,14 +64,16 @@ assert(!(p1 == p2)); assert(p1 != p2); - assert((p1 < p2) == (ptr1 < ptr2)); - assert((p1 <= p2) == (ptr1 <= ptr2)); - assert((p1 > p2) == (ptr1 > ptr2)); - assert((p1 >= p2) == (ptr1 >= ptr2)); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert((p1 < p2) == (ptr1 < ptr2)); + assert((p1 <= p2) == (ptr1 <= ptr2)); + assert((p1 > p2) == (ptr1 > ptr2)); + assert((p1 >= p2) == (ptr1 >= ptr2)); #if TEST_STD_VER > 17 - assert((p1 <=> p2) != std::strong_ordering::equal); - assert((p1 <=> p2) == (ptr1 <=> ptr2)); + assert((p1 <=> p2) != std::strong_ordering::equal); + assert((p1 <=> p2) == (ptr1 <=> ptr2)); #endif + } } // Pointers of different type { @@ -98,14 +83,16 @@ const std::unique_ptr > p2(ptr2); assert(!(p1 == p2)); assert(p1 != p2); - assert((p1 < p2) == (ptr1 < ptr2)); - assert((p1 <= p2) == (ptr1 <= ptr2)); - assert((p1 > p2) == (ptr1 > ptr2)); - assert((p1 >= p2) == (ptr1 >= ptr2)); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert((p1 < p2) == (ptr1 < ptr2)); + assert((p1 <= p2) == (ptr1 <= ptr2)); + assert((p1 > p2) == (ptr1 > ptr2)); + assert((p1 >= p2) == (ptr1 >= ptr2)); #if TEST_STD_VER > 17 assert((p1 <=> p2) != std::strong_ordering::equal); assert((p1 <=> p2) == (ptr1 <=> ptr2)); #endif + } } // Pointers of same array type { @@ -115,14 +102,16 @@ const std::unique_ptr > p2(ptr2); assert(!(p1 == p2)); assert(p1 != p2); - assert((p1 < p2) == (ptr1 < ptr2)); - assert((p1 <= p2) == (ptr1 <= ptr2)); - assert((p1 > p2) == (ptr1 > ptr2)); - assert((p1 >= p2) == (ptr1 >= ptr2)); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert((p1 < p2) == (ptr1 < ptr2)); + assert((p1 <= p2) == (ptr1 <= ptr2)); + assert((p1 > p2) == (ptr1 > ptr2)); + assert((p1 >= p2) == (ptr1 >= ptr2)); #if TEST_STD_VER > 17 assert((p1 <=> p2) != std::strong_ordering::equal); assert((p1 <=> p2) == (ptr1 <=> ptr2)); #endif + } } // Pointers of different array types { @@ -132,14 +121,16 @@ const std::unique_ptr > p2(ptr2); assert(!(p1 == p2)); assert(p1 != p2); - assert((p1 < p2) == (ptr1 < ptr2)); - assert((p1 <= p2) == (ptr1 <= ptr2)); - assert((p1 > p2) == (ptr1 > ptr2)); - assert((p1 >= p2) == (ptr1 >= ptr2)); + if (!TEST_IS_CONSTANT_EVALUATED) { + assert((p1 < p2) == (ptr1 < ptr2)); + assert((p1 <= p2) == (ptr1 <= ptr2)); + assert((p1 > p2) == (ptr1 > ptr2)); + assert((p1 >= p2) == (ptr1 >= ptr2)); #if TEST_STD_VER > 17 assert((p1 <=> p2) != std::strong_ordering::equal); assert((p1 <=> p2) == (ptr1 <=> ptr2)); #endif + } } // Default-constructed pointers of same type { @@ -147,7 +138,8 @@ const std::unique_ptr > p2; assert(p1 == p2); #if TEST_STD_VER > 17 - assert((p1 <=> p2) == std::strong_ordering::equal); + if (!TEST_IS_CONSTANT_EVALUATED) + assert((p1 <=> p2) == std::strong_ordering::equal); #endif } // Default-constructed pointers of different type @@ -156,9 +148,19 @@ const std::unique_ptr > p2; assert(p1 == p2); #if TEST_STD_VER > 17 - assert((p1 <=> p2) == std::strong_ordering::equal); + if (!TEST_IS_CONSTANT_EVALUATED) + assert((p1 <=> p2) == std::strong_ordering::equal); #endif } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp +++ 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; } Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp =================================================================== --- libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp @@ -22,31 +22,45 @@ { int state_; static int count; - A() : state_(0) {++count;} - explicit A(int i) : state_(i) {++count;} - A(const A& a) : state_(a.state_) {++count;} - A& operator=(const A& a) {state_ = a.state_; return *this;} - ~A() {--count;} + TEST_CONSTEXPR_CXX23 A() : state_(0) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 explicit A(int i) : state_(i) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 A(const A& a) : state_(a.state_) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 A& operator=(const A& a) { + state_ = a.state_; + return *this; + } + TEST_CONSTEXPR_CXX23 ~A() { + if (!TEST_IS_CONSTANT_EVALUATED) + --count; + } - friend bool operator==(const A& x, const A& y) - {return x.state_ == y.state_;} + friend TEST_CONSTEXPR_CXX23 bool operator==(const A& x, const A& y) { return x.state_ == y.state_; } }; int A::count = 0; template struct NonSwappableDeleter { - explicit NonSwappableDeleter(int) {} - NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; } - void operator()(T*) const {} + TEST_CONSTEXPR_CXX23 explicit NonSwappableDeleter(int) {} + TEST_CONSTEXPR_CXX23 NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; } + TEST_CONSTEXPR_CXX23 void operator()(T*) const {} + private: NonSwappableDeleter(NonSwappableDeleter const&); }; -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX23 bool test() { + { A* p1 = new A(1); std::unique_ptr > s1(p1, Deleter(1)); A* p2 = new A(2); @@ -64,10 +78,12 @@ assert(s2.get() == p1); assert(*s2 == A(1)); assert(s2.get_deleter().state() == 1); - assert(A::count == 2); - } + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 2); + } + if (!TEST_IS_CONSTANT_EVALUATED) assert(A::count == 0); - { + { A* p1 = new A[3]; std::unique_ptr > s1(p1, Deleter(1)); A* p2 = new A[3]; @@ -81,8 +97,10 @@ assert(s1.get_deleter().state() == 2); assert(s2.get() == p1); assert(s2.get_deleter().state() == 1); - assert(A::count == 6); - } + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 6); + } + if (!TEST_IS_CONSTANT_EVALUATED) assert(A::count == 0); #if TEST_STD_VER >= 11 { @@ -99,5 +117,14 @@ } #endif + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } Index: libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.cpp =================================================================== --- libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.cpp +++ libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.cpp @@ -1,111 +1,111 @@ -// Copyright (c) Microsoft Corporation. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include -#include -#include - -using namespace std; - -struct U {}; // class type so const-qualification is not stripped from a prvalue -using CU = const U; -using T = int; -using CT = const T; - -U u{}; -const U& cu = u; - -static_assert(is_same_v(U{})), U&&>); -static_assert(is_same_v(CU{})), CU&&>); -static_assert(is_same_v(u)), U&&>); -static_assert(is_same_v(cu)), CU&&>); -static_assert(is_same_v(std::move(u))), U&&>); -static_assert(is_same_v(std::move(cu))), CU&&>); - -static_assert(is_same_v(U{})), CU&&>); -static_assert(is_same_v(CU{})), CU&&>); -static_assert(is_same_v(u)), CU&&>); -static_assert(is_same_v(cu)), CU&&>); -static_assert(is_same_v(std::move(u))), CU&&>); -static_assert(is_same_v(std::move(cu))), CU&&>); - -static_assert(is_same_v(U{})), U&>); -static_assert(is_same_v(CU{})), CU&>); -static_assert(is_same_v(u)), U&>); -static_assert(is_same_v(cu)), CU&>); -static_assert(is_same_v(std::move(u))), U&>); -static_assert(is_same_v(std::move(cu))), CU&>); - -static_assert(is_same_v(U{})), CU&>); -static_assert(is_same_v(CU{})), CU&>); -static_assert(is_same_v(u)), CU&>); -static_assert(is_same_v(cu)), CU&>); -static_assert(is_same_v(std::move(u))), CU&>); -static_assert(is_same_v(std::move(cu))), CU&>); - -static_assert(is_same_v(U{})), U&&>); -static_assert(is_same_v(CU{})), CU&&>); -static_assert(is_same_v(u)), U&&>); -static_assert(is_same_v(cu)), CU&&>); -static_assert(is_same_v(std::move(u))), U&&>); -static_assert(is_same_v(std::move(cu))), CU&&>); - -static_assert(is_same_v(U{})), CU&&>); -static_assert(is_same_v(CU{})), CU&&>); -static_assert(is_same_v(u)), CU&&>); -static_assert(is_same_v(cu)), CU&&>); -static_assert(is_same_v(std::move(u))), CU&&>); -static_assert(is_same_v(std::move(cu))), CU&&>); - -static_assert(noexcept(forward_like(u))); - -static_assert(is_same_v(u)), U&>); -static_assert(is_same_v(cu)), CU&>); -static_assert(is_same_v(std::move(u))), U&&>); -static_assert(is_same_v(std::move(cu))), CU&&>); - -struct NoCtorCopyMove { - NoCtorCopyMove() = delete; - NoCtorCopyMove(const NoCtorCopyMove&) = delete; - NoCtorCopyMove(NoCtorCopyMove&&) = delete; -}; - -static_assert(is_same_v(declval())), const NoCtorCopyMove&&>); -static_assert(is_same_v(declval())), const NoCtorCopyMove&>); -static_assert(is_same_v(declval())), NoCtorCopyMove&&>); -static_assert(is_same_v(declval())), NoCtorCopyMove&>); - -static_assert(noexcept(forward_like(declval()))); - -constexpr bool test() { - { - int val = 1729; - auto&& result = forward_like(val); - static_assert(is_same_v); - assert(&result == &val); - } - { - int val = 1729; - auto&& result = forward_like(val); - static_assert(is_same_v); - assert(&result == &val); - } - { - int val = 1729; - auto&& result = forward_like(val); - static_assert(is_same_v); - assert(&result == &val); - } - { - int val = 1729; - auto&& result = forward_like(val); - static_assert(is_same_v); - assert(&result == &val); - } - return true; -} - -int main() { - assert(test()); - static_assert(test()); -} +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +using namespace std; + +struct U {}; // class type so const-qualification is not stripped from a prvalue +using CU = const U; +using T = int; +using CT = const T; + +U u{}; +const U& cu = u; + +static_assert(is_same_v(U{})), U&&>); +static_assert(is_same_v(CU{})), CU&&>); +static_assert(is_same_v(u)), U&&>); +static_assert(is_same_v(cu)), CU&&>); +static_assert(is_same_v(std::move(u))), U&&>); +static_assert(is_same_v(std::move(cu))), CU&&>); + +static_assert(is_same_v(U{})), CU&&>); +static_assert(is_same_v(CU{})), CU&&>); +static_assert(is_same_v(u)), CU&&>); +static_assert(is_same_v(cu)), CU&&>); +static_assert(is_same_v(std::move(u))), CU&&>); +static_assert(is_same_v(std::move(cu))), CU&&>); + +static_assert(is_same_v(U{})), U&>); +static_assert(is_same_v(CU{})), CU&>); +static_assert(is_same_v(u)), U&>); +static_assert(is_same_v(cu)), CU&>); +static_assert(is_same_v(std::move(u))), U&>); +static_assert(is_same_v(std::move(cu))), CU&>); + +static_assert(is_same_v(U{})), CU&>); +static_assert(is_same_v(CU{})), CU&>); +static_assert(is_same_v(u)), CU&>); +static_assert(is_same_v(cu)), CU&>); +static_assert(is_same_v(std::move(u))), CU&>); +static_assert(is_same_v(std::move(cu))), CU&>); + +static_assert(is_same_v(U{})), U&&>); +static_assert(is_same_v(CU{})), CU&&>); +static_assert(is_same_v(u)), U&&>); +static_assert(is_same_v(cu)), CU&&>); +static_assert(is_same_v(std::move(u))), U&&>); +static_assert(is_same_v(std::move(cu))), CU&&>); + +static_assert(is_same_v(U{})), CU&&>); +static_assert(is_same_v(CU{})), CU&&>); +static_assert(is_same_v(u)), CU&&>); +static_assert(is_same_v(cu)), CU&&>); +static_assert(is_same_v(std::move(u))), CU&&>); +static_assert(is_same_v(std::move(cu))), CU&&>); + +static_assert(noexcept(forward_like(u))); + +static_assert(is_same_v(u)), U&>); +static_assert(is_same_v(cu)), CU&>); +static_assert(is_same_v(std::move(u))), U&&>); +static_assert(is_same_v(std::move(cu))), CU&&>); + +struct NoCtorCopyMove { + NoCtorCopyMove() = delete; + NoCtorCopyMove(const NoCtorCopyMove&) = delete; + NoCtorCopyMove(NoCtorCopyMove&&) = delete; +}; + +static_assert(is_same_v(declval())), const NoCtorCopyMove&&>); +static_assert(is_same_v(declval())), const NoCtorCopyMove&>); +static_assert(is_same_v(declval())), NoCtorCopyMove&&>); +static_assert(is_same_v(declval())), NoCtorCopyMove&>); + +static_assert(noexcept(forward_like(declval()))); + +constexpr bool test() { + { + int val = 1729; + auto&& result = forward_like(val); + static_assert(is_same_v); + assert(&result == &val); + } + { + int val = 1729; + auto&& result = forward_like(val); + static_assert(is_same_v); + assert(&result == &val); + } + { + int val = 1729; + auto&& result = forward_like(val); + static_assert(is_same_v); + assert(&result == &val); + } + { + int val = 1729; + auto&& result = forward_like(val); + static_assert(is_same_v); + assert(&result == &val); + } + return true; +} + +int main() { + assert(test()); + static_assert(test()); +} Index: libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.pass.cpp =================================================================== --- libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.pass.cpp +++ libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.pass.cpp @@ -1,13 +1,13 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 - -// Includes Microsoft's test that tests the entire header. - -#include "test.cpp" +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// Includes Microsoft's test that tests the entire header. + +#include "test.cpp" Index: libcxx/test/support/deleter_types.h =================================================================== --- libcxx/test/support/deleter_types.h +++ 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 Index: libcxx/test/support/test_macros.h =================================================================== --- libcxx/test/support/test_macros.h +++ libcxx/test/support/test_macros.h @@ -166,7 +166,7 @@ # define TEST_CONSTEXPR_CXX20 #endif -#if TEST_STD_VER > 20 +#if TEST_STD_VER >= 23 # define TEST_CONSTEXPR_CXX23 constexpr #else # define TEST_CONSTEXPR_CXX23 Index: libcxx/test/support/unique_ptr_test_helper.h =================================================================== --- libcxx/test/support/unique_ptr_test_helper.h +++ libcxx/test/support/unique_ptr_test_helper.h @@ -17,32 +17,48 @@ struct A { static int count; - A() { ++count; } - A(const A&) { ++count; } - virtual ~A() { --count; } + TEST_CONSTEXPR_CXX23 A() { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 A(const A&) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 virtual ~A() { + if (!TEST_IS_CONSTANT_EVALUATED) + --count; + } }; int A::count = 0; struct B : public A { static int count; - B() { ++count; } - B(const B& other) : A(other) { ++count; } - virtual ~B() { --count; } + TEST_CONSTEXPR_CXX23 B() { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 B(const B& other) : A(other) { + if (!TEST_IS_CONSTANT_EVALUATED) + ++count; + } + TEST_CONSTEXPR_CXX23 virtual ~B() { + if (!TEST_IS_CONSTANT_EVALUATED) + --count; + } }; 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 +73,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 +111,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 +126,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 Index: libcxx/utils/generate_feature_test_macro_components.py =================================================================== --- libcxx/utils/generate_feature_test_macro_components.py +++ libcxx/utils/generate_feature_test_macro_components.py @@ -242,7 +242,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",