summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities/smartptr
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2017-04-16 01:51:04 +0000
committerEric Fiselier <eric@efcs.ca>2017-04-16 01:51:04 +0000
commit4727272254eb3121eaa5b7f38f8f01694007ed99 (patch)
tree350133441ba22c24efa2500eae6c3b633551a1b8 /libcxx/test/std/utilities/smartptr
parent9edfb08d935a3d4c2bd662732cd5a93254452f51 (diff)
downloadbcm5719-llvm-4727272254eb3121eaa5b7f38f8f01694007ed99.tar.gz
bcm5719-llvm-4727272254eb3121eaa5b7f38f8f01694007ed99.zip
Overhaul unique_ptr - Implement LWG 2801, 2905, 2520.
This patch overhauls both specializations of unique_ptr while implementing the following LWG issues: * LWG 2801 - This issue constrains unique_ptr's constructors when the deleter type is not default constructible. Additionally it adds SFINAE conditions to unique_ptr<T[]>::unique_ptr(Up). * LWG 2905 - This issue reworks the unique_ptr(pointer, /* see below */ deleter) constructors so that they correctly SFINAE when the deleter argument cannot be used to construct the stored deleter. * LWG 2520 - This issue fixes initializing unique_ptr<T[]> from nullptr. Libc++ had previously implemented this issue, but the suggested resolution still broke initialization from NULL. This patch re-works the unique_ptr<T[]>(Up, deleter) overloads so that they accept NULL as well as nullptr. llvm-svn: 300406
Diffstat (limited to 'libcxx/test/std/utilities/smartptr')
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp9
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp414
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp4
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp25
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp124
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp5
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp30
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp39
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp10
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp8
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp43
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp4
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp8
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp82
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp8
15 files changed, 746 insertions, 67 deletions
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 378421866bc..5d2f955aa18 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
@@ -82,31 +82,32 @@ void test_sfinae() {
static_assert(!std::is_assignable<U, U&>::value, "");
static_assert(!std::is_assignable<U, const U&>::value, "");
static_assert(!std::is_assignable<U, const U&&>::value, "");
- static_assert(std::is_assignable<U, U&&>::value, "");
+ static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
}
{
typedef std::unique_ptr<VT, GenericDeleter> U;
static_assert(!std::is_assignable<U, U&>::value, "");
static_assert(!std::is_assignable<U, const U&>::value, "");
static_assert(!std::is_assignable<U, const U&&>::value, "");
- static_assert(std::is_assignable<U, U&&>::value, "");
+ static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
}
{
typedef std::unique_ptr<VT, NCDeleter<VT>&> U;
static_assert(!std::is_assignable<U, U&>::value, "");
static_assert(!std::is_assignable<U, const U&>::value, "");
static_assert(!std::is_assignable<U, const U&&>::value, "");
- static_assert(std::is_assignable<U, U&&>::value, "");
+ static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
}
{
typedef std::unique_ptr<VT, const NCDeleter<VT>&> U;
static_assert(!std::is_assignable<U, U&>::value, "");
static_assert(!std::is_assignable<U, const U&>::value, "");
static_assert(!std::is_assignable<U, const U&&>::value, "");
- static_assert(std::is_assignable<U, U&&>::value, "");
+ static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
}
}
+
int main() {
{
test_basic</*IsArray*/ false>();
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
new file mode 100644
index 00000000000..185b1849b8a
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp
@@ -0,0 +1,414 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr converting move ctor
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+#include "type_id.h"
+
+template <int ID = 0>
+struct GenericDeleter {
+ void operator()(void*) const {}
+};
+
+template <int ID = 0>
+struct GenericConvertingDeleter {
+
+ template <int OID>
+ GenericConvertingDeleter(GenericConvertingDeleter<OID>) {}
+
+ template <int OID>
+ GenericConvertingDeleter& operator=(GenericConvertingDeleter<OID> const&) {
+ return *this;
+ }
+
+ void operator()(void*) const {}
+};
+
+template <class T, class U>
+using EnableIfNotSame = typename std::enable_if<
+ !std::is_same<typename std::decay<T>::type, typename std::decay<U>::type>::value
+>::type;
+
+template <template <int> class Templ, class Other>
+struct is_specialization : std::false_type {};
+
+template <template <int> class Templ, int ID>
+struct is_specialization<Templ, Templ<ID> > : std::true_type {};
+
+template <template <int> class Templ, class Other>
+using EnableIfSpecialization = typename std::enable_if<
+ is_specialization<Templ, typename std::decay<Other>::type >::value
+ >::type;
+
+template <int ID>
+struct TrackingDeleter {
+ TrackingDeleter() : arg_type(&makeArgumentID<>()) {}
+
+ TrackingDeleter(TrackingDeleter const&)
+ : arg_type(&makeArgumentID<TrackingDeleter const&>()) {}
+
+ TrackingDeleter(TrackingDeleter&&)
+ : arg_type(&makeArgumentID<TrackingDeleter &&>()) {}
+
+ template <class T, class = EnableIfSpecialization<TrackingDeleter, T> >
+ TrackingDeleter(T&&) : arg_type(&makeArgumentID<T&&>()) {}
+
+ TrackingDeleter& operator=(TrackingDeleter const&) {
+ arg_type = &makeArgumentID<TrackingDeleter const&>();
+ return *this;
+ }
+
+ TrackingDeleter& operator=(TrackingDeleter &&) {
+ arg_type = &makeArgumentID<TrackingDeleter &&>();
+ return *this;
+ }
+
+ template <class T, class = EnableIfSpecialization<TrackingDeleter, T> >
+ TrackingDeleter& operator=(T&&) {
+ arg_type = &makeArgumentID<T&&>();
+ return *this;
+ }
+
+ void operator()(void*) const {}
+
+public:
+ TypeID const* reset() const {
+ TypeID const* tmp = arg_type;
+ arg_type = nullptr;
+ return tmp;
+ }
+
+ mutable TypeID const* arg_type;
+};
+
+template <int ID>
+struct ConstTrackingDeleter {
+ ConstTrackingDeleter() : arg_type(&makeArgumentID<>()) {}
+
+ ConstTrackingDeleter(ConstTrackingDeleter const&)
+ : arg_type(&makeArgumentID<ConstTrackingDeleter const&>()) {}
+
+ ConstTrackingDeleter(ConstTrackingDeleter&&)
+ : arg_type(&makeArgumentID<ConstTrackingDeleter &&>()) {}
+
+ template <class T, class = EnableIfSpecialization<ConstTrackingDeleter, T> >
+ ConstTrackingDeleter(T&&) : arg_type(&makeArgumentID<T&&>()) {}
+
+ const ConstTrackingDeleter& operator=(ConstTrackingDeleter const&) const {
+ arg_type = &makeArgumentID<ConstTrackingDeleter const&>();
+ return *this;
+ }
+
+ const ConstTrackingDeleter& operator=(ConstTrackingDeleter &&) const {
+ arg_type = &makeArgumentID<ConstTrackingDeleter &&>();
+ return *this;
+ }
+
+ template <class T, class = EnableIfSpecialization<ConstTrackingDeleter, T> >
+ const ConstTrackingDeleter& operator=(T&&) const {
+ arg_type = &makeArgumentID<T&&>();
+ return *this;
+ }
+
+ void operator()(void*) const {}
+
+public:
+ TypeID const* reset() const {
+ TypeID const* tmp = arg_type;
+ arg_type = nullptr;
+ return tmp;
+ }
+
+ mutable TypeID const* arg_type;
+};
+
+template <class ExpectT, int ID>
+bool checkArg(TrackingDeleter<ID> const& d) {
+ return d.arg_type && *d.arg_type == makeArgumentID<ExpectT>();
+}
+
+template <class ExpectT, int ID>
+bool checkArg(ConstTrackingDeleter<ID> const& d) {
+ return d.arg_type && *d.arg_type == makeArgumentID<ExpectT>();
+}
+
+template <class From, bool AssignIsConst = false>
+struct AssignDeleter {
+ AssignDeleter() = default;
+ AssignDeleter(AssignDeleter const&) = default;
+ AssignDeleter(AssignDeleter&&) = default;
+
+ AssignDeleter& operator=(AssignDeleter const&) = delete;
+ AssignDeleter& operator=(AssignDeleter &&) = delete;
+
+ 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>
+ const AssignDeleter& operator=(T&&) const & { return *this; }
+
+ template <class T>
+ 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);
+}
+
+template <bool IsArray>
+void test_sfinae() {
+ typedef typename std::conditional<IsArray, A[], A>::type VT;
+
+ { // Test that different non-reference deleter types are allowed so long
+ // as they convert to each other.
+ using U1 = std::unique_ptr<VT, GenericConvertingDeleter<0> >;
+ using U2 = std::unique_ptr<VT, GenericConvertingDeleter<1> >;
+ static_assert(std::is_assignable<U1, U2&&>::value, "");
+ }
+ { // Test that different non-reference deleter types are disallowed when
+ // they cannot convert.
+ using U1 = std::unique_ptr<VT, GenericDeleter<0> >;
+ using U2 = std::unique_ptr<VT, GenericDeleter<1> >;
+ static_assert(!std::is_assignable<U1, U2&&>::value, "");
+ }
+ { // Test that if the deleter assignment is not valid the assignment operator
+ // SFINAEs.
+ using U1 = std::unique_ptr<VT, GenericConvertingDeleter<0> const& >;
+ using U2 = std::unique_ptr<VT, GenericConvertingDeleter<0> >;
+ using U3 = std::unique_ptr<VT, GenericConvertingDeleter<0> &>;
+ using U4 = std::unique_ptr<VT, GenericConvertingDeleter<1> >;
+ using U5 = std::unique_ptr<VT, GenericConvertingDeleter<1> const&>;
+ static_assert(!std::is_assignable<U1, U2&&>::value, "");
+ static_assert(!std::is_assignable<U1, U3&&>::value, "");
+ static_assert(!std::is_assignable<U1, U4&&>::value, "");
+ static_assert(!std::is_assignable<U1, U5&&>::value, "");
+
+ using U1C = std::unique_ptr<const VT, GenericConvertingDeleter<0> const&>;
+ static_assert(std::is_nothrow_assignable<U1C, U1&&>::value, "");
+ }
+ { // Test that if the deleter assignment is not valid the assignment operator
+ // SFINAEs.
+ using U1 = std::unique_ptr<VT, GenericConvertingDeleter<0> & >;
+ using U2 = std::unique_ptr<VT, GenericConvertingDeleter<0> >;
+ using U3 = std::unique_ptr<VT, GenericConvertingDeleter<0> &>;
+ using U4 = std::unique_ptr<VT, GenericConvertingDeleter<1> >;
+ using U5 = std::unique_ptr<VT, GenericConvertingDeleter<1> const&>;
+
+ static_assert(std::is_nothrow_assignable<U1, U2&&>::value, "");
+ static_assert(std::is_nothrow_assignable<U1, U3&&>::value, "");
+ static_assert(std::is_nothrow_assignable<U1, U4&&>::value, "");
+ static_assert(std::is_nothrow_assignable<U1, U5&&>::value, "");
+
+ using U1C = std::unique_ptr<const VT, GenericConvertingDeleter<0> &>;
+ static_assert(std::is_nothrow_assignable<U1C, U1&&>::value, "");
+ }
+ { // Test that non-reference destination deleters can be assigned
+ // from any source deleter type with a sutible conversion. Including
+ // reference types.
+ using U1 = std::unique_ptr<VT, GenericConvertingDeleter<0> >;
+ using U2 = std::unique_ptr<VT, GenericConvertingDeleter<0> &>;
+ using U3 = std::unique_ptr<VT, GenericConvertingDeleter<0> const &>;
+ using U4 = std::unique_ptr<VT, GenericConvertingDeleter<1> >;
+ using U5 = std::unique_ptr<VT, GenericConvertingDeleter<1> &>;
+ using U6 = std::unique_ptr<VT, GenericConvertingDeleter<1> const&>;
+ static_assert(std::is_assignable<U1, U2&&>::value, "");
+ static_assert(std::is_assignable<U1, U3&&>::value, "");
+ static_assert(std::is_assignable<U1, U4&&>::value, "");
+ static_assert(std::is_assignable<U1, U5&&>::value, "");
+ static_assert(std::is_assignable<U1, U6&&>::value, "");
+ }
+ /////////////////////////////////////////////////////////////////////////////
+ {
+ using Del = GenericDeleter<0>;
+ using AD = AssignDeleter<Del&&>;
+ using ADC = AssignDeleter<Del&&, /*AllowConstAssign*/true>;
+ doDeleterTest<VT, AD, Del>();
+ doDeleterTest<VT, AD&, Del>();
+ doDeleterTest<VT, ADC const&, Del>();
+ }
+ {
+ using Del = GenericDeleter<0>;
+ using AD = AssignDeleter<Del&>;
+ using ADC = AssignDeleter<Del&, /*AllowConstAssign*/true>;
+ doDeleterTest<VT, AD, Del&>();
+ doDeleterTest<VT, AD&, Del&>();
+ doDeleterTest<VT, ADC const&, Del&>();
+ }
+ {
+ using Del = GenericDeleter<0>;
+ using AD = AssignDeleter<Del const&>;
+ using ADC = AssignDeleter<Del const&, /*AllowConstAssign*/true>;
+ doDeleterTest<VT, AD, Del const&>();
+ doDeleterTest<VT, AD&, Del const&>();
+ doDeleterTest<VT, ADC const&, Del const&>();
+ }
+}
+
+
+template <bool IsArray>
+void test_noexcept() {
+ typedef typename std::conditional<IsArray, A[], A>::type VT;
+ {
+ typedef std::unique_ptr<const VT> APtr;
+ typedef std::unique_ptr<VT> BPtr;
+ static_assert(std::is_nothrow_assignable<APtr, BPtr>::value, "");
+ }
+ {
+ typedef std::unique_ptr<const VT, CDeleter<const VT> > APtr;
+ typedef std::unique_ptr<VT, CDeleter<VT> > BPtr;
+ static_assert(std::is_nothrow_assignable<APtr, BPtr>::value, "");
+ }
+ {
+ typedef std::unique_ptr<const VT, NCDeleter<const VT>&> APtr;
+ typedef std::unique_ptr<VT, NCDeleter<const VT>&> BPtr;
+ static_assert(std::is_nothrow_assignable<APtr, BPtr>::value, "");
+ }
+ {
+ typedef std::unique_ptr<const VT, const NCConstDeleter<const VT>&> APtr;
+ typedef std::unique_ptr<VT, const NCConstDeleter<const VT>&> BPtr;
+ static_assert(std::is_nothrow_assignable<APtr, BPtr>::value, "");
+ }
+}
+
+template <bool IsArray>
+void test_deleter_value_category() {
+ typedef typename std::conditional<IsArray, A[], A>::type VT;
+ using TD1 = TrackingDeleter<1>;
+ using TD2 = TrackingDeleter<2>;
+ TD1 d1;
+ TD2 d2;
+ using CD1 = ConstTrackingDeleter<1>;
+ using CD2 = ConstTrackingDeleter<2>;
+ CD1 cd1;
+ CD2 cd2;
+
+ { // Test non-reference deleter conversions
+ using U1 = std::unique_ptr<VT, TD1 >;
+ using U2 = std::unique_ptr<VT, TD2 >;
+ U1 u1;
+ U2 u2;
+ u1.get_deleter().reset();
+ u1 = std::move(u2);
+ assert(checkArg<TD2&&>(u1.get_deleter()));
+ }
+ { // Test assignment to non-const ref
+ using U1 = std::unique_ptr<VT, TD1& >;
+ using U2 = std::unique_ptr<VT, TD2 >;
+ U1 u1(nullptr, d1);
+ U2 u2;
+ u1.get_deleter().reset();
+ u1 = std::move(u2);
+ assert(checkArg<TD2&&>(u1.get_deleter()));
+ }
+ { // Test assignment to const&.
+ using U1 = std::unique_ptr<VT, CD1 const& >;
+ using U2 = std::unique_ptr<VT, CD2 >;
+ U1 u1(nullptr, cd1);
+ U2 u2;
+ u1.get_deleter().reset();
+ u1 = std::move(u2);
+ assert(checkArg<CD2&&>(u1.get_deleter()));
+ }
+
+ { // Test assignment from non-const ref
+ using U1 = std::unique_ptr<VT, TD1 >;
+ using U2 = std::unique_ptr<VT, TD2& >;
+ U1 u1;
+ U2 u2(nullptr, d2);
+ u1.get_deleter().reset();
+ u1 = std::move(u2);
+ assert(checkArg<TD2&>(u1.get_deleter()));
+ }
+ { // Test assignment from const ref
+ using U1 = std::unique_ptr<VT, TD1 >;
+ using U2 = std::unique_ptr<VT, TD2 const& >;
+ U1 u1;
+ U2 u2(nullptr, d2);
+ u1.get_deleter().reset();
+ u1 = std::move(u2);
+ assert(checkArg<TD2 const&>(u1.get_deleter()));
+ }
+
+ { // Test assignment from non-const ref
+ using U1 = std::unique_ptr<VT, TD1& >;
+ using U2 = std::unique_ptr<VT, TD2& >;
+ U1 u1(nullptr, d1);
+ U2 u2(nullptr, d2);
+ u1.get_deleter().reset();
+ u1 = std::move(u2);
+ assert(checkArg<TD2&>(u1.get_deleter()));
+ }
+ { // Test assignment from const ref
+ using U1 = std::unique_ptr<VT, TD1& >;
+ using U2 = std::unique_ptr<VT, TD2 const& >;
+ U1 u1(nullptr, d1);
+ U2 u2(nullptr, d2);
+ u1.get_deleter().reset();
+ u1 = std::move(u2);
+ assert(checkArg<TD2 const&>(u1.get_deleter()));
+ }
+
+ { // Test assignment from non-const ref
+ using U1 = std::unique_ptr<VT, CD1 const& >;
+ using U2 = std::unique_ptr<VT, CD2 & >;
+ U1 u1(nullptr, cd1);
+ U2 u2(nullptr, cd2);
+ u1.get_deleter().reset();
+ u1 = std::move(u2);
+ assert(checkArg<CD2 &>(u1.get_deleter()));
+ }
+ { // Test assignment from const ref
+ using U1 = std::unique_ptr<VT, CD1 const& >;
+ using U2 = std::unique_ptr<VT, CD2 const& >;
+ U1 u1(nullptr, cd1);
+ U2 u2(nullptr, cd2);
+ u1.get_deleter().reset();
+ u1 = std::move(u2);
+ assert(checkArg<CD2 const&>(u1.get_deleter()));
+ }
+}
+
+int main() {
+ {
+ test_sfinae</*IsArray*/false>();
+ test_noexcept<false>();
+ test_deleter_value_category<false>();
+ }
+ {
+ test_sfinae</*IsArray*/true>();
+ test_noexcept<true>();
+ test_deleter_value_category<true>();
+ }
+}
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 03bd6c5737a..51d9aa708c4 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
@@ -31,8 +31,6 @@
#include "deleter_types.h"
#include "unique_ptr_test_helper.h"
-#include "test_workarounds.h" // For TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES
-
#if defined(_LIBCPP_VERSION) && TEST_STD_VER >= 11
_LIBCPP_SAFE_STATIC std::unique_ptr<int> global_static_unique_ptr_single;
_LIBCPP_SAFE_STATIC std::unique_ptr<int[]> global_static_unique_ptr_runtime;
@@ -47,7 +45,7 @@ struct NonDefaultDeleter {
template <class ElemType>
void test_sfinae() {
-#if TEST_STD_VER >= 11 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+#if TEST_STD_VER >= 11
{ // the constructor does not participate in overload resultion when
// the deleter is a pointer type
using U = std::unique_ptr<ElemType, void (*)(void*)>;
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 8f52fe5ee97..c102f27fb8e 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
@@ -18,7 +18,6 @@
#include <cassert>
#include "test_macros.h"
-#include "deleter_types.h"
#include "unique_ptr_test_helper.h"
//=============================================================================
@@ -139,13 +138,37 @@ void test_basic() {
assert(A::count == 0);
}
+template <class VT>
+void test_noexcept() {
+#if TEST_STD_VER >= 11
+ {
+ typedef std::unique_ptr<VT> U;
+ static_assert(std::is_nothrow_move_constructible<U>::value, "");
+ }
+ {
+ typedef std::unique_ptr<VT, Deleter<VT> > U;
+ static_assert(std::is_nothrow_move_constructible<U>::value, "");
+ }
+ {
+ typedef std::unique_ptr<VT, NCDeleter<VT> &> U;
+ static_assert(std::is_nothrow_move_constructible<U>::value, "");
+ }
+ {
+ typedef std::unique_ptr<VT, const NCConstDeleter<VT> &> U;
+ static_assert(std::is_nothrow_move_constructible<U>::value, "");
+ }
+#endif
+}
+
int main() {
{
test_basic</*IsArray*/ false>();
test_sfinae<int>();
+ test_noexcept<int>();
}
{
test_basic</*IsArray*/ true>();
test_sfinae<int[]>();
+ test_noexcept<int[]>();
}
}
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
new file mode 100644
index 00000000000..6e5db86c97f
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp
@@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr converting move ctor
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+template <int ID = 0>
+struct GenericDeleter {
+ void operator()(void*) const {}
+};
+
+template <int ID = 0>
+struct GenericConvertingDeleter {
+ template <int OID>
+ GenericConvertingDeleter(GenericConvertingDeleter<OID>) {}
+ void operator()(void*) const {}
+};
+
+template <bool IsArray>
+void test_sfinae() {
+#if TEST_STD_VER >= 11
+ typedef typename std::conditional<IsArray, A[], A>::type VT;
+
+ { // Test that different non-reference deleter types are allowed so long
+ // as they convert to each other.
+ using U1 = std::unique_ptr<VT, GenericConvertingDeleter<0> >;
+ using U2 = std::unique_ptr<VT, GenericConvertingDeleter<1> >;
+ static_assert(std::is_constructible<U1, U2&&>::value, "");
+ }
+ { // Test that different non-reference deleter types are disallowed when
+ // they cannot convert.
+ using U1 = std::unique_ptr<VT, GenericDeleter<0> >;
+ using U2 = std::unique_ptr<VT, GenericDeleter<1> >;
+ static_assert(!std::is_constructible<U1, U2&&>::value, "");
+ }
+ { // Test that if the destination deleter is a reference type then only
+ // exact matches are allowed.
+ using U1 = std::unique_ptr<VT, GenericConvertingDeleter<0> const& >;
+ using U2 = std::unique_ptr<VT, GenericConvertingDeleter<0> >;
+ using U3 = std::unique_ptr<VT, GenericConvertingDeleter<0> &>;
+ using U4 = std::unique_ptr<VT, GenericConvertingDeleter<1> >;
+ using U5 = std::unique_ptr<VT, GenericConvertingDeleter<1> const&>;
+ static_assert(!std::is_constructible<U1, U2&&>::value, "");
+ static_assert(!std::is_constructible<U1, U3&&>::value, "");
+ static_assert(!std::is_constructible<U1, U4&&>::value, "");
+ static_assert(!std::is_constructible<U1, U5&&>::value, "");
+
+ using U1C = std::unique_ptr<const VT, GenericConvertingDeleter<0> const&>;
+ static_assert(std::is_nothrow_constructible<U1C, U1&&>::value, "");
+ }
+ { // Test that non-reference destination deleters can be constructed
+ // from any source deleter type with a sutible conversion. Including
+ // reference types.
+ using U1 = std::unique_ptr<VT, GenericConvertingDeleter<0> >;
+ using U2 = std::unique_ptr<VT, GenericConvertingDeleter<0> &>;
+ using U3 = std::unique_ptr<VT, GenericConvertingDeleter<0> const &>;
+ using U4 = std::unique_ptr<VT, GenericConvertingDeleter<1> >;
+ using U5 = std::unique_ptr<VT, GenericConvertingDeleter<1> &>;
+ using U6 = std::unique_ptr<VT, GenericConvertingDeleter<1> const&>;
+ static_assert(std::is_constructible<U1, U2&&>::value, "");
+ static_assert(std::is_constructible<U1, U3&&>::value, "");
+ static_assert(std::is_constructible<U1, U4&&>::value, "");
+ static_assert(std::is_constructible<U1, U5&&>::value, "");
+ static_assert(std::is_constructible<U1, U6&&>::value, "");
+ }
+#endif
+}
+
+
+template <bool IsArray>
+void test_noexcept() {
+#if TEST_STD_VER >= 11
+ typedef typename std::conditional<IsArray, A[], A>::type VT;
+ {
+ typedef std::unique_ptr<const VT> APtr;
+ typedef std::unique_ptr<VT> BPtr;
+ static_assert(std::is_nothrow_constructible<APtr, BPtr>::value, "");
+ }
+ {
+ typedef std::unique_ptr<const VT, CDeleter<const VT> > APtr;
+ typedef std::unique_ptr<VT, CDeleter<VT> > BPtr;
+ static_assert(std::is_nothrow_constructible<APtr, BPtr>::value, "");
+ }
+ {
+ typedef std::unique_ptr<const VT, NCDeleter<const VT>&> APtr;
+ typedef std::unique_ptr<VT, NCDeleter<const VT>&> BPtr;
+ static_assert(std::is_nothrow_constructible<APtr, BPtr>::value, "");
+ }
+ {
+ typedef std::unique_ptr<const VT, const NCConstDeleter<const VT>&> APtr;
+ typedef std::unique_ptr<VT, const NCConstDeleter<const VT>&> BPtr;
+ static_assert(std::is_nothrow_constructible<APtr, BPtr>::value, "");
+ }
+#endif
+}
+
+
+int main() {
+ {
+ test_sfinae</*IsArray*/false>();
+ test_noexcept<false>();
+ }
+ {
+ test_sfinae</*IsArray*/true>();
+ test_noexcept<true>();
+ }
+}
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 b259049fcfe..09e842b5987 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
@@ -77,4 +77,7 @@ void test_sfinae() {
}
}
-int main() { test_sfinae(); }
+
+int main() {
+ test_sfinae();
+}
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 e2e5cc67da9..4e2a6dfa3dd 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
@@ -22,7 +22,7 @@
#include <utility>
#include <cassert>
-#include "deleter_types.h"
+#include "test_macros.h"
#include "unique_ptr_test_helper.h"
// test converting move ctor. Should only require a MoveConstructible deleter, or if
@@ -135,8 +135,35 @@ void test_sfinae() {
}
}
+void test_noexcept() {
+ {
+ typedef std::unique_ptr<A> APtr;
+ typedef std::unique_ptr<B> BPtr;
+ static_assert(std::is_nothrow_constructible<APtr, BPtr>::value, "");
+ }
+ {
+ typedef std::unique_ptr<A, Deleter<A> > APtr;
+ typedef std::unique_ptr<B, Deleter<B> > BPtr;
+ static_assert(std::is_nothrow_constructible<APtr, BPtr>::value, "");
+ }
+ {
+ typedef std::unique_ptr<A, NCDeleter<A>&> APtr;
+ typedef std::unique_ptr<B, NCDeleter<A>&> BPtr;
+ static_assert(std::is_nothrow_constructible<APtr, BPtr>::value, "");
+ }
+ {
+ typedef std::unique_ptr<A, const NCConstDeleter<A>&> APtr;
+ typedef std::unique_ptr<B, const NCConstDeleter<A>&> BPtr;
+ static_assert(std::is_nothrow_constructible<APtr, BPtr>::value, "");
+ }
+}
+
int main() {
{
+ test_sfinae();
+ test_noexcept();
+ }
+ {
typedef std::unique_ptr<A> APtr;
typedef std::unique_ptr<B> BPtr;
{ // explicit
@@ -218,5 +245,4 @@ int main() {
}
checkNoneAlive();
}
- test_sfinae();
}
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 8e4ee7bb118..6764935fee1 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
@@ -17,25 +17,14 @@
#include <cassert>
#include "test_macros.h"
-#include "deleter_types.h"
#include "unique_ptr_test_helper.h"
-#include "test_workarounds.h" // For TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES
-// default unique_ptr ctor should only require default Deleter ctor
-class DefaultDeleter {
- int state_;
-
- DefaultDeleter(DefaultDeleter&);
- DefaultDeleter& operator=(DefaultDeleter&);
-
-public:
- DefaultDeleter() : state_(5) {}
-
- int state() const { return state_; }
+#if defined(_LIBCPP_VERSION) && TEST_STD_VER >= 11
+_LIBCPP_SAFE_STATIC std::unique_ptr<int> global_static_unique_ptr_single(nullptr);
+_LIBCPP_SAFE_STATIC std::unique_ptr<int[]> global_static_unique_ptr_runtime(nullptr);
+#endif
- void operator()(void*) {}
-};
#if TEST_STD_VER >= 11
struct NonDefaultDeleter {
@@ -46,15 +35,6 @@ struct NonDefaultDeleter {
template <class VT>
void test_basic() {
- {
- std::unique_ptr<VT> p(nullptr);
- assert(p.get() == 0);
- }
- {
- std::unique_ptr<VT, DefaultDeleter> p(nullptr);
- assert(p.get() == 0);
- assert(p.get_deleter().state() == 5);
- }
#if TEST_STD_VER >= 11
{
using U1 = std::unique_ptr<VT>;
@@ -65,11 +45,20 @@ void test_basic() {
"");
}
#endif
+ {
+ std::unique_ptr<VT> p(nullptr);
+ assert(p.get() == 0);
+ }
+ {
+ std::unique_ptr<VT, NCDeleter<VT> > p(nullptr);
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 0);
+ }
}
template <class VT>
void test_sfinae() {
-#if TEST_STD_VER >= 11 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+#if TEST_STD_VER >= 11
{ // the constructor does not participate in overload resultion when
// the deleter is a pointer type
using U = std::unique_ptr<VT, void (*)(void*)>;
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 3ae77d384b2..8df259bd4e1 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
@@ -35,8 +35,6 @@
#include "test_macros.h"
#include "unique_ptr_test_helper.h"
-#include "test_workarounds.h" // For TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES
-
// unique_ptr(pointer) ctor should only require default Deleter ctor
template <bool IsArray>
@@ -47,8 +45,14 @@ void test_pointer() {
{
using U1 = std::unique_ptr<ValueT>;
using U2 = std::unique_ptr<ValueT, Deleter<ValueT> >;
+
+ // Test for noexcept
static_assert(std::is_nothrow_constructible<U1, A*>::value, "");
static_assert(std::is_nothrow_constructible<U2, A*>::value, "");
+
+ // Test for explicit
+ static_assert(!std::is_convertible<A*, U1>::value, "");
+ static_assert(!std::is_convertible<A*, U2>::value, "");
}
#endif
{
@@ -103,7 +107,7 @@ struct GenericDeleter {
template <class T>
void test_sfinae() {
-#if TEST_STD_VER >= 11 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+#if TEST_STD_VER >= 11
{ // the constructor does not participate in overload resultion when
// the deleter is a pointer type
using U = std::unique_ptr<T, void (*)(void*)>;
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp
index 4ef4f1463b0..b4cd3f36ab5 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp
@@ -19,17 +19,11 @@
#include <memory>
-#include "test_workarounds.h"
-
struct Deleter {
void operator()(int* p) const { delete p; }
};
int main() {
-#if defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
-// expected-error@memory:* {{static_assert failed "rvalue deleter bound to reference"}}
-#else
-// expected-error@+2 {{call to deleted constructor of 'std::unique_ptr<int, const Deleter &>}}
-#endif
+ // expected-error@+1 {{call to deleted constructor of 'std::unique_ptr<int, const Deleter &>}}
std::unique_ptr<int, const Deleter&> s((int*)nullptr, Deleter());
}
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 601751eb335..781794d41b5 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
@@ -29,8 +29,6 @@
#include "test_macros.h"
#include "unique_ptr_test_helper.h"
-#include "test_workarounds.h" // For TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES
-
bool my_free_called = false;
void my_free(void*) { my_free_called = true; }
@@ -56,7 +54,7 @@ struct NoCopyMoveDeleter : DeleterBase {
template <bool IsArray>
void test_sfinae() {
-#if TEST_STD_VER >= 11 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+#if TEST_STD_VER >= 11
typedef typename std::conditional<!IsArray, int, int[]>::type VT;
{
using D = CopyOnlyDeleter;
@@ -137,13 +135,13 @@ void test_noexcept() {
}
void test_sfinae_runtime() {
-#if TEST_STD_VER >= 11 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+#if TEST_STD_VER >= 11
{
using D = CopyOnlyDeleter;
using U = std::unique_ptr<A[], D>;
- static_assert(std::is_constructible<U, A*, D const&>::value, "");
- static_assert(std::is_constructible<U, A*, D&>::value, "");
- static_assert(std::is_constructible<U, A*, D&&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, A*, D const&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, A*, D&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, A*, D&&>::value, "");
static_assert(!std::is_constructible<U, B*, D const&>::value, "");
static_assert(!std::is_constructible<U, B*, D&>::value, "");
@@ -158,7 +156,7 @@ void test_sfinae_runtime() {
using U = std::unique_ptr<A[], D>;
static_assert(!std::is_constructible<U, A*, D const&>::value, "");
static_assert(!std::is_constructible<U, A*, D&>::value, "");
- static_assert(std::is_constructible<U, A*, D&&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, A*, D&&>::value, "");
static_assert(!std::is_constructible<U, B*, D const&>::value, "");
static_assert(!std::is_constructible<U, B*, D&>::value, "");
@@ -181,7 +179,7 @@ void test_sfinae_runtime() {
using D = NoCopyMoveDeleter;
using U = std::unique_ptr<A[], D&>;
static_assert(!std::is_constructible<U, A*, D const&>::value, "");
- static_assert(std::is_constructible<U, A*, D&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, A*, D&>::value, "");
static_assert(!std::is_constructible<U, A*, D&&>::value, "");
static_assert(!std::is_constructible<U, A*, const D&&>::value, "");
@@ -193,8 +191,8 @@ void test_sfinae_runtime() {
{
using D = NoCopyMoveDeleter;
using U = std::unique_ptr<A[], const D&>;
- static_assert(std::is_constructible<U, A*, D const&>::value, "");
- static_assert(std::is_constructible<U, A*, D&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, A*, D const&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, A*, D&>::value, "");
static_assert(!std::is_constructible<U, A*, D&&>::value, "");
static_assert(!std::is_constructible<U, A*, const D&&>::value, "");
@@ -291,15 +289,38 @@ void test_basic_single() {
}
}
+template <bool IsArray>
+void test_nullptr() {
+#if TEST_STD_VER >= 11
+ typedef typename std::conditional<!IsArray, A, A[]>::type VT;
+ {
+ std::unique_ptr<VT, Deleter<VT> > u(nullptr, Deleter<VT>{});
+ assert(u.get() == nullptr);
+ }
+ {
+ NCDeleter<VT> d;
+ std::unique_ptr<VT, NCDeleter<VT>& > u(nullptr, d);
+ assert(u.get() == nullptr);
+ }
+ {
+ NCConstDeleter<VT> d;
+ std::unique_ptr<VT, NCConstDeleter<VT> const& > u(nullptr, d);
+ assert(u.get() == nullptr);
+ }
+#endif
+}
+
int main() {
{
test_basic</*IsArray*/ false>();
+ test_nullptr<false>();
test_basic_single();
test_sfinae<false>();
test_noexcept<false>();
}
{
test_basic</*IsArray*/ true>();
+ test_nullptr<true>();
test_sfinae<true>();
test_sfinae_runtime();
test_noexcept<true>();
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 5507e7e34ee..fa10ade5120 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
@@ -35,8 +35,8 @@ void test_basic() {
Deleter d;
assert(d.state() == 0);
{
- std::unique_ptr<T, Deleter&> p(0, d);
- assert(p.get() == 0);
+ std::unique_ptr<T, Deleter&> p(nullptr, d);
+ assert(p.get() == nullptr);
assert(&p.get_deleter() == &d);
}
assert(d.state() == 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 581340f6104..f7f20945094 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
@@ -16,12 +16,20 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
#include "unique_ptr_test_helper.h"
template <bool IsArray>
void test_basic() {
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);
+ ASSERT_NOEXCEPT(u.release());
+ }
+#endif
{
std::unique_ptr<VT> p(newValue<VT>(expect_alive));
assert(A::count == expect_alive);
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 302023b6077..c95c55b4adf 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
@@ -16,36 +16,102 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
#include "unique_ptr_test_helper.h"
template <bool IsArray>
-void test_basic() {
+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);
+ ASSERT_NOEXCEPT(u.reset((A*)nullptr));
+ }
+#endif
{
std::unique_ptr<VT> p(newValue<VT>(expect_alive));
assert(A::count == expect_alive);
A* i = p.get();
assert(i != nullptr);
- p.reset();
- assert(A::count == 0);
- assert(p.get() == 0);
+ A* new_value = newValue<VT>(expect_alive);
+ assert(A::count == (expect_alive * 2));
+ p.reset(new_value);
+ assert(A::count == expect_alive);
+ assert(p.get() == new_value);
}
assert(A::count == 0);
{
- std::unique_ptr<VT> p(newValue<VT>(expect_alive));
+ std::unique_ptr<const VT> p(newValue<const VT>(expect_alive));
assert(A::count == expect_alive);
- A* i = p.get();
+ const A* i = p.get();
assert(i != nullptr);
A* new_value = newValue<VT>(expect_alive);
assert(A::count == (expect_alive * 2));
p.reset(new_value);
assert(A::count == expect_alive);
+ assert(p.get() == new_value);
+ }
+ assert(A::count == 0);
+}
+
+template <bool IsArray>
+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);
+ ASSERT_NOEXCEPT(u.reset(nullptr));
+ }
+#endif
+ {
+ std::unique_ptr<VT> p(newValue<VT>(expect_alive));
+ assert(A::count == expect_alive);
+ A* i = p.get();
+ assert(i != nullptr);
+ p.reset(nullptr);
+ assert(A::count == 0);
+ assert(p.get() == nullptr);
+ }
+ assert(A::count == 0);
+}
+
+
+template <bool IsArray>
+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);
+ ASSERT_NOEXCEPT(u.reset());
+ }
+#endif
+ {
+ std::unique_ptr<VT> p(newValue<VT>(expect_alive));
+ assert(A::count == expect_alive);
+ A* i = p.get();
+ assert(i != nullptr);
+ p.reset();
+ assert(A::count == 0);
+ assert(p.get() == nullptr);
}
assert(A::count == 0);
}
int main() {
- test_basic</*IsArray*/ false>();
- test_basic<true>();
+ {
+ test_reset_pointer</*IsArray*/ false>();
+ test_reset_nullptr<false>();
+ test_reset_no_arg<false>();
+ }
+ {
+ test_reset_pointer</*IsArray*/true>();
+ test_reset_nullptr<true>();
+ test_reset_no_arg<true>();
+ }
}
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 0316398061e..de18865c50a 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
@@ -16,6 +16,7 @@
#include <memory>
#include <cassert>
+#include "test_macros.h"
#include "unique_ptr_test_helper.h"
struct TT {
@@ -51,6 +52,13 @@ template <bool IsArray>
void test_basic() {
typedef typename std::conditional<IsArray, TT[], TT>::type VT;
const int expect_alive = IsArray ? 5 : 1;
+#if TEST_STD_VER >= 11
+ {
+ using U = std::unique_ptr<VT, Deleter<VT> >;
+ U u; ((void)u);
+ ASSERT_NOEXCEPT(u.swap(u));
+ }
+#endif
{
TT* p1 = newValueInit<VT>(expect_alive, 1);
std::unique_ptr<VT, Deleter<VT> > s1(p1, Deleter<VT>(1));
OpenPOWER on IntegriCloud