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