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// UNSUPPORTED: c++03
10
11// <memory>
12
13// shared_ptr
14
15// template<class Y> shared_ptr(shared_ptr<Y>&& r);
16
17#include <memory>
18#include <type_traits>
19#include <utility>
20#include <cassert>
21
22#include "test_macros.h"
23
24struct B
25{
26 static int count;
27
28 B() {++count;}
29 B(const B&) {++count;}
30 virtual ~B() {--count;}
31};
32
33int B::count = 0;
34
35struct A
36 : public B
37{
38 static int count;
39
40 A() {++count;}
41 A(const A& other) : B(other) {++count;}
42 ~A() {--count;}
43};
44
45int A::count = 0;
46
47struct C
48{
49 static int count;
50
51 C() {++count;}
52 C(const C&) {++count;}
53 virtual ~C() {--count;}
54};
55
56int C::count = 0;
57
58// https://llvm.org/PR60258
59// Invalid constructor SFINAE for std::shared_ptr's array ctors
60static_assert(!std::is_constructible<std::shared_ptr<int>, std::shared_ptr<long>&&>::value, "");
61static_assert( std::is_constructible<std::shared_ptr<B>, std::shared_ptr<A>&&>::value, "");
62static_assert( std::is_constructible<std::shared_ptr<const A>, std::shared_ptr<A>&&>::value, "");
63static_assert(!std::is_constructible<std::shared_ptr<A>, std::shared_ptr<const A>&&>::value, "");
64
65#if TEST_STD_VER >= 17
66static_assert(!std::is_constructible<std::shared_ptr<int>, std::shared_ptr<int[]>&&>::value, "");
67static_assert(!std::is_constructible<std::shared_ptr<int>, std::shared_ptr<int[5]>&&>::value, "");
68static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::shared_ptr<int>&&>::value, "");
69static_assert( std::is_constructible<std::shared_ptr<int[]>, std::shared_ptr<int[5]>&&>::value, "");
70static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::shared_ptr<int>&&>::value, "");
71static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::shared_ptr<int[]>&&>::value, "");
72static_assert(!std::is_constructible<std::shared_ptr<int[7]>, std::shared_ptr<int[5]>&&>::value, "");
73#endif
74
75int main(int, char**)
76{
77 static_assert(( std::is_convertible<std::shared_ptr<A>, std::shared_ptr<B> >::value), "");
78 static_assert((!std::is_convertible<std::shared_ptr<B>, std::shared_ptr<A> >::value), "");
79 static_assert((!std::is_convertible<std::shared_ptr<A>, std::shared_ptr<C> >::value), "");
80 {
81 std::shared_ptr<A> pA(new A);
82 assert(pA.use_count() == 1);
83 assert(B::count == 1);
84 assert(A::count == 1);
85 {
86 B* p = pA.get();
87 std::shared_ptr<B> pB(std::move(pA));
88 assert(B::count == 1);
89 assert(A::count == 1);
90#if TEST_STD_VER >= 11
91 assert(pB.use_count() == 1);
92 assert(pA.use_count() == 0);
93#else
94 assert(pB.use_count() == 2);
95 assert(pA.use_count() == 2);
96#endif
97 assert(p == pB.get());
98 }
99#if TEST_STD_VER >= 11
100 assert(pA.use_count() == 0);
101 assert(B::count == 0);
102 assert(A::count == 0);
103#else
104 assert(pA.use_count() == 1);
105 assert(B::count == 1);
106 assert(A::count == 1);
107#endif
108 }
109 assert(B::count == 0);
110 assert(A::count == 0);
111 {
112 std::shared_ptr<A> pA;
113 assert(pA.use_count() == 0);
114 assert(B::count == 0);
115 assert(A::count == 0);
116 {
117 std::shared_ptr<B> pB(std::move(pA));
118 assert(B::count == 0);
119 assert(A::count == 0);
120 assert(pB.use_count() == 0);
121 assert(pA.use_count() == 0);
122 assert(pA.get() == pB.get());
123 }
124 assert(pA.use_count() == 0);
125 assert(B::count == 0);
126 assert(A::count == 0);
127 }
128 assert(B::count == 0);
129 assert(A::count == 0);
130
131#if TEST_STD_VER > 14
132 {
133 std::shared_ptr<A[]> p1;
134 assert(p1.use_count() == 0);
135 assert(A::count == 0);
136 {
137 std::shared_ptr<const A[]> p2(p1);
138 assert(A::count == 0);
139 assert(p2.use_count() == 0);
140 assert(p1.use_count() == 0);
141 assert(p1.get() == p2.get());
142 }
143 assert(p1.use_count() == 0);
144 assert(A::count == 0);
145 }
146 assert(A::count == 0);
147#endif
148
149 {
150 std::shared_ptr<A const> pA(new A);
151 B const* p = pA.get();
152 std::shared_ptr<B const> pB(std::move(pA));
153 assert(pB.get() == p);
154 }
155
156 return 0;
157}
158

source code of libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp