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, T *p);
14 
15 #include <memory>
16 #include <cassert>
17 #include <utility>
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     ~B() {--count;}
28 };
29 
30 int B::count = 0;
31 
32 struct A
33 {
34     static int count;
35 
AA36     A() {++count;}
AA37     A(const A&) {++count;}
~AA38     ~A() {--count;}
39 };
40 
41 int A::count = 0;
42 
main(int,char **)43 int main(int, char**)
44 {
45     {
46         std::shared_ptr<A> pA(new A);
47         assert(pA.use_count() == 1);
48 
49         {
50             B b;
51             std::shared_ptr<B> pB(pA, &b);
52             assert(A::count == 1);
53             assert(B::count == 1);
54             assert(pA.use_count() == 2);
55             assert(pB.use_count() == 2);
56             assert(pB.get() == &b);
57         }
58         assert(pA.use_count() == 1);
59         assert(A::count == 1);
60         assert(B::count == 0);
61     }
62     assert(A::count == 0);
63     assert(B::count == 0);
64 
65     {
66         std::shared_ptr<A const> pA(new A);
67         assert(pA.use_count() == 1);
68 
69         {
70             B const b;
71             std::shared_ptr<B const> pB(pA, &b);
72             assert(A::count == 1);
73             assert(B::count == 1);
74             assert(pA.use_count() == 2);
75             assert(pB.use_count() == 2);
76             assert(pB.get() == &b);
77         }
78         assert(pA.use_count() == 1);
79         assert(A::count == 1);
80         assert(B::count == 0);
81     }
82     assert(A::count == 0);
83     assert(B::count == 0);
84 
85     int *pi = new int;
86     {
87       std::shared_ptr<int> p1(nullptr);
88       std::shared_ptr<int> p2(p1, pi);
89       assert(p2.get() == pi);
90     }
91     delete pi;
92     {
93       std::shared_ptr<int> p1(new int);
94       std::shared_ptr<int> p2(p1, nullptr);
95       assert(p2.get() == nullptr);
96     }
97 
98 #if TEST_STD_VER > 17 && defined(_LIBCPP_VERSION)
99     {
100       std::shared_ptr<A> pA(new A);
101       assert(pA.use_count() == 1);
102 
103 #  if TEST_STD_VER >= 20
104       // LWG-2996 is only implemented in c++20 and beyond.
105       // We don't backport because it is an evolutionary change.
106       {
107         B b;
108         std::shared_ptr<B> pB(std::move(pA), &b);
109         assert(A::count == 1);
110         assert(B::count == 1);
111         assert(pA.use_count() == 0);
112         assert(pB.use_count() == 1);
113         assert(pB.get() == &b);
114       }
115 #  endif // TEST_STD_VER > 20
116     }
117     assert(A::count == 0);
118     assert(B::count == 0);
119 #endif
120 
121     return 0;
122 }
123