diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/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_invoke_r`` *unimplemented* diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -39,6 +39,7 @@ ------------------ - P2499R0 - ``string_view`` range constructor should be ``explicit`` - P2417R2 - A more constexpr bitset +- P2273R3 - Making ``std::unique_ptr`` constexpr Improvements and New Features ----------------------------- diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv --- a/libcxx/docs/Status/Cxx2bPapers.csv +++ b/libcxx/docs/Status/Cxx2bPapers.csv @@ -44,7 +44,7 @@ "`P1206R7 <https://wg21.link/P1206R7>`__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","","" "`P1413R3 <https://wg21.link/P1413R3>`__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","","" "`P2255R3 <https://wg21.link/P2255R3>`__","LWG","A type trait to detect reference binding to temporary","February 2022","","" -"`P2273R3 <https://wg21.link/P2273R3>`__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","","" +"`P2273R3 <https://wg21.link/P2273R3>`__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Complete|","16.0" "`P2387R3 <https://wg21.link/P2387R3>`__","LWG","Pipe support for user-defined range adaptors","February 2022","","" "`P2440R1 <https://wg21.link/P2440R1>`__","LWG","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","February 2022","","" "`P2441R2 <https://wg21.link/P2441R2>`__","LWG","``views::join_view``","February 2022","","" diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -40,12 +40,10 @@ _LIBCPP_INLINE_VISIBILITY default_delete() {} #endif template <class _Up> - _LIBCPP_INLINE_VISIBILITY - default_delete(const default_delete<_Up>&, - typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* = - 0) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 default_delete( + const default_delete<_Up>&, typename enable_if<is_convertible<_Up*, _Tp*>::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 <class _Up> - _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 <class _Up> - _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 <bool _Dummy = true, - class = _EnableIfDeleterDefaultConstructible<_Dummy> > - _LIBCPP_INLINE_VISIBILITY - explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} + template <bool _Dummy = true, class = _EnableIfDeleterDefaultConstructible<_Dummy> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT + : __ptr_(__p, __value_init_tag()) {} - template <bool _Dummy = true, - class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT + template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {} - template <bool _Dummy = true, - class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT - : __ptr_(__p, _VSTD::move(__d)) { + template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 + unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, _VSTD::move(__d)) { static_assert(!is_reference<deleter_type>::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<deleter_type>(__u.get_deleter())) { - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT + : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {} - template <class _Up, class _Ep, - class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, - class = _EnableIfDeleterConvertible<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT + template <class _Up, + class _Ep, + class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _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<deleter_type>(__u.get_deleter()); return *this; } - template <class _Up, class _Ep, - class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, - class = _EnableIfDeleterAssignable<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { + template <class _Up, + class _Ep, + class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _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 _Pp, bool _Dummy = true, - class = _EnableIfDeleterDefaultConstructible<_Dummy>, - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - explicit unique_ptr(_Pp __p) _NOEXCEPT + template <class _Pp, + bool _Dummy = true, + class = _EnableIfDeleterDefaultConstructible<_Dummy>, + class = _EnableIfPointerConvertible<_Pp> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(_Pp __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} - template <class _Pp, bool _Dummy = true, - class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >, - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT + template <class _Pp, + bool _Dummy = true, + class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >, + class = _EnableIfPointerConvertible<_Pp> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {} - template <bool _Dummy = true, - class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT + template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(nullptr, __d) {} - template <class _Pp, bool _Dummy = true, - class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >, - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT + template <class _Pp, + bool _Dummy = true, + class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >, + 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<deleter_type>::value, "rvalue deleter bound to reference"); } - template <bool _Dummy = true, - class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT + template <bool _Dummy = true, class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(nullptr, _VSTD::move(__d)) { static_assert(!is_reference<deleter_type>::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<deleter_type>(__u.get_deleter())) { - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT + : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__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<deleter_type>(__u.get_deleter()); return *this; } - template <class _Up, class _Ep, - class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _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 <class _Up, + class _Ep, + class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _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 <class _Up, class _Ep, - class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>, - class = _EnableIfDeleterAssignable<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr& - operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { + template <class _Up, + class _Ep, + class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _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 <class _Pp> - _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 <class _Tp, class _Dp> -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 <class _T1, class _D1, class _T2, class _D2> -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 <class _T1, class _D1, class _T2, class _D2> @@ -607,11 +553,9 @@ #endif template <class _T1, class _D1> -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 <class _T1, class _D1> -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 <class _T1, class _D1> -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 <class _T1, class _D1> -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 <class _T1, class _D1> -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 <class _T1, class _D1> -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 <class _T1, class _D1> -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 <class _T1, class _D1> -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 <class _T1, class _D1> -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 <class _T1, class _D1> -requires three_way_comparable<typename unique_ptr<_T1, _D1>::pointer> -_LIBCPP_HIDE_FROM_ABI -compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer> + requires three_way_comparable< + typename unique_ptr<_T1, _D1>::pointer> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 + compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer> operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr)); } @@ -736,21 +664,17 @@ typedef void __unique_array_known_bound; }; -template<class _Tp, class... _Args> -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 <class _Tp, class... _Args> +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<class _Tp> -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 <class _Tp> +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<class _Tp, class... _Args> diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -406,16 +406,17 @@ struct default_delete { constexpr default_delete() noexcept = default; - template <class U> default_delete(const default_delete<U>&) noexcept; + template <class U> constexpr default_delete(const default_delete<U>&) noexcept; // constexpr since C++23 - void operator()(T*) const noexcept; + constexpr void operator()(T*) const noexcept; // constexpr since C++23 }; template <class T> struct default_delete<T[]> { constexpr default_delete() noexcept = default; - void operator()(T*) const noexcept; + template <class U> constexpr default_delete(const default_delete <U[]>&) noexcept; // constexpr since C++23 + constexpr void operator()(T*) const noexcept; // constexpr since C++23 template <class U> 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 <class U, class E> - unique_ptr(unique_ptr<U, E>&& u) noexcept; + constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept; // constexpr since C++23 template <class U> - unique_ptr(auto_ptr<U>&& u) noexcept; // removed in C++17 + unique_ptr(auto_ptr<U>&& 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 <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; - unique_ptr& operator=(nullptr_t) noexcept; + constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; // constexpr since C++23 + template <class U, class E> + constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; // constexpr since C++23 + constexpr unique_ptr& operator=(nullptr_t) noexcept; // constexpr since C++23 // observers - typename add_lvalue_reference<T>::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<T>::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 <class T, class D> @@ -471,41 +473,41 @@ // constructors constexpr unique_ptr() noexcept; - explicit unique_ptr(pointer p) noexcept; - unique_ptr(pointer p, see below d) noexcept; - unique_ptr(pointer p, see below d) noexcept; - unique_ptr(unique_ptr&& u) noexcept; - unique_ptr(nullptr_t) noexcept : unique_ptr() { } + constexpr explicit unique_ptr(pointer p) noexcept; // constexpr since C++23 + constexpr unique_ptr(pointer p, see below d) noexcept; // constexpr since C++23 + constexpr unique_ptr(pointer p, see below d) noexcept; // constexpr since C++23 + constexpr unique_ptr(unique_ptr&& u) noexcept; // constexpr since C++23 + constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { } // constexpr since C++23 // destructor - ~unique_ptr(); + constexpr ~unique_ptr(); // constexpr since C++23 // assignment - unique_ptr& operator=(unique_ptr&& u) noexcept; - unique_ptr& operator=(nullptr_t) noexcept; + constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; // constexpr since C++23 + constexpr unique_ptr& operator=(nullptr_t) noexcept; // constexpr since C++23 // observers - T& operator[](size_t i) const; - pointer get() const noexcept; - deleter_type& get_deleter() noexcept; - const deleter_type& get_deleter() const noexcept; - explicit operator bool() const noexcept; + constexpr T& operator[](size_t i) const; // constexpr since C++23 + constexpr pointer get() const noexcept; // constexpr since C++23 + constexpr deleter_type& get_deleter() noexcept; // constexpr since C++23 + constexpr const deleter_type& get_deleter() const noexcept; // constexpr since C++23 + constexpr explicit operator bool() const noexcept; // constexpr since C++23 // modifiers - pointer release() noexcept; - void reset(pointer p = pointer()) noexcept; - void reset(nullptr_t) noexcept; + constexpr pointer release() noexcept; // constexpr since C++23 + constexpr void reset(pointer p = pointer()) noexcept; // constexpr since C++23 + constexpr void reset(nullptr_t) noexcept; // constexpr since C++23 template <class U> void reset(U) = delete; - void swap(unique_ptr& u) noexcept; + constexpr void swap(unique_ptr& u) noexcept; // constexpr since C++23 }; template <class T, class D> - void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; + constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; // constexpr since C++23 template <class T1, class D1, class T2, class D2> - bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); + constexpr bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // constexpr since C++23 template <class T1, class D1, class T2, class D2> - bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // removed in C++20 + bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // removed in C++20 template <class T1, class D1, class T2, class D2> bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); template <class T1, class D1, class T2, class D2> @@ -522,34 +524,34 @@ operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // C++20 template <class T, class D> - bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; + constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; // constexpr since C++23 template <class T, class D> - bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; // removed in C++20 + bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; // removed in C++20 template <class T, class D> - bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; // removed in C++20 + bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; // removed in C++20 template <class T, class D> - bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; // removed in C++20 + bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; // removed in C++20 template <class T, class D> - bool operator<(const unique_ptr<T, D>& x, nullptr_t); + constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t); // constexpr since C++23 template <class T, class D> - bool operator<(nullptr_t, const unique_ptr<T, D>& y); + constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& y); // constexpr since C++23 template <class T, class D> - bool operator<=(const unique_ptr<T, D>& x, nullptr_t); + constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t); // constexpr since C++23 template <class T, class D> - bool operator<=(nullptr_t, const unique_ptr<T, D>& y); + constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& y); // constexpr since C++23 template <class T, class D> - bool operator>(const unique_ptr<T, D>& x, nullptr_t); + constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t); // constexpr since C++23 template <class T, class D> - bool operator>(nullptr_t, const unique_ptr<T, D>& y); + constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& y); // constexpr since C++23 template <class T, class D> - bool operator>=(const unique_ptr<T, D>& x, nullptr_t); + constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t); // constexpr since C++23 template <class T, class D> - bool operator>=(nullptr_t, const unique_ptr<T, D>& y); + constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& y); // constexpr since C++23 template<class T, class D> requires three_way_comparable<typename unique_ptr<T, D>::pointer> compare_three_way_result_t<typename unique_ptr<T, D>::pointer> - operator<=>(const unique_ptr<T, D>& x, nullptr_t); // C++20 + constexpr operator<=>(const unique_ptr<T, D>& x, nullptr_t); // C++20, constexpr since C++23 class bad_weak_ptr : public std::exception @@ -557,8 +559,10 @@ bad_weak_ptr() noexcept; }; -template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args); // C++14 -template<class T> unique_ptr<T> make_unique(size_t n); // C++14 +template<class T, class... Args> +constexpr unique_ptr<T> make_unique(Args&&... args); // C++14, constexpr since C++23 +template<class T> +constexpr unique_ptr<T> make_unique(size_t n); // C++14, constexpr since C++23 template<class T, class... Args> unspecified make_unique(Args&&...) = delete; // C++14, T == U[N] template<class E, class T, class Y, class D> diff --git a/libcxx/include/version b/libcxx/include/version --- a/libcxx/include/version +++ b/libcxx/include/version @@ -62,7 +62,8 @@ __cpp_lib_constexpr_dynamic_alloc 201907L <memory> __cpp_lib_constexpr_functional 201907L <functional> __cpp_lib_constexpr_iterator 201811L <iterator> -__cpp_lib_constexpr_memory 201811L <memory> +__cpp_lib_constexpr_memory 202202L <memory> + 201811L // C++20 __cpp_lib_constexpr_numeric 201911L <numeric> __cpp_lib_constexpr_string 201907L <string> __cpp_lib_constexpr_string_view 201811L <string_view> @@ -383,6 +384,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_invoke_r 202106L # define __cpp_lib_is_scoped_enum 202011L diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp @@ -23,6 +23,7 @@ __cpp_lib_atomic_value_initialization 201911L [C++20] __cpp_lib_constexpr_dynamic_alloc 201907L [C++20] __cpp_lib_constexpr_memory 201811L [C++20] + 202202L [C++2b] __cpp_lib_enable_shared_from_this 201603L [C++17] __cpp_lib_make_unique 201304L [C++14] __cpp_lib_out_ptr 202106L [C++2b] @@ -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 diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -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] @@ -3933,8 +3934,8 @@ # ifndef __cpp_lib_constexpr_memory # error "__cpp_lib_constexpr_memory should be defined in c++2b" # endif -# if __cpp_lib_constexpr_memory != 201811L -# error "__cpp_lib_constexpr_memory should have the value 201811L in c++2b" +# if __cpp_lib_constexpr_memory != 202202L +# error "__cpp_lib_constexpr_memory should have the value 202202L in c++2b" # endif # ifndef __cpp_lib_constexpr_numeric diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp @@ -33,34 +33,40 @@ }; template <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional<IsArray, A[], A>::type VT; const int expect_alive = IsArray ? 5 : 1; { std::unique_ptr<VT> s1(newValue<VT>(expect_alive)); A* p = s1.get(); std::unique_ptr<VT> s2(newValue<VT>(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<VT, Deleter<VT> > s1(newValue<VT>(expect_alive), Deleter<VT>(5)); A* p = s1.get(); std::unique_ptr<VT, Deleter<VT> > s2(newValue<VT>(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<VT> d1(5); std::unique_ptr<VT, CDeleter<VT>&> s1(newValue<VT>(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<VT> s(newValue<VT>(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 <bool IsArray> -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { typedef typename std::conditional<IsArray, int[], int>::type VT; { typedef std::unique_ptr<VT> U; @@ -118,8 +128,7 @@ } } - -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_basic</*IsArray*/ false>(); test_sfinae<false>(); @@ -129,5 +138,14 @@ test_sfinae<true>(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp @@ -23,21 +23,20 @@ template <int ID = 0> struct GenericDeleter { - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; template <int ID = 0> struct GenericConvertingDeleter { - template <int OID> - GenericConvertingDeleter(GenericConvertingDeleter<OID>) {} + TEST_CONSTEXPR_CXX23 GenericConvertingDeleter(GenericConvertingDeleter<OID>) {} template <int OID> - GenericConvertingDeleter& operator=(GenericConvertingDeleter<OID> const&) { + TEST_CONSTEXPR_CXX23 GenericConvertingDeleter& operator=(GenericConvertingDeleter<OID> const&) { return *this; } - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; template <class T, class U> @@ -156,9 +155,9 @@ template <class From, bool AssignIsConst = false> 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 <class T> AssignDeleter& operator=(T&&) && = delete; template <class T> AssignDeleter& operator=(T&&) const && = delete; - template <class T, class = typename std::enable_if< - std::is_same<T&&, From>::value && !AssignIsConst - >::type> - AssignDeleter& operator=(T&&) & { return *this; } + template <class T, class = typename std::enable_if< std::is_same<T&&, From>::value && !AssignIsConst >::type> + TEST_CONSTEXPR_CXX23 AssignDeleter& operator=(T&&) & { + return *this; + } - template <class T, class = typename std::enable_if< - std::is_same<T&&, From>::value && AssignIsConst - >::type> - const AssignDeleter& operator=(T&&) const & { return *this; } + template <class T, class = typename std::enable_if< std::is_same<T&&, From>::value && AssignIsConst >::type> + TEST_CONSTEXPR_CXX23 const AssignDeleter& operator=(T&&) const& { + return *this; + } template <class T> - void operator()(T) const {} + TEST_CONSTEXPR_CXX23 void operator()(T) const {} }; template <class VT, class DDest, class DSource> - void doDeleterTest() { - using U1 = std::unique_ptr<VT, DDest>; - using U2 = std::unique_ptr<VT, DSource>; - static_assert(std::is_nothrow_assignable<U1, U2&&>::value, ""); - typename std::decay<DDest>::type ddest; - typename std::decay<DSource>::type dsource; - U1 u1(nullptr, ddest); - U2 u2(nullptr, dsource); - u1 = std::move(u2); +TEST_CONSTEXPR_CXX23 void doDeleterTest() { + using U1 = std::unique_ptr<VT, DDest>; + using U2 = std::unique_ptr<VT, DSource>; + static_assert(std::is_nothrow_assignable<U1, U2&&>::value, ""); + typename std::decay<DDest>::type ddest; + typename std::decay<DSource>::type dsource; + U1 u1(nullptr, ddest); + U2 u2(nullptr, dsource); + u1 = std::move(u2); } template <bool IsArray> -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { typedef typename std::conditional<IsArray, A[], A>::type VT; { // Test that different non-reference deleter types are allowed so long @@ -281,9 +280,8 @@ } } - template <bool IsArray> -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { typedef typename std::conditional<IsArray, A[], A>::type VT; { typedef std::unique_ptr<const VT> APtr; @@ -405,17 +403,28 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_sfinae</*IsArray*/false>(); test_noexcept<false>(); - test_deleter_value_category<false>(); + if (!TEST_IS_CONSTANT_EVALUATED) + test_deleter_value_category<false>(); } { test_sfinae</*IsArray*/true>(); test_noexcept<true>(); - test_deleter_value_category<true>(); + if (!TEST_IS_CONSTANT_EVALUATED) + test_deleter_value_category<true>(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp +++ b/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 <class APtr, class BPtr> -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 <class LHS, class RHS> -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 <class T> struct NCConvertingDeleter { - NCConvertingDeleter() = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; - NCConvertingDeleter(NCConvertingDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default; template <class U> - NCConvertingDeleter(NCConvertingDeleter<U>&&) {} + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {} - void operator()(T*) const {} + TEST_CONSTEXPR_CXX23 void operator()(T*) const {} }; template <class T> struct NCConvertingDeleter<T[]> { - NCConvertingDeleter() = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; - NCConvertingDeleter(NCConvertingDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default; template <class U> - NCConvertingDeleter(NCConvertingDeleter<U>&&) {} + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {} - 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<A>; // non-copyable deleters using DB = NCConvertingDeleter<B>; using UA = std::unique_ptr<A>; @@ -114,15 +117,17 @@ } } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { test_sfinae(); { std::unique_ptr<B> bptr(new B); std::unique_ptr<A> 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<B> del(42); std::unique_ptr<B, Deleter<B> > 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<A> adel(6); CDeleter<B> 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; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp +++ b/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 <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional<IsArray, A[], A>::type VT; const int expect_alive = IsArray ? 5 : 1; { std::unique_ptr<VT> s2(newValue<VT>(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</*IsArray*/ false>(); test_basic<true>(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp +++ b/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 <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional<IsArray, A[], A>::type VT; const int expect_alive = IsArray ? 5 : 1; { std::unique_ptr<VT> s2(newValue<VT>(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</*IsArray*/ false>(); test_basic<true>(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp @@ -36,7 +36,7 @@ struct NonDefaultDeleter { NonDefaultDeleter() = delete; - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; #endif @@ -51,9 +51,9 @@ { // the constructor does not participate in overload resolution when // the deleter is not default constructible using Del = CDeleter<ElemType>; - using U1 = std::unique_ptr<ElemType, NonDefaultDeleter>; - using U2 = std::unique_ptr<ElemType, Del&>; - using U3 = std::unique_ptr<ElemType, Del const&>; + using U1 = std::unique_ptr<ElemType, NonDefaultDeleter>; + using U2 = std::unique_ptr<ElemType, Del&>; + using U3 = std::unique_ptr<ElemType, Del const&>; static_assert(!std::is_default_constructible<U1>::value, ""); static_assert(!std::is_default_constructible<U2>::value, ""); static_assert(!std::is_default_constructible<U3>::value, ""); @@ -62,7 +62,7 @@ } template <class ElemType> -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { #if TEST_STD_VER >= 11 { using U1 = std::unique_ptr<ElemType>; @@ -87,6 +87,8 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 0); } + + return true; } DEFINE_AND_RUN_IS_INCOMPLETE_TEST({ @@ -101,10 +103,16 @@ { test_sfinae<int>(); test_basic<int>(); +#if TEST_STD_VER >= 23 + static_assert(test_basic<int>()); +#endif } { test_sfinae<int[]>(); test_basic<int[]>(); +#if TEST_STD_VER >= 23 + static_assert(test_basic<int[]>()); +#endif } return 0; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp +++ b/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 <class VT> -std::unique_ptr<VT> source1() { +TEST_CONSTEXPR_CXX23 std::unique_ptr<VT> source1() { return std::unique_ptr<VT>(newValue<VT>(1)); } template <class VT> -std::unique_ptr<VT, Deleter<VT> > source2() { +TEST_CONSTEXPR_CXX23 std::unique_ptr<VT, Deleter<VT> > source2() { return std::unique_ptr<VT, Deleter<VT> >(newValue<VT>(1), Deleter<VT>(5)); } @@ -54,12 +54,12 @@ } template <class VT> -void sink1(std::unique_ptr<VT> p) { +TEST_CONSTEXPR_CXX23 void sink1(std::unique_ptr<VT> p) { assert(p.get() != nullptr); } template <class VT> -void sink2(std::unique_ptr<VT, Deleter<VT> > p) { +TEST_CONSTEXPR_CXX23 void sink2(std::unique_ptr<VT, Deleter<VT> > p) { assert(p.get() != nullptr); assert(p.get_deleter().state() == 5); } @@ -72,7 +72,7 @@ } template <class ValueT> -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { typedef std::unique_ptr<ValueT> U; { // Ensure unique_ptr is non-copyable static_assert((!std::is_constructible<U, U const&>::value), ""); @@ -81,7 +81,7 @@ } template <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional<!IsArray, A, A[]>::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<VT> MoveDel; typedef std::unique_ptr<VT, MoveDel> 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<VT> NonCopyDel; typedef std::unique_ptr<VT, NonCopyDel&> 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<VT>(source1<VT>()); - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); sink2<VT>(source2<VT>()); - assert(A::count == 0); - sink3<VT>(source3<VT>()); - 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 <class VT> -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { #if TEST_STD_VER >= 11 { typedef std::unique_ptr<VT> U; @@ -159,7 +166,7 @@ #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_basic</*IsArray*/ false>(); test_sfinae<int>(); @@ -171,5 +178,23 @@ test_noexcept<int[]>(); } + return true; +} + +template <bool IsArray> +void test_sink3() { + typedef typename std::conditional<!IsArray, A, A[]>::type VT; + sink3<VT>(source3<VT>()); + assert(A::count == 0); +} + +int main(int, char**) { + test_sink3</*IsArray*/ false>(); + test_sink3</*IsArray*/ true>(); + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp @@ -23,14 +23,14 @@ template <int ID = 0> struct GenericDeleter { - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; template <int ID = 0> struct GenericConvertingDeleter { template <int OID> - GenericConvertingDeleter(GenericConvertingDeleter<OID>) {} - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 GenericConvertingDeleter(GenericConvertingDeleter<OID>) {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; template <class Templ, class Other> @@ -50,37 +50,35 @@ template <int ID> struct TrackingDeleter { - TrackingDeleter() : arg_type(&makeArgumentID<>()) {} + TEST_CONSTEXPR_CXX23 TrackingDeleter() : arg_type(&makeArgumentID<>()) {} - TrackingDeleter(TrackingDeleter const&) - : arg_type(&makeArgumentID<TrackingDeleter const&>()) {} + TEST_CONSTEXPR_CXX23 TrackingDeleter(TrackingDeleter const&) : arg_type(&makeArgumentID<TrackingDeleter const&>()) {} - TrackingDeleter(TrackingDeleter&&) - : arg_type(&makeArgumentID<TrackingDeleter &&>()) {} + TEST_CONSTEXPR_CXX23 TrackingDeleter(TrackingDeleter&&) : arg_type(&makeArgumentID<TrackingDeleter&&>()) {} template <class T, class = EnableIfSpecialization<TrackingDeleter, T> > - TrackingDeleter(T&&) : arg_type(&makeArgumentID<T&&>()) {} + TEST_CONSTEXPR_CXX23 TrackingDeleter(T&&) : arg_type(&makeArgumentID<T&&>()) {} - TrackingDeleter& operator=(TrackingDeleter const&) { + TEST_CONSTEXPR_CXX23 TrackingDeleter& operator=(TrackingDeleter const&) { arg_type = &makeArgumentID<TrackingDeleter const&>(); return *this; } - TrackingDeleter& operator=(TrackingDeleter &&) { + TEST_CONSTEXPR_CXX23 TrackingDeleter& operator=(TrackingDeleter&&) { arg_type = &makeArgumentID<TrackingDeleter &&>(); return *this; } template <class T, class = EnableIfSpecialization<TrackingDeleter, T> > - TrackingDeleter& operator=(T&&) { + TEST_CONSTEXPR_CXX23 TrackingDeleter& operator=(T&&) { arg_type = &makeArgumentID<T&&>(); 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<ExpectT>(); } - template <bool IsArray> -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { typedef typename std::conditional<IsArray, A[], A>::type VT; { // Test that different non-reference deleter types are allowed so long @@ -144,9 +141,8 @@ } } - template <bool IsArray> -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { typedef typename std::conditional<IsArray, A[], A>::type VT; { typedef std::unique_ptr<const VT> APtr; @@ -170,9 +166,8 @@ } } - template <bool IsArray> -void test_deleter_value_category() { +TEST_CONSTEXPR_CXX23 void test_deleter_value_category() { typedef typename std::conditional<IsArray, A[], A>::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</*IsArray*/false>(); test_noexcept<false>(); - test_deleter_value_category<false>(); + if (!TEST_IS_CONSTANT_EVALUATED) + test_deleter_value_category<false>(); } { test_sfinae</*IsArray*/true>(); test_noexcept<true>(); - test_deleter_value_category<true>(); + if (!TEST_IS_CONSTANT_EVALUATED) + test_deleter_value_category<true>(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp +++ b/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<A[], GenericConvertingDeleter<0> >; using U2 = std::unique_ptr<A[], GenericConvertingDeleter<1> >; @@ -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; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp +++ b/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 <class LHS, class RHS> -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<NewDel>::value, ""); rhs.get_deleter().set_state(42); @@ -41,57 +41,61 @@ } template <class LHS, class RHS> -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 <class LHS, class RHS> -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 <class T> struct NCConvertingDeleter { - NCConvertingDeleter() = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; - NCConvertingDeleter(NCConvertingDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default; template <class U> - NCConvertingDeleter(NCConvertingDeleter<U>&&) {} + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {} - void operator()(T*) const {} + TEST_CONSTEXPR_CXX23 void operator()(T*) const {} }; template <class T> struct NCConvertingDeleter<T[]> { - NCConvertingDeleter() = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter() = default; NCConvertingDeleter(NCConvertingDeleter const&) = delete; - NCConvertingDeleter(NCConvertingDeleter&&) = default; + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter&&) = default; template <class U> - NCConvertingDeleter(NCConvertingDeleter<U>&&) {} + TEST_CONSTEXPR_CXX23 NCConvertingDeleter(NCConvertingDeleter<U>&&) {} - 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<A>; // non-copyable deleters using DB = NCConvertingDeleter<B>; using UA = std::unique_ptr<A>; @@ -134,7 +138,7 @@ } } -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { { typedef std::unique_ptr<A> APtr; typedef std::unique_ptr<B> 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; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp @@ -23,7 +23,7 @@ #include "unique_ptr_test_helper.h" template <class VT> -void test_pointer_ctor() { +TEST_CONSTEXPR_CXX23 bool test_pointer_ctor() { { std::unique_ptr<VT> p(0); assert(p.get() == 0); @@ -33,10 +33,12 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 0); } + + return true; } template <class VT> -void test_pointer_deleter_ctor() { +TEST_CONSTEXPR_CXX23 bool test_pointer_deleter_ctor() { { std::default_delete<VT> d; std::unique_ptr<VT> p(0, d); @@ -59,16 +61,25 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 5); } + + return true; } int main(int, char**) { { // test_pointer_ctor<int>(); test_pointer_deleter_ctor<int>(); +#if TEST_STD_VER >= 23 + static_assert(test_pointer_deleter_ctor<int>()); +#endif } { test_pointer_ctor<int[]>(); test_pointer_deleter_ctor<int[]>(); +#if TEST_STD_VER >= 23 + static_assert(test_pointer_ctor<int[]>()); + static_assert(test_pointer_deleter_ctor<int[]>()); +#endif } return 0; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp @@ -18,7 +18,6 @@ #include "test_macros.h" #include "unique_ptr_test_helper.h" - #if TEST_STD_VER >= 11 TEST_CONSTINIT std::unique_ptr<int> global_static_unique_ptr_single(nullptr); TEST_CONSTINIT std::unique_ptr<int[]> global_static_unique_ptr_runtime(nullptr); @@ -30,15 +29,13 @@ #endif template <class VT> -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { #if TEST_STD_VER >= 11 { using U1 = std::unique_ptr<VT>; using U2 = std::unique_ptr<VT, Deleter<VT> >; - static_assert(std::is_nothrow_constructible<U1, decltype(nullptr)>::value, - ""); - static_assert(std::is_nothrow_constructible<U2, decltype(nullptr)>::value, - ""); + static_assert(std::is_nothrow_constructible<U1, decltype(nullptr)>::value, ""); + static_assert(std::is_nothrow_constructible<U2, decltype(nullptr)>::value, ""); } #endif { @@ -55,10 +52,12 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 0); } + + return true; } template <class VT> -void test_sfinae() { +TEST_CONSTEXPR_CXX23 bool test_sfinae() { #if TEST_STD_VER >= 11 { // the constructor does not participate in overload resolution when // the deleter is a pointer type @@ -68,30 +67,26 @@ { // the constructor does not participate in overload resolution when // the deleter is not default constructible using Del = CDeleter<VT>; - using U1 = std::unique_ptr<VT, NonDefaultDeleter>; - using U2 = std::unique_ptr<VT, Del&>; - using U3 = std::unique_ptr<VT, Del const&>; + using U1 = std::unique_ptr<VT, NonDefaultDeleter>; + using U2 = std::unique_ptr<VT, Del&>; + using U3 = std::unique_ptr<VT, Del const&>; static_assert(!std::is_constructible<U1, decltype(nullptr)>::value, ""); static_assert(!std::is_constructible<U2, decltype(nullptr)>::value, ""); static_assert(!std::is_constructible<U3, decltype(nullptr)>::value, ""); } #endif + + return true; } DEFINE_AND_RUN_IS_INCOMPLETE_TEST({ { doIncompleteTypeTest(0, nullptr); } checkNumIncompleteTypeAlive(0); - { - doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(0, - nullptr); - } + { doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(0, nullptr); } checkNumIncompleteTypeAlive(0); { doIncompleteTypeTest<IncompleteType[]>(0, nullptr); } checkNumIncompleteTypeAlive(0); - { - doIncompleteTypeTest<IncompleteType[], NCDeleter<IncompleteType[]> >( - 0, nullptr); - } + { doIncompleteTypeTest<IncompleteType[], NCDeleter<IncompleteType[]> >(0, nullptr); } checkNumIncompleteTypeAlive(0); }) @@ -99,10 +94,18 @@ { test_basic<int>(); test_sfinae<int>(); +#if TEST_STD_VER >= 23 + static_assert(test_basic<int>()); + static_assert(test_sfinae<int>()); +#endif } { test_basic<int[]>(); test_sfinae<int[]>(); +#if TEST_STD_VER >= 23 + static_assert(test_basic<int[]>()); + static_assert(test_sfinae<int[]>()); +#endif } return 0; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp +++ b/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 <bool IsArray> -void test_pointer() { +TEST_CONSTEXPR_CXX23 void test_pointer() { typedef typename std::conditional<!IsArray, A, A[]>::type ValueT; const int expect_alive = IsArray ? 5 : 1; #if TEST_STD_VER >= 11 @@ -56,49 +56,66 @@ #endif { A* p = newValue<ValueT>(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); + std::unique_ptr<ValueT> s(p); assert(s.get() == p); } - assert(A::count == 0); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == 0); { A* p = newValue<ValueT>(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); + std::unique_ptr<ValueT, NCDeleter<ValueT> > 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<ValueT>(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); + std::unique_ptr<ValueT, DefaultCtorDeleter<ValueT> > 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<A> 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<A, NCDeleter<A> > 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 <class T> -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</*IsArray*/ false>(); 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; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp +++ b/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 <bool IsArray> -void test_sfinae() { +TEST_CONSTEXPR_CXX23 void test_sfinae() { #if TEST_STD_VER >= 11 typedef typename std::conditional<!IsArray, int, int[]>::type VT; { @@ -102,7 +102,7 @@ } template <bool IsArray> -void test_noexcept() { +TEST_CONSTEXPR_CXX23 void test_noexcept() { #if TEST_STD_VER >= 11 typedef typename std::conditional<!IsArray, int, int[]>::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 <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional<!IsArray, A, A[]>::type VT; const int expect_alive = IsArray ? 5 : 1; { // MoveConstructible deleter (C-1) A* p = newValue<VT>(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); std::unique_ptr<VT, Deleter<VT> > s(p, Deleter<VT>(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<VT>(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); CopyDeleter<VT> d(5); std::unique_ptr<VT, CopyDeleter<VT> > 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<VT>(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); NCDeleter<VT> d(5); std::unique_ptr<VT, NCDeleter<VT>&> 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<VT>(expect_alive); - assert(A::count == expect_alive); + if (!TEST_IS_CONSTANT_EVALUATED) + assert(A::count == expect_alive); NCConstDeleter<VT> d(5); std::unique_ptr<VT, NCConstDeleter<VT> 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<IsArray, int[], int>::type VT2; - my_free_called = false; - { - int i = 0; - std::unique_ptr<VT2, void (*)(void*)> 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<IsArray, int[], int>::type VT2; + my_free_called = false; + { + int i = 0; + std::unique_ptr<VT2, void (*)(void*)> 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<A, Deleter<A> > s(p, Deleter<A>(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<void, void (*)(void*)> 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<void, void (*)(void*)> 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 <bool IsArray> -void test_nullptr() { +TEST_CONSTEXPR_CXX23 void test_nullptr() { #if TEST_STD_VER >= 11 typedef typename std::conditional<!IsArray, A, A[]>::type VT; { @@ -309,7 +325,7 @@ #endif } -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { { test_basic</*IsArray*/ false>(); test_nullptr<false>(); @@ -325,5 +341,14 @@ test_noexcept<true>(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp @@ -24,15 +24,15 @@ Deleter& operator=(Deleter&); public: - Deleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {} - int state() const { return state_; } + TEST_CONSTEXPR_CXX23 int state() const { return state_; } - void operator()(void*) { ++state_; } + TEST_CONSTEXPR_CXX23 void operator()(void*) { ++state_; } }; template <class T> -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { Deleter d; assert(d.state() == 0); { @@ -41,11 +41,17 @@ assert(&p.get_deleter() == &d); } assert(d.state() == 0); + + return true; } int main(int, char**) { test_basic<int>(); test_basic<int[]>(); +#if TEST_STD_VER >= 23 + static_assert(test_basic<int>()); + static_assert(test_basic<int[]>()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp +++ b/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 <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional<IsArray, A[], A>::type VT; const int expect_alive = IsArray ? 3 : 1; #if TEST_STD_VER >= 11 @@ -31,10 +31,12 @@ #endif { std::unique_ptr<VT> p(newValue<VT>(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</*IsArray*/ false>(); test_basic<true>(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp +++ b/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 <bool IsArray> -void test_reset_pointer() { +TEST_CONSTEXPR_CXX23 void test_reset_pointer() { typedef typename std::conditional<IsArray, A[], A>::type VT; const int expect_alive = IsArray ? 3 : 1; #if TEST_STD_VER >= 11 { using U = std::unique_ptr<VT>; - U u; ((void)u); + U u; + ((void)u); ASSERT_NOEXCEPT(u.reset((A*)nullptr)); } #endif { std::unique_ptr<VT> p(newValue<VT>(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<VT>(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<const VT> p(newValue<const VT>(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<VT>(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 <bool IsArray> -void test_reset_nullptr() { +TEST_CONSTEXPR_CXX23 void test_reset_nullptr() { typedef typename std::conditional<IsArray, A[], A>::type VT; const int expect_alive = IsArray ? 3 : 1; #if TEST_STD_VER >= 11 { using U = std::unique_ptr<VT>; - U u; ((void)u); + U u; + ((void)u); ASSERT_NOEXCEPT(u.reset(nullptr)); } #endif { std::unique_ptr<VT> p(newValue<VT>(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 <bool IsArray> -void test_reset_no_arg() { +TEST_CONSTEXPR_CXX23 void test_reset_no_arg() { typedef typename std::conditional<IsArray, A[], A>::type VT; const int expect_alive = IsArray ? 3 : 1; #if TEST_STD_VER >= 11 { using U = std::unique_ptr<VT>; - U u; ((void)u); + U u; + ((void)u); ASSERT_NOEXCEPT(u.reset()); } #endif { std::unique_ptr<VT> p(newValue<VT>(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</*IsArray*/ false>(); test_reset_nullptr<false>(); @@ -114,5 +130,14 @@ test_reset_no_arg<true>(); } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp +++ b/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<A> 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<A> 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; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp @@ -13,16 +13,28 @@ // test reset against resetting self #include <memory> +#include <cassert> #include "test_macros.h" struct A { std::unique_ptr<A> ptr_; - A() : ptr_(this) {} - void reset() { ptr_.reset(); } + TEST_CONSTEXPR_CXX23 A() : ptr_(this) {} + TEST_CONSTEXPR_CXX23 void reset() { ptr_.reset(); } }; -int main(int, char**) { (new A)->reset(); +TEST_CONSTEXPR_CXX23 bool test() { + (new A)->reset(); + + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp +++ b/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 <class T> -typename std::remove_all_extents<T>::type* newValueInit(int size, - int new_value) { +TEST_CONSTEXPR_CXX23 typename std::remove_all_extents<T>::type* newValueInit(int size, int new_value) { typedef typename std::remove_all_extents<T>::type VT; VT* p = newValue<T>(size); for (int i = 0; i < size; ++i) @@ -48,7 +57,7 @@ } template <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 void test_basic() { typedef typename std::conditional<IsArray, TT[], TT>::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</*IsArray*/ false>(); test_basic<true>(); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp @@ -17,9 +17,17 @@ #include "test_macros.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { std::unique_ptr<int> p(new int(3)); assert(*p == 3); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp @@ -19,7 +19,7 @@ #include "unique_ptr_test_helper.h" template <class UPtr> -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 <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { typedef typename std::conditional<IsArray, int[], int>::type VT; typedef std::unique_ptr<VT> U; { @@ -57,11 +57,17 @@ doTest(p, false); doTest(cp, false); } + + return true; } int main(int, char**) { test_basic</*IsArray*/ false>(); test_basic<true>(); +#if TEST_STD_VER >= 23 + static_assert(test_basic</*IsArray*/ false>()); + static_assert(test_basic<true>()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp @@ -19,7 +19,7 @@ #include "unique_ptr_test_helper.h" template <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { typedef typename std::conditional<IsArray, int[], int>::type VT; typedef const VT CVT; { @@ -42,11 +42,17 @@ assert(s.get() == p); assert(sc.get() == s.get()); } + + return true; } int main(int, char**) { test_basic</*IsArray*/ false>(); test_basic<true>(); +#if TEST_STD_VER >= 23 + static_assert(test_basic</*IsArray*/ false>()); + static_assert(test_basic<true>()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp @@ -17,16 +17,16 @@ #include "test_macros.h" struct Deleter { - Deleter() {} + TEST_CONSTEXPR_CXX23 Deleter() {} - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} - int test() { return 5; } - int test() const { return 6; } + TEST_CONSTEXPR_CXX23 int test() { return 5; } + TEST_CONSTEXPR_CXX23 int test() const { return 6; } }; template <bool IsArray> -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { typedef typename std::conditional<IsArray, int[], int>::type VT; { std::unique_ptr<int, Deleter> p; @@ -56,11 +56,17 @@ assert(p.get_deleter().test() == 5); assert(cp.get_deleter().test() == 5); } + + return true; } int main(int, char**) { test_basic</*IsArray*/ false>(); test_basic<true>(); +#if TEST_STD_VER >= 23 + static_assert(test_basic</*IsArray*/ false>()); + static_assert(test_basic<true>()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp @@ -20,12 +20,21 @@ struct A { int i_; - A() : i_(7) {} + TEST_CONSTEXPR_CXX23 A() : i_(7) {} }; -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { std::unique_ptr<A> p(new A); assert(p->i_ == 7); + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp @@ -22,12 +22,21 @@ static int next_; public: - A() : state_(++next_) {} - int get() const { return state_; } + TEST_CONSTEXPR_CXX23 A() { +#if TEST_STD_VER >= 23 + if (TEST_IS_CONSTANT_EVALUATED) { + state_ = 0; + } else +#endif + { + 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 +44,13 @@ int A::next_ = 0; -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { std::unique_ptr<A[]> 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 +58,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; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp @@ -17,31 +17,39 @@ class foo { public: - foo () : val_(3) {} - int get () const { return val_; } + TEST_CONSTEXPR_CXX23 foo() : val_(3) {} + TEST_CONSTEXPR_CXX23 int get() const { return val_; } + private: - int val_; - }; + int val_; +}; -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX23 bool test() { + { auto p1 = std::make_unique<int[]>(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<std::string[]>(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<foo[]>(7); - for ( int i = 0; i < 7; ++i ) - assert ( p3[i].get () == 3 ); - } + for (int i = 0; i < 7; ++i) + assert(p3[i].get() == 3); + } + + return true; +} +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp @@ -13,23 +13,30 @@ #include "test_macros.h" -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX23 bool test() { + { std::unique_ptr<int> p1 = std::make_unique<int>(1); - assert ( *p1 == 1 ); - p1 = std::make_unique<int> (); - assert ( *p1 == 0 ); - } + assert(*p1 == 1); + p1 = std::make_unique<int>(); + assert(*p1 == 0); + } - { - std::unique_ptr<std::string> p2 = std::make_unique<std::string> ( "Meow!" ); - assert ( *p2 == "Meow!" ); - p2 = std::make_unique<std::string> (); - assert ( *p2 == "" ); - p2 = std::make_unique<std::string> ( 6, 'z' ); - assert ( *p2 == "zzzzzz" ); - } + { + std::unique_ptr<std::string> p2 = std::make_unique<std::string>("Meow!"); + assert(*p2 == "Meow!"); + p2 = std::make_unique<std::string>(); + assert(*p2 == ""); + p2 = std::make_unique<std::string>(6, 'z'); + assert(*p2 == "zzzzzz"); + } + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp @@ -14,38 +14,30 @@ #include <cassert> #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<B> d2; - std::default_delete<A> d1 = d2; - A* p = new B; +TEST_CONSTEXPR_CXX23 bool test() { + std::default_delete<B> d2; + std::default_delete<A> 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; +} - return 0; +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp @@ -14,24 +14,25 @@ #include <cassert> #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<A> 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<A> d; - A* p = new A; - assert(A::count == 1); - d(p); + if (!TEST_IS_CONSTANT_EVALUATED) assert(A::count == 0); - return 0; + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp @@ -11,7 +11,7 @@ // default_delete[] // template <class U> -// default_delete(const default_delete<U[]>&); +// constexpr default_delete(const default_delete<U[]>&); // constexpr since C++23 // // This constructor shall not participate in overload resolution unless // U(*)[] is convertible to T(*)[]. @@ -21,11 +21,17 @@ #include "test_macros.h" -int main(int, char**) -{ - std::default_delete<int[]> d1; - std::default_delete<const int[]> d2 = d1; - ((void)d2); +TEST_CONSTEXPR_CXX23 bool test() { + std::default_delete<int[]> d1; + std::default_delete<const int[]> d2 = d1; + ((void)d2); - return 0; + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp @@ -16,24 +16,25 @@ #include <cassert> #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<A[]> 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<A[]> d; - A* p = new A[3]; - assert(A::count == 3); - d(p); + if (!TEST_IS_CONSTANT_EVALUATED) assert(A::count == 0); - return 0; + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp @@ -0,0 +1,138 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include <cassert> +#include <memory> +#include <utility> + +#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<int>(42); + //auto p2 = make_unique_for_overwrite<int>(); + //swap(p1, p2); + //assert(p1 == p1); + //assert(p1 != p2); + + //auto p3 = make_unique<int[]>(10); + //auto p4 = make_unique_for_overwrite<int[]>(4); + //swap(p3, p4); + //assert(p3 == p3); + //assert(p3 != p4); + + auto p5 = unique_ptr<int>{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<int>{new int{}}; + auto d1 = default_delete<int>{}; + auto p2 = unique_ptr<int>{new int{}, d1}; + auto p3 = unique_ptr<int>{new int{}, default_delete<int>{}}; + auto p4 = std::move(p3); + auto p5 = unique_ptr<int>{nullptr}; + auto p6 = unique_ptr<int, default_delete<int>&>{new int{}, d1}; + auto p7 = unique_ptr<int>{std::move(p6)}; + + // assignment + p3 = std::move(p4); + auto p8 = unique_ptr<int, default_delete<int>&>{new int{}, d1}; + p7 = std::move(p8); + p1 = nullptr; + + // observers + assert(*p2 == 0); + auto p9 = unique_ptr<Dummy>{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<bool>(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<int[]>{new int[5]}; + auto d1 = default_delete<int[]>{}; + auto p2 = unique_ptr<int[]>{new int[5], d1}; + auto p3 = unique_ptr<int[]>{new int[5], default_delete<int[]>{}}; + auto p4 = std::move(p1); + auto p5 = unique_ptr<int[], default_delete<int[]>&>{new int[5], d1}; + auto p6 = unique_ptr<int[]>{std::move(p5)}; + + // assignment + p1 = std::move(p4); + auto p7 = unique_ptr<int[], default_delete<int[]>&>{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<bool>(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 diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp +++ b/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<std::unique_ptr<int> >(); #if TEST_STD_VER > 17 AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>>(); @@ -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<B, Deleter<B> > 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<A[], Deleter<A[]> > 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<B[], Deleter<B[]> > 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<A, Deleter<A> > 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<B, Deleter<B> > 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; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp @@ -8,69 +8,74 @@ // <memory> -// shared_ptr +// unique_ptr // template <class T, class D> -// bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; +// constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; // constexpr since C++23 // template <class T, class D> -// bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; +// bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept; // removed in C++20 // template <class T, class D> -// bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; +// bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept; // removed in C++20 // template <class T, class D> -// bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; +// bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept; // removed in C++20 // template <class T, class D> -// bool operator<(const unique_ptr<T, D>& x, nullptr_t); +// constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t); // constexpr since C++23 // template <class T, class D> -// bool operator<(nullptr_t, const unique_ptr<T, D>& y); +// constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& y); // constexpr since C++23 // template <class T, class D> -// bool operator<=(const unique_ptr<T, D>& x, nullptr_t); +// constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t); // constexpr since C++23 // template <class T, class D> -// bool operator<=(nullptr_t, const unique_ptr<T, D>& y); +// constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& y); // constexpr since C++23 // template <class T, class D> -// bool operator>(const unique_ptr<T, D>& x, nullptr_t); +// constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t); // constexpr since C++23 // template <class T, class D> -// bool operator>(nullptr_t, const unique_ptr<T, D>& y); +// constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& y); // constexpr since C++23 // template <class T, class D> -// bool operator>=(const unique_ptr<T, D>& x, nullptr_t); +// constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t); // constexpr since C++23 // template <class T, class D> -// bool operator>=(nullptr_t, const unique_ptr<T, D>& y); +// constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& y); // constexpr since C++23 // template<class T, class D> // requires three_Âway_Âcomparable<typename unique_ptr<T, D>::pointer> // constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer> -// operator<=>(const unique_ptr<T, D>& x, nullptr_t); // C++20 +// operator<=>(const unique_ptr<T, D>& x, nullptr_t); // C++20 #include <memory> #include <cassert> +#include <type_traits> #include "test_macros.h" #include "test_comparisons.h" -int main(int, char**) -{ - AssertEqualityAreNoexcept<std::unique_ptr<int>, nullptr_t>(); - AssertEqualityAreNoexcept<nullptr_t, std::unique_ptr<int> >(); - AssertComparisonsReturnBool<std::unique_ptr<int>, nullptr_t>(); - AssertComparisonsReturnBool<nullptr_t, std::unique_ptr<int> >(); +TEST_CONSTEXPR_CXX23 bool test() { + if (!TEST_IS_CONSTANT_EVALUATED) { + AssertEqualityAreNoexcept<std::unique_ptr<int>, nullptr_t>(); + AssertEqualityAreNoexcept<nullptr_t, std::unique_ptr<int> >(); + AssertComparisonsReturnBool<std::unique_ptr<int>, nullptr_t>(); + AssertComparisonsReturnBool<nullptr_t, std::unique_ptr<int> >(); #if TEST_STD_VER > 17 - AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>, nullptr_t>(); - AssertOrderReturn<std::strong_ordering, nullptr_t, std::unique_ptr<int>>(); + AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>, nullptr_t>(); + AssertOrderReturn<std::strong_ordering, nullptr_t, std::unique_ptr<int>>(); #endif + } const std::unique_ptr<int> 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<int> p2; assert((p2 == nullptr)); @@ -87,5 +92,14 @@ assert((nullptr <=> p2) == std::strong_ordering::equivalent); #endif + return true; +} + +int main(int, char**) { + test(); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp +++ b/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 <class T> 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<A, Deleter<A> > s1(p1, Deleter<A>(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<A[], Deleter<A[]> > s1(p1, Deleter<A[]>(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; } diff --git a/libcxx/test/support/deleter_types.h b/libcxx/test/support/deleter_types.h --- a/libcxx/test/support/deleter_types.h +++ b/libcxx/test/support/deleter_types.h @@ -25,441 +25,440 @@ #if TEST_STD_VER >= 11 template <class T> -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 <class U> - Deleter(Deleter<U>&& d, - typename std::enable_if<!std::is_same<U, T>::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 <class U> + TEST_CONSTEXPR_CXX23 Deleter(Deleter<U>&& d, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) + : state_(d.state()) { + d.set_state(0); + } private: - template <class U> - Deleter(const Deleter<U>& d, - typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); + template <class U> + Deleter(const Deleter<U>& d, typename std::enable_if<!std::is_same<U, T>::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 T> -class Deleter<T[]> -{ - int state_; +class Deleter<T[]> { + 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 T> -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 <class U> - Deleter(Deleter<U> d, - typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) - : state_(d.state()) {} + template <class U> + Deleter(Deleter<U> d, typename std::enable_if<!std::is_same<U, T>::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 T> -class Deleter<T[]> -{ - mutable int state_; +class Deleter<T[]> { + 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 <class T> -void -swap(Deleter<T>& x, Deleter<T>& y) -{ - Deleter<T> t(std::move(x)); - x = std::move(y); - y = std::move(t); +TEST_CONSTEXPR_CXX23 void swap(Deleter<T>& x, Deleter<T>& y) { + Deleter<T> t(std::move(x)); + x = std::move(y); + y = std::move(t); } - template <class T> -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 <class U> - CDeleter(const CDeleter<U>& d) - : state_(d.state()) {} + template <class U> + TEST_CONSTEXPR_CXX23 CDeleter(const CDeleter<U>& 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 T> -class CDeleter<T[]> -{ - int state_; +class CDeleter<T[]> { + int state_; public: + TEST_CONSTEXPR_CXX23 CDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit CDeleter(int s) : state_(s) {} + template <class U> + TEST_CONSTEXPR_CXX23 CDeleter(const CDeleter<U>& d) : state_(d.state()) {} - CDeleter() : state_(0) {} - explicit CDeleter(int s) : state_(s) {} - template <class U> - CDeleter(const CDeleter<U>& 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 <class T> -void -swap(CDeleter<T>& x, CDeleter<T>& y) -{ - CDeleter<T> t(std::move(x)); - x = std::move(y); - y = std::move(t); +TEST_CONSTEXPR_CXX23 void swap(CDeleter<T>& x, CDeleter<T>& y) { + CDeleter<T> t(std::move(x)); + x = std::move(y); + y = std::move(t); } // Non-copyable deleter template <class T> -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 T> -class NCDeleter<T[]> -{ - int state_; - NCDeleter(NCDeleter const&); - NCDeleter& operator=(NCDeleter const&); -public: +class NCDeleter<T[]> { + 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 T> -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 T> -class NCConstDeleter<T[]> -{ - int state_; - NCConstDeleter(NCConstDeleter const&); - NCConstDeleter& operator=(NCConstDeleter const&); -public: +class NCConstDeleter<T[]> { + 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 T> -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 T> -class CopyDeleter<T[]> -{ - int state_; +class CopyDeleter<T[]> { + 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 T> -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 <class T> -void -swap(test_deleter<T>& x, test_deleter<T>& y) -{ - test_deleter<T> t(std::move(x)); - x = std::move(y); - y = std::move(t); +void swap(test_deleter<T>& x, test_deleter<T>& y) { + test_deleter<T> t(std::move(x)); + x = std::move(y); + y = std::move(t); } #if TEST_STD_VER >= 11 template <class T, size_t ID = 0> -class PointerDeleter -{ - PointerDeleter(const PointerDeleter&); - PointerDeleter& operator=(const PointerDeleter&); +class PointerDeleter { + PointerDeleter(const PointerDeleter&); + PointerDeleter& operator=(const PointerDeleter&); public: - typedef min_pointer<T, std::integral_constant<size_t, ID>> pointer; + typedef min_pointer<T, std::integral_constant<size_t, ID>> 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 <class U> - PointerDeleter(PointerDeleter<U, ID>&&, - typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) - {} + template <class U> + TEST_CONSTEXPR_CXX23 + PointerDeleter(PointerDeleter<U, ID>&&, typename std::enable_if<!std::is_same<U, T>::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 <class U> - PointerDeleter(const PointerDeleter<U, ID>&, - typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); + template <class U> + PointerDeleter(const PointerDeleter<U, ID>&, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); }; - template <class T, size_t ID> -class PointerDeleter<T[], ID> -{ - PointerDeleter(const PointerDeleter&); - PointerDeleter& operator=(const PointerDeleter&); +class PointerDeleter<T[], ID> { + PointerDeleter(const PointerDeleter&); + PointerDeleter& operator=(const PointerDeleter&); public: - typedef min_pointer<T, std::integral_constant<size_t, ID> > pointer; + typedef min_pointer<T, std::integral_constant<size_t, ID> > 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 <class U> - PointerDeleter(PointerDeleter<U, ID>&&, - typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) - {} + template <class U> + TEST_CONSTEXPR_CXX23 + PointerDeleter(PointerDeleter<U, ID>&&, typename std::enable_if<!std::is_same<U, T>::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 <class U> - PointerDeleter(const PointerDeleter<U, ID>&, - typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); + template <class U> + PointerDeleter(const PointerDeleter<U, ID>&, typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); }; #endif // TEST_STD_VER >= 11 template <class T> -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 T> -class DefaultCtorDeleter<T[]> -{ - int state_; +class DefaultCtorDeleter<T[]> { + int state_; public: - int state() const {return state_;} - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; #endif // SUPPORT_DELETER_TYPES_H diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -166,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 diff --git a/libcxx/test/support/unique_ptr_test_helper.h b/libcxx/test/support/unique_ptr_test_helper.h --- a/libcxx/test/support/unique_ptr_test_helper.h +++ b/libcxx/test/support/unique_ptr_test_helper.h @@ -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 <class T> -typename std::enable_if<!std::is_array<T>::value, T*>::type -newValue(int num_elements) { +TEST_CONSTEXPR_CXX23 typename std::enable_if<!std::is_array<T>::value, T*>::type newValue(int num_elements) { assert(num_elements == 1); return new T; } template <class T> -typename std::enable_if<std::is_array<T>::value, - typename std::remove_all_extents<T>::type*>::type +TEST_CONSTEXPR_CXX23 typename std::enable_if<std::is_array<T>::value, typename std::remove_all_extents<T>::type*>::type newValue(int num_elements) { typedef typename std::remove_all_extents<T>::type VT; assert(num_elements >= 1); @@ -57,33 +73,34 @@ IncompleteType* getNewIncompleteArray(int size); #if TEST_STD_VER >= 11 -template <class ThisT, class ...Args> +template <class ThisT, class... Args> struct args_is_this_type : std::false_type {}; template <class ThisT, class A1> struct args_is_this_type<ThisT, A1> : std::is_same<ThisT, typename std::decay<A1>::type> {}; #endif -template <class IncompleteT = IncompleteType, - class Del = std::default_delete<IncompleteT> > +template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT> > struct StoresIncomplete { - static_assert((std::is_same<IncompleteT, IncompleteType>::value || - std::is_same<IncompleteT, IncompleteType[]>::value), ""); + static_assert( + (std::is_same<IncompleteT, IncompleteType>::value || std::is_same<IncompleteT, IncompleteType[]>::value), ""); std::unique_ptr<IncompleteT, Del> m_ptr; #if TEST_STD_VER >= 11 StoresIncomplete(StoresIncomplete const&) = delete; - StoresIncomplete(StoresIncomplete&&) = default; + StoresIncomplete(StoresIncomplete&&) = default; - template <class ...Args> + template <class... Args> StoresIncomplete(Args&&... args) : m_ptr(std::forward<Args>(args)...) { static_assert(!args_is_this_type<StoresIncomplete, Args...>::value, ""); } #else + private: StoresIncomplete(); StoresIncomplete(StoresIncomplete const&); + public: #endif @@ -94,8 +111,7 @@ }; #if TEST_STD_VER >= 11 -template <class IncompleteT = IncompleteType, - class Del = std::default_delete<IncompleteT>, class... Args> +template <class IncompleteT = IncompleteType, class Del = std::default_delete<IncompleteT>, 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 <class IncompleteT, class Del> \ +#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 <class IncompleteT, class Del> \ StoresIncomplete<IncompleteT, Del>::~StoresIncomplete() {} # #if TEST_STD_VER >= 11 -#define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ - static int is_incomplete_test() { __VA_ARGS__ return 0; } \ - INCOMPLETE_TEST_EPILOGUE() +# define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ + static int is_incomplete_test() { __VA_ARGS__ return 0; } \ + INCOMPLETE_TEST_EPILOGUE() #else -#define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ - static int is_incomplete_test() { return 0; } \ - INCOMPLETE_TEST_EPILOGUE() +# define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ + static int is_incomplete_test() { return 0; } \ + INCOMPLETE_TEST_EPILOGUE() #endif #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -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",