// // Tests for // template // intrusive_shared_ptr& operator=(intrusive_shared_ptr&& other); // // intrusive_shared_ptr& operator=(intrusive_shared_ptr&& other); // #include #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}; // Move-assign non-null to non-null { tracked_shared_ptr from(&obj1, libkern::retain); tracked_shared_ptr to(&obj2, libkern::retain); tracking_policy::reset(); tracked_shared_ptr& ref = (to = std::move(from)); CHECK(tracking_policy::releases == 1); CHECK(tracking_policy::retains == 0); CHECK(&ref == &to); CHECK(from.get() == nullptr); CHECK(to.get() == &obj1); } // Move-assign non-null to null { tracked_shared_ptr from(&obj1, libkern::retain); tracked_shared_ptr to = nullptr; tracking_policy::reset(); tracked_shared_ptr& ref = (to = std::move(from)); CHECK(tracking_policy::releases == 0); CHECK(tracking_policy::retains == 0); CHECK(&ref == &to); CHECK(from.get() == nullptr); CHECK(to.get() == &obj1); } // Move-assign null to non-null { tracked_shared_ptr from = nullptr; tracked_shared_ptr to(&obj2, libkern::retain); tracking_policy::reset(); tracked_shared_ptr& ref = (to = std::move(from)); CHECK(tracking_policy::releases == 1); CHECK(tracking_policy::retains == 0); CHECK(&ref == &to); CHECK(from.get() == nullptr); CHECK(to.get() == nullptr); } // Move-assign null to null { tracked_shared_ptr from = nullptr; tracked_shared_ptr to = nullptr; tracking_policy::reset(); tracked_shared_ptr& ref = (to = std::move(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_move, "intrusive_shared_ptr.assign.move", 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_move_assignable_v >); // Make sure downcasts are disabled static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr&&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr&&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr&&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr&&>); // Make sure const-casting away doesn't work static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr&&>); // Make sure casting to unrelated types doesn't work static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr&&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr&&>); static_assert(!std::is_assignable_v, /*from*/ test_shared_ptr&&>); // Make sure constructing with different policies doesn't work static_assert(!std::is_assignable_v >, /*from*/ libkern::intrusive_shared_ptr >&&>); }