1 // 2 // Tests for 3 // template<typename To, typename From, typename R> 4 // intrusive_shared_ptr<To, R> reinterpret_pointer_cast(intrusive_shared_ptr<From, R> const& ptr) noexcept; 5 // 6 // template<typename To, typename From, typename R> 7 // intrusive_shared_ptr<To, R> reinterpret_pointer_cast(intrusive_shared_ptr<From, R>&& ptr) noexcept 8 // 9 10 #include <libkern/c++/intrusive_shared_ptr.h> 11 #include <utility> 12 #include <darwintest.h> 13 #include "test_policy.h" 14 15 struct Base { int i; }; 16 struct Derived : Base { }; 17 18 // Layout compatible with Derived 19 struct Unrelated { int i; }; 20 21 template <typename Stored, typename From, typename To> 22 static void 23 tests() 24 { 25 Stored obj{3}; 26 27 { 28 tracked_shared_ptr<From> const from(&obj, libkern::no_retain); 29 tracking_policy::reset(); 30 tracked_shared_ptr<To> to = libkern::reinterpret_pointer_cast<To>(from); 31 CHECK(tracking_policy::retains == 1); 32 CHECK(tracking_policy::releases == 0); 33 CHECK(to.get() == reinterpret_cast<To const*>(&obj)); 34 CHECK(from.get() == &obj); 35 } 36 { 37 tracked_shared_ptr<From> from(&obj, libkern::no_retain); 38 tracking_policy::reset(); 39 tracked_shared_ptr<To> to = libkern::reinterpret_pointer_cast<To>(std::move(from)); 40 CHECK(tracking_policy::retains == 0); 41 CHECK(tracking_policy::releases == 0); 42 CHECK(to.get() == reinterpret_cast<To const*>(&obj)); 43 CHECK(from.get() == nullptr); 44 } 45 46 // Test `reinterpret_pointer_cast`ing a null pointer 47 { 48 tracked_shared_ptr<From> const from = nullptr; 49 tracking_policy::reset(); 50 tracked_shared_ptr<To> to = libkern::reinterpret_pointer_cast<To>(from); 51 CHECK(tracking_policy::retains == 0); 52 CHECK(tracking_policy::releases == 0); 53 CHECK(to.get() == nullptr); 54 CHECK(from.get() == nullptr); 55 } 56 { 57 tracked_shared_ptr<From> from = nullptr; 58 tracking_policy::reset(); 59 tracked_shared_ptr<To> to = libkern::reinterpret_pointer_cast<To>(std::move(from)); 60 CHECK(tracking_policy::retains == 0); 61 CHECK(tracking_policy::releases == 0); 62 CHECK(to.get() == nullptr); 63 CHECK(from.get() == nullptr); 64 } 65 } 66 67 T_DECL(cast_reinterpret, "intrusive_shared_ptr.cast.reinterpret") { 68 tests</*stored*/ Derived, /*from*/ Derived, /*to*/ Base>(); 69 tests</*stored*/ Derived, /*from*/ Derived const, /*to*/ Base const>(); 70 71 tests</*stored*/ Derived, /*from*/ Derived, /*to*/ char>(); 72 tests</*stored*/ Derived, /*from*/ Derived const, /*to*/ char const>(); 73 74 tests</*stored*/ Derived, /*from*/ Derived, /*to*/ Unrelated>(); 75 tests</*stored*/ Derived, /*from*/ Derived const, /*to*/ Unrelated const>(); 76 } 77