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 
19 #include "test_macros.h"
20 
21 struct B
22 {
23     static int count;
24 
BB25     B() {++count;}
BB26     B(const B&) {++count;}
~BB27     virtual ~B() {--count;}
28 };
29 
30 int B::count = 0;
31 
32 struct A
33     : public B
34 {
35     static int count;
36 
AA37     A() {++count;}
AA38     A(const A& other) : B(other) {++count;}
~AA39     ~A() {--count;}
40 };
41 
42 int A::count = 0;
43 
44 template <class T>
45 struct StatefulArrayDeleter {
46   int state = 0;
47 
StatefulArrayDeleterStatefulArrayDeleter48   StatefulArrayDeleter(int val = 0) : state(val) {}
StatefulArrayDeleterStatefulArrayDeleter49   StatefulArrayDeleter(StatefulArrayDeleter const&) { assert(false); }
50 
operator ()StatefulArrayDeleter51   void operator()(T* ptr) {
52     assert(state == 42);
53     delete []ptr;
54   }
55 };
56 
main(int,char **)57 int main(int, char**)
58 {
59     {
60         std::unique_ptr<A> pA(new A);
61         A* ptrA = pA.get();
62         {
63             std::shared_ptr<B> pB(new B);
64             pB = std::move(pA);
65             assert(B::count == 1);
66             assert(A::count == 1);
67             assert(pB.use_count() == 1);
68             assert(pA.get() == 0);
69             assert(pB.get() == ptrA);
70         }
71         assert(B::count == 0);
72         assert(A::count == 0);
73     }
74     assert(B::count == 0);
75     assert(A::count == 0);
76     {
77         std::unique_ptr<A> pA;
78         A* ptrA = pA.get();
79         {
80             std::shared_ptr<B> pB(new B);
81             pB = std::move(pA);
82             assert(B::count == 0);
83             assert(A::count == 0);
84 //          assert(pB.use_count() == 1); // no longer true due to LWG 2415
85             assert(pA.get() == 0);
86             assert(pB.get() == ptrA);
87         }
88         assert(B::count == 0);
89         assert(A::count == 0);
90     }
91     assert(B::count == 0);
92     assert(A::count == 0);
93     {
94         std::unique_ptr<A> pA(new A);
95         A* ptrA = pA.get();
96         {
97             std::shared_ptr<B> pB;
98             pB = std::move(pA);
99             assert(B::count == 1);
100             assert(A::count == 1);
101             assert(pB.use_count() == 1);
102             assert(pA.get() == 0);
103             assert(pB.get() == ptrA);
104         }
105         assert(B::count == 0);
106         assert(A::count == 0);
107     }
108     assert(B::count == 0);
109     assert(A::count == 0);
110     {
111         std::unique_ptr<A> pA;
112         A* ptrA = pA.get();
113         {
114             std::shared_ptr<B> pB;
115             pB = std::move(pA);
116             assert(B::count == 0);
117             assert(A::count == 0);
118 //          assert(pB.use_count() == 1); // no longer true due to LWG 2415
119             assert(pA.get() == 0);
120             assert(pB.get() == ptrA);
121         }
122         assert(B::count == 0);
123         assert(A::count == 0);
124     }
125     assert(B::count == 0);
126     assert(A::count == 0);
127 
128 #ifdef _LIBCPP_VERSION // https://llvm.org/PR53368
129     {
130       std::unique_ptr<A[]> ptr(new A[8]);
131       A* raw_ptr = ptr.get();
132       std::shared_ptr<B> p;
133       p = std::move(ptr);
134       assert(A::count == 8);
135       assert(B::count == 8);
136       assert(p.use_count() == 1);
137       assert(p.get() == raw_ptr);
138       assert(ptr.get() == 0);
139     }
140     assert(A::count == 0);
141     assert(B::count == 0);
142 
143     {
144       std::unique_ptr<A[]> ptr(new A[8]);
145       A* raw_ptr = ptr.get();
146       std::shared_ptr<A> p;
147       p = std::move(ptr);
148       assert(A::count == 8);
149       assert(p.use_count() == 1);
150       assert(p.get() == raw_ptr);
151       assert(ptr.get() == 0);
152     }
153     assert(A::count == 0);
154 
155     {
156       std::unique_ptr<int[]> ptr(new int[8]);
157       std::shared_ptr<int> p;
158       p = std::move(ptr);
159     }
160 #endif // _LIBCPP_VERSION
161 
162 #if TEST_STD_VER > 14
163     {
164       StatefulArrayDeleter<A> d;
165       std::unique_ptr<A[], StatefulArrayDeleter<A>&> u(new A[4], d);
166       std::shared_ptr<A[]> p;
167       p = std::move(u);
168       d.state = 42;
169       assert(A::count == 4);
170     }
171     assert(A::count == 0);
172     assert(B::count == 0);
173 
174 #ifdef _LIBCPP_VERSION // https://llvm.org/PR53368
175     {
176       std::unique_ptr<A[]> ptr(new A[8]);
177       A* raw_ptr = ptr.get();
178       std::shared_ptr<B[]> p;
179       p = std::move(ptr);
180       assert(A::count == 8);
181       assert(B::count == 8);
182       assert(p.use_count() == 1);
183       assert(p.get() == raw_ptr);
184       assert(ptr.get() == 0);
185     }
186     assert(A::count == 0);
187     assert(B::count == 0);
188 #endif // _LIBCPP_VERSION
189 
190     {
191       std::unique_ptr<A[]> ptr(new A[8]);
192       A* raw_ptr = ptr.get();
193       std::shared_ptr<A[]> p;
194       p = std::move(ptr);
195       assert(A::count == 8);
196       assert(p.use_count() == 1);
197       assert(p.get() == raw_ptr);
198       assert(ptr.get() == 0);
199     }
200     assert(A::count == 0);
201 
202     {
203       std::unique_ptr<int[]> ptr(new int[8]);
204       std::shared_ptr<int[]> p;
205       p = std::move(ptr);
206     }
207 #endif // TEST_STD_VER >= 14
208 
209   return 0;
210 }
211