// // Tests for // template // intrusive_shared_ptr& operator=(intrusive_shared_ptr const& other); // // intrusive_shared_ptr& operator=(intrusive_shared_ptr const& other); // #include #include #include #include "test_policy.h" struct Base { int i; }; struct Derived : Base { }; struct Base1 { int i; }; struct Base2 { long l; }; struct DerivedMultiple : Base1, Base2 { DerivedMultiple(int i) : Base1{i}, Base2{i + 10} { } }; struct Unrelated { }; template static void tests() { Stored obj1{1}; Stored obj2{2}; // Copy-assign non-null to non-null { tracked_shared_ptr const from(&obj1, libkern::retain); tracked_shared_ptr to(&obj2, libkern::retain); tracking_policy::reset(); tracked_shared_ptr& ref = (to = from); CHECK(tracking_policy::releases == 1); CHECK(tracking_policy::retains == 1); CHECK(&ref == &to); CHECK(from.get() == &obj1); CHECK(to.get() == &obj1); } // Copy-assign non-null to null { tracked_shared_ptr const from(&obj1, libkern::retain); tracked_shared_ptr to = nullptr; tracking_policy::reset(); tracked_shared_ptr& ref = (to = from); CHECK(tracking_policy::releases == 0); CHECK(tracking_policy::retains == 1); CHECK(&ref == &to); CHECK(from.get() == &obj1); CHECK(to.get() == &obj1); } // Copy-assign null to non-null { tracked_shared_ptr const from = nullptr; tracked_shared_ptr to(&obj2, libkern::retain); tracking_policy::reset(); tracked_shared_ptr& ref = (to = from); CHECK(tracking_policy::releases == 1); CHECK(tracking_policy::retains == 0); CHECK(&ref == &to); CHECK(from.get() == nullptr); CHECK(to.get() == nullptr); } // Copy-assign null to null { tracked_shared_ptr const from = nullptr; tracked_shared_ptr to = nullptr; tracking_policy::reset(); tracked_shared_ptr& ref = (to = from); CHECK(tracking_policy::releases == 0); CHECK(tracking_policy::retains == 0); CHECK(&ref == &to); CHECK(from.get() == nullptr); CHECK(to.get() == nullptr); } } T_DECL(assign_copy, "intrusive_shared_ptr.assign.copy", T_META_TAG_VM_PREFERRED) { tests(); tests(); tests(); tests(); tests(); tests(); tests(); tests(); tests(); tests(); // Make sure basic trait querying works static_assert(std::is_copy_assignable_v >); // Make sure downcasts are disabled static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr const&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr const&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr const&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr const&>); // Make sure const-casting away doesn't work static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr const&>); // Make sure casting to unrelated types doesn't work static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr const&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr const&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr const&>); // Make sure constructing with different policies doesn't work static_assert(!std::is_assignable_v >, /*from*/ libkern::intrusive_shared_ptr > const &>); }