1 // 2 // Tests for 3 // template<typename To, typename From, typename R> 4 // intrusive_shared_ptr<To, R> static_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> static_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 struct Base1 { int i; }; 19 struct Base2 { long l; }; 20 struct DerivedMultiple : Base1, Base2 { 21 DerivedMultiple(int i) : Base1{i}, Base2{i + 10} 22 { 23 } 24 }; 25 26 template <typename Stored, typename From, typename To> 27 static void 28 tests() 29 { 30 Stored obj{3}; 31 32 { 33 tracked_shared_ptr<From> const from(&obj, libkern::no_retain); 34 tracking_policy::reset(); 35 tracked_shared_ptr<To> to = libkern::static_pointer_cast<To>(from); 36 CHECK(tracking_policy::retains == 1); 37 CHECK(tracking_policy::releases == 0); 38 CHECK(to.get() == static_cast<To const*>(&obj)); 39 CHECK(from.get() == &obj); 40 } 41 { 42 tracked_shared_ptr<From> from(&obj, libkern::no_retain); 43 tracking_policy::reset(); 44 tracked_shared_ptr<To> to = libkern::static_pointer_cast<To>(std::move(from)); 45 CHECK(tracking_policy::retains == 0); 46 CHECK(tracking_policy::releases == 0); 47 CHECK(to.get() == static_cast<To const*>(&obj)); 48 CHECK(from.get() == nullptr); 49 } 50 51 // Test `static_pointer_cast`ing a null pointer 52 { 53 tracked_shared_ptr<From> const from = nullptr; 54 tracking_policy::reset(); 55 tracked_shared_ptr<To> to = libkern::static_pointer_cast<To>(from); 56 CHECK(tracking_policy::retains == 0); 57 CHECK(tracking_policy::releases == 0); 58 CHECK(to.get() == nullptr); 59 CHECK(from.get() == nullptr); 60 } 61 { 62 tracked_shared_ptr<From> from = nullptr; 63 tracking_policy::reset(); 64 tracked_shared_ptr<To> to = libkern::static_pointer_cast<To>(std::move(from)); 65 CHECK(tracking_policy::retains == 0); 66 CHECK(tracking_policy::releases == 0); 67 CHECK(to.get() == nullptr); 68 CHECK(from.get() == nullptr); 69 } 70 } 71 72 T_DECL(cast_static, "intrusive_shared_ptr.cast.static") { 73 tests</*stored*/ Derived, /*from*/ Derived, /*to*/ Base>(); 74 tests</*stored*/ Derived, /*from*/ Derived const, /*to*/ Base const>(); 75 76 tests</*stored*/ DerivedMultiple, /*from*/ DerivedMultiple, /*to*/ Base1>(); 77 tests</*stored*/ DerivedMultiple, /*from*/ DerivedMultiple const, /*to*/ Base1 const>(); 78 } 79