summaryrefslogtreecommitdiff
path: root/test/std/utilities/smartptr/unique.ptr
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:03:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:03:23 +0000
commit0dc0969cd0a732760f0aa79942a04e0eaef297c4 (patch)
tree051bdb57b1ac6ee143f61ddbb47bd0da619f6f0c /test/std/utilities/smartptr/unique.ptr
parent868847c6900e575417c03bced6e562b3af891318 (diff)
Notes
Diffstat (limited to 'test/std/utilities/smartptr/unique.ptr')
-rw-r--r--test/std/utilities/smartptr/unique.ptr/README.TXT16
-rw-r--r--test/std/utilities/smartptr/unique.ptr/nothing_to_do.pass.cpp12
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp61
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp120
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp420
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp124
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp145
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp39
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp40
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/auto_pointer.pass.cpp97
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp107
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp174
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp124
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp83
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp248
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp74
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp106
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp171
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp29
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp328
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp48
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp56
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp117
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.runtime.fail.cpp30
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp46
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp25
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp88
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.runtime.fail.cpp24
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp22
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp66
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp51
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp65
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.runtime.fail.cpp32
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp28
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp48
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.single.fail.cpp24
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp44
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array1.fail.cpp17
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array2.fail.cpp17
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array3.fail.cpp17
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp17
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp32
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/nothing_to_do.pass.cpp12
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp48
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp34
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/incomplete.fail.cpp26
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/void.fail.cpp24
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.fail.cpp32
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp28
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp36
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/incomplete.fail.cpp26
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.general/nothing_to_do.pass.cpp12
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp69
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp86
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp100
-rw-r--r--test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp102
56 files changed, 4067 insertions, 0 deletions
diff --git a/test/std/utilities/smartptr/unique.ptr/README.TXT b/test/std/utilities/smartptr/unique.ptr/README.TXT
new file mode 100644
index 0000000000000..20f77f61827ce
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/README.TXT
@@ -0,0 +1,16 @@
+Test Naming and Directory Structure
+===================================
+
+The directory structure for the unique_ptr class templates differs from the
+normal test directory naming conventions (e.g. matching the stable name in the standard).
+
+Instead of having a [unique.ptr.single] and [unique.ptr.runtime] directory,
+each containing their own tests, a single directory, "unique.ptr.class",
+contains both sets of tests.
+
+This allows the common behavior of the two unique_ptr specializations to be
+tested in the same place without duplication.
+
+Tests specific to [unique.ptr.single] have the suffix ".single.pass.cpp"
+and those specific to [unique.ptr.runtime] are named "*.runtime.pass.cpp".
+Tests for both specializations are named normally.
diff --git a/test/std/utilities/smartptr/unique.ptr/nothing_to_do.pass.cpp b/test/std/utilities/smartptr/unique.ptr/nothing_to_do.pass.cpp
new file mode 100644
index 0000000000000..b58f5c55b643a
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
new file mode 100644
index 0000000000000..54c2cf16ecc72
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr::pointer type
+
+#include <memory>
+#include <type_traits>
+
+#include "test_macros.h"
+
+struct Deleter {
+ struct pointer {};
+};
+
+struct D2 {
+private:
+ typedef void pointer;
+};
+
+struct D3 {
+ static long pointer;
+};
+
+template <bool IsArray>
+void test_basic() {
+ typedef typename std::conditional<IsArray, int[], int>::type VT;
+ {
+ typedef std::unique_ptr<VT> P;
+ static_assert((std::is_same<typename P::pointer, int*>::value), "");
+ }
+ {
+ typedef std::unique_ptr<VT, Deleter> P;
+ static_assert((std::is_same<typename P::pointer, Deleter::pointer>::value),
+ "");
+ }
+#if TEST_STD_VER >= 11
+ {
+ typedef std::unique_ptr<VT, D2> P;
+ static_assert(std::is_same<typename P::pointer, int*>::value, "");
+ }
+ {
+ typedef std::unique_ptr<VT, D3> P;
+ static_assert(std::is_same<typename P::pointer, int*>::value, "");
+ }
+#endif
+}
+
+int main() {
+ test_basic</*IsArray*/ false>();
+ test_basic<true>();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
new file mode 100644
index 0000000000000..5d2f955aa185f
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
@@ -0,0 +1,120 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 move assignment
+
+// test move assignment. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+
+#include <memory>
+#include <utility>
+#include <cassert>
+
+#include "deleter_types.h"
+#include "unique_ptr_test_helper.h"
+
+struct GenericDeleter {
+ void operator()(void*) const;
+};
+
+template <bool IsArray>
+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));
+ s2 = std::move(s1);
+ assert(A::count == expect_alive);
+ assert(s2.get() == p);
+ assert(s1.get() == 0);
+ }
+ 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));
+ s2 = std::move(s1);
+ assert(s2.get() == p);
+ assert(s1.get() == 0);
+ assert(A::count == expect_alive);
+ assert(s2.get_deleter().state() == 5);
+ assert(s1.get_deleter().state() == 0);
+ }
+ assert(A::count == 0);
+ {
+ CDeleter<VT> d1(5);
+ std::unique_ptr<VT, CDeleter<VT>&> s1(newValue<VT>(expect_alive), d1);
+ A* p = s1.get();
+ CDeleter<VT> d2(6);
+ std::unique_ptr<VT, CDeleter<VT>&> s2(newValue<VT>(expect_alive), d2);
+ s2 = std::move(s1);
+ assert(s2.get() == p);
+ assert(s1.get() == 0);
+ assert(A::count == expect_alive);
+ assert(d1.state() == 5);
+ assert(d2.state() == 5);
+ }
+ assert(A::count == 0);
+}
+
+template <bool IsArray>
+void test_sfinae() {
+ typedef typename std::conditional<IsArray, int[], int>::type VT;
+ {
+ typedef std::unique_ptr<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_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_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_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_nothrow_assignable<U, U&&>::value, "");
+ }
+}
+
+
+int main() {
+ {
+ test_basic</*IsArray*/ false>();
+ test_sfinae<false>();
+ }
+ {
+ test_basic</*IsArray*/ true>();
+ test_sfinae<true>();
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp
new file mode 100644
index 0000000000000..8d83c3c8888a9
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.pass.cpp
@@ -0,0 +1,420 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 <class Templ, class Other>
+struct is_specialization;
+
+template <template <int> class Templ, int ID1, class Other>
+struct is_specialization<Templ<ID1>, Other> : std::false_type {};
+
+template <template <int> class Templ, int ID1, int ID2>
+struct is_specialization<Templ<ID1>, Templ<ID2> > : std::true_type {};
+
+template <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;
+template <int ID> struct ConstTrackingDeleter;
+
+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/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp
new file mode 100644
index 0000000000000..9b946a733fea6
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.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 assignment
+
+#include <memory>
+#include <utility>
+#include <cassert>
+
+#include "unique_ptr_test_helper.h"
+
+template <class APtr, class BPtr>
+void testAssign(APtr& aptr, BPtr& bptr) {
+ A* p = bptr.get();
+ assert(A::count == 2);
+ aptr = std::move(bptr);
+ assert(aptr.get() == p);
+ assert(bptr.get() == 0);
+ assert(A::count == 1);
+ assert(B::count == 1);
+}
+
+template <class LHS, class RHS>
+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;
+ NCConvertingDeleter(NCConvertingDeleter const&) = delete;
+ NCConvertingDeleter(NCConvertingDeleter&&) = default;
+
+ template <class U>
+ NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+
+ void operator()(T*) const {}
+};
+
+template <class T>
+struct NCConvertingDeleter<T[]> {
+ NCConvertingDeleter() = default;
+ NCConvertingDeleter(NCConvertingDeleter const&) = delete;
+ NCConvertingDeleter(NCConvertingDeleter&&) = default;
+
+ template <class U>
+ NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+
+ void operator()(T*) const {}
+};
+
+struct GenericDeleter {
+ void operator()(void*) const;
+};
+
+struct NCGenericDeleter {
+ NCGenericDeleter() = default;
+ NCGenericDeleter(NCGenericDeleter const&) = delete;
+ NCGenericDeleter(NCGenericDeleter&&) = default;
+
+ void operator()(void*) const {}
+};
+
+void test_sfinae() {
+ using DA = NCConvertingDeleter<A[]>; // non-copyable deleters
+ using DAC = NCConvertingDeleter<const A[]>; // non-copyable deleters
+
+ using DB = NCConvertingDeleter<B[]>;
+ using UA = std::unique_ptr<A[]>;
+ using UAC = std::unique_ptr<const A[]>;
+ using UB = std::unique_ptr<B[]>;
+ using UAD = std::unique_ptr<A[], DA>;
+ using UACD = std::unique_ptr<const A[], DAC>;
+
+ using UBD = std::unique_ptr<B[], DB>;
+ { // cannot move from an lvalue
+ static_assert(std::is_assignable<UAC, UA&&>::value, "");
+ static_assert(!std::is_assignable<UAC, UA&>::value, "");
+ static_assert(!std::is_assignable<UAC, const UA&>::value, "");
+ }
+ { // cannot move if the deleter-types cannot convert
+ static_assert(std::is_assignable<UACD, UAD&&>::value, "");
+ static_assert(!std::is_assignable<UACD, UAC&&>::value, "");
+ static_assert(!std::is_assignable<UAC, UACD&&>::value, "");
+ }
+ { // cannot move-convert with reference deleters of different types
+ using UA1 = std::unique_ptr<A[], DA&>;
+ using UA2 = std::unique_ptr<A[], DAC&>;
+ static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
+ }
+ { // cannot move-convert with reference deleters of different types
+ using UA1 = std::unique_ptr<A[], const DA&>;
+ using UA2 = std::unique_ptr<A[], const DAC&>;
+ static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
+ }
+ { // cannot move-convert from unique_ptr<Single>
+ using UA1 = std::unique_ptr<A[]>;
+ using UA2 = std::unique_ptr<A>;
+ static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
+ }
+ { // cannot move-convert from unique_ptr<Array[]>
+ using UA1 = std::unique_ptr<A[], NCGenericDeleter>;
+ using UA2 = std::unique_ptr<A, NCGenericDeleter>;
+ static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
+ }
+}
+
+int main() {
+ test_sfinae();
+ // FIXME: add tests
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp
new file mode 100644
index 0000000000000..3f2ea422dab33
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 assignment
+
+#include <memory>
+#include <utility>
+#include <cassert>
+
+#include "deleter_types.h"
+#include "unique_ptr_test_helper.h"
+
+template <class APtr, class BPtr>
+void testAssign(APtr& aptr, BPtr& bptr) {
+ A* p = bptr.get();
+ assert(A::count == 2);
+ aptr = std::move(bptr);
+ assert(aptr.get() == p);
+ assert(bptr.get() == 0);
+ assert(A::count == 1);
+ assert(B::count == 1);
+}
+
+template <class LHS, class RHS>
+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;
+ NCConvertingDeleter(NCConvertingDeleter const&) = delete;
+ NCConvertingDeleter(NCConvertingDeleter&&) = default;
+
+ template <class U>
+ NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+
+ void operator()(T*) const {}
+};
+
+template <class T>
+struct NCConvertingDeleter<T[]> {
+ NCConvertingDeleter() = default;
+ NCConvertingDeleter(NCConvertingDeleter const&) = delete;
+ NCConvertingDeleter(NCConvertingDeleter&&) = default;
+
+ template <class U>
+ NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+
+ void operator()(T*) const {}
+};
+
+struct NCGenericDeleter {
+ NCGenericDeleter() = default;
+ NCGenericDeleter(NCGenericDeleter const&) = delete;
+ NCGenericDeleter(NCGenericDeleter&&) = default;
+
+ void operator()(void*) const {}
+};
+
+void test_sfinae() {
+ using DA = NCConvertingDeleter<A>; // non-copyable deleters
+ using DB = NCConvertingDeleter<B>;
+ using UA = std::unique_ptr<A>;
+ using UB = std::unique_ptr<B>;
+ using UAD = std::unique_ptr<A, DA>;
+ using UBD = std::unique_ptr<B, DB>;
+ { // cannot move from an lvalue
+ static_assert(std::is_assignable<UA, UB&&>::value, "");
+ static_assert(!std::is_assignable<UA, UB&>::value, "");
+ static_assert(!std::is_assignable<UA, const UB&>::value, "");
+ }
+ { // cannot move if the deleter-types cannot convert
+ static_assert(std::is_assignable<UAD, UBD&&>::value, "");
+ static_assert(!std::is_assignable<UAD, UB&&>::value, "");
+ static_assert(!std::is_assignable<UA, UBD&&>::value, "");
+ }
+ { // cannot move-convert with reference deleters of different types
+ using UA1 = std::unique_ptr<A, DA&>;
+ using UB1 = std::unique_ptr<B, DB&>;
+ static_assert(!std::is_assignable<UA1, UB1&&>::value, "");
+ }
+ { // cannot move-convert with reference deleters of different types
+ using UA1 = std::unique_ptr<A, const DA&>;
+ using UB1 = std::unique_ptr<B, const DB&>;
+ static_assert(!std::is_assignable<UA1, UB1&&>::value, "");
+ }
+ { // cannot move-convert from unique_ptr<Array[]>
+ using UA1 = std::unique_ptr<A>;
+ using UA2 = std::unique_ptr<A[]>;
+ using UB1 = std::unique_ptr<B[]>;
+ static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
+ static_assert(!std::is_assignable<UA1, UB1&&>::value, "");
+ }
+ { // cannot move-convert from unique_ptr<Array[]>
+ using UA1 = std::unique_ptr<A, NCGenericDeleter>;
+ using UA2 = std::unique_ptr<A[], NCGenericDeleter>;
+ using UB1 = std::unique_ptr<B[], NCGenericDeleter>;
+ static_assert(!std::is_assignable<UA1, UA2&&>::value, "");
+ static_assert(!std::is_assignable<UA1, UB1&&>::value, "");
+ }
+}
+
+int main() {
+ 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);
+ {
+ Deleter<B> del(42);
+ std::unique_ptr<B, Deleter<B> > bptr(new B, std::move(del));
+ std::unique_ptr<A, Deleter<A> > aptr(new A);
+ testAssign(aptr, bptr);
+ checkDeleter(aptr, bptr, 42, 0);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+ {
+ CDeleter<A> adel(6);
+ CDeleter<B> bdel(42);
+ std::unique_ptr<B, CDeleter<B>&> bptr(new B, bdel);
+ std::unique_ptr<A, CDeleter<A>&> aptr(new A, adel);
+ testAssign(aptr, bptr);
+ checkDeleter(aptr, bptr, 42, 42);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp
new file mode 100644
index 0000000000000..165d48a1caa53
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr move assignment
+
+#include <memory>
+#include <cassert>
+
+#include "unique_ptr_test_helper.h"
+
+// test assignment from null
+template <bool IsArray>
+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);
+ s2 = NULL;
+ assert(A::count == 0);
+ assert(s2.get() == 0);
+ }
+ assert(A::count == 0);
+}
+
+int main() {
+ test_basic</*IsArray*/ false>();
+ test_basic<true>();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp
new file mode 100644
index 0000000000000..e1e2e32e23c48
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr move assignment
+
+#include <memory>
+#include <cassert>
+
+#include "unique_ptr_test_helper.h"
+
+// test assignment from null
+
+template <bool IsArray>
+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);
+ s2 = nullptr;
+ assert(A::count == 0);
+ assert(s2.get() == 0);
+ }
+ assert(A::count == 0);
+}
+
+int main() {
+ test_basic</*IsArray*/ false>();
+ test_basic<true>();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/auto_pointer.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/auto_pointer.pass.cpp
new file mode 100644
index 0000000000000..7d5e9bca63c45
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/auto_pointer.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// libc++ cannot safely provide the auto_ptr constructor without rvalue
+// references.
+// REQUIRES: c++11 || c++14
+
+// <memory>
+
+// unique_ptr
+
+// template <class U> unique_ptr(auto_ptr<U>&&) noexcept
+
+#include <memory>
+#include <utility>
+#include <cassert>
+
+#include "test_macros.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&) { ++count; }
+ virtual ~B() { --count; }
+};
+
+int B::count = 0;
+
+struct C {};
+
+struct Deleter {
+ void operator()(void*) {}
+};
+
+void test_sfinae() {
+ {
+ // the auto_ptr constructor should be disable with a non-default deleter.
+ using AP = std::auto_ptr<int>;
+ using U = std::unique_ptr<int, Deleter>;
+ static_assert(!std::is_constructible<U, AP&&>::value, "");
+ }
+ {
+ // the auto_ptr constructor should be disabled when the pointer types are incompatible.
+ using AP = std::auto_ptr<A>;
+ using U = std::unique_ptr<C>;
+ static_assert(!std::is_constructible<U, AP&&>::value, "");
+ }
+}
+
+int main() {
+ {
+ B* p = new B;
+ std::auto_ptr<B> ap(p);
+ std::unique_ptr<A> up(std::move(ap));
+ assert(up.get() == p);
+ assert(ap.get() == 0);
+ assert(A::count == 1);
+ assert(B::count == 1);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+ {
+ B* p = new B;
+ std::auto_ptr<B> ap(p);
+ std::unique_ptr<A> up;
+ up = std::move(ap);
+ assert(up.get() == p);
+ assert(ap.get() == 0);
+ assert(A::count == 1);
+ assert(B::count == 1);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+#if TEST_STD_VER >= 11
+ {
+ static_assert(std::is_nothrow_constructible<std::unique_ptr<A>,
+ std::auto_ptr<B>&&>::value,
+ "");
+ }
+#endif
+ test_sfinae();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
new file mode 100644
index 0000000000000..51d9aa708c407
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+//=============================================================================
+// TESTING std::unique_ptr::unique_ptr()
+//
+// Concerns:
+// 1 The default constructor works for any default constructible deleter types.
+// 2 The stored type 'T' is allowed to be incomplete.
+//
+// Plan
+// 1 Default construct unique_ptr's with various deleter types (C-1)
+// 2 Default construct a unique_ptr with an incomplete element_type and
+// various deleter types (C-1,2)
+
+#include <memory>
+#include <cassert>
+#include "test_macros.h"
+
+#include "test_macros.h"
+#include "deleter_types.h"
+#include "unique_ptr_test_helper.h"
+
+#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;
+#endif
+
+#if TEST_STD_VER >= 11
+struct NonDefaultDeleter {
+ NonDefaultDeleter() = delete;
+ void operator()(void*) const {}
+};
+#endif
+
+template <class ElemType>
+void test_sfinae() {
+#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*)>;
+ static_assert(!std::is_default_constructible<U>::value, "");
+ }
+ { // 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&>;
+ static_assert(!std::is_default_constructible<U1>::value, "");
+ static_assert(!std::is_default_constructible<U2>::value, "");
+ static_assert(!std::is_default_constructible<U3>::value, "");
+ }
+#endif
+}
+
+template <class ElemType>
+void test_basic() {
+#if TEST_STD_VER >= 11
+ {
+ using U1 = std::unique_ptr<ElemType>;
+ using U2 = std::unique_ptr<ElemType, Deleter<ElemType> >;
+ static_assert(std::is_nothrow_default_constructible<U1>::value, "");
+ static_assert(std::is_nothrow_default_constructible<U2>::value, "");
+ }
+#endif
+ {
+ std::unique_ptr<ElemType> p;
+ assert(p.get() == 0);
+ }
+ {
+ std::unique_ptr<ElemType, NCDeleter<ElemType> > p;
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 0);
+ p.get_deleter().set_state(5);
+ assert(p.get_deleter().state() == 5);
+ }
+}
+
+DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
+ doIncompleteTypeTest(0);
+ doIncompleteTypeTest<IncompleteType, Deleter<IncompleteType> >(0);
+} {
+ doIncompleteTypeTest<IncompleteType[]>(0);
+ doIncompleteTypeTest<IncompleteType[], Deleter<IncompleteType[]> >(0);
+})
+
+int main() {
+ {
+ test_sfinae<int>();
+ test_basic<int>();
+ }
+ {
+ test_sfinae<int[]>();
+ test_basic<int[]>();
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
new file mode 100644
index 0000000000000..c102f27fb8e6d
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
@@ -0,0 +1,174 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr move ctor
+
+#include <memory>
+#include <utility>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+//=============================================================================
+// TESTING unique_ptr(unique_ptr&&)
+//
+// Concerns
+// 1 The moved from pointer is empty and the new pointer stores the old value.
+// 2 The only requirement on the deleter is that it is MoveConstructible
+// or a reference.
+// 3 The constructor works for explicitly moved values (ie std::move(x))
+// 4 The constructor works for true temporaries (ie a return value)
+//
+// Plan
+// 1 Explicitly construct unique_ptr<T, D> for various deleter types 'D'.
+// check that the value and deleter have been properly moved. (C-1,2,3)
+//
+// 2 Use the expression 'sink(source())' to move construct a unique_ptr<T, D>
+// from a temporary. 'source' should return the unique_ptr by value and
+// 'sink' should accept the unique_ptr by value. (C-1,2,4)
+
+template <class VT>
+std::unique_ptr<VT> source1() {
+ return std::unique_ptr<VT>(newValue<VT>(1));
+}
+
+template <class VT>
+std::unique_ptr<VT, Deleter<VT> > source2() {
+ return std::unique_ptr<VT, Deleter<VT> >(newValue<VT>(1), Deleter<VT>(5));
+}
+
+template <class VT>
+std::unique_ptr<VT, NCDeleter<VT>&> source3() {
+ static NCDeleter<VT> d(5);
+ return std::unique_ptr<VT, NCDeleter<VT>&>(newValue<VT>(1), d);
+}
+
+template <class VT>
+void sink1(std::unique_ptr<VT> p) {
+ assert(p.get() != nullptr);
+}
+
+template <class VT>
+void sink2(std::unique_ptr<VT, Deleter<VT> > p) {
+ assert(p.get() != nullptr);
+ assert(p.get_deleter().state() == 5);
+}
+
+template <class VT>
+void sink3(std::unique_ptr<VT, NCDeleter<VT>&> p) {
+ assert(p.get() != nullptr);
+ assert(p.get_deleter().state() == 5);
+ assert(&p.get_deleter() == &source3<VT>().get_deleter());
+}
+
+template <class ValueT>
+void test_sfinae() {
+ typedef std::unique_ptr<ValueT> U;
+ { // Ensure unique_ptr is non-copyable
+ static_assert((!std::is_constructible<U, U const&>::value), "");
+ static_assert((!std::is_constructible<U, U&>::value), "");
+ }
+}
+
+template <bool IsArray>
+void test_basic() {
+ typedef typename std::conditional<!IsArray, A, A[]>::type VT;
+ const int expect_alive = IsArray ? 5 : 1;
+ {
+ typedef std::unique_ptr<VT> APtr;
+ APtr s(newValue<VT>(expect_alive));
+ A* p = s.get();
+ APtr s2 = std::move(s);
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ assert(A::count == expect_alive);
+ }
+ assert(A::count == 0);
+ {
+ typedef Deleter<VT> MoveDel;
+ typedef std::unique_ptr<VT, MoveDel> APtr;
+ MoveDel d(5);
+ APtr s(newValue<VT>(expect_alive), std::move(d));
+ assert(d.state() == 0);
+ assert(s.get_deleter().state() == 5);
+ A* p = s.get();
+ APtr s2 = std::move(s);
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ assert(A::count == expect_alive);
+ assert(s2.get_deleter().state() == 5);
+ assert(s.get_deleter().state() == 0);
+ }
+ assert(A::count == 0);
+ {
+ typedef NCDeleter<VT> NonCopyDel;
+ typedef std::unique_ptr<VT, NonCopyDel&> APtr;
+
+ NonCopyDel d;
+ APtr s(newValue<VT>(expect_alive), d);
+ A* p = s.get();
+ APtr s2 = std::move(s);
+ assert(s2.get() == p);
+ assert(s.get() == 0);
+ 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);
+ {
+ sink1<VT>(source1<VT>());
+ assert(A::count == 0);
+ sink2<VT>(source2<VT>());
+ assert(A::count == 0);
+ sink3<VT>(source3<VT>());
+ assert(A::count == 0);
+ }
+ 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/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp
new file mode 100644
index 0000000000000..6e5db86c97fc4
--- /dev/null
+++ b/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/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp
new file mode 100644
index 0000000000000..09e842b5987f5
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "deleter_types.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 {}
+};
+
+void test_sfinae() {
+ { // Disallow copying
+ using U1 = std::unique_ptr<A[], GenericConvertingDeleter<0> >;
+ using U2 = std::unique_ptr<A[], GenericConvertingDeleter<1> >;
+ static_assert(std::is_constructible<U1, U2&&>::value, "");
+ static_assert(!std::is_constructible<U1, U2&>::value, "");
+ static_assert(!std::is_constructible<U1, const U2&>::value, "");
+ static_assert(!std::is_constructible<U1, const U2&&>::value, "");
+ }
+ { // Disallow illegal qualified conversions
+ using U1 = std::unique_ptr<const A[]>;
+ using U2 = std::unique_ptr<A[]>;
+ static_assert(std::is_constructible<U1, U2&&>::value, "");
+ static_assert(!std::is_constructible<U2, U1&&>::value, "");
+ }
+ { // Disallow base-to-derived conversions.
+ using UA = std::unique_ptr<A[]>;
+ using UB = std::unique_ptr<B[]>;
+ static_assert(!std::is_constructible<UA, UB&&>::value, "");
+ }
+ { // Disallow base-to-derived conversions.
+ using UA = std::unique_ptr<A[], GenericConvertingDeleter<0> >;
+ using UB = std::unique_ptr<B[], GenericConvertingDeleter<1> >;
+ static_assert(!std::is_constructible<UA, UB&&>::value, "");
+ }
+ { // Disallow invalid deleter initialization
+ using U1 = std::unique_ptr<A[], GenericDeleter<0> >;
+ using U2 = std::unique_ptr<A[], GenericDeleter<1> >;
+ static_assert(!std::is_constructible<U1, U2&&>::value, "");
+ }
+ { // Disallow reference deleters with different qualifiers
+ using U1 = std::unique_ptr<A[], Deleter<A[]>&>;
+ using U2 = std::unique_ptr<A[], const Deleter<A[]>&>;
+ static_assert(!std::is_constructible<U1, U2&&>::value, "");
+ static_assert(!std::is_constructible<U2, U1&&>::value, "");
+ }
+ {
+ using U1 = std::unique_ptr<A[]>;
+ using U2 = std::unique_ptr<A>;
+ static_assert(!std::is_constructible<U1, U2&&>::value, "");
+ static_assert(!std::is_constructible<U2, U1&&>::value, "");
+ }
+}
+
+
+int main() {
+ test_sfinae();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp
new file mode 100644
index 0000000000000..4e2a6dfa3dd11
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp
@@ -0,0 +1,248 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// Test unique_ptr converting move ctor
+
+// NOTE: unique_ptr does not provide converting constructors in c++03
+// UNSUPPORTED: c++98, c++03
+
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+// test converting move ctor. Should only require a MoveConstructible deleter, or if
+// deleter is a reference, not even that.
+// Explicit version
+
+template <class LHS, class RHS>
+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);
+ assert(rhs.get_deleter().state() == 42);
+ assert(lhs.get_deleter().state() == 42);
+ lhs.get_deleter().set_state(99);
+ assert(lhs.get_deleter().state() == 99);
+ assert(rhs.get_deleter().state() == 99);
+}
+
+template <class LHS, class RHS>
+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) {
+ assert(lhs.get() == RHSVal);
+ assert(rhs.get() == nullptr);
+ assert(A::count == 1);
+ assert(B::count == 1);
+}
+
+void checkNoneAlive() {
+ assert(A::count == 0);
+ assert(B::count == 0);
+}
+
+template <class T>
+struct NCConvertingDeleter {
+ NCConvertingDeleter() = default;
+ NCConvertingDeleter(NCConvertingDeleter const&) = delete;
+ NCConvertingDeleter(NCConvertingDeleter&&) = default;
+
+ template <class U>
+ NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+
+ void operator()(T*) const {}
+};
+
+template <class T>
+struct NCConvertingDeleter<T[]> {
+ NCConvertingDeleter() = default;
+ NCConvertingDeleter(NCConvertingDeleter const&) = delete;
+ NCConvertingDeleter(NCConvertingDeleter&&) = default;
+
+ template <class U>
+ NCConvertingDeleter(NCConvertingDeleter<U>&&) {}
+
+ void operator()(T*) const {}
+};
+
+struct NCGenericDeleter {
+ NCGenericDeleter() = default;
+ NCGenericDeleter(NCGenericDeleter const&) = delete;
+ NCGenericDeleter(NCGenericDeleter&&) = default;
+
+ void operator()(void*) const {}
+};
+
+void test_sfinae() {
+ using DA = NCConvertingDeleter<A>; // non-copyable deleters
+ using DB = NCConvertingDeleter<B>;
+ using UA = std::unique_ptr<A>;
+ using UB = std::unique_ptr<B>;
+ using UAD = std::unique_ptr<A, DA>;
+ using UBD = std::unique_ptr<B, DB>;
+ { // cannot move from an lvalue
+ static_assert(std::is_constructible<UA, UB&&>::value, "");
+ static_assert(!std::is_constructible<UA, UB&>::value, "");
+ static_assert(!std::is_constructible<UA, const UB&>::value, "");
+ }
+ { // cannot move if the deleter-types cannot convert
+ static_assert(std::is_constructible<UAD, UBD&&>::value, "");
+ static_assert(!std::is_constructible<UAD, UB&&>::value, "");
+ static_assert(!std::is_constructible<UA, UBD&&>::value, "");
+ }
+ { // cannot move-convert with reference deleters of different types
+ using UA1 = std::unique_ptr<A, DA&>;
+ using UB1 = std::unique_ptr<B, DB&>;
+ static_assert(!std::is_constructible<UA1, UB1&&>::value, "");
+ }
+ { // cannot move-convert with reference deleters of different types
+ using UA1 = std::unique_ptr<A, const DA&>;
+ using UB1 = std::unique_ptr<B, const DB&>;
+ static_assert(!std::is_constructible<UA1, UB1&&>::value, "");
+ }
+ { // cannot move-convert from unique_ptr<Array[]>
+ using UA1 = std::unique_ptr<A>;
+ using UA2 = std::unique_ptr<A[]>;
+ using UB1 = std::unique_ptr<B[]>;
+ static_assert(!std::is_constructible<UA1, UA2&&>::value, "");
+ static_assert(!std::is_constructible<UA1, UB1&&>::value, "");
+ }
+ { // cannot move-convert from unique_ptr<Array[]>
+ using UA1 = std::unique_ptr<A, NCGenericDeleter>;
+ using UA2 = std::unique_ptr<A[], NCGenericDeleter>;
+ using UB1 = std::unique_ptr<B[], NCGenericDeleter>;
+ static_assert(!std::is_constructible<UA1, UA2&&>::value, "");
+ static_assert(!std::is_constructible<UA1, UB1&&>::value, "");
+ }
+}
+
+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
+ BPtr b(new B);
+ A* p = b.get();
+ APtr a(std::move(b));
+ checkCtor(a, b, p);
+ }
+ checkNoneAlive();
+ { // implicit
+ BPtr b(new B);
+ A* p = b.get();
+ APtr a = std::move(b);
+ checkCtor(a, b, p);
+ }
+ checkNoneAlive();
+ }
+ { // test with moveable deleters
+ typedef std::unique_ptr<A, Deleter<A> > APtr;
+ typedef std::unique_ptr<B, Deleter<B> > BPtr;
+ {
+ Deleter<B> del(5);
+ BPtr b(new B, std::move(del));
+ A* p = b.get();
+ APtr a(std::move(b));
+ checkCtor(a, b, p);
+ checkDeleter(a, b, 5, 0);
+ }
+ checkNoneAlive();
+ {
+ Deleter<B> del(5);
+ BPtr b(new B, std::move(del));
+ A* p = b.get();
+ APtr a = std::move(b);
+ checkCtor(a, b, p);
+ checkDeleter(a, b, 5, 0);
+ }
+ checkNoneAlive();
+ }
+ { // test with reference deleters
+ typedef std::unique_ptr<A, NCDeleter<A>&> APtr;
+ typedef std::unique_ptr<B, NCDeleter<A>&> BPtr;
+ NCDeleter<A> del(5);
+ {
+ BPtr b(new B, del);
+ A* p = b.get();
+ APtr a(std::move(b));
+ checkCtor(a, b, p);
+ checkReferenceDeleter(a, b);
+ }
+ checkNoneAlive();
+ {
+ BPtr b(new B, del);
+ A* p = b.get();
+ APtr a = std::move(b);
+ checkCtor(a, b, p);
+ checkReferenceDeleter(a, b);
+ }
+ checkNoneAlive();
+ }
+ {
+ typedef std::unique_ptr<A, CDeleter<A> > APtr;
+ typedef std::unique_ptr<B, CDeleter<B>&> BPtr;
+ CDeleter<B> del(5);
+ {
+ BPtr b(new B, del);
+ A* p = b.get();
+ APtr a(std::move(b));
+ checkCtor(a, b, p);
+ checkDeleter(a, b, 5, 5);
+ }
+ checkNoneAlive();
+ {
+ BPtr b(new B, del);
+ A* p = b.get();
+ APtr a = std::move(b);
+ checkCtor(a, b, p);
+ checkDeleter(a, b, 5, 5);
+ }
+ checkNoneAlive();
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp
new file mode 100644
index 0000000000000..8bc8a57c1c8d8
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// FIXME(EricWF): This test contains tests for constructing a unique_ptr from NULL.
+// The behavior demonstrated in this test is not meant to be standard; It simply
+// tests the current status quo in libc++.
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+template <class VT>
+void test_pointer_ctor() {
+ {
+ std::unique_ptr<VT> p(0);
+ assert(p.get() == 0);
+ }
+ {
+ std::unique_ptr<VT, Deleter<VT> > p(0);
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 0);
+ }
+}
+
+template <class VT>
+void test_pointer_deleter_ctor() {
+ {
+ std::default_delete<VT> d;
+ std::unique_ptr<VT> p(0, d);
+ assert(p.get() == 0);
+ }
+ {
+ std::unique_ptr<VT, Deleter<VT> > p(0, Deleter<VT>(5));
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 5);
+ }
+ {
+ NCDeleter<VT> d(5);
+ std::unique_ptr<VT, NCDeleter<VT>&> p(0, d);
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 5);
+ }
+ {
+ NCConstDeleter<VT> d(5);
+ std::unique_ptr<VT, NCConstDeleter<VT> const&> p(0, d);
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 5);
+ }
+}
+
+int main() {
+ {
+ // test_pointer_ctor<int>();
+ test_pointer_deleter_ctor<int>();
+ }
+ {
+ test_pointer_ctor<int[]>();
+ test_pointer_deleter_ctor<int[]>();
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
new file mode 100644
index 0000000000000..6764935fee14c
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// unique_ptr(nullptr_t);
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+
+#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
+
+
+#if TEST_STD_VER >= 11
+struct NonDefaultDeleter {
+ NonDefaultDeleter() = delete;
+ void operator()(void*) const {}
+};
+#endif
+
+template <class VT>
+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,
+ "");
+ }
+#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
+ { // the constructor does not participate in overload resultion when
+ // the deleter is a pointer type
+ using U = std::unique_ptr<VT, void (*)(void*)>;
+ static_assert(!std::is_constructible<U, decltype(nullptr)>::value, "");
+ }
+ { // 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&>;
+ static_assert(!std::is_constructible<U1, decltype(nullptr)>::value, "");
+ static_assert(!std::is_constructible<U2, decltype(nullptr)>::value, "");
+ static_assert(!std::is_constructible<U3, decltype(nullptr)>::value, "");
+ }
+#endif
+}
+
+DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
+ { doIncompleteTypeTest(0, nullptr); }
+ checkNumIncompleteTypeAlive(0);
+ {
+ doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(0,
+ nullptr);
+ }
+ checkNumIncompleteTypeAlive(0);
+ { doIncompleteTypeTest<IncompleteType[]>(0, nullptr); }
+ checkNumIncompleteTypeAlive(0);
+ {
+ doIncompleteTypeTest<IncompleteType[], NCDeleter<IncompleteType[]> >(
+ 0, nullptr);
+ }
+ checkNumIncompleteTypeAlive(0);
+})
+
+int main() {
+ {
+ test_basic<int>();
+ test_sfinae<int>();
+ }
+ {
+ test_basic<int[]>();
+ test_sfinae<int[]>();
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
new file mode 100644
index 0000000000000..8df259bd4e1d1
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
@@ -0,0 +1,171 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+//=============================================================================
+// TESTING std::unique_ptr::unique_ptr(pointer)
+//
+// Concerns:
+// 1 The pointer constructor works for any default constructible deleter types.
+// 2 The pointer constructor accepts pointers to derived types.
+// 2 The stored type 'T' is allowed to be incomplete.
+//
+// Plan
+// 1 Construct unique_ptr<T, D>'s with a pointer to 'T' and various deleter
+// types (C-1)
+// 2 Construct unique_ptr<T, D>'s with a pointer to 'D' and various deleter
+// types where 'D' is derived from 'T'. (C-1,2)
+// 3 Construct a unique_ptr<T, D> with a pointer to 'T' and various deleter
+// types where 'T' is an incomplete type (C-1,3)
+
+// Test unique_ptr(pointer) ctor
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+// unique_ptr(pointer) ctor should only require default Deleter ctor
+
+template <bool IsArray>
+void test_pointer() {
+ typedef typename std::conditional<!IsArray, A, A[]>::type ValueT;
+ const int expect_alive = IsArray ? 5 : 1;
+#if TEST_STD_VER >= 11
+ {
+ 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
+ {
+ A* p = newValue<ValueT>(expect_alive);
+ assert(A::count == expect_alive);
+ std::unique_ptr<ValueT> s(p);
+ assert(s.get() == p);
+ }
+ assert(A::count == 0);
+ {
+ A* p = newValue<ValueT>(expect_alive);
+ 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);
+}
+
+void test_derived() {
+ {
+ B* p = new B;
+ 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);
+ {
+ B* p = new B;
+ 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_STD_VER >= 11
+struct NonDefaultDeleter {
+ NonDefaultDeleter() = delete;
+ void operator()(void*) const {}
+};
+
+struct GenericDeleter {
+ void operator()(void*) const;
+};
+#endif
+
+template <class T>
+void test_sfinae() {
+#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*)>;
+ static_assert(!std::is_constructible<U, T*>::value, "");
+ }
+ { // the constructor does not participate in overload resolution when
+ // the deleter is not default constructible
+ using Del = CDeleter<T>;
+ using U1 = std::unique_ptr<T, NonDefaultDeleter>;
+ using U2 = std::unique_ptr<T, Del&>;
+ using U3 = std::unique_ptr<T, Del const&>;
+ static_assert(!std::is_constructible<U1, T*>::value, "");
+ static_assert(!std::is_constructible<U2, T*>::value, "");
+ static_assert(!std::is_constructible<U3, T*>::value, "");
+ }
+#endif
+}
+
+static void test_sfinae_runtime() {
+#if TEST_STD_VER >= 11
+ { // the constructor does not participate in overload resolution when
+ // a base <-> derived conversion would occur.
+ using UA = std::unique_ptr<A[]>;
+ using UAD = std::unique_ptr<A[], GenericDeleter>;
+ using UAC = std::unique_ptr<const A[]>;
+ using UB = std::unique_ptr<B[]>;
+ using UBD = std::unique_ptr<B[], GenericDeleter>;
+ using UBC = std::unique_ptr<const B[]>;
+
+ static_assert(!std::is_constructible<UA, B*>::value, "");
+ static_assert(!std::is_constructible<UB, A*>::value, "");
+ static_assert(!std::is_constructible<UAD, B*>::value, "");
+ static_assert(!std::is_constructible<UBD, A*>::value, "");
+ static_assert(!std::is_constructible<UAC, const B*>::value, "");
+ static_assert(!std::is_constructible<UBC, const A*>::value, "");
+ }
+#endif
+}
+
+DEFINE_AND_RUN_IS_INCOMPLETE_TEST({
+ { doIncompleteTypeTest(1, getNewIncomplete()); }
+ checkNumIncompleteTypeAlive(0);
+ {
+ doIncompleteTypeTest<IncompleteType, NCDeleter<IncompleteType> >(
+ 1, getNewIncomplete());
+ }
+ checkNumIncompleteTypeAlive(0);
+})
+
+int main() {
+ {
+ test_pointer</*IsArray*/ false>();
+ test_derived();
+ test_sfinae<int>();
+ }
+ {
+ test_pointer</*IsArray*/ true>();
+ test_sfinae<int[]>();
+ test_sfinae_runtime();
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp
new file mode 100644
index 0000000000000..b4cd3f36ab573
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// Without rvalue references it is impossible to detect when a rvalue deleter
+// is given.
+// XFAIL: c++98, c++03
+
+// <memory>
+
+// unique_ptr
+
+// unique_ptr<T, const D&>(pointer, D()) should not compile
+
+#include <memory>
+
+struct Deleter {
+ void operator()(int* p) const { delete p; }
+};
+
+int main() {
+ // 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/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
new file mode 100644
index 0000000000000..781794d41b5e3
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
@@ -0,0 +1,328 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+//=============================================================================
+// TESTING unique_ptr(pointer, deleter)
+//
+// Concerns:
+// 1 unique_ptr(pointer, deleter&&) only requires a MoveConstructible deleter.
+// 2 unique_ptr(pointer, deleter&) requires a CopyConstructible deleter.
+// 3 unique_ptr<T, D&>(pointer, deleter) does not require a CopyConstructible deleter.
+// 4 unique_ptr<T, D const&>(pointer, deleter) does not require a CopyConstructible deleter.
+// 5 unique_ptr(pointer, deleter) should work for derived pointers.
+// 6 unique_ptr(pointer, deleter) should work with function pointers.
+// 7 unique_ptr<void> should work.
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+bool my_free_called = false;
+
+void my_free(void*) { my_free_called = true; }
+
+#if TEST_STD_VER >= 11
+struct DeleterBase {
+ void operator()(void*) const {}
+};
+struct CopyOnlyDeleter : DeleterBase {
+ CopyOnlyDeleter() = default;
+ CopyOnlyDeleter(CopyOnlyDeleter const&) = default;
+ CopyOnlyDeleter(CopyOnlyDeleter&&) = delete;
+};
+struct MoveOnlyDeleter : DeleterBase {
+ MoveOnlyDeleter() = default;
+ MoveOnlyDeleter(MoveOnlyDeleter&&) = default;
+};
+struct NoCopyMoveDeleter : DeleterBase {
+ NoCopyMoveDeleter() = default;
+ NoCopyMoveDeleter(NoCopyMoveDeleter const&) = delete;
+};
+#endif
+
+template <bool IsArray>
+void test_sfinae() {
+#if TEST_STD_VER >= 11
+ typedef typename std::conditional<!IsArray, int, int[]>::type VT;
+ {
+ using D = CopyOnlyDeleter;
+ using U = std::unique_ptr<VT, D>;
+ static_assert(std::is_constructible<U, int*, D const&>::value, "");
+ static_assert(std::is_constructible<U, int*, D&>::value, "");
+ static_assert(std::is_constructible<U, int*, D&&>::value, "");
+ // FIXME: __libcpp_compressed_pair attempts to perform a move even though
+ // it should only copy.
+ //D d;
+ //U u(nullptr, std::move(d));
+ }
+ {
+ using D = MoveOnlyDeleter;
+ using U = std::unique_ptr<VT, D>;
+ static_assert(!std::is_constructible<U, int*, D const&>::value, "");
+ static_assert(!std::is_constructible<U, int*, D&>::value, "");
+ static_assert(std::is_constructible<U, int*, D&&>::value, "");
+ D d;
+ U u(nullptr, std::move(d));
+ }
+ {
+ using D = NoCopyMoveDeleter;
+ using U = std::unique_ptr<VT, D>;
+ static_assert(!std::is_constructible<U, int*, D const&>::value, "");
+ static_assert(!std::is_constructible<U, int*, D&>::value, "");
+ static_assert(!std::is_constructible<U, int*, D&&>::value, "");
+ }
+ {
+ using D = NoCopyMoveDeleter;
+ using U = std::unique_ptr<VT, D&>;
+ static_assert(!std::is_constructible<U, int*, D const&>::value, "");
+ static_assert(std::is_constructible<U, int*, D&>::value, "");
+ static_assert(!std::is_constructible<U, int*, D&&>::value, "");
+ static_assert(!std::is_constructible<U, int*, const D&&>::value, "");
+ }
+ {
+ using D = NoCopyMoveDeleter;
+ using U = std::unique_ptr<VT, const D&>;
+ static_assert(std::is_constructible<U, int*, D const&>::value, "");
+ static_assert(std::is_constructible<U, int*, D&>::value, "");
+ static_assert(!std::is_constructible<U, int*, D&&>::value, "");
+ static_assert(!std::is_constructible<U, int*, const D&&>::value, "");
+ }
+#endif
+}
+
+template <bool IsArray>
+void test_noexcept() {
+#if TEST_STD_VER >= 11
+ typedef typename std::conditional<!IsArray, int, int[]>::type VT;
+ {
+ using D = CopyOnlyDeleter;
+ using U = std::unique_ptr<VT, D>;
+ static_assert(std::is_nothrow_constructible<U, int*, D const&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, int*, D&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, int*, D&&>::value, "");
+ }
+ {
+ using D = MoveOnlyDeleter;
+ using U = std::unique_ptr<VT, D>;
+ static_assert(std::is_nothrow_constructible<U, int*, D&&>::value, "");
+ D d;
+ U u(nullptr, std::move(d));
+ }
+ {
+ using D = NoCopyMoveDeleter;
+ using U = std::unique_ptr<VT, D&>;
+ static_assert(std::is_nothrow_constructible<U, int*, D&>::value, "");
+ }
+ {
+ using D = NoCopyMoveDeleter;
+ using U = std::unique_ptr<VT, const D&>;
+ static_assert(std::is_nothrow_constructible<U, int*, D const&>::value, "");
+ static_assert(std::is_nothrow_constructible<U, int*, D&>::value, "");
+ }
+#endif
+}
+
+void test_sfinae_runtime() {
+#if TEST_STD_VER >= 11
+ {
+ using D = CopyOnlyDeleter;
+ using U = std::unique_ptr<A[], D>;
+ 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, "");
+ static_assert(!std::is_constructible<U, B*, D&&>::value, "");
+ // FIXME: __libcpp_compressed_pair attempts to perform a move even though
+ // it should only copy.
+ //D d;
+ //U u(nullptr, std::move(d));
+ }
+ {
+ using D = MoveOnlyDeleter;
+ 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, B*, D const&>::value, "");
+ static_assert(!std::is_constructible<U, B*, D&>::value, "");
+ static_assert(!std::is_constructible<U, B*, D&&>::value, "");
+ D d;
+ U u(nullptr, std::move(d));
+ }
+ {
+ 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_constructible<U, A*, D&&>::value, "");
+
+ static_assert(!std::is_constructible<U, B*, D const&>::value, "");
+ static_assert(!std::is_constructible<U, B*, D&>::value, "");
+ static_assert(!std::is_constructible<U, B*, D&&>::value, "");
+ }
+ {
+ using D = NoCopyMoveDeleter;
+ using U = std::unique_ptr<A[], D&>;
+ static_assert(!std::is_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, "");
+
+ static_assert(!std::is_constructible<U, B*, D const&>::value, "");
+ static_assert(!std::is_constructible<U, B*, D&>::value, "");
+ static_assert(!std::is_constructible<U, B*, D&&>::value, "");
+ static_assert(!std::is_constructible<U, B*, const D&&>::value, "");
+ }
+ {
+ using D = NoCopyMoveDeleter;
+ using U = std::unique_ptr<A[], const D&>;
+ 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, "");
+
+ static_assert(!std::is_constructible<U, B*, D const&>::value, "");
+ static_assert(!std::is_constructible<U, B*, D&>::value, "");
+ static_assert(!std::is_constructible<U, B*, D&&>::value, "");
+ static_assert(!std::is_constructible<U, B*, const D&&>::value, "");
+ }
+#endif
+}
+
+template <bool IsArray>
+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);
+ 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);
+ { // CopyConstructible deleter (C-2)
+ A* p = newValue<VT>(expect_alive);
+ assert(A::count == expect_alive);
+ CopyDeleter<VT> d(5);
+ std::unique_ptr<VT, CopyDeleter<VT> > s(p, d);
+ assert(s.get() == p);
+ assert(s.get_deleter().state() == 5);
+ d.set_state(6);
+ assert(s.get_deleter().state() == 5);
+ }
+ assert(A::count == 0);
+ { // Reference deleter (C-3)
+ A* p = newValue<VT>(expect_alive);
+ assert(A::count == expect_alive);
+ NCDeleter<VT> d(5);
+ std::unique_ptr<VT, NCDeleter<VT>&> s(p, d);
+ assert(s.get() == p);
+ assert(&s.get_deleter() == &d);
+ assert(s.get_deleter().state() == 5);
+ d.set_state(6);
+ assert(s.get_deleter().state() == 6);
+ }
+ assert(A::count == 0);
+ { // Const Reference deleter (C-4)
+ A* p = newValue<VT>(expect_alive);
+ 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);
+ }
+ assert(my_free_called);
+ }
+}
+
+void test_basic_single() {
+ assert(A::count == 0);
+ assert(B::count == 0);
+ { // Derived pointers (C-5)
+ B* p = new B;
+ 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);
+ }
+ assert(my_free_called);
+ }
+}
+
+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/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp
new file mode 100644
index 0000000000000..fa10ade512064
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// The deleter is not called if get() == 0
+
+#include <memory>
+#include <cassert>
+
+class Deleter {
+ int state_;
+
+ Deleter(Deleter&);
+ Deleter& operator=(Deleter&);
+
+public:
+ Deleter() : state_(0) {}
+
+ int state() const { return state_; }
+
+ void operator()(void*) { ++state_; }
+};
+
+template <class T>
+void test_basic() {
+ Deleter d;
+ assert(d.state() == 0);
+ {
+ std::unique_ptr<T, Deleter&> p(nullptr, d);
+ assert(p.get() == nullptr);
+ assert(&p.get_deleter() == &d);
+ }
+ assert(d.state() == 0);
+}
+
+int main() {
+ test_basic<int>();
+ test_basic<int[]>();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp
new file mode 100644
index 0000000000000..f7f20945094e8
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test release
+
+#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);
+ A* ap = p.get();
+ A* a = p.release();
+ assert(A::count == expect_alive);
+ assert(p.get() == nullptr);
+ assert(ap == a);
+ assert(a != nullptr);
+
+ if (IsArray)
+ delete[] a;
+ else
+ delete a;
+
+ assert(A::count == 0);
+ }
+ assert(A::count == 0);
+}
+
+int main() {
+ test_basic</*IsArray*/ false>();
+ test_basic<true>();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp
new file mode 100644
index 0000000000000..c95c55b4adf88
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test reset
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+template <bool IsArray>
+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);
+ 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<const VT> p(newValue<const VT>(expect_alive));
+ 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));
+ 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_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/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.runtime.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.runtime.fail.cpp
new file mode 100644
index 0000000000000..0d067b9abff5b
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.runtime.fail.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test reset
+
+#include <memory>
+#include <cassert>
+
+#include "unique_ptr_test_helper.h"
+
+int main() {
+ {
+ std::unique_ptr<A[]> p;
+ p.reset(static_cast<B*>(nullptr)); // expected-error {{no matching member function for call to 'reset'}}
+ }
+ {
+ std::unique_ptr<int[]> p;
+ p.reset(static_cast<const int*>(nullptr)); // expected-error {{no matching member function for call to 'reset'}}
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp
new file mode 100644
index 0000000000000..8f2a69913dde0
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test reset
+
+#include <memory>
+#include <cassert>
+
+#include "unique_ptr_test_helper.h"
+
+int main() {
+ {
+ std::unique_ptr<A> p(new A);
+ 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);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+ {
+ std::unique_ptr<A> p(new B);
+ 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);
+ }
+ assert(A::count == 0);
+ assert(B::count == 0);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp
new file mode 100644
index 0000000000000..f838661c53f0e
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test reset against resetting self
+
+#include <memory>
+
+struct A {
+ std::unique_ptr<A> ptr_;
+
+ A() : ptr_(this) {}
+ void reset() { ptr_.reset(); }
+};
+
+int main() { (new A)->reset(); }
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp
new file mode 100644
index 0000000000000..de18865c50aec
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test swap
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+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) {
+ state_ = a.state_;
+ return *this;
+ }
+ ~TT() { --count; }
+
+ friend 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) {
+ typedef typename std::remove_all_extents<T>::type VT;
+ VT* p = newValue<T>(size);
+ for (int i = 0; i < size; ++i)
+ (p + i)->state_ = new_value;
+ return p;
+}
+
+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));
+ TT* p2 = newValueInit<VT>(expect_alive, 2);
+ std::unique_ptr<VT, Deleter<VT> > s2(p2, Deleter<VT>(2));
+ assert(s1.get() == p1);
+ assert(*s1.get() == TT(1));
+ assert(s1.get_deleter().state() == 1);
+ assert(s2.get() == p2);
+ assert(*s2.get() == TT(2));
+ assert(s2.get_deleter().state() == 2);
+ s1.swap(s2);
+ assert(s1.get() == p2);
+ assert(*s1.get() == TT(2));
+ assert(s1.get_deleter().state() == 2);
+ assert(s2.get() == p1);
+ assert(*s2.get() == TT(1));
+ assert(s2.get_deleter().state() == 1);
+ assert(TT::count == (expect_alive * 2));
+ }
+ assert(TT::count == 0);
+}
+
+int main() {
+ test_basic</*IsArray*/ false>();
+ test_basic<true>();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.runtime.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.runtime.fail.cpp
new file mode 100644
index 0000000000000..b05fb71cdc677
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.runtime.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test op*()
+
+#include <memory>
+#include <cassert>
+
+int main() {
+ std::unique_ptr<int[]> p(new int(3));
+ const std::unique_ptr<int[]>& cp = p;
+ (void)(*p); // expected-error {{indirection requires pointer operand ('std::unique_ptr<int []>' invalid)}}
+ (void)(*cp); // expected-error {{indirection requires pointer operand ('const std::unique_ptr<int []>' invalid)}}
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
new file mode 100644
index 0000000000000..b2d3da48daee5
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test op*()
+
+#include <memory>
+#include <cassert>
+
+int main() {
+ std::unique_ptr<int> p(new int(3));
+ assert(*p == 3);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp
new file mode 100644
index 0000000000000..9a6d6c65fa810
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test op*()
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "unique_ptr_test_helper.h"
+
+template <class UPtr>
+void doTest(UPtr& p, bool ExpectTrue) {
+ if (p)
+ assert(ExpectTrue);
+ else
+ assert(!ExpectTrue);
+
+ if (!p)
+ assert(!ExpectTrue);
+ else
+ assert(ExpectTrue);
+}
+
+template <bool IsArray>
+void test_basic() {
+ typedef typename std::conditional<IsArray, int[], int>::type VT;
+ typedef std::unique_ptr<VT> U;
+ {
+ static_assert((std::is_constructible<bool, U>::value), "");
+ static_assert((std::is_constructible<bool, U const&>::value), "");
+ }
+#if TEST_STD_VER >= 11
+ {
+ static_assert(!std::is_convertible<U, bool>::value, "");
+ static_assert(!std::is_convertible<U const&, bool>::value, "");
+ }
+#endif
+ {
+ U p(newValue<VT>(1));
+ U const& cp = p;
+ doTest(p, true);
+ doTest(cp, true);
+ }
+ {
+ U p;
+ const U& cp = p;
+ doTest(p, false);
+ doTest(cp, false);
+ }
+}
+
+int main() {
+ test_basic</*IsArray*/ false>();
+ test_basic<true>();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp
new file mode 100644
index 0000000000000..518e31cf94872
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test get
+
+#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, int[], int>::type VT;
+ typedef const VT CVT;
+ {
+ typedef std::unique_ptr<VT> U;
+ int* p = newValue<VT>(1);
+ U s(p);
+ U const& sc = s;
+ ASSERT_SAME_TYPE(decltype(s.get()), int*);
+ ASSERT_SAME_TYPE(decltype(sc.get()), int*);
+ assert(s.get() == p);
+ assert(sc.get() == s.get());
+ }
+ {
+ typedef std::unique_ptr<CVT> U;
+ const int* p = newValue<VT>(1);
+ U s(p);
+ U const& sc = s;
+ ASSERT_SAME_TYPE(decltype(s.get()), const int*);
+ ASSERT_SAME_TYPE(decltype(sc.get()), const int*);
+ assert(s.get() == p);
+ assert(sc.get() == s.get());
+ }
+}
+
+int main() {
+ test_basic</*IsArray*/ false>();
+ test_basic<true>();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp
new file mode 100644
index 0000000000000..6a00d14a2cae4
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test get_deleter()
+
+#include <memory>
+#include <cassert>
+#include "test_macros.h"
+
+struct Deleter {
+ Deleter() {}
+
+ void operator()(void*) const {}
+
+ int test() { return 5; }
+ int test() const { return 6; }
+};
+
+template <bool IsArray>
+void test_basic() {
+ typedef typename std::conditional<IsArray, int[], int>::type VT;
+ {
+ std::unique_ptr<int, Deleter> p;
+ assert(p.get_deleter().test() == 5);
+ }
+ {
+ const std::unique_ptr<VT, Deleter> p;
+ assert(p.get_deleter().test() == 6);
+ }
+ {
+ typedef std::unique_ptr<VT, const Deleter&> UPtr;
+ const Deleter d;
+ UPtr p(nullptr, d);
+ const UPtr& cp = p;
+ ASSERT_SAME_TYPE(decltype(p.get_deleter()), const Deleter&);
+ ASSERT_SAME_TYPE(decltype(cp.get_deleter()), const Deleter&);
+ assert(p.get_deleter().test() == 6);
+ assert(cp.get_deleter().test() == 6);
+ }
+ {
+ typedef std::unique_ptr<VT, Deleter&> UPtr;
+ Deleter d;
+ UPtr p(nullptr, d);
+ const UPtr& cp = p;
+ ASSERT_SAME_TYPE(decltype(p.get_deleter()), Deleter&);
+ ASSERT_SAME_TYPE(decltype(cp.get_deleter()), Deleter&);
+ assert(p.get_deleter().test() == 5);
+ assert(cp.get_deleter().test() == 5);
+ }
+}
+
+int main() {
+ test_basic</*IsArray*/ false>();
+ test_basic<true>();
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.runtime.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.runtime.fail.cpp
new file mode 100644
index 0000000000000..d66af054ce649
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.runtime.fail.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test op->()
+
+#include <memory>
+#include <cassert>
+
+struct V {
+ int member;
+};
+
+int main() {
+ std::unique_ptr<V[]> p;
+ std::unique_ptr<V[]> const& cp = p;
+
+ p->member; // expected-error {{member reference type 'std::unique_ptr<V []>' is not a pointer}}
+ // expected-error@-1 {{no member named 'member'}}
+
+ cp->member; // expected-error {{member reference type 'const std::unique_ptr<V []>' is not a pointer}}
+ // expected-error@-1 {{no member named 'member'}}
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp
new file mode 100644
index 0000000000000..8bed9dda2ead3
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test op->()
+
+#include <memory>
+#include <cassert>
+
+struct A {
+ int i_;
+
+ A() : i_(7) {}
+};
+
+int main() {
+ std::unique_ptr<A> p(new A);
+ assert(p->i_ == 7);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
new file mode 100644
index 0000000000000..b47c35afb4f58
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test op[](size_t)
+
+#include <memory>
+#include <cassert>
+
+class A {
+ int state_;
+ static int next_;
+
+public:
+ A() : state_(++next_) {}
+ int get() const { return state_; }
+
+ friend bool operator==(const A& x, int y) { return x.state_ == y; }
+
+ A& operator=(int i) {
+ state_ = i;
+ return *this;
+ }
+};
+
+int A::next_ = 0;
+
+int main() {
+ std::unique_ptr<A[]> p(new A[3]);
+ assert(p[0] == 1);
+ assert(p[1] == 2);
+ assert(p[2] == 3);
+ p[0] = 3;
+ p[1] = 2;
+ p[2] = 1;
+ assert(p[0] == 3);
+ assert(p[1] == 2);
+ assert(p[2] == 1);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.single.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.single.fail.cpp
new file mode 100644
index 0000000000000..529749da67e99
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.single.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// test op[](size_t)
+
+#include <memory>
+#include <cassert>
+
+int main() {
+ std::unique_ptr<int> p(new int[3]);
+ std::unique_ptr<int> const& cp = p;
+ p[0]; // expected-error {{type 'std::unique_ptr<int>' does not provide a subscript operator}}
+ cp[1]; // expected-error {{type 'const std::unique_ptr<int>' does not provide a subscript operator}}
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp
new file mode 100644
index 0000000000000..30b4ecb94e18f
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11
+#include <memory>
+#include <string>
+#include <cassert>
+
+// The only way to create an unique_ptr<T[]> is to default construct them.
+
+class foo {
+public:
+ foo () : val_(3) {}
+ int get () const { return val_; }
+private:
+ int val_;
+ };
+
+int main()
+{
+ {
+ auto p1 = std::make_unique<int[]>(5);
+ 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 );
+ }
+
+ {
+ auto p3 = std::make_unique<foo[]>(7);
+ for ( int i = 0; i < 7; ++i )
+ assert ( p3[i].get () == 3 );
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array1.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array1.fail.cpp
new file mode 100644
index 0000000000000..00987919413bb
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array1.fail.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include <memory>
+#include <string>
+#include <cassert>
+
+int main()
+{
+ auto up1 = std::make_unique<std::string[]>("error"); // doesn't compile - no bound
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array2.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array2.fail.cpp
new file mode 100644
index 0000000000000..cc94e9ab3aaab
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array2.fail.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include <memory>
+#include <string>
+#include <cassert>
+
+int main()
+{
+ auto up2 = std::make_unique<int[]>(10, 20, 30, 40);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array3.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array3.fail.cpp
new file mode 100644
index 0000000000000..cfdc2e1d886b0
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array3.fail.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include <memory>
+#include <string>
+#include <cassert>
+
+int main()
+{
+ auto up3 = std::make_unique<int[5]>(); // this is deleted
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp
new file mode 100644
index 0000000000000..07aa659bd9b02
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp
@@ -0,0 +1,17 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include <memory>
+#include <string>
+#include <cassert>
+
+int main()
+{
+ auto up4 = std::make_unique<int[5]>(11, 22, 33, 44, 55); // deleted
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp
new file mode 100644
index 0000000000000..ace2e4fc71370
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11
+#include <memory>
+#include <string>
+#include <cassert>
+
+int main()
+{
+ {
+ std::unique_ptr<int> p1 = std::make_unique<int>(1);
+ 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" );
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/nothing_to_do.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/nothing_to_do.pass.cpp
new file mode 100644
index 0000000000000..b58f5c55b643a
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp
new file mode 100644
index 0000000000000..9bf794caeda27
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// default_delete
+
+#include <memory>
+#include <cassert>
+
+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&) {++count;}
+ virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+int main()
+{
+ std::default_delete<B> d2;
+ std::default_delete<A> d1 = d2;
+ A* p = new B;
+ assert(A::count == 1);
+ assert(B::count == 1);
+ d1(p);
+ assert(A::count == 0);
+ assert(B::count == 0);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp
new file mode 100644
index 0000000000000..f686e9f01f113
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// default_delete
+
+#include <memory>
+#include <cassert>
+
+struct A
+{
+ static int count;
+ A() {++count;}
+ A(const A&) {++count;}
+ ~A() {--count;}
+};
+
+int A::count = 0;
+
+int main()
+{
+ std::default_delete<A> d;
+ A* p = new A;
+ assert(A::count == 1);
+ d(p);
+ assert(A::count == 0);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/incomplete.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/incomplete.fail.cpp
new file mode 100644
index 0000000000000..255e5cd39c69b
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/incomplete.fail.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// default_delete
+
+// Test that default_delete's operator() requires a complete type
+
+#include <memory>
+#include <cassert>
+
+struct A;
+
+int main()
+{
+ std::default_delete<A> d;
+ A* p = 0;
+ d(p);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/void.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/void.fail.cpp
new file mode 100644
index 0000000000000..5d1cf1ff4981e
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/void.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// default_delete
+
+// Test that default_delete's operator() requires a complete type
+
+#include <memory>
+#include <cassert>
+
+int main()
+{
+ std::default_delete<const void> d;
+ const void* p = 0;
+ d(p);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.fail.cpp
new file mode 100644
index 0000000000000..41209d977b71e
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.fail.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// default_delete
+
+// Test that default_delete<T[]> does not have a working converting constructor
+
+#include <memory>
+#include <cassert>
+
+struct A
+{
+};
+
+struct B
+ : public A
+{
+};
+
+int main()
+{
+ std::default_delete<B[]> d2;
+ std::default_delete<A[]> d1 = d2;
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
new file mode 100644
index 0000000000000..2949d6310c598
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// default_delete[]
+
+// template <class U>
+// default_delete(const default_delete<U[]>&);
+//
+// This constructor shall not participate in overload resolution unless
+// U(*)[] is convertible to T(*)[].
+
+#include <memory>
+#include <cassert>
+
+int main()
+{
+ std::default_delete<int[]> d1;
+ std::default_delete<const int[]> d2 = d1;
+ ((void)d2);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp
new file mode 100644
index 0000000000000..7a409766412fd
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// default_delete
+
+// Test that default_delete<T[]> has a working default constructor
+
+#include <memory>
+#include <cassert>
+
+struct A
+{
+ static int count;
+ A() {++count;}
+ A(const A&) {++count;}
+ ~A() {--count;}
+};
+
+int A::count = 0;
+
+int main()
+{
+ std::default_delete<A[]> d;
+ A* p = new A[3];
+ assert(A::count == 3);
+ d(p);
+ assert(A::count == 0);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/incomplete.fail.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/incomplete.fail.cpp
new file mode 100644
index 0000000000000..528b10e9085d6
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/incomplete.fail.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// default_delete
+
+// Test that default_delete<T[]>'s operator() requires a complete type
+
+#include <memory>
+#include <cassert>
+
+struct A;
+
+int main()
+{
+ std::default_delete<A[]> d;
+ A* p = 0;
+ d(p);
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.general/nothing_to_do.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.general/nothing_to_do.pass.cpp
new file mode 100644
index 0000000000000..b58f5c55b643a
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.general/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
new file mode 100644
index 0000000000000..22ae217a61d64
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// shared_ptr
+
+// template <class T, class D>
+// bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+// template <class T, class D>
+// bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+// template <class T, class D>
+// bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+// template <class T, class D>
+// bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+// template <class T, class D>
+// bool operator<(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+// template <class T, class D>
+// bool operator<(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+// template <class T, class D>
+// bool operator<=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+// template <class T, class D>
+// bool operator<=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+// template <class T, class D>
+// bool operator>(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+// template <class T, class D>
+// bool operator>(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+// template <class T, class D>
+// bool operator>=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+// template <class T, class D>
+// bool operator>=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+
+#include <memory>
+#include <cassert>
+
+void do_nothing(int*) {}
+
+int main()
+{
+ 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));
+
+ const std::unique_ptr<int> p2;
+ assert( (p2 == nullptr));
+ assert( (nullptr == p2));
+ assert(!(p2 < nullptr));
+ assert(!(nullptr < p2));
+ assert( (p2 <= nullptr));
+ assert( (nullptr <= p2));
+ assert(!(p2 > nullptr));
+ assert(!(nullptr > p2));
+ assert( (p2 >= nullptr));
+ assert( (nullptr >= p2));
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp
new file mode 100644
index 0000000000000..88a1e04ba4ec5
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// 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>
+// bool
+// operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+#include <memory>
+#include <cassert>
+
+#include "deleter_types.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&) {++count;}
+ virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+int main()
+{
+ {
+ const std::unique_ptr<A, Deleter<A> > p1(new A);
+ const std::unique_ptr<A, Deleter<A> > p2(new A);
+ assert(!(p1 == p2));
+ assert(p1 != p2);
+ }
+ {
+ const std::unique_ptr<A, Deleter<A> > p1(new A);
+ const std::unique_ptr<B, Deleter<B> > p2(new B);
+ assert(!(p1 == p2));
+ assert(p1 != p2);
+ }
+ {
+ const std::unique_ptr<A[], Deleter<A[]> > p1(new A[3]);
+ const std::unique_ptr<A[], Deleter<A[]> > p2(new A[3]);
+ assert(!(p1 == p2));
+ assert(p1 != p2);
+ }
+ {
+ const std::unique_ptr<A[], Deleter<A[]> > p1(new A[3]);
+ const std::unique_ptr<B[], Deleter<B[]> > p2(new B[3]);
+ assert(!(p1 == p2));
+ assert(p1 != p2);
+ }
+ {
+ const std::unique_ptr<A, Deleter<A> > p1;
+ const std::unique_ptr<A, Deleter<A> > p2;
+ assert(p1 == p2);
+ assert(!(p1 != p2));
+ }
+ {
+ const std::unique_ptr<A, Deleter<A> > p1;
+ const std::unique_ptr<B, Deleter<B> > p2;
+ assert(p1 == p2);
+ assert(!(p1 != p2));
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp
new file mode 100644
index 0000000000000..94ae89ba92b39
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// 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>
+// bool
+// operator> (const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+// 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>
+// bool
+// operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+#include <memory>
+#include <cassert>
+
+#include "deleter_types.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&) {++count;}
+ virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+int main()
+{
+ {
+ const std::unique_ptr<A, Deleter<A> > p1(new A);
+ const std::unique_ptr<A, Deleter<A> > p2(new A);
+ assert((p1 < p2) == !(p1 > p2));
+ assert((p1 < p2) == (p1 <= p2));
+ assert((p1 < p2) == !(p1 >= p2));
+ }
+ {
+ const std::unique_ptr<A, Deleter<A> > p1(new A);
+ const std::unique_ptr<B, Deleter<B> > p2(new B);
+ assert((p1 < p2) == !(p1 > p2));
+ assert((p1 < p2) == (p1 <= p2));
+ assert((p1 < p2) == !(p1 >= p2));
+ }
+ {
+ const std::unique_ptr<A[], Deleter<A[]> > p1(new A[3]);
+ const std::unique_ptr<A[], Deleter<A[]> > p2(new A[3]);
+ assert((p1 < p2) == !(p1 > p2));
+ assert((p1 < p2) == (p1 <= p2));
+ assert((p1 < p2) == !(p1 >= p2));
+ }
+ {
+ const std::unique_ptr<A[], Deleter<A[]> > p1(new A[3]);
+ const std::unique_ptr<B[], Deleter<B[]> > p2(new B[3]);
+ assert((p1 < p2) == !(p1 > p2));
+ assert((p1 < p2) == (p1 <= p2));
+ assert((p1 < p2) == !(p1 >= p2));
+ }
+ {
+ const std::unique_ptr<A, Deleter<A> > p1;
+ const std::unique_ptr<A, Deleter<A> > p2;
+ assert((p1 < p2) == (p1 > p2));
+ assert((p1 < p2) == !(p1 <= p2));
+ assert((p1 < p2) == !(p1 >= p2));
+ }
+ {
+ const std::unique_ptr<A, Deleter<A> > p1;
+ const std::unique_ptr<B, Deleter<B> > p2;
+ assert((p1 < p2) == (p1 > p2));
+ assert((p1 < p2) == !(p1 <= p2));
+ assert((p1 < p2) == !(p1 >= p2));
+ }
+}
diff --git a/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp b/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp
new file mode 100644
index 0000000000000..7ac0ba490e970
--- /dev/null
+++ b/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// Test swap
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "deleter_types.h"
+
+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;}
+
+ friend 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 {}
+private:
+ NonSwappableDeleter(NonSwappableDeleter const&);
+
+};
+
+int main()
+{
+ {
+ A* p1 = new A(1);
+ std::unique_ptr<A, Deleter<A> > s1(p1, Deleter<A>(1));
+ A* p2 = new A(2);
+ std::unique_ptr<A, Deleter<A> > s2(p2, Deleter<A>(2));
+ assert(s1.get() == p1);
+ assert(*s1 == A(1));
+ assert(s1.get_deleter().state() == 1);
+ assert(s2.get() == p2);
+ assert(*s2 == A(2));
+ assert(s2.get_deleter().state() == 2);
+ swap(s1, s2);
+ assert(s1.get() == p2);
+ assert(*s1 == A(2));
+ assert(s1.get_deleter().state() == 2);
+ assert(s2.get() == p1);
+ assert(*s2 == A(1));
+ assert(s2.get_deleter().state() == 1);
+ assert(A::count == 2);
+ }
+ 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];
+ std::unique_ptr<A[], Deleter<A[]> > s2(p2, Deleter<A[]>(2));
+ assert(s1.get() == p1);
+ assert(s1.get_deleter().state() == 1);
+ assert(s2.get() == p2);
+ assert(s2.get_deleter().state() == 2);
+ swap(s1, s2);
+ assert(s1.get() == p2);
+ assert(s1.get_deleter().state() == 2);
+ assert(s2.get() == p1);
+ assert(s2.get_deleter().state() == 1);
+ assert(A::count == 6);
+ }
+ assert(A::count == 0);
+#if TEST_STD_VER >= 11
+ {
+ // test that unique_ptr's specialized swap is disabled when the deleter
+ // is non-swappable. Instead we should pick up the generic swap(T, T)
+ // and perform 3 move constructions.
+ typedef NonSwappableDeleter<int> D;
+ D d(42);
+ int x = 42;
+ int y = 43;
+ std::unique_ptr<int, D&> p(&x, d);
+ std::unique_ptr<int, D&> p2(&y, d);
+ std::swap(p, p2);
+ }
+#endif
+}