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