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> explicit shared_ptr(const weak_ptr<Y>& r);
14 
15 #include <cassert>
16 #include <memory>
17 #include <type_traits>
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 // https://llvm.org/PR60258
45 // Invalid constructor SFINAE for std::shared_ptr's array ctors
46 static_assert(!std::is_constructible<std::shared_ptr<int>,     const std::weak_ptr<long>&>::value, "");
47 static_assert( std::is_constructible<std::shared_ptr<B>,       const std::weak_ptr<A>&>::value, "");
48 static_assert( std::is_constructible<std::shared_ptr<const A>, const std::weak_ptr<A>&>::value, "");
49 static_assert(!std::is_constructible<std::shared_ptr<A>,       const std::weak_ptr<const A>&>::value, "");
50 
51 #if TEST_STD_VER >= 17
52 static_assert(!std::is_constructible<std::shared_ptr<int>,     const std::weak_ptr<int[]>&>::value, "");
53 static_assert(!std::is_constructible<std::shared_ptr<int>,     const std::weak_ptr<int[5]>&>::value, "");
54 static_assert(!std::is_constructible<std::shared_ptr<int[]>,   const std::weak_ptr<int>&>::value, "");
55 static_assert( std::is_constructible<std::shared_ptr<int[]>,   const std::weak_ptr<int[5]>&>::value, "");
56 static_assert(!std::is_constructible<std::shared_ptr<int[5]>,  const std::weak_ptr<int>&>::value, "");
57 static_assert(!std::is_constructible<std::shared_ptr<int[5]>,  const std::weak_ptr<int[]>&>::value, "");
58 static_assert(!std::is_constructible<std::shared_ptr<int[7]>,  const std::weak_ptr<int[5]>&>::value, "");
59 #endif
60 
main(int,char **)61 int main(int, char**)
62 {
63 #ifndef TEST_HAS_NO_EXCEPTIONS
64     {
65         std::weak_ptr<A> wp;
66         try
67         {
68             std::shared_ptr<A> sp(wp);
69             assert(false);
70         }
71         catch (std::bad_weak_ptr&)
72         {
73         }
74         assert(A::count == 0);
75     }
76 #endif
77     {
78         std::shared_ptr<A> sp0(new A);
79         std::weak_ptr<A> wp(sp0);
80         std::shared_ptr<A> sp(wp);
81         assert(sp.use_count() == 2);
82         assert(sp.get() == sp0.get());
83         assert(A::count == 1);
84     }
85     assert(A::count == 0);
86     {
87         std::shared_ptr<A const> sp0(new A);
88         std::weak_ptr<A const> wp(sp0);
89         std::shared_ptr<A const> sp(wp);
90         assert(sp.use_count() == 2);
91         assert(sp.get() == sp0.get());
92         assert(A::count == 1);
93     }
94     assert(A::count == 0);
95 #ifndef TEST_HAS_NO_EXCEPTIONS
96     {
97         std::shared_ptr<A> sp0(new A);
98         std::weak_ptr<A> wp(sp0);
99         sp0.reset();
100         try
101         {
102             std::shared_ptr<A> sp(wp);
103             assert(false);
104         }
105         catch (std::bad_weak_ptr&)
106         {
107         }
108     }
109     assert(A::count == 0);
110 #endif
111 
112 #if TEST_STD_VER > 14
113     {
114         std::shared_ptr<A[]> sp0(new A[8]);
115         std::weak_ptr<A[]> wp(sp0);
116         std::shared_ptr<const A[]> sp(wp);
117         assert(sp.use_count() == 2);
118         assert(sp.get() == sp0.get());
119         assert(A::count == 8);
120     }
121     assert(A::count == 0);
122 #endif
123 
124   return 0;
125 }
126