1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03
10
11 // <memory>
12
13 // unique_ptr
14
15 // Test unique_ptr move assignment
16
17 // test move assignment. Should only require a MoveConstructible deleter, or if
18 // deleter is a reference, not even that.
19
20 #include <memory>
21 #include <utility>
22 #include <cassert>
23
24 #include "test_macros.h"
25 #include "deleter_types.h"
26 #include "unique_ptr_test_helper.h"
27
28 struct GenericDeleter {
29 void operator()(void*) const;
30 };
31
32 template <bool IsArray>
test_basic()33 void test_basic() {
34 typedef typename std::conditional<IsArray, A[], A>::type VT;
35 const int expect_alive = IsArray ? 5 : 1;
36 {
37 std::unique_ptr<VT> s1(newValue<VT>(expect_alive));
38 A* p = s1.get();
39 std::unique_ptr<VT> s2(newValue<VT>(expect_alive));
40 assert(A::count == (expect_alive * 2));
41 s2 = std::move(s1);
42 assert(A::count == expect_alive);
43 assert(s2.get() == p);
44 assert(s1.get() == 0);
45 }
46 assert(A::count == 0);
47 {
48 std::unique_ptr<VT, Deleter<VT> > s1(newValue<VT>(expect_alive),
49 Deleter<VT>(5));
50 A* p = s1.get();
51 std::unique_ptr<VT, Deleter<VT> > s2(newValue<VT>(expect_alive));
52 assert(A::count == (expect_alive * 2));
53 s2 = std::move(s1);
54 assert(s2.get() == p);
55 assert(s1.get() == 0);
56 assert(A::count == expect_alive);
57 assert(s2.get_deleter().state() == 5);
58 assert(s1.get_deleter().state() == 0);
59 }
60 assert(A::count == 0);
61 {
62 CDeleter<VT> d1(5);
63 std::unique_ptr<VT, CDeleter<VT>&> s1(newValue<VT>(expect_alive), d1);
64 A* p = s1.get();
65 CDeleter<VT> d2(6);
66 std::unique_ptr<VT, CDeleter<VT>&> s2(newValue<VT>(expect_alive), d2);
67 s2 = std::move(s1);
68 assert(s2.get() == p);
69 assert(s1.get() == 0);
70 assert(A::count == expect_alive);
71 assert(d1.state() == 5);
72 assert(d2.state() == 5);
73 }
74 assert(A::count == 0);
75 }
76
77 template <bool IsArray>
test_sfinae()78 void test_sfinae() {
79 typedef typename std::conditional<IsArray, int[], int>::type VT;
80 {
81 typedef std::unique_ptr<VT> U;
82 static_assert(!std::is_assignable<U, U&>::value, "");
83 static_assert(!std::is_assignable<U, const U&>::value, "");
84 static_assert(!std::is_assignable<U, const U&&>::value, "");
85 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
86 }
87 {
88 typedef std::unique_ptr<VT, GenericDeleter> U;
89 static_assert(!std::is_assignable<U, U&>::value, "");
90 static_assert(!std::is_assignable<U, const U&>::value, "");
91 static_assert(!std::is_assignable<U, const U&&>::value, "");
92 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
93 }
94 {
95 typedef std::unique_ptr<VT, NCDeleter<VT>&> U;
96 static_assert(!std::is_assignable<U, U&>::value, "");
97 static_assert(!std::is_assignable<U, const U&>::value, "");
98 static_assert(!std::is_assignable<U, const U&&>::value, "");
99 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
100 }
101 {
102 typedef std::unique_ptr<VT, const NCDeleter<VT>&> U;
103 static_assert(!std::is_assignable<U, U&>::value, "");
104 static_assert(!std::is_assignable<U, const U&>::value, "");
105 static_assert(!std::is_assignable<U, const U&&>::value, "");
106 static_assert(std::is_nothrow_assignable<U, U&&>::value, "");
107 }
108 }
109
110
main(int,char **)111 int main(int, char**) {
112 {
113 test_basic</*IsArray*/ false>();
114 test_sfinae<false>();
115 }
116 {
117 test_basic</*IsArray*/ true>();
118 test_sfinae<true>();
119 }
120
121 return 0;
122 }
123