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>
14 //     shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept;
15 // template<class T, class U>
16 //     shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept;
17 
18 #include "test_macros.h"
19 
20 #include <cassert>
21 #include <memory>
22 #include <type_traits>
23 #include <utility>
24 
25 struct A {
26   int x;
27 };
28 
29 struct Base { };
30 struct Derived : public Base { };
31 
main(int,char **)32 int main(int, char**) {
33   {
34     const std::shared_ptr<A> pA(new A);
35     ASSERT_NOEXCEPT(std::reinterpret_pointer_cast<int>(pA));
36     std::shared_ptr<int> pi = std::reinterpret_pointer_cast<int>(pA);
37     std::shared_ptr<A> pA2 = std::reinterpret_pointer_cast<A>(pi);
38     assert(pA2.get() == pA.get());
39     assert(!pi.owner_before(pA) && !pA.owner_before(pi));
40   }
41   {
42     const std::shared_ptr<A> pA;
43     std::shared_ptr<int> pi = std::reinterpret_pointer_cast<int>(pA);
44     std::shared_ptr<A> pA2 = std::reinterpret_pointer_cast<A>(pi);
45     assert(pA2.get() == pA.get());
46     assert(!pi.owner_before(pA) && !pA.owner_before(pi));
47   }
48   {
49     const std::shared_ptr<A> pA(new A);
50     std::shared_ptr<int> pi = std::reinterpret_pointer_cast<int>(pA);
51     pA->x = 42;
52     assert(*pi == 42);
53   }
54   {
55     const std::shared_ptr<Derived> pDerived(new Derived);
56     std::shared_ptr<Base> pBase = std::reinterpret_pointer_cast<Base>(pDerived);
57     std::shared_ptr<Derived> pDerived2 = std::reinterpret_pointer_cast<Derived>(pBase);
58     assert(pDerived2.get() == pDerived2.get());
59     assert(!pBase.owner_before(pDerived) && !pDerived.owner_before(pBase));
60   }
61   {
62     const std::shared_ptr<Base> pBase(new Base);
63     std::shared_ptr<Derived> pDerived = std::reinterpret_pointer_cast<Derived>(pBase);
64     std::shared_ptr<Base> pBase2 = std::reinterpret_pointer_cast<Base>(pDerived);
65     assert(pBase2.get() == pBase.get());
66     assert(!pDerived.owner_before(pBase) && !pBase.owner_before(pDerived));
67   }
68 #if TEST_STD_VER > 14
69   {
70     const std::shared_ptr<A[8]> pA;
71     std::shared_ptr<int[8]> pi = std::reinterpret_pointer_cast<int[8]>(pA);
72     std::shared_ptr<A[8]> pA2 = std::reinterpret_pointer_cast<A[8]>(pi);
73     assert(pA2.get() == pA.get());
74     assert(!pi.owner_before(pA) && !pA.owner_before(pi));
75   }
76 #endif // TEST_STD_VER > 14
77 #if TEST_STD_VER > 20
78   {
79     A* pA_raw = new A;
80     std::shared_ptr<A> pA(pA_raw);
81     ASSERT_NOEXCEPT(std::reinterpret_pointer_cast<int>(std::move(pA)));
82     std::shared_ptr<int> pi = std::reinterpret_pointer_cast<int>(std::move(pA));
83     assert(pA.get() == nullptr);
84     assert(pi.use_count() == 1);
85     std::shared_ptr<A> pA2 = std::reinterpret_pointer_cast<A>(std::move(pi));
86     assert(pi.get() == nullptr);
87     assert(pA2.get() == pA_raw);
88     assert(pA2.use_count() == 1);
89   }
90 #endif // TEST_STD_VER > 20
91 
92   return 0;
93 }
94