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
77 // https://llvm.org/PR60258
78 // Invalid constructor SFINAE for std::shared_ptr's array ctors
79 static_assert(!std::is_constructible<std::shared_ptr<int>, const std::shared_ptr<long>&>::value, "");
80 static_assert( std::is_constructible<std::shared_ptr<B>, const std::shared_ptr<A>&>::value, "");
81 static_assert( std::is_constructible<std::shared_ptr<const A>, const std::shared_ptr<A>&>::value, "");
82 static_assert(!std::is_constructible<std::shared_ptr<A>, const std::shared_ptr<const A>&>::value, "");
83
84 #if TEST_STD_VER >= 17
85 static_assert(!std::is_constructible<std::shared_ptr<int>, const std::shared_ptr<int[]>&>::value, "");
86 static_assert(!std::is_constructible<std::shared_ptr<int>, const std::shared_ptr<int[5]>&>::value, "");
87 static_assert(!std::is_constructible<std::shared_ptr<int[]>, const std::shared_ptr<int>&>::value, "");
88 static_assert( std::is_constructible<std::shared_ptr<int[]>, const std::shared_ptr<int[5]>&>::value, "");
89 static_assert(!std::is_constructible<std::shared_ptr<int[5]>, const std::shared_ptr<int>&>::value, "");
90 static_assert(!std::is_constructible<std::shared_ptr<int[5]>, const std::shared_ptr<int[]>&>::value, "");
91 static_assert(!std::is_constructible<std::shared_ptr<int[7]>, const std::shared_ptr<int[5]>&>::value, "");
92 #endif
93
main(int,char **)94 int main(int, char**)
95 {
96 static_assert(( std::is_convertible<std::shared_ptr<A>, std::shared_ptr<B> >::value), "");
97 static_assert((!std::is_convertible<std::shared_ptr<B>, std::shared_ptr<A> >::value), "");
98 static_assert((!std::is_convertible<std::shared_ptr<A>, std::shared_ptr<C> >::value), "");
99 {
100 const std::shared_ptr<A> pA(new A);
101 assert(pA.use_count() == 1);
102 assert(B::count == 1);
103 assert(A::count == 1);
104 {
105 std::shared_ptr<B> pB(pA);
106 assert(B::count == 1);
107 assert(A::count == 1);
108 assert(pB.use_count() == 2);
109 assert(pA.use_count() == 2);
110 assert(pA.get() == pB.get());
111 }
112 assert(pA.use_count() == 1);
113 assert(B::count == 1);
114 assert(A::count == 1);
115 }
116 assert(B::count == 0);
117 assert(A::count == 0);
118 {
119 std::shared_ptr<A> pA;
120 assert(pA.use_count() == 0);
121 assert(B::count == 0);
122 assert(A::count == 0);
123 {
124 std::shared_ptr<B> pB(pA);
125 assert(B::count == 0);
126 assert(A::count == 0);
127 assert(pB.use_count() == 0);
128 assert(pA.use_count() == 0);
129 assert(pA.get() == pB.get());
130 }
131 assert(pA.use_count() == 0);
132 assert(B::count == 0);
133 assert(A::count == 0);
134 }
135 assert(B::count == 0);
136 assert(A::count == 0);
137
138 // This should work in C++03 but we get errors when trying to do SFINAE with the delete operator.
139 // GCC also complains about this.
140 #if TEST_STD_VER >= 11 && !defined(TEST_COMPILER_GCC)
141 {
142 // LWG2874: Make sure that when T (for std::shared_ptr<T>) is an array type,
143 // this constructor only participates in overload resolution when
144 // `delete[] p` is well formed. And when T is not an array type,
145 // this constructor only participates in overload resolution when
146 // `delete p` is well formed.
147 static_assert(!std::is_constructible<std::shared_ptr<private_delete_op>,
148 private_delete_op*>::value, "");
149 static_assert(!std::is_constructible<std::shared_ptr<private_delete_arr_op[4]>,
150 private_delete_arr_op*>::value, "");
151 }
152 #endif
153
154 #if TEST_STD_VER > 14
155 {
156 std::shared_ptr<A[]> p1(new A[8]);
157 assert(p1.use_count() == 1);
158 assert(A::count == 8);
159 {
160 std::shared_ptr<const A[]> p2(p1);
161 assert(A::count == 8);
162 assert(p2.use_count() == 2);
163 assert(p1.use_count() == 2);
164 assert(p1.get() == p2.get());
165 }
166 assert(p1.use_count() == 1);
167 assert(A::count == 8);
168 }
169 assert(A::count == 0);
170 #endif
171
172 {
173 std::shared_ptr<A const> pA(new A);
174 std::shared_ptr<B const> pB(pA);
175 assert(pB.get() == pA.get());
176 }
177
178 return 0;
179 }
180