1 // 2 // Tests for 3 // template <typename U> 4 // intrusive_shared_ptr(intrusive_shared_ptr<U, RefcountPolicy> const& other); 5 // 6 // intrusive_shared_ptr(intrusive_shared_ptr const& other); 7 // 8 9 #include <libkern/c++/intrusive_shared_ptr.h> 10 #include <darwintest.h> 11 #include <darwintest_utils.h> 12 #include <type_traits> 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 struct Unrelated { }; 27 28 template <typename Stored, typename From, typename To> 29 static void 30 tests() 31 { 32 Stored obj{3}; 33 34 // Test with non-null pointers 35 { 36 test_policy::retain_count = 0; 37 libkern::intrusive_shared_ptr<From, test_policy> const from(&obj, libkern::retain); 38 libkern::intrusive_shared_ptr<To, test_policy> to(from); // explicit 39 CHECK(test_policy::retain_count == 2); 40 CHECK(to.get() == &obj); 41 } 42 { 43 test_policy::retain_count = 0; 44 libkern::intrusive_shared_ptr<From, test_policy> const from(&obj, libkern::retain); 45 libkern::intrusive_shared_ptr<To, test_policy> to{from}; // explicit 46 CHECK(test_policy::retain_count == 2); 47 CHECK(to.get() == &obj); 48 } 49 { 50 test_policy::retain_count = 0; 51 libkern::intrusive_shared_ptr<From, test_policy> const from(&obj, libkern::retain); 52 libkern::intrusive_shared_ptr<To, test_policy> to = from; // implicit 53 CHECK(test_policy::retain_count == 2); 54 CHECK(to.get() == &obj); 55 } 56 57 // Test with a null pointer 58 { 59 test_policy::retain_count = 0; 60 libkern::intrusive_shared_ptr<From, test_policy> const from = nullptr; 61 libkern::intrusive_shared_ptr<To, test_policy> to = from; 62 CHECK(test_policy::retain_count == 0); 63 CHECK(to.get() == nullptr); 64 } 65 } 66 67 T_DECL(ctor_copy, "intrusive_shared_ptr.ctor.copy") { 68 tests</*stored*/ Derived, /*from*/ Derived, /*to*/ Derived>(); 69 tests</*stored*/ Derived, /*from*/ Derived, /*to*/ Derived const>(); 70 tests</*stored*/ Derived, /*from*/ Derived const, /*to*/ Derived const>(); 71 72 tests</*stored*/ Derived, /*from*/ Derived, /*to*/ Base>(); 73 tests</*stored*/ Derived, /*from*/ Derived, /*to*/ Base const>(); 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 tests</*stored*/ DerivedMultiple, /*from*/ DerivedMultiple, /*to*/ Base2>(); 80 tests</*stored*/ DerivedMultiple, /*from*/ DerivedMultiple const, /*to*/ Base2 const>(); 81 82 // Make sure basic trait querying works 83 static_assert(std::is_copy_constructible_v<test_shared_ptr<Derived> >); 84 85 // Make sure downcasts are disabled 86 static_assert(!std::is_constructible_v</*to*/ test_shared_ptr<Derived>, /*from*/ test_shared_ptr<Base> const&>); 87 static_assert(!std::is_constructible_v</*to*/ test_shared_ptr<DerivedMultiple>, /*from*/ test_shared_ptr<Base1> const&>); 88 static_assert(!std::is_constructible_v</*to*/ test_shared_ptr<DerivedMultiple>, /*from*/ test_shared_ptr<Base2> const&>); 89 static_assert(!std::is_constructible_v</*to*/ test_shared_ptr<Base2>, /*from*/ test_shared_ptr<Base1> const&>); 90 91 // Make sure const-casting away doesn't work 92 static_assert(!std::is_constructible_v</*to*/ test_shared_ptr<Derived>, /*from*/ test_shared_ptr<Derived const> const&>); 93 94 // Make sure casting to unrelated types doesn't work 95 static_assert(!std::is_constructible_v</*to*/ test_shared_ptr<char>, /*from*/ test_shared_ptr<Derived> const&>); 96 static_assert(!std::is_constructible_v</*to*/ test_shared_ptr<Unrelated>, /*from*/ test_shared_ptr<Derived> const&>); 97 static_assert(!std::is_constructible_v</*to*/ test_shared_ptr<Base2>, /*from*/ test_shared_ptr<Base1> const&>); 98 99 // Make sure constructing with different policies doesn't work 100 static_assert(!std::is_constructible_v</*to*/ libkern::intrusive_shared_ptr<Derived, dummy_policy<2> >, /*from*/ libkern::intrusive_shared_ptr<Derived, dummy_policy<1> > const &>); 101 } 102