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 T, class U> shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
14 // template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept;
15 
16 #include <cassert>
17 #include <memory>
18 #include <type_traits>
19 #include <utility>
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 
main(int,char **)46 int main(int, char**)
47 {
48     {
49         const std::shared_ptr<A> pA(new A);
50         ASSERT_NOEXCEPT(std::static_pointer_cast<B>(pA));
51         std::shared_ptr<B> pB = std::static_pointer_cast<B>(pA);
52         assert(pB.get() == pA.get());
53         assert(!pB.owner_before(pA) && !pA.owner_before(pB));
54     }
55     {
56         const std::shared_ptr<B> pA(new A);
57         std::shared_ptr<A> pB = std::static_pointer_cast<A>(pA);
58         assert(pB.get() == pA.get());
59         assert(!pB.owner_before(pA) && !pA.owner_before(pB));
60     }
61     {
62         const std::shared_ptr<A> pA;
63         std::shared_ptr<B> pB = std::static_pointer_cast<B>(pA);
64         assert(pB.get() == pA.get());
65         assert(!pB.owner_before(pA) && !pA.owner_before(pB));
66     }
67     {
68         const std::shared_ptr<B> pA;
69         std::shared_ptr<A> pB = std::static_pointer_cast<A>(pA);
70         assert(pB.get() == pA.get());
71         assert(!pB.owner_before(pA) && !pA.owner_before(pB));
72     }
73 #if TEST_STD_VER > 14
74     {
75       const std::shared_ptr<A[8]> pA;
76       std::shared_ptr<B[8]> pB = std::static_pointer_cast<B[8]>(pA);
77       assert(pB.get() == pA.get());
78       assert(!pB.owner_before(pA) && !pA.owner_before(pB));
79     }
80     {
81       const std::shared_ptr<B[8]> pA;
82       std::shared_ptr<A[8]> pB = std::static_pointer_cast<A[8]>(pA);
83       assert(pB.get() == pA.get());
84       assert(!pB.owner_before(pA) && !pA.owner_before(pB));
85     }
86 #endif // TEST_STD_VER > 14
87 #if TEST_STD_VER > 20
88     {
89       A* pA_raw = new A;
90       std::shared_ptr<A> pA(pA_raw);
91       ASSERT_NOEXCEPT(std::static_pointer_cast<B>(std::move(pA)));
92       std::shared_ptr<B> pB = std::static_pointer_cast<B>(std::move(pA));
93       assert(pA.get() == nullptr);
94       assert(pB.get() == pA_raw);
95       assert(pB.use_count() == 1);
96     }
97 #endif // TEST_STD_VER > 20
98 
99     return 0;
100 }
101