/* * Copyright Andrey Semashev 2007 - 2015. * 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) */ /*! * \file util_dynamic_type_disp.cpp * \author Andrey Semashev * \date 09.01.2009 * * \brief This header contains tests for the dynamic type dispatcher. */ #define BOOST_TEST_MODULE util_dynamic_type_disp #include #include #include #include #include namespace logging = boost::log; namespace { // A simple attribute value template< typename T > struct my_value { T m_Value; explicit my_value(T const& value) : m_Value(value) {} // The function passes the contained type into the dispatcher bool dispatch(logging::type_dispatcher& dispatcher) { logging::type_dispatcher::callback< T > callback = dispatcher.get_callback< T >(); if (callback) { callback(m_Value); return true; } else return false; } }; struct my_visitor { enum type_expected { none_expected, int_expected, double_expected, string_expected }; my_visitor() : m_Expected(none_expected), m_Int(0), m_Double(0.0) {} void set_expected() { m_Expected = none_expected; } void set_expected(int value) { m_Expected = int_expected; m_Int = value; } void set_expected(double value) { m_Expected = double_expected; m_Double = value; } void set_expected(std::string const& value) { m_Expected = string_expected; m_String = value; } // Implement visitation logic for all supported types void on_int(int const& value) { BOOST_CHECK_EQUAL(m_Expected, int_expected); BOOST_CHECK_EQUAL(m_Int, value); } void on_double(double const& value) { BOOST_CHECK_EQUAL(m_Expected, double_expected); BOOST_CHECK_CLOSE(m_Double, value, 0.001); } void on_string(std::string const& value) { BOOST_CHECK_EQUAL(m_Expected, string_expected); BOOST_CHECK_EQUAL(m_String, value); } private: type_expected m_Expected; int m_Int; double m_Double; std::string m_String; }; } // namespace // The test checks that general functionality works BOOST_AUTO_TEST_CASE(type_dispatch) { my_visitor vis; logging::dynamic_type_dispatcher disp; // Register type visitors disp.register_type< int >(boost::bind(&my_visitor::on_int, &vis, _1)); disp.register_type< double >(boost::bind(&my_visitor::on_double, &vis, _1)); BOOST_CHECK(disp.registered_types_count() == 2); // Right now strings are not supported by the dispatcher my_value< std::string > val1("Hello world!"); BOOST_CHECK(!val1.dispatch(disp)); // And now they are disp.register_type< std::string >(boost::bind(&my_visitor::on_string, &vis, _1)); BOOST_CHECK(disp.registered_types_count() == 3); vis.set_expected(val1.m_Value); BOOST_CHECK(val1.dispatch(disp)); my_value< double > val2(1.2); vis.set_expected(val2.m_Value); BOOST_CHECK(val2.dispatch(disp)); // This one is not supported my_value< float > val3(static_cast< float >(-4.3)); vis.set_expected(); BOOST_CHECK(!val3.dispatch(disp)); }