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 // <memory>
10
11 // shared_ptr
12
13 // template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
14
15 #include <memory>
16 #include <type_traits>
17 #include <cassert>
18 #include <utility>
19
20 #include "test_macros.h"
21
22 struct B
23 {
24 static int count;
25
BB26 B() {++count;}
BB27 B(const B&) {++count;}
~BB28 virtual ~B() {--count;}
29 };
30
31 int B::count = 0;
32
33 struct A
34 : public B
35 {
36 static int count;
37
AA38 A() {++count;}
AA39 A(const A& other) : B(other) {++count;}
~AA40 ~A() {--count;}
41 };
42
43 int A::count = 0;
44
45 template <class T>
46 struct StatefulArrayDeleter {
47 int state = 0;
48
StatefulArrayDeleterStatefulArrayDeleter49 StatefulArrayDeleter(int val = 0) : state(val) {}
StatefulArrayDeleterStatefulArrayDeleter50 StatefulArrayDeleter(StatefulArrayDeleter const&) { assert(false); }
51
operator ()StatefulArrayDeleter52 void operator()(T* ptr) {
53 assert(state == 42);
54 delete []ptr;
55 }
56 };
57
58 // https://llvm.org/PR53368
59 // Bogus unique_ptr-to-shared_ptr conversions should be forbidden
60 #if TEST_STD_VER >= 17
61 static_assert( std::is_assignable<std::shared_ptr<A>&, std::unique_ptr<A>&&>::value, "");
62 static_assert( std::is_assignable<std::shared_ptr<A[]>&, std::unique_ptr<A[]>&&>::value, "");
63 static_assert(!std::is_assignable<std::shared_ptr<A>&, std::unique_ptr<A[]>&&>::value, "");
64 static_assert(!std::is_assignable<std::shared_ptr<B[]>&, std::unique_ptr<A[]>&&>::value, "");
65 static_assert(!std::is_assignable<std::shared_ptr<B>&, std::unique_ptr<A[]>&&>::value, "");
66 #endif
67
main(int,char **)68 int main(int, char**)
69 {
70 {
71 std::unique_ptr<A> pA(new A);
72 A* ptrA = pA.get();
73 {
74 std::shared_ptr<B> pB(new B);
75 pB = std::move(pA);
76 assert(B::count == 1);
77 assert(A::count == 1);
78 assert(pB.use_count() == 1);
79 assert(pA.get() == 0);
80 assert(pB.get() == ptrA);
81 }
82 assert(B::count == 0);
83 assert(A::count == 0);
84 }
85 assert(B::count == 0);
86 assert(A::count == 0);
87 {
88 std::unique_ptr<A> pA;
89 A* ptrA = pA.get();
90 {
91 std::shared_ptr<B> pB(new B);
92 pB = std::move(pA);
93 assert(B::count == 0);
94 assert(A::count == 0);
95 // assert(pB.use_count() == 1); // no longer true due to LWG 2415
96 assert(pA.get() == 0);
97 assert(pB.get() == ptrA);
98 }
99 assert(B::count == 0);
100 assert(A::count == 0);
101 }
102 assert(B::count == 0);
103 assert(A::count == 0);
104 {
105 std::unique_ptr<A> pA(new A);
106 A* ptrA = pA.get();
107 {
108 std::shared_ptr<B> pB;
109 pB = std::move(pA);
110 assert(B::count == 1);
111 assert(A::count == 1);
112 assert(pB.use_count() == 1);
113 assert(pA.get() == 0);
114 assert(pB.get() == ptrA);
115 }
116 assert(B::count == 0);
117 assert(A::count == 0);
118 }
119 assert(B::count == 0);
120 assert(A::count == 0);
121 {
122 std::unique_ptr<A> pA;
123 A* ptrA = pA.get();
124 {
125 std::shared_ptr<B> pB;
126 pB = std::move(pA);
127 assert(B::count == 0);
128 assert(A::count == 0);
129 // assert(pB.use_count() == 1); // no longer true due to LWG 2415
130 assert(pA.get() == 0);
131 assert(pB.get() == ptrA);
132 }
133 assert(B::count == 0);
134 assert(A::count == 0);
135 }
136 assert(B::count == 0);
137 assert(A::count == 0);
138
139 #if TEST_STD_VER > 14
140 {
141 StatefulArrayDeleter<A> d;
142 std::unique_ptr<A[], StatefulArrayDeleter<A>&> u(new A[4], d);
143 std::shared_ptr<A[]> p;
144 p = std::move(u);
145 d.state = 42;
146 assert(A::count == 4);
147 }
148 assert(A::count == 0);
149 assert(B::count == 0);
150
151 {
152 std::unique_ptr<A[]> ptr(new A[8]);
153 A* raw_ptr = ptr.get();
154 std::shared_ptr<A[]> p;
155 p = std::move(ptr);
156 assert(A::count == 8);
157 assert(p.use_count() == 1);
158 assert(p.get() == raw_ptr);
159 assert(ptr.get() == 0);
160 }
161 assert(A::count == 0);
162
163 {
164 std::unique_ptr<int[]> ptr(new int[8]);
165 std::shared_ptr<int[]> p;
166 p = std::move(ptr);
167 }
168 #endif // TEST_STD_VER >= 14
169
170 return 0;
171 }
172