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 // weak_ptr
12 
13 // template<class Y> weak_ptr(const weak_ptr<Y>& r);
14 // template<class Y> weak_ptr(weak_ptr<Y>&& r);
15 
16 #include <memory>
17 #include <type_traits>
18 #include <utility>
19 #include <cassert>
20 
21 #include "test_macros.h"
22 
23 struct B
24 {
25     static int count;
26 
BB27     B() {++count;}
BB28     B(const B&) {++count;}
~BB29     virtual ~B() {--count;}
30 };
31 
32 int B::count = 0;
33 
34 struct A
35     : public B
36 {
37     static int count;
38 
AA39     A() {++count;}
AA40     A(const A& other) : B(other) {++count;}
~AA41     ~A() {--count;}
42 };
43 
44 int A::count = 0;
45 
46 struct C
47 {
48     static int count;
49 
CC50     C() {++count;}
CC51     C(const C&) {++count;}
~CC52     virtual ~C() {--count;}
53 };
54 
55 int C::count = 0;
56 
57 template <class T>
source(std::shared_ptr<T> p)58 std::weak_ptr<T> source (std::shared_ptr<T> p) { return std::weak_ptr<T>(p); }
59 
main(int,char **)60 int main(int, char**)
61 {
62     static_assert(( std::is_convertible<std::weak_ptr<A>, std::weak_ptr<B> >::value), "");
63     static_assert((!std::is_convertible<std::weak_ptr<B>, std::weak_ptr<A> >::value), "");
64     static_assert((!std::is_convertible<std::weak_ptr<A>, std::weak_ptr<C> >::value), "");
65     {
66         const std::weak_ptr<A> pA(std::shared_ptr<A>(new A));
67         assert(pA.use_count() == 0);
68         assert(B::count == 0);
69         assert(A::count == 0);
70         {
71             std::weak_ptr<B> pB(pA);
72             assert(B::count == 0);
73             assert(A::count == 0);
74             assert(pB.use_count() == 0);
75             assert(pA.use_count() == 0);
76         }
77         assert(pA.use_count() == 0);
78         assert(B::count == 0);
79         assert(A::count == 0);
80     }
81     assert(B::count == 0);
82     assert(A::count == 0);
83     {
84         std::weak_ptr<A> pA;
85         assert(pA.use_count() == 0);
86         assert(B::count == 0);
87         assert(A::count == 0);
88         {
89             std::weak_ptr<B> pB(pA);
90             assert(B::count == 0);
91             assert(A::count == 0);
92             assert(pB.use_count() == 0);
93             assert(pA.use_count() == 0);
94         }
95         assert(pA.use_count() == 0);
96         assert(B::count == 0);
97         assert(A::count == 0);
98     }
99     assert(B::count == 0);
100     assert(A::count == 0);
101 
102     {
103         std::shared_ptr<A> ps(new A);
104         std::weak_ptr<A> pA = source(ps);
105         std::weak_ptr<B> pB(std::move(pA));
106         assert(pB.use_count() == 1);
107     }
108     assert(B::count == 0);
109     assert(A::count == 0);
110 
111 #if TEST_STD_VER > 14
112     {
113         std::shared_ptr<A[]> ps(new A[8]);
114         std::weak_ptr<A[]> p1 = source(ps);
115         std::weak_ptr<const A[]> p2(p1);
116         assert(p2.use_count() == 1);
117     }
118     assert(A::count == 0);
119 
120     {
121         std::shared_ptr<A[]> ps(new A[8]);
122         std::weak_ptr<A[]> p1 = source(ps);
123         std::weak_ptr<const A[]> p2(std::move(p1));
124         assert(p2.use_count() == 1);
125     }
126     assert(A::count == 0);
127 #endif
128 
129   return 0;
130 }
131