// qright (c) 2018-2025 Jean-Louis Leroy // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt // or q at http://www.boost.org/LICENSE_1_0.txt) #include #include #include #define BOOST_TEST_MODULE openmethod #include using namespace boost::openmethod; BOOST_AUTO_TEST_CASE(virtual_ptr_examples) { { // clang-format off struct Animal { virtual ~Animal() { } }; // polymorphic struct Dog : Animal {}; // polymorphic BOOST_OPENMETHOD_CLASSES(Animal, Dog); initialize(); // clang-format on { virtual_ptr p{nullptr}; BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } { Dog snoopy; Animal& animal = snoopy; virtual_ptr p = animal; BOOST_TEST(p.get() == &snoopy); BOOST_TEST(p.vptr() == default_registry::static_vptr); } { Dog snoopy; Animal* animal = &snoopy; virtual_ptr p = animal; BOOST_TEST(p.get() == &snoopy); BOOST_TEST(p.vptr() == default_registry::static_vptr); } { virtual_ptr p{nullptr}; Dog snoopy; Animal* animal = &snoopy; p = animal; BOOST_TEST(p.get() == &snoopy); BOOST_TEST(p.vptr() == default_registry::static_vptr); } { Dog snoopy; virtual_ptr p = final_virtual_ptr(snoopy); p = nullptr; BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } } { struct Animal {}; // polymorphic not required struct Dog : Animal {}; // polymorphic not required BOOST_OPENMETHOD_CLASSES(Animal, Dog); initialize(); { Dog snoopy; virtual_ptr dog = final_virtual_ptr(snoopy); virtual_ptr p(dog); BOOST_TEST(p.get() == &snoopy); BOOST_TEST(p.vptr() == default_registry::static_vptr); } { Dog snoopy; virtual_ptr dog = final_virtual_ptr(snoopy); virtual_ptr p{nullptr}; p = dog; BOOST_TEST(p.get() == &snoopy); BOOST_TEST(p.vptr() == default_registry::static_vptr); } { virtual_ptr> snoopy = make_shared_virtual(); virtual_ptr p = snoopy; BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == default_registry::static_vptr); } static_assert( std::is_constructible_v< shared_virtual_ptr, virtual_ptr> == false); { virtual_ptr> snoopy = make_shared_virtual(); virtual_ptr p; p = snoopy; BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == default_registry::static_vptr); } static_assert( std::is_assignable_v< shared_virtual_ptr&, virtual_ptr> == false); } } BOOST_AUTO_TEST_CASE(smart_virtual_ptr_examples) { { // clang-format off struct Animal { virtual ~Animal() { } }; // polymorphic struct Dog : Animal {}; // polymorphic BOOST_OPENMETHOD_CLASSES(Animal, Dog); initialize(); // clang-format on { virtual_ptr> p; BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } { virtual_ptr> p{nullptr}; BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } { const std::shared_ptr snoopy = std::make_shared(); virtual_ptr> p = snoopy; BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == default_registry::static_vptr); } { std::shared_ptr snoopy = std::make_shared(); virtual_ptr> p = snoopy; BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == default_registry::static_vptr); } { std::shared_ptr snoopy = std::make_shared(); Dog* moving = snoopy.get(); virtual_ptr> p = std::move(snoopy); BOOST_TEST(p.get() == moving); BOOST_TEST(p.vptr() == default_registry::static_vptr); BOOST_TEST(snoopy.get() == nullptr); } } { struct Animal {}; // polymorphic not required struct Dog : Animal {}; // polymorphic not required BOOST_OPENMETHOD_CLASSES(Animal, Dog); initialize(); { const virtual_ptr> snoopy = make_shared_virtual(); virtual_ptr> p = std::move(snoopy); BOOST_TEST(snoopy.get() != nullptr); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == default_registry::static_vptr); } { virtual_ptr> snoopy = make_shared_virtual(); Dog* moving = snoopy.get(); virtual_ptr> p = std::move(snoopy); BOOST_TEST(p.get() == moving); BOOST_TEST(p.vptr() == default_registry::static_vptr); BOOST_TEST(snoopy.get() == nullptr); BOOST_TEST(snoopy.vptr() == nullptr); } { virtual_ptr> p = make_shared_virtual(); p = nullptr; BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); BOOST_TEST((p == virtual_ptr>())); } { const virtual_ptr> snoopy = make_shared_virtual(); virtual_ptr> p; p = snoopy; BOOST_TEST(p.get() != nullptr); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == default_registry::static_vptr); BOOST_TEST(snoopy.vptr() == default_registry::static_vptr); } { virtual_ptr> snoopy = make_shared_virtual(); Dog* moving = snoopy.get(); virtual_ptr> p; p = std::move(snoopy); BOOST_TEST(p.get() == moving); BOOST_TEST(p.vptr() == default_registry::static_vptr); BOOST_TEST(snoopy.get() == nullptr); BOOST_TEST(snoopy.vptr() == nullptr); } } }