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> shared_ptr(const shared_ptr<Y>& 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 struct C
45 {
46     static int count;
47 
CC48     C() {++count;}
CC49     C(const C&) {++count;}
~CC50     virtual ~C() {--count;}
51 };
52 
53 int C::count = 0;
54 
55 class private_delete_op
56 {
operator delete(void * p)57     static void operator delete (void *p) {
58         return delete static_cast<char*>(p);
59     }
60 public:
operator delete[](void * p)61     static void operator delete[] (void *p) {
62         return delete[] static_cast<char*>(p);
63     }
64 };
65 
66 class private_delete_arr_op
67 {
operator delete[](void * p)68     static void operator delete[] (void *p) {
69         return delete[] static_cast<char*>(p);
70     }
71 public:
operator delete(void * p)72     static void operator delete (void *p) {
73         return delete static_cast<char*>(p);
74     }
75 };
76 
main(int,char **)77 int main(int, char**)
78 {
79     static_assert(( std::is_convertible<std::shared_ptr<A>, std::shared_ptr<B> >::value), "");
80     static_assert((!std::is_convertible<std::shared_ptr<B>, std::shared_ptr<A> >::value), "");
81     static_assert((!std::is_convertible<std::shared_ptr<A>, std::shared_ptr<C> >::value), "");
82     {
83         const std::shared_ptr<A> pA(new A);
84         assert(pA.use_count() == 1);
85         assert(B::count == 1);
86         assert(A::count == 1);
87         {
88             std::shared_ptr<B> pB(pA);
89             assert(B::count == 1);
90             assert(A::count == 1);
91             assert(pB.use_count() == 2);
92             assert(pA.use_count() == 2);
93             assert(pA.get() == pB.get());
94         }
95         assert(pA.use_count() == 1);
96         assert(B::count == 1);
97         assert(A::count == 1);
98     }
99     assert(B::count == 0);
100     assert(A::count == 0);
101     {
102         std::shared_ptr<A> pA;
103         assert(pA.use_count() == 0);
104         assert(B::count == 0);
105         assert(A::count == 0);
106         {
107             std::shared_ptr<B> pB(pA);
108             assert(B::count == 0);
109             assert(A::count == 0);
110             assert(pB.use_count() == 0);
111             assert(pA.use_count() == 0);
112             assert(pA.get() == pB.get());
113         }
114         assert(pA.use_count() == 0);
115         assert(B::count == 0);
116         assert(A::count == 0);
117     }
118     assert(B::count == 0);
119     assert(A::count == 0);
120 
121     // This should work in C++03 but we get errors when trying to do SFINAE with the delete operator.
122     // GCC also complains about this.
123 #if TEST_STD_VER >= 11 && !defined(TEST_COMPILER_GCC)
124     {
125         // LWG2874: Make sure that when T (for std::shared_ptr<T>) is an array type,
126         //          this constructor only participates in overload resolution when
127         //          `delete[] p` is well formed. And when T is not an array type,
128         //          this constructor only participates in overload resolution when
129         //          `delete p` is well formed.
130         static_assert(!std::is_constructible<std::shared_ptr<private_delete_op>,
131                                                              private_delete_op*>::value, "");
132         static_assert(!std::is_constructible<std::shared_ptr<private_delete_arr_op[4]>,
133                                                              private_delete_arr_op*>::value, "");
134     }
135 #endif
136 
137 #if TEST_STD_VER > 14
138     {
139         std::shared_ptr<A[]> p1(new A[8]);
140         assert(p1.use_count() == 1);
141         assert(A::count == 8);
142         {
143             std::shared_ptr<const A[]> p2(p1);
144             assert(A::count == 8);
145             assert(p2.use_count() == 2);
146             assert(p1.use_count() == 2);
147             assert(p1.get() == p2.get());
148         }
149         assert(p1.use_count() == 1);
150         assert(A::count == 8);
151     }
152     assert(A::count == 0);
153 #endif
154 
155     {
156         std::shared_ptr<A const> pA(new A);
157         std::shared_ptr<B const> pB(pA);
158         assert(pB.get() == pA.get());
159     }
160 
161     return 0;
162 }
163