1 // 2 // Tests for 3 // void reset(pointer p, retain_t) noexcept; 4 // 5 6 #include <libkern/c++/intrusive_shared_ptr.h> 7 #include <darwintest.h> 8 #include "test_policy.h" 9 10 struct T { 11 int i; 12 }; 13 14 template <typename T> 15 static void 16 tests() 17 { 18 T obj1{1}; 19 T obj2{2}; 20 21 // reset() non-null shared pointer to non-null raw pointer 22 { 23 tracked_shared_ptr<T> ptr(&obj1, libkern::retain); 24 tracking_policy::reset(); 25 ptr.reset(&obj2, libkern::retain); 26 CHECK(tracking_policy::releases == 1); 27 CHECK(tracking_policy::retains == 1); 28 CHECK(ptr.get() == &obj2); 29 } 30 31 // reset() non-null shared pointer to null raw pointer 32 { 33 tracked_shared_ptr<T> ptr(&obj1, libkern::retain); 34 tracking_policy::reset(); 35 ptr.reset(nullptr, libkern::retain); 36 CHECK(tracking_policy::releases == 1); 37 CHECK(tracking_policy::retains == 0); 38 CHECK(ptr.get() == nullptr); 39 } 40 41 // reset() null shared pointer to non-null raw pointer 42 { 43 tracked_shared_ptr<T> ptr = nullptr; 44 tracking_policy::reset(); 45 ptr.reset(&obj2, libkern::retain); 46 CHECK(tracking_policy::releases == 0); 47 CHECK(tracking_policy::retains == 1); 48 CHECK(ptr.get() == &obj2); 49 } 50 51 // reset() null shared pointer to null raw pointer 52 { 53 tracked_shared_ptr<T> ptr = nullptr; 54 tracking_policy::reset(); 55 ptr.reset(nullptr, libkern::retain); 56 CHECK(tracking_policy::releases == 0); 57 CHECK(tracking_policy::retains == 0); 58 CHECK(ptr.get() == nullptr); 59 } 60 61 // self-reset() should not cause the refcount to hit 0, ever 62 { 63 tracking_policy::reset(); 64 tracked_shared_ptr<T> ptr(&obj1, libkern::retain); 65 CHECK(tracking_policy::retains == 1); 66 ptr.reset(ptr.get(), libkern::retain); 67 CHECK(tracking_policy::retains == 2); 68 CHECK(tracking_policy::releases == 1); 69 CHECK(tracking_policy::refcount == 1); 70 CHECK(!tracking_policy::hit_zero); 71 CHECK(ptr.get() == &obj1); 72 } 73 74 // reset() as a self-reference 75 { 76 tracked_shared_ptr<T> ptr; 77 tracked_shared_ptr<T> ptr2; 78 CHECK(ptr.reset(&obj2, libkern::retain)); 79 80 // check short-circuiting 81 bool ok = (ptr.reset() && ptr2.reset(&obj1, libkern::retain)); 82 CHECK(ptr2.get() == nullptr); 83 } 84 } 85 86 T_DECL(reset_retain, "intrusive_shared_ptr.reset.retain") { 87 tests<T>(); 88 tests<T const>(); 89 } 90