// Copyright (c) 2018-2025 Jean-Louis Leroy // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include #include #include #include #include #define BOOST_TEST_MODULE openmethod #include using namespace boost::openmethod; #define MAKE_CLASSES() \ struct Animal : boost::intrusive_ref_counter { \ explicit Animal(std::string str) { \ name = std::move(str); \ } \ \ Animal(const Animal&) = delete; \ Animal(Animal&&) = default; \ virtual ~Animal() = default; \ \ std::string name; \ }; \ \ struct Dog : Animal { \ using Animal::Animal; \ }; \ \ struct Cat : virtual Animal { \ using Animal::Animal; \ }; \ \ BOOST_OPENMETHOD_CLASSES(Animal, Dog, Cat); namespace BOOST_OPENMETHOD_GENSYM { // ----------------------------------------------------------------------------- // pass virtual args by shared_ptr by value MAKE_CLASSES(); BOOST_OPENMETHOD( name, (virtual_>), std::string); BOOST_OPENMETHOD_OVERRIDE( name, (boost::intrusive_ptr cat), std::string) { return cat->name + " the cat"; } BOOST_OPENMETHOD_OVERRIDE( name, (boost::intrusive_ptr dog), std::string) { return dog->name + " the dog"; } BOOST_AUTO_TEST_CASE(intrusive_ptr_by_value) { initialize(); auto spot = boost::intrusive_ptr(new Dog("Spot")); BOOST_TEST(name(spot) == "Spot the dog"); auto felix = boost::intrusive_ptr(new Cat("Felix")); BOOST_TEST(name(felix) == "Felix the cat"); } } // namespace BOOST_OPENMETHOD_GENSYM namespace BOOST_OPENMETHOD_GENSYM { // ----------------------------------------------------------------------------- // pass virtual args by shared_ptr by const& MAKE_CLASSES(); BOOST_OPENMETHOD( name, (virtual_&>), std::string); BOOST_OPENMETHOD_OVERRIDE( name, (const boost::intrusive_ptr& cat), std::string) { return cat->name + " the cat"; } BOOST_OPENMETHOD_OVERRIDE( name, (const boost::intrusive_ptr& dog), std::string) { return dog->name + " the dog"; } BOOST_AUTO_TEST_CASE(intrusive_ptr_by_const_ref) { initialize(); auto spot = boost::intrusive_ptr(new Dog("Spot")); BOOST_TEST(name(spot) == "Spot the dog"); auto felix = boost::intrusive_ptr(new Cat("Felix")); BOOST_TEST(name(felix) == "Felix the cat"); } } // namespace BOOST_OPENMETHOD_GENSYM namespace BOOST_OPENMETHOD_GENSYM { // ----------------------------------------------------------------------------- // virtual_ptr by value MAKE_CLASSES(); BOOST_OPENMETHOD( name, (boost_intrusive_virtual_ptr), std::string); BOOST_OPENMETHOD_OVERRIDE( name, (boost_intrusive_virtual_ptr cat), std::string) { return cat->name + " the cat"; } BOOST_OPENMETHOD_OVERRIDE( name, (boost_intrusive_virtual_ptr dog), std::string) { return dog->name + " the dog"; } BOOST_AUTO_TEST_CASE(intrusive_virtual_ptr_by_value) { initialize(); auto spot = make_boost_intrusive_virtual("Spot"); BOOST_TEST(name(spot) == "Spot the dog"); auto felix = make_boost_intrusive_virtual("Felix"); BOOST_TEST(name(felix) == "Felix the cat"); } } // namespace BOOST_OPENMETHOD_GENSYM namespace BOOST_OPENMETHOD_GENSYM { // ----------------------------------------------------------------------------- // virtual_ptr by const& MAKE_CLASSES(); BOOST_OPENMETHOD( name, (const boost_intrusive_virtual_ptr&), std::string); BOOST_OPENMETHOD_OVERRIDE( name, (const boost_intrusive_virtual_ptr& cat), std::string) { return cat->name + " the cat"; } BOOST_OPENMETHOD_OVERRIDE( name, (const boost_intrusive_virtual_ptr& dog), std::string) { return dog->name + " the dog"; } BOOST_AUTO_TEST_CASE(intrusive_virtual_ptr_by_const_ref) { initialize(); auto spot = make_boost_intrusive_virtual("Spot"); BOOST_TEST(name(spot) == "Spot the dog"); auto felix = make_boost_intrusive_virtual("Felix"); BOOST_TEST(name(felix) == "Felix the cat"); } } // namespace BOOST_OPENMETHOD_GENSYM