summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities/smartptr/unique.ptr
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/test/std/utilities/smartptr/unique.ptr')
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/README.TXT16
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/nothing_to_do.pass.cpp12
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp61
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp119
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp124
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp145
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp39
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp40
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/auto_pointer.pass.cpp97
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp109
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp151
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp80
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp222
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp74
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp117
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp167
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp35
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp307
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp48
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp48
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp51
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.runtime.fail.cpp30
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp46
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp25
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp80
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.runtime.fail.cpp24
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp22
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp66
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp51
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp65
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.runtime.fail.cpp32
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp28
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp48
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.single.fail.cpp24
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp44
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array1.fail.cpp17
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array2.fail.cpp17
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array3.fail.cpp17
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp17
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp32
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/nothing_to_do.pass.cpp12
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp48
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp34
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/incomplete.fail.cpp26
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/void.fail.cpp24
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.fail.cpp32
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp28
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp36
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/incomplete.fail.cpp26
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.general/nothing_to_do.pass.cpp12
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp69
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp86
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp100
-rw-r--r--libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp102
54 files changed, 3382 insertions, 0 deletions
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/README.TXT b/libcxx/test/std/utilities/smartptr/unique.ptr/README.TXT
new file mode 100644
index 00000000000..20f77f61827
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/nothing_to_do.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/nothing_to_do.pass.cpp
new file mode 100644
index 00000000000..b58f5c55b64
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/pointer_type.pass.cpp
new file mode 100644
index 00000000000..54c2cf16ecc
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
new file mode 100644
index 00000000000..378421866bc
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move.pass.cpp
@@ -0,0 +1,119 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_assignable<U, U&&>::value, "");
+ }
+ {
+ typedef std::unique_ptr<VT, GenericDeleter> U;
+ static_assert(!std::is_assignable<U, U&>::value, "");
+ static_assert(!std::is_assignable<U, const U&>::value, "");
+ static_assert(!std::is_assignable<U, const U&&>::value, "");
+ static_assert(std::is_assignable<U, U&&>::value, "");
+ }
+ {
+ typedef std::unique_ptr<VT, NCDeleter<VT>&> U;
+ static_assert(!std::is_assignable<U, U&>::value, "");
+ static_assert(!std::is_assignable<U, const U&>::value, "");
+ static_assert(!std::is_assignable<U, const U&&>::value, "");
+ static_assert(std::is_assignable<U, U&&>::value, "");
+ }
+ {
+ typedef std::unique_ptr<VT, const NCDeleter<VT>&> U;
+ static_assert(!std::is_assignable<U, U&>::value, "");
+ static_assert(!std::is_assignable<U, const U&>::value, "");
+ static_assert(!std::is_assignable<U, const U&&>::value, "");
+ static_assert(std::is_assignable<U, U&&>::value, "");
+ }
+}
+
+int main() {
+ {
+ test_basic</*IsArray*/ false>();
+ test_sfinae<false>();
+ }
+ {
+ test_basic</*IsArray*/ true>();
+ test_sfinae<true>();
+ }
+}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.runtime.pass.cpp
new file mode 100644
index 00000000000..9b946a733fe
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/move_convert.single.pass.cpp
new file mode 100644
index 00000000000..3f2ea422dab
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/null.pass.cpp
new file mode 100644
index 00000000000..165d48a1caa
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.asgn/nullptr.pass.cpp
new file mode 100644
index 00000000000..e1e2e32e23c
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/auto_pointer.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/auto_pointer.pass.cpp
new file mode 100644
index 00000000000..7d5e9bca63c
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
new file mode 100644
index 00000000000..03bd6c5737a
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/default.pass.cpp
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// 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"
+
+#include "test_workarounds.h" // For TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES
+
+#if defined(_LIBCPP_VERSION) && TEST_STD_VER >= 11
+_LIBCPP_SAFE_STATIC std::unique_ptr<int> global_static_unique_ptr_single;
+_LIBCPP_SAFE_STATIC std::unique_ptr<int[]> global_static_unique_ptr_runtime;
+#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 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+ { // 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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
new file mode 100644
index 00000000000..8f52fe5ee97
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move.pass.cpp
@@ -0,0 +1,151 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "deleter_types.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);
+}
+
+int main() {
+ {
+ test_basic</*IsArray*/ false>();
+ test_sfinae<int>();
+ }
+ {
+ test_basic</*IsArray*/ true>();
+ test_sfinae<int[]>();
+ }
+}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp
new file mode 100644
index 00000000000..b259049fcfe
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.runtime.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp
new file mode 100644
index 00000000000..e2e5cc67da9
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.single.pass.cpp
@@ -0,0 +1,222 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "deleter_types.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, "");
+ }
+}
+
+int main() {
+ {
+ 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();
+ }
+ test_sfinae();
+}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp
new file mode 100644
index 00000000000..8bc8a57c1c8
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.pass.cpp
new file mode 100644
index 00000000000..8e4ee7bb118
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/nullptr.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
+
+// unique_ptr(nullptr_t);
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "deleter_types.h"
+#include "unique_ptr_test_helper.h"
+
+#include "test_workarounds.h" // For TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES
+
+// default unique_ptr ctor should only require default Deleter ctor
+class DefaultDeleter {
+ int state_;
+
+ DefaultDeleter(DefaultDeleter&);
+ DefaultDeleter& operator=(DefaultDeleter&);
+
+public:
+ DefaultDeleter() : state_(5) {}
+
+ int state() const { return state_; }
+
+ void operator()(void*) {}
+};
+
+#if TEST_STD_VER >= 11
+struct NonDefaultDeleter {
+ NonDefaultDeleter() = delete;
+ void operator()(void*) const {}
+};
+#endif
+
+template <class VT>
+void test_basic() {
+ {
+ std::unique_ptr<VT> p(nullptr);
+ assert(p.get() == 0);
+ }
+ {
+ std::unique_ptr<VT, DefaultDeleter> p(nullptr);
+ assert(p.get() == 0);
+ assert(p.get_deleter().state() == 5);
+ }
+#if TEST_STD_VER >= 11
+ {
+ using U1 = std::unique_ptr<VT>;
+ 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
+}
+
+template <class VT>
+void test_sfinae() {
+#if TEST_STD_VER >= 11 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+ { // 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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
new file mode 100644
index 00000000000..3ae77d384b2
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer.pass.cpp
@@ -0,0 +1,167 @@
+//===----------------------------------------------------------------------===//
+//
+// 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"
+
+#include "test_workarounds.h" // For TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES
+
+// 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> >;
+ static_assert(std::is_nothrow_constructible<U1, A*>::value, "");
+ static_assert(std::is_nothrow_constructible<U2, A*>::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 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+ { // 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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp
new file mode 100644
index 00000000000..4ef4f1463b0
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.fail.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+#include "test_workarounds.h"
+
+struct Deleter {
+ void operator()(int* p) const { delete p; }
+};
+
+int main() {
+#if defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+// expected-error@memory:* {{static_assert failed "rvalue deleter bound to reference"}}
+#else
+// expected-error@+2 {{call to deleted constructor of 'std::unique_ptr<int, const Deleter &>}}
+#endif
+ std::unique_ptr<int, const Deleter&> s((int*)nullptr, Deleter());
+}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
new file mode 100644
index 00000000000..601751eb335
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
@@ -0,0 +1,307 @@
+//===----------------------------------------------------------------------===//
+//
+// 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"
+
+#include "test_workarounds.h" // For TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES
+
+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 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+ 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 && !defined(TEST_WORKAROUND_UPCOMING_UNIQUE_PTR_CHANGES)
+ {
+ using D = CopyOnlyDeleter;
+ using U = std::unique_ptr<A[], D>;
+ static_assert(std::is_constructible<U, A*, D const&>::value, "");
+ static_assert(std::is_constructible<U, A*, D&>::value, "");
+ static_assert(std::is_constructible<U, A*, D&&>::value, "");
+
+ static_assert(!std::is_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_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_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_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, 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);
+ }
+}
+
+int main() {
+ {
+ test_basic</*IsArray*/ false>();
+ test_basic_single();
+ test_sfinae<false>();
+ test_noexcept<false>();
+ }
+ {
+ test_basic</*IsArray*/ true>();
+ test_sfinae<true>();
+ test_sfinae_runtime();
+ test_noexcept<true>();
+ }
+}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.dtor/null.pass.cpp
new file mode 100644
index 00000000000..5507e7e34ee
--- /dev/null
+++ b/libcxx/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(0, d);
+ assert(p.get() == 0);
+ assert(&p.get_deleter() == &d);
+ }
+ assert(d.state() == 0);
+}
+
+int main() {
+ test_basic<int>();
+ test_basic<int[]>();
+}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.pass.cpp
new file mode 100644
index 00000000000..581340f6104
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/release.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 release
+
+#include <memory>
+#include <cassert>
+
+#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;
+ {
+ 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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.pass.cpp
new file mode 100644
index 00000000000..302023b6077
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.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 reset
+
+#include <memory>
+#include <cassert>
+
+#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;
+ {
+ std::unique_ptr<VT> p(newValue<VT>(expect_alive));
+ assert(A::count == expect_alive);
+ A* i = p.get();
+ assert(i != nullptr);
+ p.reset();
+ assert(A::count == 0);
+ assert(p.get() == 0);
+ }
+ assert(A::count == 0);
+ {
+ 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(A::count == 0);
+}
+
+int main() {
+ test_basic</*IsArray*/ false>();
+ test_basic<true>();
+}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.runtime.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.runtime.fail.cpp
new file mode 100644
index 00000000000..0d067b9abff
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset.single.pass.cpp
new file mode 100644
index 00000000000..8f2a69913dd
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/reset_self.pass.cpp
new file mode 100644
index 00000000000..f838661c53f
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp
new file mode 100644
index 00000000000..0316398061e
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.modifiers/swap.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "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;
+ {
+ 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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.runtime.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.runtime.fail.cpp
new file mode 100644
index 00000000000..b05fb71cdc6
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/dereference.single.pass.cpp
new file mode 100644
index 00000000000..b2d3da48dae
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/explicit_bool.pass.cpp
new file mode 100644
index 00000000000..9a6d6c65fa8
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get.pass.cpp
new file mode 100644
index 00000000000..518e31cf948
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/get_deleter.pass.cpp
new file mode 100644
index 00000000000..6a00d14a2ca
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.runtime.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.runtime.fail.cpp
new file mode 100644
index 00000000000..d66af054ce6
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_arrow.single.pass.cpp
new file mode 100644
index 00000000000..8bed9dda2ea
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.runtime.pass.cpp
new file mode 100644
index 00000000000..b47c35afb4f
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.single.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/op_subscript.single.fail.cpp
new file mode 100644
index 00000000000..529749da67e
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array.pass.cpp
new file mode 100644
index 00000000000..30b4ecb94e1
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array1.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array1.fail.cpp
new file mode 100644
index 00000000000..00987919413
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array2.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array2.fail.cpp
new file mode 100644
index 00000000000..cc94e9ab3aa
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array3.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array3.fail.cpp
new file mode 100644
index 00000000000..cfdc2e1d886
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.array4.fail.cpp
new file mode 100644
index 00000000000..07aa659bd9b
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.single.pass.cpp
new file mode 100644
index 00000000000..ace2e4fc713
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/nothing_to_do.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/nothing_to_do.pass.cpp
new file mode 100644
index 00000000000..b58f5c55b64
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/convert_ctor.pass.cpp
new file mode 100644
index 00000000000..9bf794caeda
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/default.pass.cpp
new file mode 100644
index 00000000000..f686e9f01f1
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/incomplete.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/incomplete.fail.cpp
new file mode 100644
index 00000000000..255e5cd39c6
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/void.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt/void.fail.cpp
new file mode 100644
index 00000000000..5d1cf1ff498
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.fail.cpp
new file mode 100644
index 00000000000..41209d977b7
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/convert_ctor.pass.cpp
new file mode 100644
index 00000000000..2949d6310c5
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/default.pass.cpp
new file mode 100644
index 00000000000..7a409766412
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/incomplete.fail.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.dflt1/incomplete.fail.cpp
new file mode 100644
index 00000000000..528b10e9085
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.general/nothing_to_do.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.dltr/unique.ptr.dltr.general/nothing_to_do.pass.cpp
new file mode 100644
index 00000000000..b58f5c55b64
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
new file mode 100644
index 00000000000..22ae217a61d
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp
new file mode 100644
index 00000000000..88a1e04ba4e
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp
new file mode 100644
index 00000000000..94ae89ba92b
--- /dev/null
+++ b/libcxx/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/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/swap.pass.cpp
new file mode 100644
index 00000000000..7ac0ba490e9
--- /dev/null
+++ b/libcxx/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
+}
OpenPOWER on IntegriCloud