// 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 using std::make_shared; using std::shared_ptr; using std::string; using boost::openmethod::make_shared_virtual; using boost::openmethod::shared_virtual_ptr; using boost::openmethod::virtual_ptr; struct matrix { virtual ~matrix() { } virtual auto at(int row, int col) const -> double = 0; // ... }; struct dense_matrix : matrix { virtual auto at(int /*row*/, int /*col*/) const -> double { return 0; } }; struct diagonal_matrix : matrix { virtual auto at(int /*row*/, int /*col*/) const -> double { return 0; } }; BOOST_OPENMETHOD_CLASSES(matrix, dense_matrix, diagonal_matrix); BOOST_OPENMETHOD(to_json, (virtual_ptr), string); BOOST_OPENMETHOD_OVERRIDE(to_json, (virtual_ptr), string) { return "json for dense matrix..."; } BOOST_OPENMETHOD_OVERRIDE( to_json, (virtual_ptr), string) { return "json for diagonal matrix..."; } // ----------------------------------------------------------------------------- // matrix * matrix BOOST_OPENMETHOD( times, (shared_virtual_ptr, shared_virtual_ptr), shared_virtual_ptr); // catch-all matrix * matrix -> dense_matrix BOOST_OPENMETHOD_OVERRIDE( times, (shared_virtual_ptr /*a*/, shared_virtual_ptr /*b*/), shared_virtual_ptr) { return make_shared(); } // diagonal_matrix * diagonal_matrix -> diagonal_matrix BOOST_OPENMETHOD_OVERRIDE( times, (shared_virtual_ptr /*a*/, shared_virtual_ptr /*b*/), shared_virtual_ptr) { return make_shared_virtual(); } inline auto operator*(shared_ptr a, shared_ptr b) -> shared_virtual_ptr { return times(a, b); } // ----------------------------------------------------------------------------- // scalar * matrix BOOST_OPENMETHOD( times, (double, shared_virtual_ptr), shared_virtual_ptr); // catch-all matrix * scalar -> dense_matrix BOOST_OPENMETHOD_OVERRIDE( times, (double /*a*/, shared_virtual_ptr /*b*/), shared_virtual_ptr) { return make_shared_virtual(); } BOOST_OPENMETHOD_OVERRIDE( times, (double /*a*/, shared_virtual_ptr /*b*/), shared_virtual_ptr) { return make_shared_virtual(); } // ----------------------------------------------------------------------------- // matrix * scalar // just swap inline auto times(shared_virtual_ptr a, double b) -> shared_virtual_ptr { return times(b, a); } // ----------------------------------------------------------------------------- // main #define check(expr) \ { \ if (!(expr)) { \ cerr << #expr << " failed\n"; \ } \ } auto main() -> int { using std::cerr; using std::cout; boost::openmethod::initialize(); shared_ptr a = make_shared(); shared_ptr b = make_shared(); double s = 1; #ifdef BOOST_CLANG #pragma clang diagnostic ignored "-Wpotentially-evaluated-expression" #endif check(typeid(*times(a, a)) == typeid(dense_matrix)); check(typeid(*times(a, b)) == typeid(dense_matrix)); check(typeid(*times(b, b)) == typeid(diagonal_matrix)); check(typeid(*times(s, a)) == typeid(dense_matrix)); check(typeid(*times(s, b)) == typeid(diagonal_matrix)); cout << to_json(*a) << "\n"; // json for dense matrix cout << to_json(*b) << "\n"; // json for diagonal matrix return 0; }