// 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 #define BOOST_TEST_MODULE openmethod #include #include "test_virtual_ptr_value_semantics.hpp" #include static_assert(detail::same_smart_ptr< std::shared_ptr, std::shared_ptr, default_registry>); static_assert(!detail::same_smart_ptr< std::shared_ptr, std::unique_ptr, default_registry>); static_assert(!detail::same_smart_ptr< std::shared_ptr, shared_virtual_ptr>, default_registry>); BOOST_AUTO_TEST_CASE_TEMPLATE( shared_virtual_ptr_value, Registry, test_policies) { static_assert(std::is_same_v< typename shared_virtual_ptr::element_type, Animal>); static_assert(std::is_same_v< decltype(std::declval>() .get()), Animal*>); static_assert(shared_virtual_ptr::is_smart_ptr); static_assert(shared_virtual_ptr::is_smart_ptr); static_assert( std::is_same_v< decltype(*std::declval>()), Animal&>); init_test(); // construction and assignment from a plain pointer or reference is not // allowed static_assert(!construct_assign_ok, Dog>); static_assert( !construct_assign_ok, Dog&&>); static_assert( !construct_assign_ok, const Dog&>); static_assert( !construct_assign_ok, const Dog*>); // ------------------------------------------------------------------------- // construction and assignment from plain references and pointers { shared_virtual_ptr p{nullptr}; BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } { auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); auto hector = std::make_shared(); p = hector; BOOST_TEST(p.get() == hector.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } { auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); auto felix = std::make_shared(); p = felix; BOOST_TEST(p.get() == felix.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } { auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); auto hector = std::make_shared(); p = hector; BOOST_TEST(p.get() == hector.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } { auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); auto felix = std::make_shared(); p = felix; BOOST_TEST(p.get() == felix.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } { auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); auto hector = std::make_shared(); p = hector; BOOST_TEST(p.get() == hector.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } { auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); auto felix = std::make_shared(); p = felix; BOOST_TEST(p.get() == felix.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } { auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); auto hector = std::make_shared(); p = hector; BOOST_TEST(p.get() == hector.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } { auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); auto felix = std::make_shared(); p = felix; BOOST_TEST(p.get() == felix.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } // shared_virtual_ptr p{Dog()}; static_assert( !construct_assign_ok, Dog&&>); // ------------------------------------------------------------------------- // construction and assignment from other shared_virtual_ptr { // shared_virtual_ptr(const shared_virtual_ptr&) auto snoopy = std::make_shared(); const shared_virtual_ptr p(snoopy); shared_virtual_ptr q(p); BOOST_TEST(q.get() == snoopy.get()); BOOST_TEST(q.vptr() == Registry::template static_vptr); } { // shared_virtual_ptr(shared_virtual_ptr&) auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); shared_virtual_ptr q(p); BOOST_TEST(q.get() == snoopy.get()); BOOST_TEST(q.vptr() == Registry::template static_vptr); } { // shared_virtual_ptr(shared_virtual_ptr&&) auto snoopy = std::make_shared(); shared_virtual_ptr p(snoopy); shared_virtual_ptr q(std::move(p)); BOOST_TEST(q.get() == snoopy.get()); BOOST_TEST(q.vptr() == Registry::template static_vptr); BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } { // shared_virtual_ptr(const shared_virtual_ptr&) auto snoopy = std::make_shared(); const shared_virtual_ptr p(snoopy); shared_virtual_ptr base(p); BOOST_TEST(base.get() == snoopy.get()); BOOST_TEST(base.vptr() == Registry::template static_vptr); } { // shared_virtual_ptr(const shared_virtual_ptr&) auto snoopy = std::make_shared(); const shared_virtual_ptr p(snoopy); shared_virtual_ptr const_q(p); BOOST_TEST(const_q.get() == snoopy.get()); BOOST_TEST(const_q.vptr() == Registry::template static_vptr); } { // shared_virtual_ptr(const shared_virtual_ptr&) auto snoopy = std::make_shared(); const shared_virtual_ptr p(snoopy); shared_virtual_ptr const_base_q(p); BOOST_TEST(const_base_q.get() == snoopy.get()); BOOST_TEST(const_base_q.vptr() == Registry::template static_vptr); } { // shared_virtual_ptr() shared_virtual_ptr p{nullptr}; BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } { shared_virtual_ptr p{std::shared_ptr()}; BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } // ------------------------------------------------------------------------- // assignment { shared_virtual_ptr p; auto snoopy = std::make_shared(); p = snoopy; BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } { shared_virtual_ptr p; auto snoopy = std::make_shared(); p = snoopy; BOOST_TEST(p.get() == snoopy.get()); BOOST_TEST(p.vptr() == Registry::template static_vptr); } { auto p = make_shared_virtual(); p = nullptr; BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } { auto p = make_shared_virtual(); p = std::shared_ptr(); BOOST_TEST(p.get() == nullptr); BOOST_TEST(p.vptr() == nullptr); } static_assert( !construct_assign_ok, const Dog&>); static_assert( !construct_assign_ok, const Dog*>); } template struct check_illegal_smart_ops< std::shared_ptr, std::unique_ptr, direct_vector>; // Cannot construct or assign a virtual_ptr from a non-polymorphic object. static_assert(!construct_assign_ok< virtual_ptr>, const std::shared_ptr&>); static_assert(!construct_assign_ok< virtual_ptr>, std::shared_ptr&>); static_assert(!construct_assign_ok< virtual_ptr>, std::shared_ptr&&>); // OK from another virtual_ptr though, because it can be constructed using // 'final'. static_assert(std::is_assignable_v< virtual_ptr>, const virtual_ptr>&>); static_assert(construct_assign_ok< virtual_ptr>, virtual_ptr>&>); static_assert(construct_assign_ok< virtual_ptr>, virtual_ptr>&&>);