[libcxx-commits] [libcxx] 30dadaa - [libc++] Implement P2273R3 (`constexpr` `unique_ptr`)
Igor Zhukov via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Sep 3 04:51:28 PDT 2022
Author: Igor Zhukov
Date: 2022-09-03T18:49:50+07:00
New Revision: 30dadaa2eb499395f5bef44b9e1a18db6360ad1f
URL: https://github.com/llvm/llvm-project/commit/30dadaa2eb499395f5bef44b9e1a18db6360ad1f
DIFF: https://github.com/llvm/llvm-project/commit/30dadaa2eb499395f5bef44b9e1a18db6360ad1f.diff
LOG: [libc++] Implement P2273R3 (`constexpr` `unique_ptr`)
Reviewed By: mordante, #libc
Differential Revision: https://reviews.llvm.org/D131315
Added:
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/docs/ReleaseNotes.rst
libcxx/docs/Status/Cxx2b.rst
libcxx/docs/Status/Cxx2bPapers.csv
libcxx/include/__memory/unique_ptr.h
libcxx/include/memory
libcxx/include/version
libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp
libcxx/test/support/deleter_types.h
libcxx/test/support/test_macros.h
libcxx/test/support/unique_ptr_test_helper.h
libcxx/utils/generate_feature_test_macro_components.py
Removed:
################################################################################
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 88605787ab839..8d38beb3e9adc 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -312,6 +312,8 @@ Status
------------------------------------------------- -----------------
``__cpp_lib_constexpr_cmath`` *unimplemented*
------------------------------------------------- -----------------
+ ``__cpp_lib_constexpr_memory`` ``202202L``
+ ------------------------------------------------- -----------------
``__cpp_lib_constexpr_typeinfo`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_forward_like`` ``202207L``
diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 5c1585254d820..9831d03a6ec45 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -40,6 +40,7 @@ Implemented Papers
- P2499R0 - ``string_view`` range constructor should be ``explicit``
- P2417R2 - A more constexpr bitset
- P2445R1 - ``std::forward_like``
+- P2273R3 - Making ``std::unique_ptr`` constexpr
Improvements and New Features
-----------------------------
diff --git a/libcxx/docs/Status/Cxx2b.rst b/libcxx/docs/Status/Cxx2b.rst
index de891629300dd..15374949d5acf 100644
--- a/libcxx/docs/Status/Cxx2b.rst
+++ b/libcxx/docs/Status/Cxx2b.rst
@@ -37,6 +37,10 @@ Paper Status
:header-rows: 1
:widths: auto
+.. note::
+
+ .. [#note-P2273] P2273: ``make_unique_for_overwrite`` isn't done yet since `P1020` hasn't been implemented yet.
+
.. _issues-status-cxx2b:
Library Working Group Issues Status
diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv
index cbf0db4bd794e..d4d1176eb1b9d 100644
--- 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","|Partial| [#note-P2273]_","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
index 739966ab96592..399db50ad1199 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -40,12 +40,10 @@ struct _LIBCPP_TEMPLATE_VIS default_delete {
_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 @@ struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
#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 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
_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 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
_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 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
: __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 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
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 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
_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 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
_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 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
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 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
#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 @@ operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
#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 @@ struct __unique_if<_Tp[_Np]>
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
index 0da19ee2d8135..9776de630f148 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -406,16 +406,17 @@ template <class T>
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 @@ public:
// 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,45 @@ public:
// constructors
constexpr unique_ptr() noexcept;
- explicit unique_ptr(pointer p) noexcept;
- unique_ptr(pointer p, see below d) noexcept;
- unique_ptr(pointer p, see below d) noexcept;
- unique_ptr(unique_ptr&& u) noexcept;
- unique_ptr(nullptr_t) noexcept : unique_ptr() { }
+ constexpr explicit unique_ptr(pointer p) noexcept; // constexpr since C++23
+ constexpr unique_ptr(pointer p, see below d) noexcept; // constexpr since C++23
+ constexpr unique_ptr(pointer p, see below d) noexcept; // constexpr since C++23
+ constexpr unique_ptr(unique_ptr&& u) noexcept; // constexpr since C++23
+ template <class U, class E>
+ constexpr unique_ptr(unique_ptr <U, E>&& u) noexcept; // constexpr since C++23
+ constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
// destructor
- ~unique_ptr();
+ constexpr ~unique_ptr(); // constexpr since C++23
// assignment
- unique_ptr& operator=(unique_ptr&& u) noexcept;
- unique_ptr& operator=(nullptr_t) noexcept;
+ constexpr unique_ptr& operator=(unique_ptr&& u) noexcept; // constexpr since C++23
+ template <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
- 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 +528,34 @@ template<class T1, class D1, class T2, class D2>
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 +563,10 @@ class bad_weak_ptr
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
index 3c24a6d7b9dfb..858f8849fe623 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -62,7 +62,8 @@ __cpp_lib_constexpr_complex 201711L <complex>
__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>
@@ -384,6 +385,8 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_byteswap 202110L
# define __cpp_lib_constexpr_bitset 202207L
// # define __cpp_lib_constexpr_cmath 202202L
+# undef __cpp_lib_constexpr_memory
+# define __cpp_lib_constexpr_memory 202202L
// # define __cpp_lib_constexpr_typeinfo 202106L
# define __cpp_lib_forward_like 202207L
// # define __cpp_lib_invoke_r 202106L
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
index dd659f6521b01..e99c75d7d20f2 100644
--- 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
index d3ac7b7dc002d..ca84e43ee2a7c 100644
--- 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]
@@ -3950,8 +3951,8 @@
# ifndef __cpp_lib_constexpr_memory
# error "__cpp_lib_constexpr_memory should be defined in c++2b"
# endif
-# if __cpp_lib_constexpr_memory != 201811L
-# error "__cpp_lib_constexpr_memory should have the value 201811L in c++2b"
+# if __cpp_lib_constexpr_memory != 202202L
+# error "__cpp_lib_constexpr_memory should have the value 202202L in c++2b"
# endif
# ifndef __cpp_lib_constexpr_numeric
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
index f0ca5b0ea86f0..424da1f578452 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
@@ -31,7 +31,7 @@ struct D3 {
};
template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
typedef typename std::conditional<IsArray, int[], int>::type VT;
{
typedef std::unique_ptr<VT> P;
@@ -54,9 +54,18 @@ void test_basic() {
#endif
}
-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/move.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
index 4057534fe7df3..9a21d46e0162b 100644
--- 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 @@ struct GenericDeleter {
};
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 @@ void test_basic() {
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 @@ void test_sfinae() {
}
}
-
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
{
test_basic</*IsArray*/ false>();
test_sfinae<false>();
@@ -129,5 +138,14 @@ int main(int, char**) {
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
index e2fd0c8b34904..61a2bfbbc2e05 100644
--- 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 @@ bool checkArg(ConstTrackingDeleter<ID> const& d) {
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 @@ struct AssignDeleter {
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
diff erent non-reference deleter types are allowed so long
@@ -281,9 +280,8 @@ void test_sfinae() {
}
}
-
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 @@ void test_deleter_value_category() {
}
}
-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
index 73b4634af9147..0201e9c4385a4 100644
--- 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 @@ void test_sfinae() {
}
}
-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 @@ int main(int, char**) {
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 @@ int main(int, char**) {
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
index 1af7eccb38c5e..f2e3f6bd9a6b5 100644
--- 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
index 4a44a92dd2a86..e69973a43966c 100644
--- 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/deduct.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp
index 7243f5857fcd1..c6fef01066462 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/deduct.pass.cpp
@@ -15,9 +15,9 @@
// The following constructors should not be selected by class template argument
// deduction:
//
-// explicit unique_ptr(pointer p)
-// unique_ptr(pointer p, const D& d) noexcept
-// unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept
+// constexpr explicit unique_ptr(pointer p) // constexpr since C++23
+// constexpr unique_ptr(pointer p, const D& d) noexcept // constexpr since C++23
+// constexpr unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept // constexpr since C++23
#include <memory>
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
index bfe9a632c2f42..7f4c90922d6c3 100644
--- 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,12 +36,12 @@ TEST_CONSTINIT std::unique_ptr<int[]> global_static_unique_ptr_runtime;
struct NonDefaultDeleter {
NonDefaultDeleter() = delete;
- void operator()(void*) const {}
+ TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
};
#endif
template <class ElemType>
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
#if TEST_STD_VER >= 11
{ // the constructor does not participate in overload resolution when
// the deleter is a pointer type
@@ -51,9 +51,9 @@ void test_sfinae() {
{ // 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 @@ void test_sfinae() {
}
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 @@ void test_basic() {
assert(p.get() == 0);
assert(p.get_deleter().state() == 0);
}
+
+ return true;
}
DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
@@ -97,7 +99,7 @@ DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
doIncompleteTypeTest<IncompleteType[], Deleter<IncompleteType[]> >(0);
})
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
{
test_sfinae<int>();
test_basic<int>();
@@ -107,5 +109,14 @@ int main(int, char**) {
test_basic<int[]>();
}
+ 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.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
index 5ccc5d60aeecf..318f4b18a0d1e 100644
--- 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 @@ std::unique_ptr<VT, NCDeleter<VT>&> source3() {
}
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 @@ void sink3(std::unique_ptr<VT, NCDeleter<VT>&> p) {
}
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 @@ void test_sfinae() {
}
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 @@ void test_basic() {
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 @@ void test_basic() {
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 @@ void test_basic() {
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 @@ void test_noexcept() {
#endif
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
{
test_basic</*IsArray*/ false>();
test_sfinae<int>();
@@ -171,5 +178,23 @@ int main(int, char**) {
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
index 9153f0a93b0fa..3a868626f46f9 100644
--- 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 @@ using EnableIfSpecialization = typename std::enable_if<
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 @@ bool checkArg(TrackingDeleter<ID> const& d) {
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
diff erent non-reference deleter types are allowed so long
@@ -144,9 +141,8 @@ void test_sfinae() {
}
}
-
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 @@ void test_noexcept() {
}
}
-
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 @@ void test_deleter_value_category() {
}
}
-
-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
index a75ebff347036..2bd6f7511ff4f 100644
--- 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 @@ struct GenericConvertingDeleter {
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 @@ void test_sfinae() {
}
}
+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
index 4c3883ea0a419..13d40b9f6d3bc 100644
--- 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 @@ void checkReferenceDeleter(LHS& lhs, RHS& rhs) {
}
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_sfinae() {
}
}
-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 @@ void test_noexcept() {
}
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
{
test_sfinae();
test_noexcept();
@@ -245,5 +249,14 @@ int main(int, char**) {
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
index 0ccbf05f58a67..51e5ec732aa27 100644
--- 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 void test_pointer_ctor() {
{
std::unique_ptr<VT> p(0);
assert(p.get() == 0);
@@ -36,7 +36,7 @@ void test_pointer_ctor() {
}
template <class VT>
-void test_pointer_deleter_ctor() {
+TEST_CONSTEXPR_CXX23 void test_pointer_deleter_ctor() {
{
std::default_delete<VT> d;
std::unique_ptr<VT> p(0, d);
@@ -61,7 +61,7 @@ void test_pointer_deleter_ctor() {
}
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
{
// test_pointer_ctor<int>();
test_pointer_deleter_ctor<int>();
@@ -71,5 +71,14 @@ int main(int, char**) {
test_pointer_deleter_ctor<int[]>();
}
+ 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/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
index 95393b677d61c..45017a03b95dd 100644
--- 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
@@ -10,7 +10,7 @@
// unique_ptr
-// unique_ptr(nullptr_t);
+// constexpr unique_ptr(nullptr_t); // constexpr since C++23
#include <memory>
#include <cassert>
@@ -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 @@ struct NonDefaultDeleter {
#endif
template <class VT>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void 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
{
@@ -58,7 +55,7 @@ void test_basic() {
}
template <class VT>
-void test_sfinae() {
+TEST_CONSTEXPR_CXX23 void test_sfinae() {
#if TEST_STD_VER >= 11
{ // the constructor does not participate in overload resolution when
// the deleter is a pointer type
@@ -68,9 +65,9 @@ void test_sfinae() {
{ // 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, "");
@@ -81,21 +78,15 @@ void test_sfinae() {
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);
})
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
{
test_basic<int>();
test_sfinae<int>();
@@ -105,5 +96,14 @@ int main(int, char**) {
test_sfinae<int[]>();
}
+ 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.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
index 364dd3aa3adef..cbce5c9c74c5a 100644
--- 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 @@ void test_pointer() {
#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 @@ struct GenericDeleter {
#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 @@ void test_sfinae() {
#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 @@ DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
checkNumIncompleteTypeAlive(0);
})
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
{
test_pointer</*IsArray*/ false>();
test_derived();
@@ -176,5 +193,14 @@ int main(int, char**) {
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
index 59861effb4eff..a91abc856fb19 100644
--- 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 @@ void my_free(void*) { my_free_called = true; }
#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 @@ void test_sfinae() {
}
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 @@ void test_noexcept() {
#endif
}
-void test_sfinae_runtime() {
+TEST_CONSTEXPR_CXX23 void test_sfinae_runtime() {
#if TEST_STD_VER >= 11
{
using D = CopyOnlyDeleter;
@@ -204,20 +204,23 @@ void test_sfinae_runtime() {
}
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 @@ void test_basic() {
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 @@ void test_basic() {
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 @@ void test_nullptr() {
#endif
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
{
test_basic</*IsArray*/ false>();
test_nullptr<false>();
@@ -325,5 +341,14 @@ int main(int, char**) {
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
index c067f642e6766..54aec49af368e 100644
--- 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 @@ class Deleter {
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 void test_basic() {
Deleter d;
assert(d.state() == 0);
{
@@ -43,9 +43,18 @@ void test_basic() {
assert(d.state() == 0);
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
test_basic<int>();
test_basic<int[]>();
+ 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/release.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp
index f080165d561ad..7aedac99030cb 100644
--- 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 @@ void test_basic() {
#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 @@ void test_basic() {
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
index 46569918a5f98..275ab3df02caf 100644
--- 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 @@ int main(int, char**) {
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
index 583cbcf50c1be..d5e5c545f313b 100644
--- 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
index 5285bca163734..8eeca6f5ce98c 100644
--- 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
@@ -19,10 +19,21 @@
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
index 35e997e30659f..41391b49fc5d2 100644
--- 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 @@ typename std::remove_all_extents<T>::type* newValueInit(int size,
}
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 @@ void test_basic() {
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
index fae3576b1252d..4a1e9704afc9c 100644
--- 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,18 @@
#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
index 500821fb8175b..cc68297c3ea2e 100644
--- 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
@@ -10,7 +10,7 @@
// unique_ptr
-// test op*()
+// test constexpr explicit operator bool() const noexcept; // constexpr since C++23
#include <memory>
#include <cassert>
@@ -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 @@ void doTest(UPtr& p, bool ExpectTrue) {
}
template <bool IsArray>
-void test_basic() {
+TEST_CONSTEXPR_CXX23 void test_basic() {
typedef typename std::conditional<IsArray, int[], int>::type VT;
typedef std::unique_ptr<VT> U;
{
@@ -59,9 +59,18 @@ void test_basic() {
}
}
-int main(int, char**) {
+TEST_CONSTEXPR_CXX23 bool test() {
test_basic</*IsArray*/ false>();
test_basic<true>();
- return 0;
+ return true;
}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 23
+ static_assert(test());
+#endif
+
+ return 0;
+}
\ No newline at end of file
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
index 1ff965f563e12..3bd3788960e2a 100644
--- 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 void test_basic() {
typedef typename std::conditional<IsArray, int[], int>::type VT;
typedef const VT CVT;
{
@@ -44,9 +44,18 @@ void test_basic() {
}
}
-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/get_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp
index e440a95991c72..fc34d17b6fdb2 100644
--- 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 void test_basic() {
typedef typename std::conditional<IsArray, int[], int>::type VT;
{
std::unique_ptr<int, Deleter> p;
@@ -58,9 +58,18 @@ void test_basic() {
}
}
-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/op_arrow.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp
index 4a50d1f29d17a..7d247b8715beb 100644
--- 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
index 1b11d695e96b5..18dfbcc0f9be9 100644
--- 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,16 @@ class A {
static int next_;
public:
- A() : state_(++next_) {}
- int get() const { return state_; }
+ TEST_CONSTEXPR_CXX23 A() : state_(0) {
+ if (!TEST_IS_CONSTANT_EVALUATED)
+ state_ = ++next_;
+ }
+
+ TEST_CONSTEXPR_CXX23 int get() const { return state_; }
- friend bool operator==(const A& x, int y) { return x.state_ == y; }
+ friend TEST_CONSTEXPR_CXX23 bool operator==(const A& x, int y) { return x.state_ == y; }
- A& operator=(int i) {
+ TEST_CONSTEXPR_CXX23 A& operator=(int i) {
state_ = i;
return *this;
}
@@ -35,11 +39,13 @@ class A {
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 +53,14 @@ int main(int, char**) {
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
index f3d9fb68f9674..7aef0eb568887 100644
--- 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,40 @@
class foo {
public:
- foo () : val_(3) {}
- int get () const { return val_; }
+ TEST_CONSTEXPR_CXX23 foo() : val_(3) {}
+ TEST_CONSTEXPR_CXX23 int get() const { return val_; }
+
private:
- int val_;
- };
+ int val_;
+};
-int main(int, char**)
-{
- {
+TEST_CONSTEXPR_CXX23 bool test() {
+ {
auto p1 = std::make_unique<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
index 08b72289ddb37..b9211f300ea5d 100644
--- 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,31 @@
#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.create/make_unique.sizezero.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp
index 85ad5316e7338..5779ba30e7c88 100644
--- 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
@@ -41,5 +41,6 @@ int main(int, char**)
assert(p != nullptr);
}
#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
index d4c00f46748f9..8dafb72a61993 100644
--- 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
@@ -10,42 +10,38 @@
// default_delete
+// convert constructor
+
#include <memory>
#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;
+}
+
+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/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp
index a5101b9889dc6..3ac3e4fc0f370 100644
--- 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,27 @@
#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 true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 23
+ static_assert(test());
+#endif
+
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
index 0eae429fd4098..f95e2d7c794a9 100644
--- 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,19 @@
#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 true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 23
+ static_assert(test());
+#endif
return 0;
}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp
index 1693d11418d8b..af4d2eebf83f2 100644
--- 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,27 @@
#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 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.msvc/test.compile.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp
new file mode 100644
index 0000000000000..f9845769d0767
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.compile.pass.cpp
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Includes Microsoft's test that tests the entire header.
+
+#include "test.cpp"
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp
new file mode 100644
index 0000000000000..8a80122a67e3d
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.msvc/test.cpp
@@ -0,0 +1,128 @@
+// Copyright (c) Microsoft Corporation.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include <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
index 68f69ea99b1cc..38e289bddcb71 100644
--- 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 @@ int main(int, char**) {
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
diff erent type
{
@@ -98,14 +83,16 @@ int main(int, char**) {
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 @@ int main(int, char**) {
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
diff erent array types
{
@@ -132,14 +121,16 @@ int main(int, char**) {
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 @@ int main(int, char**) {
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
diff erent type
@@ -156,9 +148,19 @@ int main(int, char**) {
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
index c3ab43d4509fb..ddd02a455c588 100644
--- 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 @@ int main(int, char**)
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
index 4e45bbaef355e..c47883acab06e 100644
--- 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 @@ struct A
{
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 @@ int main(int, char**)
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 @@ int main(int, char**)
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 @@ int main(int, char**)
}
#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
index f8aafc12bfdaa..c5680020b0646 100644
--- 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
index e3d1590e90fa1..7f7c6832a2565 100644
--- 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
index 83c41a4c93937..633ea9740745d 100644
--- 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* getNewIncomplete();
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 @@ struct StoresIncomplete {
};
#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 @@ void doIncompleteTypeTest(int expect_alive, Args&&... ctor_args) {
}
#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
index 38b04d261e484..41e85980bc8ff 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -242,7 +242,7 @@ def add_version_header(tc):
"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",
More information about the libcxx-commits
mailing list