diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -310,6 +310,8 @@ ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_cmath`` *unimplemented* ------------------------------------------------- ----------------- + ``__cpp_lib_constexpr_memory`` ``202202L`` + ------------------------------------------------- ----------------- ``__cpp_lib_constexpr_typeinfo`` *unimplemented* ------------------------------------------------- ----------------- ``__cpp_lib_invoke_r`` *unimplemented* diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -38,6 +38,7 @@ Implemented Papers ------------------ - P2499R0 - ``string_view`` range constructor should be ``explicit`` +- P2273R3 - Making ``std::unique_ptr`` constexpr Improvements and New Features ----------------------------- diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv --- a/libcxx/docs/Status/Cxx2bPapers.csv +++ b/libcxx/docs/Status/Cxx2bPapers.csv @@ -44,7 +44,7 @@ "`P1206R7 `__","LWG","``ranges::to``: A function to convert any range to a container","February 2022","","" "`P1413R3 `__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","","" "`P2255R3 `__","LWG","A type trait to detect reference binding to temporary","February 2022","","" -"`P2273R3 `__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","","" +"`P2273R3 `__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Complete|","16.0" "`P2387R3 `__","LWG","Pipe support for user-defined range adaptors","February 2022","","" "`P2440R1 `__","LWG","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","February 2022","","" "`P2441R2 `__","LWG","``views::join_view``","February 2022","","" diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -849,6 +849,12 @@ # define _LIBCPP_CONSTEXPR_AFTER_CXX17 # endif +# if _LIBCPP_STD_VER > 20 +# define _LIBCPP_CONSTEXPR_CXX23 constexpr +# else +# define _LIBCPP_CONSTEXPR_CXX23 +# endif + # if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC) # define _LIBCPP_NODISCARD [[nodiscard]] # elif defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG) diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h --- a/libcxx/include/__memory/unique_ptr.h +++ b/libcxx/include/__memory/unique_ptr.h @@ -32,20 +32,17 @@ template struct _LIBCPP_TEMPLATE_VIS default_delete { - static_assert(!is_function<_Tp>::value, - "default_delete cannot be instantiated for function types"); + static_assert(!is_function<_Tp>::value, "default_delete cannot be instantiated for function types"); #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default; #else _LIBCPP_INLINE_VISIBILITY default_delete() {} #endif template - _LIBCPP_INLINE_VISIBILITY - default_delete(const default_delete<_Up>&, - typename enable_if::value>::type* = - 0) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 default_delete( + const default_delete<_Up>&, typename enable_if::value>::type* = 0) _NOEXCEPT {} - _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 void operator()(_Tp* __ptr) const _NOEXCEPT { static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type"); static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type"); delete __ptr; @@ -56,8 +53,7 @@ struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> { private: template - struct _EnableIfConvertible - : enable_if::value> {}; + struct _EnableIfConvertible : enable_if::value> {}; public: #ifndef _LIBCPP_CXX03_LANG @@ -67,13 +63,11 @@ #endif template - _LIBCPP_INLINE_VISIBILITY - default_delete(const default_delete<_Up[]>&, - typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 + default_delete(const default_delete<_Up[]>&, typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {} template - _LIBCPP_INLINE_VISIBILITY - typename _EnableIfConvertible<_Up>::type + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename _EnableIfConvertible<_Up>::type operator()(_Up* __ptr) const _NOEXCEPT { static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type"); delete[] __ptr; @@ -115,127 +109,100 @@ typedef _Dp deleter_type; typedef _LIBCPP_NODEBUG typename __pointer<_Tp, deleter_type>::type pointer; - static_assert(!is_rvalue_reference::value, - "the specified deleter type cannot be an rvalue reference"); + static_assert(!is_rvalue_reference::value, "the specified deleter type cannot be an rvalue reference"); private: __compressed_pair __ptr_; - struct __nat { int __for_bool_; }; + struct __nat { + int __for_bool_; + }; typedef _LIBCPP_NODEBUG __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE; template - using _LValRefType _LIBCPP_NODEBUG = - typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; + using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; template - using _GoodRValRefType _LIBCPP_NODEBUG = - typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; + using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; template - using _BadRValRefType _LIBCPP_NODEBUG = - typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; + using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; - template , _Dummy>::type> + template , _Dummy>::type> using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG = - typename enable_if::value && - !is_pointer<_Deleter>::value>::type; + typename enable_if::value && !is_pointer<_Deleter>::value>::type; template using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = typename enable_if::value>::type; template - using _EnableIfMoveConvertible _LIBCPP_NODEBUG = typename enable_if< - is_convertible::value && - !is_array<_Up>::value - >::type; + using _EnableIfMoveConvertible _LIBCPP_NODEBUG = + typename enable_if< is_convertible::value && !is_array<_Up>::value >::type; template - using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = typename enable_if< - (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || - (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) - >::type; + using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = + typename enable_if< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || + (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >::type; template - using _EnableIfDeleterAssignable = typename enable_if< - is_assignable<_Dp&, _UDel&&>::value - >::type; + using _EnableIfDeleterAssignable = typename enable_if< is_assignable<_Dp&, _UDel&&>::value >::type; public: - template > - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} + template > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} - template > - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} + template > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT + : __ptr_(__value_init_tag(), __value_init_tag()) {} - template > - _LIBCPP_INLINE_VISIBILITY - explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} + template > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 explicit unique_ptr(pointer __p) _NOEXCEPT + : __ptr_(__p, __value_init_tag()) {} - template > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT + template > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {} - template > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT + template > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, _VSTD::move(__d)) { - static_assert(!is_reference::value, - "rvalue deleter bound to reference"); + static_assert(!is_reference::value, "rvalue deleter bound to reference"); } - template > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete; + template > > + _LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete; - _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr&& __u) _NOEXCEPT - : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT + : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) {} - template , _Up>, - class = _EnableIfDeleterConvertible<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT + template , _Up>, + class = _EnableIfDeleterConvertible<_Ep> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_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) template - _LIBCPP_INLINE_VISIBILITY - unique_ptr(auto_ptr<_Up>&& __p, - typename enable_if::value && - is_same<_Dp, default_delete<_Tp> >::value, - __nat>::type = __nat()) _NOEXCEPT - : __ptr_(__p.release(), __value_init_tag()) {} + _LIBCPP_INLINE_VISIBILITY unique_ptr( + auto_ptr<_Up>&& __p, + typename enable_if::value && is_same<_Dp, default_delete<_Tp> >::value, __nat>::type = + __nat()) _NOEXCEPT : __ptr_(__p.release(), __value_init_tag()) {} #endif - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); return *this; } - template , _Up>, - class = _EnableIfDeleterAssignable<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { + template , _Up>, + class = _EnableIfDeleterAssignable<_Ep> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter()); return *this; @@ -244,8 +211,7 @@ #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) template _LIBCPP_INLINE_VISIBILITY - typename enable_if::value && - is_same<_Dp, default_delete<_Tp> >::value, + typename enable_if::value && is_same<_Dp, default_delete<_Tp> >::value, unique_ptr&>::type operator=(auto_ptr<_Up> __p) { reset(__p.release()); @@ -254,67 +220,46 @@ #endif #ifdef _LIBCPP_CXX03_LANG - unique_ptr(unique_ptr const&) = delete; + unique_ptr(unique_ptr const&) = delete; unique_ptr& operator=(unique_ptr const&) = delete; #endif - _LIBCPP_INLINE_VISIBILITY - ~unique_ptr() { reset(); } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 ~unique_ptr() { reset(); } - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(nullptr_t) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_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_CXX23 typename add_lvalue_reference<_Tp>::type operator*() const { return *__ptr_.first(); } - _LIBCPP_INLINE_VISIBILITY - 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 { - return __ptr_.second(); - } - _LIBCPP_INLINE_VISIBILITY - const deleter_type& get_deleter() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 pointer operator->() const _NOEXCEPT { return __ptr_.first(); } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY - explicit operator bool() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; } - _LIBCPP_INLINE_VISIBILITY - pointer release() _NOEXCEPT { - pointer __t = __ptr_.first(); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 pointer release() _NOEXCEPT { + pointer __t = __ptr_.first(); __ptr_.first() = pointer(); return __t; } - _LIBCPP_INLINE_VISIBILITY - void reset(pointer __p = pointer()) _NOEXCEPT { - pointer __tmp = __ptr_.first(); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_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 { - __ptr_.swap(__u.__ptr_); - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } }; - template class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> { public: @@ -331,455 +276,363 @@ template struct _CheckArrayPointerConversion<_FromElem*> : integral_constant::value || - (is_same::value && - is_convertible<_FromElem(*)[], element_type(*)[]>::value) - > - {}; + is_same<_FromElem*, pointer>::value || + (is_same::value && + is_convertible<_FromElem (*)[], element_type (*)[]>::value) > {}; typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE; template - using _LValRefType _LIBCPP_NODEBUG = - typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; + using _LValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; template - using _GoodRValRefType _LIBCPP_NODEBUG = - typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; + using _GoodRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; template - using _BadRValRefType _LIBCPP_NODEBUG = - typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; + using _BadRValRefType _LIBCPP_NODEBUG = typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; - template , _Dummy>::type> + template , _Dummy>::type> using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG = - typename enable_if::value && - !is_pointer<_Deleter>::value>::type; + typename enable_if::value && !is_pointer<_Deleter>::value>::type; template using _EnableIfDeleterConstructible _LIBCPP_NODEBUG = typename enable_if::value>::type; template - using _EnableIfPointerConvertible _LIBCPP_NODEBUG = typename enable_if< - _CheckArrayPointerConversion<_Pp>::value - >::type; - - template - using _EnableIfMoveConvertible _LIBCPP_NODEBUG = typename enable_if< - is_array<_Up>::value && - is_same::value && - is_same::value && - is_convertible<_ElemT(*)[], element_type(*)[]>::value - >::type; + using _EnableIfPointerConvertible _LIBCPP_NODEBUG = + typename enable_if< _CheckArrayPointerConversion<_Pp>::value >::type; + + template + using _EnableIfMoveConvertible _LIBCPP_NODEBUG = + typename enable_if< is_array<_Up>::value && is_same::value && + is_same::value && + is_convertible<_ElemT (*)[], element_type (*)[]>::value >::type; template - using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = typename enable_if< - (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || - (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) - >::type; + using _EnableIfDeleterConvertible _LIBCPP_NODEBUG = + typename enable_if< (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || + (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) >::type; template - using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = typename enable_if< - is_assignable<_Dp&, _UDel&&>::value - >::type; + using _EnableIfDeleterAssignable _LIBCPP_NODEBUG = typename enable_if< is_assignable<_Dp&, _UDel&&>::value >::type; public: - template > - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} - - template > - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} - - template , - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - explicit unique_ptr(_Pp __p) _NOEXCEPT + template > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(__value_init_tag(), __value_init_tag()) {} + + template > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT + : __ptr_(__value_init_tag(), __value_init_tag()) {} + + template , + class = _EnableIfPointerConvertible<_Pp> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 explicit unique_ptr(_Pp __p) _NOEXCEPT : __ptr_(__p, __value_init_tag()) {} - template >, - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT + template >, + class = _EnableIfPointerConvertible<_Pp> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, __d) {} - template > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT + template > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(nullptr, __d) {} - template >, - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT + template >, + class = _EnableIfPointerConvertible<_Pp> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(__p, _VSTD::move(__d)) { - static_assert(!is_reference::value, - "rvalue deleter bound to reference"); + static_assert(!is_reference::value, "rvalue deleter bound to reference"); } - template > > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT + template > > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT : __ptr_(nullptr, _VSTD::move(__d)) { - static_assert(!is_reference::value, - "rvalue deleter bound to reference"); + static_assert(!is_reference::value, "rvalue deleter bound to reference"); } - template >, - class = _EnableIfPointerConvertible<_Pp> > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete; + template >, + class = _EnableIfPointerConvertible<_Pp> > + _LIBCPP_INLINE_VISIBILITY unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete; - _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr&& __u) _NOEXCEPT - : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) { - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT + : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) {} - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward(__u.get_deleter()); return *this; } - template , _Up>, - class = _EnableIfDeleterConvertible<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT - : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) { - } + template , _Up>, + class = _EnableIfDeleterConvertible<_Ep> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT + : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {} - template , _Up>, - class = _EnableIfDeleterAssignable<_Ep> - > - _LIBCPP_INLINE_VISIBILITY - unique_ptr& - operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { + template , _Up>, + class = _EnableIfDeleterAssignable<_Ep> > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT { reset(__u.release()); __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter()); return *this; } #ifdef _LIBCPP_CXX03_LANG - unique_ptr(unique_ptr const&) = delete; + unique_ptr(unique_ptr const&) = delete; unique_ptr& operator=(unique_ptr const&) = delete; #endif + public: - _LIBCPP_INLINE_VISIBILITY - ~unique_ptr() { reset(); } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 ~unique_ptr() { reset(); } - _LIBCPP_INLINE_VISIBILITY - unique_ptr& operator=(nullptr_t) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 unique_ptr& operator=(nullptr_t) _NOEXCEPT { reset(); return *this; } - _LIBCPP_INLINE_VISIBILITY - typename add_lvalue_reference<_Tp>::type + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_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_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); } - _LIBCPP_INLINE_VISIBILITY - deleter_type& get_deleter() _NOEXCEPT { - return __ptr_.second(); - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 deleter_type& get_deleter() _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY - const deleter_type& get_deleter() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 const deleter_type& get_deleter() const _NOEXCEPT { return __ptr_.second(); } - _LIBCPP_INLINE_VISIBILITY - explicit operator bool() const _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 explicit operator bool() const _NOEXCEPT { return __ptr_.first() != nullptr; } - _LIBCPP_INLINE_VISIBILITY - pointer release() _NOEXCEPT { - pointer __t = __ptr_.first(); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 pointer release() _NOEXCEPT { + pointer __t = __ptr_.first(); __ptr_.first() = pointer(); return __t; } template - _LIBCPP_INLINE_VISIBILITY - typename enable_if< - _CheckArrayPointerConversion<_Pp>::value - >::type + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename enable_if< _CheckArrayPointerConversion<_Pp>::value >::type reset(_Pp __p) _NOEXCEPT { - pointer __tmp = __ptr_.first(); + pointer __tmp = __ptr_.first(); __ptr_.first() = __p; if (__tmp) __ptr_.second()(__tmp); } - _LIBCPP_INLINE_VISIBILITY - void reset(nullptr_t = nullptr) _NOEXCEPT { - pointer __tmp = __ptr_.first(); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_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 { - __ptr_.swap(__u.__ptr_); - } - + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 void swap(unique_ptr& __u) _NOEXCEPT { __ptr_.swap(__u.__ptr_); } }; template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if< - __is_swappable<_Dp>::value, - void ->::type -swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename enable_if< __is_swappable<_Dp>::value, void >::type +swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT { + __x.swap(__y); +} template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_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 -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool +operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { + return !(__x == __y); +} #endif template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) -{ - typedef typename unique_ptr<_T1, _D1>::pointer _P1; - typedef typename unique_ptr<_T2, _D2>::pointer _P2; - typedef typename common_type<_P1, _P2>::type _Vp; - return less<_Vp>()(__x.get(), __y.get()); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool +operator<(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { + typedef typename unique_ptr<_T1, _D1>::pointer _P1; + typedef typename unique_ptr<_T2, _D2>::pointer _P2; + typedef typename common_type<_P1, _P2>::type _Vp; + return less<_Vp>()(__x.get(), __y.get()); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool +operator>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { + return __y < __x; +} template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool +operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { + return !(__y < __x); +} template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);} - +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool +operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { + return !(__x < __y); +} #if _LIBCPP_STD_VER > 17 template -requires three_way_comparable_with::pointer, - typename unique_ptr<_T2, _D2>::pointer> -_LIBCPP_HIDE_FROM_ABI -compare_three_way_result_t::pointer, - typename unique_ptr<_T2, _D2>::pointer> -operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { - return compare_three_way()(__x.get(), __y.get()); + requires three_way_comparable_with < typename unique_ptr<_T1, _D1>::pointer, +typename unique_ptr<_T2, _D2>::pointer > + _LIBCPP_HIDE_FROM_ABI + compare_three_way_result_t::pointer, typename unique_ptr<_T2, _D2>::pointer> + operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) { + return compare_three_way()(__x.get(), __y.get()); } #endif template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT -{ - return !__x; +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool +operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { + return !__x; } #if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT -{ - return !__x; +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool +operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT { + return !__x; } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT -{ - return static_cast(__x); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool +operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT { + return static_cast(__x); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT -{ - return static_cast(__x); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool +operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT { + return static_cast(__x); } #endif // _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) -{ - typedef typename unique_ptr<_T1, _D1>::pointer _P1; - return less<_P1>()(__x.get(), nullptr); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) { + typedef typename unique_ptr<_T1, _D1>::pointer _P1; + return less<_P1>()(__x.get(), nullptr); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) -{ - typedef typename unique_ptr<_T1, _D1>::pointer _P1; - return less<_P1>()(nullptr, __x.get()); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) { + typedef typename unique_ptr<_T1, _D1>::pointer _P1; + return less<_P1>()(nullptr, __x.get()); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) -{ - return nullptr < __x; +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { + return nullptr < __x; } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) -{ - return __x < nullptr; +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) { + return __x < nullptr; } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) -{ - return !(nullptr < __x); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { + return !(nullptr < __x); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) -{ - return !(__x < nullptr); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { + return !(__x < nullptr); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) -{ - return !(__x < nullptr); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) { + return !(__x < nullptr); } template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) -{ - return !(nullptr < __x); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 bool operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { + return !(nullptr < __x); } #if _LIBCPP_STD_VER > 17 template -requires three_way_comparable::pointer> -_LIBCPP_HIDE_FROM_ABI -compare_three_way_result_t::pointer> + requires three_way_comparable::pointer> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_CXX23 + compare_three_way_result_t::pointer> operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { - return compare_three_way()(__x.get(), static_cast::pointer>(nullptr)); + return compare_three_way()(__x.get(), static_cast::pointer>(nullptr)); } #endif #if _LIBCPP_STD_VER > 11 -template -struct __unique_if -{ - typedef unique_ptr<_Tp> __unique_single; +template +struct __unique_if { + typedef unique_ptr<_Tp> __unique_single; }; -template -struct __unique_if<_Tp[]> -{ - typedef unique_ptr<_Tp[]> __unique_array_unknown_bound; +template +struct __unique_if<_Tp[]> { + typedef unique_ptr<_Tp[]> __unique_array_unknown_bound; }; -template -struct __unique_if<_Tp[_Np]> -{ - typedef void __unique_array_known_bound; +template +struct __unique_if<_Tp[_Np]> { + typedef void __unique_array_known_bound; }; -template -inline _LIBCPP_INLINE_VISIBILITY -typename __unique_if<_Tp>::__unique_single -make_unique(_Args&&... __args) -{ - return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...)); +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_CXX23 typename __unique_if<_Tp>::__unique_single +make_unique(_Args&&... __args) { + return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...)); } -template -inline _LIBCPP_INLINE_VISIBILITY -typename __unique_if<_Tp>::__unique_array_unknown_bound -make_unique(size_t __n) -{ - typedef typename remove_extent<_Tp>::type _Up; - return unique_ptr<_Tp>(new _Up[__n]()); +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_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 - typename __unique_if<_Tp>::__unique_array_known_bound - make_unique(_Args&&...) = delete; +template +typename __unique_if<_Tp>::__unique_array_known_bound make_unique(_Args&&...) = delete; #endif // _LIBCPP_STD_VER > 11 -template struct _LIBCPP_TEMPLATE_VIS hash; +template +struct _LIBCPP_TEMPLATE_VIS hash; template #ifdef _LIBCPP_CXX03_LANG struct _LIBCPP_TEMPLATE_VIS hash > #else -struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< - unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> > +struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> > #endif { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type; - _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; + _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type; + _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; #endif - _LIBCPP_INLINE_VISIBILITY - size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const - { - typedef typename unique_ptr<_Tp, _Dp>::pointer pointer; - return hash()(__ptr.get()); - } + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const { + typedef typename unique_ptr<_Tp, _Dp>::pointer pointer; + return hash()(__ptr.get()); + } }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/version b/libcxx/include/version --- a/libcxx/include/version +++ b/libcxx/include/version @@ -61,7 +61,8 @@ __cpp_lib_constexpr_dynamic_alloc 201907L __cpp_lib_constexpr_functional 201907L __cpp_lib_constexpr_iterator 201811L -__cpp_lib_constexpr_memory 201811L +__cpp_lib_constexpr_memory 202202L + 201811L // C++20 __cpp_lib_constexpr_numeric 201911L __cpp_lib_constexpr_string 201907L __cpp_lib_constexpr_string_view 201811L @@ -381,6 +382,8 @@ // # define __cpp_lib_bind_back 202202L # define __cpp_lib_byteswap 202110L // # define __cpp_lib_constexpr_cmath 202202L +# undef __cpp_lib_constexpr_memory +# define __cpp_lib_constexpr_memory 202202L // # define __cpp_lib_constexpr_typeinfo 202106L // # define __cpp_lib_invoke_r 202106L # define __cpp_lib_is_scoped_enum 202011L diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp @@ -23,6 +23,7 @@ __cpp_lib_atomic_value_initialization 201911L [C++20] __cpp_lib_constexpr_dynamic_alloc 201907L [C++20] __cpp_lib_constexpr_memory 201811L [C++20] + 202202L [C++2b] __cpp_lib_enable_shared_from_this 201603L [C++17] __cpp_lib_make_unique 201304L [C++14] __cpp_lib_out_ptr 202106L [C++2b] @@ -454,8 +455,8 @@ # ifndef __cpp_lib_constexpr_memory # error "__cpp_lib_constexpr_memory should be defined in c++2b" # endif -# if __cpp_lib_constexpr_memory != 201811L -# error "__cpp_lib_constexpr_memory should have the value 201811L in c++2b" +# if __cpp_lib_constexpr_memory != 202202L +# error "__cpp_lib_constexpr_memory should have the value 202202L in c++2b" # endif # ifndef __cpp_lib_enable_shared_from_this diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -58,6 +58,7 @@ __cpp_lib_constexpr_functional 201907L [C++20] __cpp_lib_constexpr_iterator 201811L [C++20] __cpp_lib_constexpr_memory 201811L [C++20] + 202202L [C++2b] __cpp_lib_constexpr_numeric 201911L [C++20] __cpp_lib_constexpr_string 201907L [C++20] __cpp_lib_constexpr_string_view 201811L [C++20] @@ -3915,8 +3916,8 @@ # ifndef __cpp_lib_constexpr_memory # error "__cpp_lib_constexpr_memory should be defined in c++2b" # endif -# if __cpp_lib_constexpr_memory != 201811L -# error "__cpp_lib_constexpr_memory should have the value 201811L in c++2b" +# if __cpp_lib_constexpr_memory != 202202L +# error "__cpp_lib_constexpr_memory should have the value 202202L in c++2b" # endif # ifndef __cpp_lib_constexpr_numeric diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp @@ -36,7 +36,7 @@ struct NonDefaultDeleter { NonDefaultDeleter() = delete; - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} }; #endif @@ -51,9 +51,9 @@ { // the constructor does not participate in overload resolution when // the deleter is not default constructible using Del = CDeleter; - using U1 = std::unique_ptr; - using U2 = std::unique_ptr; - using U3 = std::unique_ptr; + using U1 = std::unique_ptr; + using U2 = std::unique_ptr; + using U3 = std::unique_ptr; static_assert(!std::is_default_constructible::value, ""); static_assert(!std::is_default_constructible::value, ""); static_assert(!std::is_default_constructible::value, ""); @@ -62,7 +62,7 @@ } template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { #if TEST_STD_VER >= 11 { using U1 = std::unique_ptr; @@ -87,6 +87,8 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 0); } + + return true; } DEFINE_AND_RUN_IS_INCOMPLETE_TEST({ @@ -100,11 +102,17 @@ int main(int, char**) { { test_sfinae(); - test_basic(); + assert(test_basic()); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); +#endif } { test_sfinae(); test_basic(); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); +#endif } return 0; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp @@ -23,7 +23,7 @@ #include "unique_ptr_test_helper.h" template -void test_pointer_ctor() { +TEST_CONSTEXPR_CXX23 bool test_pointer_ctor() { { std::unique_ptr p(0); assert(p.get() == 0); @@ -33,10 +33,12 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 0); } + + return true; } template -void test_pointer_deleter_ctor() { +TEST_CONSTEXPR_CXX23 bool test_pointer_deleter_ctor() { { std::default_delete d; std::unique_ptr p(0, d); @@ -59,16 +61,25 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 5); } + + return true; } int main(int, char**) { { // test_pointer_ctor(); - test_pointer_deleter_ctor(); + assert(test_pointer_deleter_ctor()); +#if TEST_STD_VER >= 23 + static_assert(test_pointer_deleter_ctor()); +#endif } { - test_pointer_ctor(); - test_pointer_deleter_ctor(); + assert(test_pointer_ctor()); + assert(test_pointer_deleter_ctor()); +#if TEST_STD_VER >= 23 + static_assert(test_pointer_ctor()); + static_assert(test_pointer_deleter_ctor()); +#endif } return 0; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp @@ -18,7 +18,6 @@ #include "test_macros.h" #include "unique_ptr_test_helper.h" - #if TEST_STD_VER >= 11 TEST_CONSTINIT std::unique_ptr global_static_unique_ptr_single(nullptr); TEST_CONSTINIT std::unique_ptr global_static_unique_ptr_runtime(nullptr); @@ -30,15 +29,13 @@ #endif template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { #if TEST_STD_VER >= 11 { using U1 = std::unique_ptr; using U2 = std::unique_ptr >; - static_assert(std::is_nothrow_constructible::value, - ""); - static_assert(std::is_nothrow_constructible::value, - ""); + static_assert(std::is_nothrow_constructible::value, ""); + static_assert(std::is_nothrow_constructible::value, ""); } #endif { @@ -55,10 +52,12 @@ assert(p.get() == 0); assert(p.get_deleter().state() == 0); } + + return true; } template -void test_sfinae() { +TEST_CONSTEXPR_CXX23 bool test_sfinae() { #if TEST_STD_VER >= 11 { // the constructor does not participate in overload resolution when // the deleter is a pointer type @@ -68,41 +67,45 @@ { // the constructor does not participate in overload resolution when // the deleter is not default constructible using Del = CDeleter; - using U1 = std::unique_ptr; - using U2 = std::unique_ptr; - using U3 = std::unique_ptr; + using U1 = std::unique_ptr; + using U2 = std::unique_ptr; + using U3 = std::unique_ptr; static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); static_assert(!std::is_constructible::value, ""); } #endif + + return true; } DEFINE_AND_RUN_IS_INCOMPLETE_TEST({ { doIncompleteTypeTest(0, nullptr); } checkNumIncompleteTypeAlive(0); - { - doIncompleteTypeTest >(0, - nullptr); - } + { doIncompleteTypeTest >(0, nullptr); } checkNumIncompleteTypeAlive(0); { doIncompleteTypeTest(0, nullptr); } checkNumIncompleteTypeAlive(0); - { - doIncompleteTypeTest >( - 0, nullptr); - } + { doIncompleteTypeTest >(0, nullptr); } checkNumIncompleteTypeAlive(0); }) int main(int, char**) { { - test_basic(); - test_sfinae(); + assert(test_basic()); + assert(test_sfinae()); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_sfinae()); +#endif } { - test_basic(); - test_sfinae(); + assert(test_basic()); + assert(test_sfinae()); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_sfinae()); +#endif } return 0; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp @@ -24,15 +24,15 @@ Deleter& operator=(Deleter&); public: - Deleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {} - int state() const { return state_; } + TEST_CONSTEXPR_CXX23 int state() const { return state_; } - void operator()(void*) { ++state_; } + TEST_CONSTEXPR_CXX23 void operator()(void*) { ++state_; } }; template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { Deleter d; assert(d.state() == 0); { @@ -41,11 +41,17 @@ assert(&p.get_deleter() == &d); } assert(d.state() == 0); + + return true; } int main(int, char**) { - test_basic(); - test_basic(); + assert(test_basic()); + assert(test_basic()); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_basic()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp @@ -13,16 +13,28 @@ // test reset against resetting self #include +#include #include "test_macros.h" struct A { std::unique_ptr ptr_; - A() : ptr_(this) {} - void reset() { ptr_.reset(); } + TEST_CONSTEXPR_CXX23 A() : ptr_(this) {} + TEST_CONSTEXPR_CXX23 void reset() { ptr_.reset(); } }; -int main(int, char**) { (new A)->reset(); +TEST_CONSTEXPR_CXX23 bool test() { + (new A)->reset(); + + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp @@ -17,9 +17,17 @@ #include "test_macros.h" -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { std::unique_ptr p(new int(3)); assert(*p == 3); + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp @@ -19,7 +19,7 @@ #include "unique_ptr_test_helper.h" template -void doTest(UPtr& p, bool ExpectTrue) { +TEST_CONSTEXPR_CXX23 void doTest(UPtr& p, bool ExpectTrue) { if (p) assert(ExpectTrue); else @@ -32,7 +32,7 @@ } template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { typedef typename std::conditional::type VT; typedef std::unique_ptr U; { @@ -57,11 +57,17 @@ doTest(p, false); doTest(cp, false); } + + return true; } int main(int, char**) { - test_basic(); - test_basic(); + assert(test_basic()); + assert(test_basic()); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_basic()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp @@ -19,7 +19,7 @@ #include "unique_ptr_test_helper.h" template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { typedef typename std::conditional::type VT; typedef const VT CVT; { @@ -42,11 +42,17 @@ assert(s.get() == p); assert(sc.get() == s.get()); } + + return true; } int main(int, char**) { - test_basic(); - test_basic(); + assert(test_basic()); + assert(test_basic()); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_basic()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp @@ -17,16 +17,16 @@ #include "test_macros.h" struct Deleter { - Deleter() {} + TEST_CONSTEXPR_CXX23 Deleter() {} - void operator()(void*) const {} + TEST_CONSTEXPR_CXX23 void operator()(void*) const {} - int test() { return 5; } - int test() const { return 6; } + TEST_CONSTEXPR_CXX23 int test() { return 5; } + TEST_CONSTEXPR_CXX23 int test() const { return 6; } }; template -void test_basic() { +TEST_CONSTEXPR_CXX23 bool test_basic() { typedef typename std::conditional::type VT; { std::unique_ptr p; @@ -56,11 +56,17 @@ assert(p.get_deleter().test() == 5); assert(cp.get_deleter().test() == 5); } + + return true; } int main(int, char**) { - test_basic(); - test_basic(); + assert(test_basic()); + assert(test_basic()); +#if TEST_STD_VER >= 23 + static_assert(test_basic()); + static_assert(test_basic()); +#endif return 0; -} +} \ No newline at end of file diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp @@ -20,12 +20,21 @@ struct A { int i_; - A() : i_(7) {} + TEST_CONSTEXPR_CXX23 A() : i_(7) {} }; -int main(int, char**) { +TEST_CONSTEXPR_CXX23 bool test() { std::unique_ptr p(new A); assert(p->i_ == 7); + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp @@ -17,31 +17,39 @@ class foo { public: - foo () : val_(3) {} - int get () const { return val_; } + TEST_CONSTEXPR_CXX23 foo() : val_(3) {} + TEST_CONSTEXPR_CXX23 int get() const { return val_; } + private: - int val_; - }; + int val_; +}; -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX23 bool test() { + { auto p1 = std::make_unique(5); - for ( int i = 0; i < 5; ++i ) - assert ( p1[i] == 0 ); - } + for (int i = 0; i < 5; ++i) + assert(p1[i] == 0); + } - { + { auto p2 = std::make_unique(5); - for ( int i = 0; i < 5; ++i ) - assert ( p2[i].size () == 0 ); - } + for (int i = 0; i < 5; ++i) + assert(p2[i].size() == 0); + } - { + { auto p3 = std::make_unique(7); - for ( int i = 0; i < 7; ++i ) - assert ( p3[i].get () == 3 ); - } + for (int i = 0; i < 7; ++i) + assert(p3[i].get() == 3); + } + + return true; +} +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif return 0; } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp @@ -13,23 +13,30 @@ #include "test_macros.h" -int main(int, char**) -{ - { +TEST_CONSTEXPR_CXX23 bool test() { + { std::unique_ptr p1 = std::make_unique(1); - assert ( *p1 == 1 ); - p1 = std::make_unique (); - assert ( *p1 == 0 ); - } + assert(*p1 == 1); + p1 = std::make_unique(); + assert(*p1 == 0); + } - { - std::unique_ptr p2 = std::make_unique ( "Meow!" ); - assert ( *p2 == "Meow!" ); - p2 = std::make_unique (); - assert ( *p2 == "" ); - p2 = std::make_unique ( 6, 'z' ); - assert ( *p2 == "zzzzzz" ); - } + { + std::unique_ptr p2 = std::make_unique("Meow!"); + assert(*p2 == "Meow!"); + p2 = std::make_unique(); + assert(*p2 == ""); + p2 = std::make_unique(6, 'z'); + assert(*p2 == "zzzzzz"); + } + return true; +} + +int main(int, char**) { + assert(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.sizezero.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp @@ -19,10 +19,9 @@ struct A { int m[0]; }; -static_assert(sizeof(A) == 0, ""); // an extension supported by GCC and Clang +static_assert(sizeof(A) == 0, ""); // an extension supported by GCC and Clang -int main(int, char**) -{ +TEST_CONSTEXPR_CXX23 bool test() { { std::unique_ptr p = std::unique_ptr(new A); assert(p != nullptr); @@ -43,3 +42,11 @@ #endif return 0; } + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; +} diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp @@ -11,7 +11,7 @@ // default_delete[] // template -// default_delete(const default_delete&); +// default_delete(const default_delete&); // constexpr since C++23 // // This constructor shall not participate in overload resolution unless // U(*)[] is convertible to T(*)[]. @@ -21,11 +21,17 @@ #include "test_macros.h" -int main(int, char**) -{ - std::default_delete d1; - std::default_delete d2 = d1; - ((void)d2); +TEST_CONSTEXPR_CXX23 bool test() { + std::default_delete d1; + std::default_delete d2 = d1; + ((void)d2); - return 0; + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif } diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp @@ -8,32 +8,32 @@ // -// shared_ptr +// unique_ptr // template -// bool operator==(const unique_ptr& x, nullptr_t) noexcept; +// bool operator==(const unique_ptr& x, nullptr_t) noexcept; // constexpr since C++23 // template -// bool operator==(nullptr_t, const unique_ptr& y) noexcept; +// bool operator==(nullptr_t, const unique_ptr& y) noexcept; // constexpr since C++23 // template -// bool operator!=(const unique_ptr& x, nullptr_t) noexcept; +// bool operator!=(const unique_ptr& x, nullptr_t) noexcept; // constexpr since C++23 // template -// bool operator!=(nullptr_t, const unique_ptr& y) noexcept; +// bool operator!=(nullptr_t, const unique_ptr& y) noexcept; // constexpr since C++23 // template -// bool operator<(const unique_ptr& x, nullptr_t); +// bool operator<(const unique_ptr& x, nullptr_t); // constexpr since C++23 // template -// bool operator<(nullptr_t, const unique_ptr& y); +// bool operator<(nullptr_t, const unique_ptr& y); // constexpr since C++23 // template -// bool operator<=(const unique_ptr& x, nullptr_t); +// bool operator<=(const unique_ptr& x, nullptr_t); // constexpr since C++23 // template -// bool operator<=(nullptr_t, const unique_ptr& y); +// bool operator<=(nullptr_t, const unique_ptr& y); // constexpr since C++23 // template -// bool operator>(const unique_ptr& x, nullptr_t); +// bool operator>(const unique_ptr& x, nullptr_t); // constexpr since C++23 // template -// bool operator>(nullptr_t, const unique_ptr& y); +// bool operator>(nullptr_t, const unique_ptr& y); // constexpr since C++23 // template -// bool operator>=(const unique_ptr& x, nullptr_t); +// bool operator>=(const unique_ptr& x, nullptr_t); // constexpr since C++23 // template -// bool operator>=(nullptr_t, const unique_ptr& y); +// bool operator>=(nullptr_t, const unique_ptr& y); // constexpr since C++23 // template // requires three_­way_­comparable::pointer> // constexpr compare_three_way_result_t::pointer> @@ -41,12 +41,12 @@ #include #include +#include #include "test_macros.h" #include "test_comparisons.h" -int main(int, char**) -{ +TEST_CONSTEXPR_CXX23 bool test() { AssertEqualityAreNoexcept, nullptr_t>(); AssertEqualityAreNoexcept >(); AssertComparisonsReturnBool, nullptr_t>(); @@ -59,18 +59,21 @@ const std::unique_ptr p1(new int(1)); assert(!(p1 == nullptr)); assert(!(nullptr == p1)); - assert(!(p1 < nullptr)); - assert((nullptr < p1)); - assert(!(p1 <= nullptr)); - assert((nullptr <= p1)); - assert((p1 > nullptr)); - assert(!(nullptr > p1)); - assert((p1 >= nullptr)); - assert(!(nullptr >= p1)); + // A pointer to allocated storage and a nullptr can't be compared at compile-time + if (!TEST_IS_CONSTANT_EVALUATED) { + assert(!(p1 < nullptr)); + assert((nullptr < p1)); + assert(!(p1 <= nullptr)); + assert((nullptr <= p1)); + assert((p1 > nullptr)); + assert(!(nullptr > p1)); + assert((p1 >= nullptr)); + assert(!(nullptr >= p1)); #if TEST_STD_VER > 17 - assert((nullptr <=> p1) == std::strong_ordering::less); - assert((p1 <=> nullptr) == std::strong_ordering::greater); + assert((nullptr <=> p1) == std::strong_ordering::less); + assert((p1 <=> nullptr) == std::strong_ordering::greater); #endif + } const std::unique_ptr p2; assert((p2 == nullptr)); @@ -87,5 +90,14 @@ assert((nullptr <=> p2) == std::strong_ordering::equivalent); #endif + return true; +} + +int main(int, char**) { + assert(test()); +#if TEST_STD_VER >= 23 + static_assert(test()); +#endif + return 0; } diff --git a/libcxx/test/support/deleter_types.h b/libcxx/test/support/deleter_types.h --- a/libcxx/test/support/deleter_types.h +++ b/libcxx/test/support/deleter_types.h @@ -25,441 +25,440 @@ #if TEST_STD_VER >= 11 template -class Deleter -{ - int state_; +class Deleter { + int state_; - Deleter(const Deleter&); - Deleter& operator=(const Deleter&); + Deleter(const Deleter&); + Deleter& operator=(const Deleter&); public: - Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} - Deleter& operator=(Deleter&& r) - { - state_ = r.state_; - r.state_ = 0; - return *this; - } - - - Deleter() : state_(0) {} - explicit Deleter(int s) : state_(s) {} - ~Deleter() {assert(state_ >= 0); state_ = -1;} - - template - Deleter(Deleter&& d, - typename std::enable_if::value>::type* = 0) - : state_(d.state()) {d.set_state(0);} + TEST_CONSTEXPR_CXX23 Deleter(Deleter&& r) : state_(r.state_) { r.state_ = 0; } + TEST_CONSTEXPR_CXX23 Deleter& operator=(Deleter&& r) { + state_ = r.state_; + r.state_ = 0; + return *this; + } + + TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit Deleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~Deleter() { + assert(state_ >= 0); + state_ = -1; + } + + template + TEST_CONSTEXPR_CXX23 Deleter(Deleter&& d, typename std::enable_if::value>::type* = 0) + : state_(d.state()) { + d.set_state(0); + } private: - template - Deleter(const Deleter& d, - typename std::enable_if::value>::type* = 0); + template + Deleter(const Deleter& d, typename std::enable_if::value>::type* = 0); + public: - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; template -class Deleter -{ - int state_; +class Deleter { + int state_; - Deleter(const Deleter&); - Deleter& operator=(const Deleter&); + Deleter(const Deleter&); + Deleter& operator=(const Deleter&); public: - - Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} - Deleter& operator=(Deleter&& r) - { - state_ = r.state_; - r.state_ = 0; - return *this; - } - - Deleter() : state_(0) {} - explicit Deleter(int s) : state_(s) {} - ~Deleter() {assert(state_ >= 0); state_ = -1;} - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 Deleter(Deleter&& r) : state_(r.state_) { r.state_ = 0; } + TEST_CONSTEXPR_CXX23 Deleter& operator=(Deleter&& r) { + state_ = r.state_; + r.state_ = 0; + return *this; + } + + TEST_CONSTEXPR_CXX23 Deleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit Deleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~Deleter() { + assert(state_ >= 0); + state_ = -1; + } + + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } + + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; #else // TEST_STD_VER < 11 template -class Deleter -{ - mutable int state_; +class Deleter { + mutable int state_; public: - Deleter() : state_(0) {} - explicit Deleter(int s) : state_(s) {} + Deleter() : state_(0) {} + explicit Deleter(int s) : state_(s) {} - Deleter(Deleter const & other) : state_(other.state_) { - other.state_ = 0; - } - Deleter& operator=(Deleter const& other) { - state_ = other.state_; - other.state_ = 0; - return *this; - } + Deleter(Deleter const& other) : state_(other.state_) { other.state_ = 0; } + Deleter& operator=(Deleter const& other) { + state_ = other.state_; + other.state_ = 0; + return *this; + } - ~Deleter() {assert(state_ >= 0); state_ = -1;} + ~Deleter() { + assert(state_ >= 0); + state_ = -1; + } - template - Deleter(Deleter d, - typename std::enable_if::value>::type* = 0) - : state_(d.state()) {} + template + Deleter(Deleter d, typename std::enable_if::value>::type* = 0) : state_(d.state()) {} public: - int state() const {return state_;} - void set_state(int i) {state_ = i;} + int state() const { return state_; } + void set_state(int i) { state_ = i; } - void operator()(T* p) {delete p;} + void operator()(T* p) { delete p; } }; template -class Deleter -{ - mutable int state_; +class Deleter { + mutable int state_; public: - - Deleter(Deleter const& other) : state_(other.state_) { - other.state_ = 0; - } - Deleter& operator=(Deleter const& other) { - state_ = other.state_; - other.state_ = 0; - return *this; - } - - Deleter() : state_(0) {} - explicit Deleter(int s) : state_(s) {} - ~Deleter() {assert(state_ >= 0); state_ = -1;} - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {delete [] p;} + Deleter(Deleter const& other) : state_(other.state_) { other.state_ = 0; } + Deleter& operator=(Deleter const& other) { + state_ = other.state_; + other.state_ = 0; + return *this; + } + + Deleter() : state_(0) {} + explicit Deleter(int s) : state_(s) {} + ~Deleter() { + assert(state_ >= 0); + state_ = -1; + } + + int state() const { return state_; } + void set_state(int i) { state_ = i; } + + void operator()(T* p) { delete[] p; } }; #endif template -void -swap(Deleter& x, Deleter& y) -{ - Deleter t(std::move(x)); - x = std::move(y); - y = std::move(t); +TEST_CONSTEXPR_CXX23 void swap(Deleter& x, Deleter& y) { + Deleter t(std::move(x)); + x = std::move(y); + y = std::move(t); } - template -class CDeleter -{ - int state_; +class CDeleter { + int state_; public: + TEST_CONSTEXPR_CXX23 CDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit CDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~CDeleter() { + assert(state_ >= 0); + state_ = -1; + } - CDeleter() : state_(0) {} - explicit CDeleter(int s) : state_(s) {} - ~CDeleter() {assert(state_ >= 0); state_ = -1;} - - template - CDeleter(const CDeleter& d) - : state_(d.state()) {} + template + TEST_CONSTEXPR_CXX23 CDeleter(const CDeleter& d) : state_(d.state()) {} - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; template -class CDeleter -{ - int state_; +class CDeleter { + int state_; public: + TEST_CONSTEXPR_CXX23 CDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit CDeleter(int s) : state_(s) {} + template + TEST_CONSTEXPR_CXX23 CDeleter(const CDeleter& d) : state_(d.state()) {} - CDeleter() : state_(0) {} - explicit CDeleter(int s) : state_(s) {} - template - CDeleter(const CDeleter& d) - : state_(d.state()) {} - - ~CDeleter() {assert(state_ >= 0); state_ = -1;} + TEST_CONSTEXPR_CXX23 ~CDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; template -void -swap(CDeleter& x, CDeleter& y) -{ - CDeleter t(std::move(x)); - x = std::move(y); - y = std::move(t); +TEST_CONSTEXPR_CXX23 void swap(CDeleter& x, CDeleter& y) { + CDeleter t(std::move(x)); + x = std::move(y); + y = std::move(t); } // Non-copyable deleter template -class NCDeleter -{ - int state_; - NCDeleter(NCDeleter const&); - NCDeleter& operator=(NCDeleter const&); -public: +class NCDeleter { + int state_; + NCDeleter(NCDeleter const&); + NCDeleter& operator=(NCDeleter const&); - NCDeleter() : state_(0) {} - explicit NCDeleter(int s) : state_(s) {} - ~NCDeleter() {assert(state_ >= 0); state_ = -1;} +public: + TEST_CONSTEXPR_CXX23 NCDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit NCDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~NCDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; - template -class NCDeleter -{ - int state_; - NCDeleter(NCDeleter const&); - NCDeleter& operator=(NCDeleter const&); -public: +class NCDeleter { + int state_; + NCDeleter(NCDeleter const&); + NCDeleter& operator=(NCDeleter const&); - NCDeleter() : state_(0) {} - explicit NCDeleter(int s) : state_(s) {} - ~NCDeleter() {assert(state_ >= 0); state_ = -1;} +public: + TEST_CONSTEXPR_CXX23 NCDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit NCDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~NCDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; - // Non-copyable deleter template -class NCConstDeleter -{ - int state_; - NCConstDeleter(NCConstDeleter const&); - NCConstDeleter& operator=(NCConstDeleter const&); -public: +class NCConstDeleter { + int state_; + NCConstDeleter(NCConstDeleter const&); + NCConstDeleter& operator=(NCConstDeleter const&); - NCConstDeleter() : state_(0) {} - explicit NCConstDeleter(int s) : state_(s) {} - ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;} +public: + TEST_CONSTEXPR_CXX23 NCConstDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit NCConstDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~NCConstDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) const {delete p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) const { delete p; } }; - template -class NCConstDeleter -{ - int state_; - NCConstDeleter(NCConstDeleter const&); - NCConstDeleter& operator=(NCConstDeleter const&); -public: +class NCConstDeleter { + int state_; + NCConstDeleter(NCConstDeleter const&); + NCConstDeleter& operator=(NCConstDeleter const&); - NCConstDeleter() : state_(0) {} - explicit NCConstDeleter(int s) : state_(s) {} - ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;} +public: + TEST_CONSTEXPR_CXX23 NCConstDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit NCConstDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~NCConstDeleter() { + assert(state_ >= 0); + state_ = -1; + } - int state() const {return state_;} - void set_state(int i) {state_ = i;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } - void operator()(T* p) const {delete [] p;} + TEST_CONSTEXPR_CXX23 void operator()(T* p) const { delete[] p; } }; - // Non-copyable deleter template -class CopyDeleter -{ - int state_; -public: +class CopyDeleter { + int state_; - CopyDeleter() : state_(0) {} - explicit CopyDeleter(int s) : state_(s) {} - ~CopyDeleter() {assert(state_ >= 0); state_ = -1;} - - CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} - CopyDeleter& operator=(CopyDeleter const& other) { - state_ = other.state_; - return *this; - } - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {delete p;} +public: + TEST_CONSTEXPR_CXX23 CopyDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit CopyDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~CopyDeleter() { + assert(state_ >= 0); + state_ = -1; + } + + TEST_CONSTEXPR_CXX23 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} + TEST_CONSTEXPR_CXX23 CopyDeleter& operator=(CopyDeleter const& other) { + state_ = other.state_; + return *this; + } + + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } + + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; - template -class CopyDeleter -{ - int state_; +class CopyDeleter { + int state_; public: - - CopyDeleter() : state_(0) {} - explicit CopyDeleter(int s) : state_(s) {} - ~CopyDeleter() {assert(state_ >= 0); state_ = -1;} - - CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} - CopyDeleter& operator=(CopyDeleter const& other) { - state_ = other.state_; - return *this; - } - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 CopyDeleter() : state_(0) {} + TEST_CONSTEXPR_CXX23 explicit CopyDeleter(int s) : state_(s) {} + TEST_CONSTEXPR_CXX23 ~CopyDeleter() { + assert(state_ >= 0); + state_ = -1; + } + + TEST_CONSTEXPR_CXX23 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {} + TEST_CONSTEXPR_CXX23 CopyDeleter& operator=(CopyDeleter const& other) { + state_ = other.state_; + return *this; + } + + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void set_state(int i) { state_ = i; } + + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; - -struct test_deleter_base -{ - static int count; - static int dealloc_count; +struct test_deleter_base { + static int count; + static int dealloc_count; }; -int test_deleter_base::count = 0; +int test_deleter_base::count = 0; int test_deleter_base::dealloc_count = 0; template -class test_deleter - : public test_deleter_base -{ - int state_; +class test_deleter : public test_deleter_base { + int state_; public: - - test_deleter() : state_(0) {++count;} - explicit test_deleter(int s) : state_(s) {++count;} - test_deleter(const test_deleter& d) - : state_(d.state_) {++count;} - ~test_deleter() {assert(state_ >= 0); --count; state_ = -1;} - - int state() const {return state_;} - void set_state(int i) {state_ = i;} - - void operator()(T* p) {assert(state_ >= 0); ++dealloc_count; delete p;} + test_deleter() : state_(0) { ++count; } + explicit test_deleter(int s) : state_(s) { ++count; } + test_deleter(const test_deleter& d) : state_(d.state_) { ++count; } + ~test_deleter() { + assert(state_ >= 0); + --count; + state_ = -1; + } + + int state() const { return state_; } + void set_state(int i) { state_ = i; } + + void operator()(T* p) { + assert(state_ >= 0); + ++dealloc_count; + delete p; + } #if TEST_STD_VER >= 11 - test_deleter* operator&() const = delete; + test_deleter* operator&() const = delete; #else + private: test_deleter* operator&() const; #endif }; template -void -swap(test_deleter& x, test_deleter& y) -{ - test_deleter t(std::move(x)); - x = std::move(y); - y = std::move(t); +void swap(test_deleter& x, test_deleter& y) { + test_deleter t(std::move(x)); + x = std::move(y); + y = std::move(t); } #if TEST_STD_VER >= 11 template -class PointerDeleter -{ - PointerDeleter(const PointerDeleter&); - PointerDeleter& operator=(const PointerDeleter&); +class PointerDeleter { + PointerDeleter(const PointerDeleter&); + PointerDeleter& operator=(const PointerDeleter&); public: - typedef min_pointer> pointer; + typedef min_pointer> pointer; - PointerDeleter() = default; - PointerDeleter(PointerDeleter&&) = default; - PointerDeleter& operator=(PointerDeleter&&) = default; - explicit PointerDeleter(int) {} + TEST_CONSTEXPR_CXX23 PointerDeleter() = default; + TEST_CONSTEXPR_CXX23 PointerDeleter(PointerDeleter&&) = default; + TEST_CONSTEXPR_CXX23 PointerDeleter& operator=(PointerDeleter&&) = default; + TEST_CONSTEXPR_CXX23 explicit PointerDeleter(int) {} - template - PointerDeleter(PointerDeleter&&, - typename std::enable_if::value>::type* = 0) - {} + template + TEST_CONSTEXPR_CXX23 + PointerDeleter(PointerDeleter&&, typename std::enable_if::value>::type* = 0) {} - void operator()(pointer p) { if (p) { delete std::addressof(*p); }} + TEST_CONSTEXPR_CXX23 void operator()(pointer p) { + if (p) { + delete std::addressof(*p); + } + } private: - template - PointerDeleter(const PointerDeleter&, - typename std::enable_if::value>::type* = 0); + template + PointerDeleter(const PointerDeleter&, typename std::enable_if::value>::type* = 0); }; - template -class PointerDeleter -{ - PointerDeleter(const PointerDeleter&); - PointerDeleter& operator=(const PointerDeleter&); +class PointerDeleter { + PointerDeleter(const PointerDeleter&); + PointerDeleter& operator=(const PointerDeleter&); public: - typedef min_pointer > pointer; + typedef min_pointer > pointer; - PointerDeleter() = default; - PointerDeleter(PointerDeleter&&) = default; - PointerDeleter& operator=(PointerDeleter&&) = default; - explicit PointerDeleter(int) {} + TEST_CONSTEXPR_CXX23 PointerDeleter() = default; + TEST_CONSTEXPR_CXX23 PointerDeleter(PointerDeleter&&) = default; + TEST_CONSTEXPR_CXX23 PointerDeleter& operator=(PointerDeleter&&) = default; + TEST_CONSTEXPR_CXX23 explicit PointerDeleter(int) {} - template - PointerDeleter(PointerDeleter&&, - typename std::enable_if::value>::type* = 0) - {} + template + TEST_CONSTEXPR_CXX23 + PointerDeleter(PointerDeleter&&, typename std::enable_if::value>::type* = 0) {} - void operator()(pointer p) { if (p) { delete [] std::addressof(*p); }} + TEST_CONSTEXPR_CXX23 void operator()(pointer p) { + if (p) { + delete[] std::addressof(*p); + } + } private: - template - PointerDeleter(const PointerDeleter&, - typename std::enable_if::value>::type* = 0); + template + PointerDeleter(const PointerDeleter&, typename std::enable_if::value>::type* = 0); }; #endif // TEST_STD_VER >= 11 template -class DefaultCtorDeleter -{ - int state_; +class DefaultCtorDeleter { + int state_; public: - int state() const {return state_;} - void operator()(T* p) {delete p;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete p; } }; template -class DefaultCtorDeleter -{ - int state_; +class DefaultCtorDeleter { + int state_; public: - int state() const {return state_;} - void operator()(T* p) {delete [] p;} + TEST_CONSTEXPR_CXX23 int state() const { return state_; } + TEST_CONSTEXPR_CXX23 void operator()(T* p) { delete[] p; } }; #endif // SUPPORT_DELETER_TYPES_H diff --git a/libcxx/test/support/test_comparisons.h b/libcxx/test/support/test_comparisons.h --- a/libcxx/test/support/test_comparisons.h +++ b/libcxx/test/support/test_comparisons.h @@ -30,121 +30,150 @@ // Test all six comparison operations for sanity template -TEST_CONSTEXPR_CXX14 bool testComparisons(const T& t1, const U& t2, bool isEqual, bool isLess) -{ - assert(!(isEqual && isLess) && "isEqual and isLess cannot be both true"); - if (isEqual) - { - if (!(t1 == t2)) return false; - if (!(t2 == t1)) return false; - if ( (t1 != t2)) return false; - if ( (t2 != t1)) return false; - if ( (t1 < t2)) return false; - if ( (t2 < t1)) return false; - if (!(t1 <= t2)) return false; - if (!(t2 <= t1)) return false; - if ( (t1 > t2)) return false; - if ( (t2 > t1)) return false; - if (!(t1 >= t2)) return false; - if (!(t2 >= t1)) return false; - } - else if (isLess) - { - if ( (t1 == t2)) return false; - if ( (t2 == t1)) return false; - if (!(t1 != t2)) return false; - if (!(t2 != t1)) return false; - if (!(t1 < t2)) return false; - if ( (t2 < t1)) return false; - if (!(t1 <= t2)) return false; - if ( (t2 <= t1)) return false; - if ( (t1 > t2)) return false; - if (!(t2 > t1)) return false; - if ( (t1 >= t2)) return false; - if (!(t2 >= t1)) return false; - } - else /* greater */ - { - if ( (t1 == t2)) return false; - if ( (t2 == t1)) return false; - if (!(t1 != t2)) return false; - if (!(t2 != t1)) return false; - if ( (t1 < t2)) return false; - if (!(t2 < t1)) return false; - if ( (t1 <= t2)) return false; - if (!(t2 <= t1)) return false; - if (!(t1 > t2)) return false; - if ( (t2 > t1)) return false; - if (!(t1 >= t2)) return false; - if ( (t2 >= t1)) return false; - } - - return true; +TEST_CONSTEXPR_CXX14 bool testComparisons(const T& t1, const U& t2, bool isEqual, bool isLess) { + assert(!(isEqual && isLess) && "isEqual and isLess cannot be both true"); + if (isEqual) { + if (!(t1 == t2)) + return false; + if (!(t2 == t1)) + return false; + if ((t1 != t2)) + return false; + if ((t2 != t1)) + return false; + if ((t1 < t2)) + return false; + if ((t2 < t1)) + return false; + if (!(t1 <= t2)) + return false; + if (!(t2 <= t1)) + return false; + if ((t1 > t2)) + return false; + if ((t2 > t1)) + return false; + if (!(t1 >= t2)) + return false; + if (!(t2 >= t1)) + return false; + } else if (isLess) { + if ((t1 == t2)) + return false; + if ((t2 == t1)) + return false; + if (!(t1 != t2)) + return false; + if (!(t2 != t1)) + return false; + if (!(t1 < t2)) + return false; + if ((t2 < t1)) + return false; + if (!(t1 <= t2)) + return false; + if ((t2 <= t1)) + return false; + if ((t1 > t2)) + return false; + if (!(t2 > t1)) + return false; + if ((t1 >= t2)) + return false; + if (!(t2 >= t1)) + return false; + } else /* greater */ + { + if ((t1 == t2)) + return false; + if ((t2 == t1)) + return false; + if (!(t1 != t2)) + return false; + if (!(t2 != t1)) + return false; + if ((t1 < t2)) + return false; + if (!(t2 < t1)) + return false; + if ((t1 <= t2)) + return false; + if (!(t2 <= t1)) + return false; + if (!(t1 > t2)) + return false; + if ((t2 > t1)) + return false; + if (!(t1 >= t2)) + return false; + if ((t2 >= t1)) + return false; + } + + return true; } // Easy call when you can init from something already comparable. template -TEST_CONSTEXPR_CXX14 bool testComparisonsValues(Param val1, Param val2) -{ - const bool isEqual = val1 == val2; - const bool isLess = val1 < val2; +TEST_CONSTEXPR_CXX14 bool testComparisonsValues(Param val1, Param val2) { + const bool isEqual = val1 == val2; + const bool isLess = val1 < val2; - return testComparisons(T(val1), T(val2), isEqual, isLess); + return testComparisons(T(val1), T(val2), isEqual, isLess); } template TEST_CONSTEXPR_CXX14 void AssertComparisonsAreNoexcept() { - ASSERT_NOEXCEPT(std::declval() == std::declval()); - ASSERT_NOEXCEPT(std::declval() != std::declval()); - ASSERT_NOEXCEPT(std::declval() < std::declval()); - ASSERT_NOEXCEPT(std::declval() <= std::declval()); - ASSERT_NOEXCEPT(std::declval() > std::declval()); - ASSERT_NOEXCEPT(std::declval() >= std::declval()); + ASSERT_NOEXCEPT(std::declval() == std::declval()); + ASSERT_NOEXCEPT(std::declval() != std::declval()); + ASSERT_NOEXCEPT(std::declval() < std::declval()); + ASSERT_NOEXCEPT(std::declval() <= std::declval()); + ASSERT_NOEXCEPT(std::declval() > std::declval()); + ASSERT_NOEXCEPT(std::declval() >= std::declval()); } template TEST_CONSTEXPR_CXX14 void AssertComparisonsReturnBool() { - ASSERT_SAME_TYPE(decltype(std::declval() == std::declval()), bool); - ASSERT_SAME_TYPE(decltype(std::declval() != std::declval()), bool); - ASSERT_SAME_TYPE(decltype(std::declval() < std::declval()), bool); - ASSERT_SAME_TYPE(decltype(std::declval() <= std::declval()), bool); - ASSERT_SAME_TYPE(decltype(std::declval() > std::declval()), bool); - ASSERT_SAME_TYPE(decltype(std::declval() >= std::declval()), bool); + ASSERT_SAME_TYPE(decltype(std::declval() == std::declval()), bool); + ASSERT_SAME_TYPE(decltype(std::declval() != std::declval()), bool); + ASSERT_SAME_TYPE(decltype(std::declval() < std::declval()), bool); + ASSERT_SAME_TYPE(decltype(std::declval() <= std::declval()), bool); + ASSERT_SAME_TYPE(decltype(std::declval() > std::declval()), bool); + ASSERT_SAME_TYPE(decltype(std::declval() >= std::declval()), bool); } template -void AssertComparisonsConvertibleToBool() -{ - static_assert((std::is_convertible() == std::declval()), bool>::value), ""); - static_assert((std::is_convertible() != std::declval()), bool>::value), ""); - static_assert((std::is_convertible() < std::declval()), bool>::value), ""); - static_assert((std::is_convertible() <= std::declval()), bool>::value), ""); - static_assert((std::is_convertible() > std::declval()), bool>::value), ""); - static_assert((std::is_convertible() >= std::declval()), bool>::value), ""); +void AssertComparisonsConvertibleToBool() { + static_assert((std::is_convertible() == std::declval()), bool>::value), ""); + static_assert((std::is_convertible() != std::declval()), bool>::value), ""); + static_assert((std::is_convertible() < std::declval()), bool>::value), ""); + static_assert((std::is_convertible() <= std::declval()), bool>::value), ""); + static_assert((std::is_convertible() > std::declval()), bool>::value), ""); + static_assert((std::is_convertible() >= std::declval()), bool>::value), ""); } #if TEST_STD_VER > 17 template constexpr void AssertOrderAreNoexcept() { - AssertComparisonsAreNoexcept(); - ASSERT_NOEXCEPT(std::declval() <=> std::declval()); + AssertComparisonsAreNoexcept(); + ASSERT_NOEXCEPT(std::declval() <=> std::declval()); } template constexpr void AssertOrderReturn() { - AssertComparisonsReturnBool(); - ASSERT_SAME_TYPE(decltype(std::declval() <=> std::declval()), Order); + AssertComparisonsReturnBool(); + ASSERT_SAME_TYPE(decltype(std::declval() <=> std::declval()), Order); } template constexpr bool testOrder(const T& t1, const U& t2, Order order) { - bool equal = order == Order::equivalent; - if constexpr (std::same_as) - equal |= order == Order::equal; + bool equal = order == Order::equivalent; + if constexpr (std::same_as) + equal |= order == Order::equal; - bool less = order == Order::less; + bool less = order == Order::less; - return (t1 <=> t2 == order) && testComparisons(t1, t2, equal, less); + return (t1 <=> t2 == order) && testComparisons(t1, t2, equal, less); } template @@ -156,55 +185,55 @@ // Test all two comparison operations for sanity template -TEST_CONSTEXPR_CXX14 bool testEquality(const T& t1, const U& t2, bool isEqual) -{ - if (isEqual) - { - if (!(t1 == t2)) return false; - if (!(t2 == t1)) return false; - if ( (t1 != t2)) return false; - if ( (t2 != t1)) return false; - } - else /* not equal */ - { - if ( (t1 == t2)) return false; - if ( (t2 == t1)) return false; - if (!(t1 != t2)) return false; - if (!(t2 != t1)) return false; - } - - return true; +TEST_CONSTEXPR_CXX14 bool testEquality(const T& t1, const U& t2, bool isEqual) { + if (isEqual) { + if (!(t1 == t2)) + return false; + if (!(t2 == t1)) + return false; + if ((t1 != t2)) + return false; + if ((t2 != t1)) + return false; + } else /* not equal */ + { + if ((t1 == t2)) + return false; + if ((t2 == t1)) + return false; + if (!(t1 != t2)) + return false; + if (!(t2 != t1)) + return false; + } + + return true; } // Easy call when you can init from something already comparable. template -TEST_CONSTEXPR_CXX14 bool testEqualityValues(Param val1, Param val2) -{ - const bool isEqual = val1 == val2; +TEST_CONSTEXPR_CXX14 bool testEqualityValues(Param val1, Param val2) { + const bool isEqual = val1 == val2; - return testEquality(T(val1), T(val2), isEqual); + return testEquality(T(val1), T(val2), isEqual); } template -void AssertEqualityAreNoexcept() -{ - ASSERT_NOEXCEPT(std::declval() == std::declval()); - ASSERT_NOEXCEPT(std::declval() != std::declval()); +TEST_CONSTEXPR_CXX23 void AssertEqualityAreNoexcept() { + ASSERT_NOEXCEPT(std::declval() == std::declval()); + ASSERT_NOEXCEPT(std::declval() != std::declval()); } template -void AssertEqualityReturnBool() -{ - ASSERT_SAME_TYPE(decltype(std::declval() == std::declval()), bool); - ASSERT_SAME_TYPE(decltype(std::declval() != std::declval()), bool); +void AssertEqualityReturnBool() { + ASSERT_SAME_TYPE(decltype(std::declval() == std::declval()), bool); + ASSERT_SAME_TYPE(decltype(std::declval() != std::declval()), bool); } - template -void AssertEqualityConvertibleToBool() -{ - static_assert((std::is_convertible() == std::declval()), bool>::value), ""); - static_assert((std::is_convertible() != std::declval()), bool>::value), ""); +void AssertEqualityConvertibleToBool() { + static_assert((std::is_convertible() == std::declval()), bool>::value), ""); + static_assert((std::is_convertible() != std::declval()), bool>::value), ""); } struct LessAndEqComp { diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -166,6 +166,12 @@ # define TEST_CONSTEXPR_CXX20 #endif +#if TEST_STD_VER >= 23 +# define TEST_CONSTEXPR_CXX23 constexpr +#else +# define TEST_CONSTEXPR_CXX23 +#endif + #define TEST_ALIGNAS_TYPE(...) TEST_ALIGNAS(TEST_ALIGNOF(__VA_ARGS__)) #if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) \ diff --git a/libcxx/test/support/unique_ptr_test_helper.h b/libcxx/test/support/unique_ptr_test_helper.h --- a/libcxx/test/support/unique_ptr_test_helper.h +++ b/libcxx/test/support/unique_ptr_test_helper.h @@ -34,15 +34,13 @@ int B::count = 0; template -typename std::enable_if::value, T*>::type -newValue(int num_elements) { +TEST_CONSTEXPR_CXX23 typename std::enable_if::value, T*>::type newValue(int num_elements) { assert(num_elements == 1); return new T; } template -typename std::enable_if::value, - typename std::remove_all_extents::type*>::type +TEST_CONSTEXPR_CXX23 typename std::enable_if::value, typename std::remove_all_extents::type*>::type newValue(int num_elements) { typedef typename std::remove_all_extents::type VT; assert(num_elements >= 1); @@ -57,33 +55,34 @@ IncompleteType* getNewIncompleteArray(int size); #if TEST_STD_VER >= 11 -template +template struct args_is_this_type : std::false_type {}; template struct args_is_this_type : std::is_same::type> {}; #endif -template > +template > struct StoresIncomplete { - static_assert((std::is_same::value || - std::is_same::value), ""); + static_assert( + (std::is_same::value || std::is_same::value), ""); std::unique_ptr m_ptr; #if TEST_STD_VER >= 11 StoresIncomplete(StoresIncomplete const&) = delete; - StoresIncomplete(StoresIncomplete&&) = default; + StoresIncomplete(StoresIncomplete&&) = default; - template + template StoresIncomplete(Args&&... args) : m_ptr(std::forward(args)...) { static_assert(!args_is_this_type::value, ""); } #else + private: StoresIncomplete(); StoresIncomplete(StoresIncomplete const&); + public: #endif @@ -94,8 +93,7 @@ }; #if TEST_STD_VER >= 11 -template , class... Args> +template , class... Args> void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) { checkNumIncompleteTypeAlive(expect_alive); { @@ -110,38 +108,34 @@ } #endif -#define INCOMPLETE_TEST_EPILOGUE() \ - int is_incomplete_test_anchor = is_incomplete_test(); \ - \ - struct IncompleteType { \ - static int count; \ - IncompleteType() { ++count; } \ - ~IncompleteType() { --count; } \ - }; \ - \ - int IncompleteType::count = 0; \ - \ - void checkNumIncompleteTypeAlive(int i) { \ - assert(IncompleteType::count == i); \ - } \ - int getNumIncompleteTypeAlive() { return IncompleteType::count; } \ - IncompleteType* getNewIncomplete() { return new IncompleteType; } \ - IncompleteType* getNewIncompleteArray(int size) { \ - return new IncompleteType[size]; \ - } \ - \ - template \ +#define INCOMPLETE_TEST_EPILOGUE() \ + int is_incomplete_test_anchor = is_incomplete_test(); \ + \ + struct IncompleteType { \ + static int count; \ + IncompleteType() { ++count; } \ + ~IncompleteType() { --count; } \ + }; \ + \ + int IncompleteType::count = 0; \ + \ + void checkNumIncompleteTypeAlive(int i) { assert(IncompleteType::count == i); } \ + int getNumIncompleteTypeAlive() { return IncompleteType::count; } \ + IncompleteType* getNewIncomplete() { return new IncompleteType; } \ + IncompleteType* getNewIncompleteArray(int size) { return new IncompleteType[size]; } \ + \ + template \ StoresIncomplete::~StoresIncomplete() {} # #if TEST_STD_VER >= 11 -#define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ - static int is_incomplete_test() { __VA_ARGS__ return 0; } \ - INCOMPLETE_TEST_EPILOGUE() +# define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ + static int is_incomplete_test() { __VA_ARGS__ return 0; } \ + INCOMPLETE_TEST_EPILOGUE() #else -#define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ - static int is_incomplete_test() { return 0; } \ - INCOMPLETE_TEST_EPILOGUE() +# define DEFINE_AND_RUN_IS_INCOMPLETE_TEST(...) \ + static int is_incomplete_test() { return 0; } \ + INCOMPLETE_TEST_EPILOGUE() #endif #endif // TEST_SUPPORT_UNIQUE_PTR_TEST_HELPER_H diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -238,7 +238,7 @@ "headers": ["iterator"], }, { "name": "__cpp_lib_constexpr_memory", - "values": { "c++20": 201811 }, + "values": { "c++20": 201811, "c++2b": 202202 }, "headers": ["memory"], }, { "name": "__cpp_lib_constexpr_numeric",