Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / log / test / run / util_dynamic_type_disp.cpp
1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
3  * Distributed under the Boost Software License, Version 1.0.
4  *    (See accompanying file LICENSE_1_0.txt or copy at
5  *          http://www.boost.org/LICENSE_1_0.txt)
6  */
7 /*!
8  * \file   util_dynamic_type_disp.cpp
9  * \author Andrey Semashev
10  * \date   09.01.2009
11  *
12  * \brief  This header contains tests for the dynamic type dispatcher.
13  */
14
15 #define BOOST_TEST_MODULE util_dynamic_type_disp
16
17 #include <string>
18 #include <boost/bind.hpp>
19 #include <boost/test/unit_test.hpp>
20 #include <boost/test/tools/floating_point_comparison.hpp>
21 #include <boost/log/utility/type_dispatch/dynamic_type_dispatcher.hpp>
22
23 namespace logging = boost::log;
24
25 namespace {
26
27     // A simple attribute value
28     template< typename T >
29     struct my_value
30     {
31         T m_Value;
32
33         explicit my_value(T const& value) : m_Value(value) {}
34
35         // The function passes the contained type into the dispatcher
36         bool dispatch(logging::type_dispatcher& dispatcher)
37         {
38             logging::type_dispatcher::callback< T > callback = dispatcher.get_callback< T >();
39             if (callback)
40             {
41                 callback(m_Value);
42                 return true;
43             }
44             else
45                 return false;
46         }
47     };
48
49     struct my_visitor
50     {
51         enum type_expected
52         {
53             none_expected,
54             int_expected,
55             double_expected,
56             string_expected
57         };
58
59         my_visitor() : m_Expected(none_expected), m_Int(0), m_Double(0.0) {}
60
61         void set_expected()
62         {
63             m_Expected = none_expected;
64         }
65         void set_expected(int value)
66         {
67             m_Expected = int_expected;
68             m_Int = value;
69         }
70         void set_expected(double value)
71         {
72             m_Expected = double_expected;
73             m_Double = value;
74         }
75         void set_expected(std::string const& value)
76         {
77             m_Expected = string_expected;
78             m_String = value;
79         }
80
81         // Implement visitation logic for all supported types
82         void on_int(int const& value)
83         {
84             BOOST_CHECK_EQUAL(m_Expected, int_expected);
85             BOOST_CHECK_EQUAL(m_Int, value);
86         }
87         void on_double(double const& value)
88         {
89             BOOST_CHECK_EQUAL(m_Expected, double_expected);
90             BOOST_CHECK_CLOSE(m_Double, value, 0.001);
91         }
92         void on_string(std::string const& value)
93         {
94             BOOST_CHECK_EQUAL(m_Expected, string_expected);
95             BOOST_CHECK_EQUAL(m_String, value);
96         }
97
98     private:
99         type_expected m_Expected;
100         int m_Int;
101         double m_Double;
102         std::string m_String;
103     };
104
105 } // namespace
106
107 // The test checks that general functionality works
108 BOOST_AUTO_TEST_CASE(type_dispatch)
109 {
110     my_visitor vis;
111     logging::dynamic_type_dispatcher disp;
112
113     // Register type visitors
114     disp.register_type< int >(boost::bind(&my_visitor::on_int, &vis, _1));
115     disp.register_type< double >(boost::bind(&my_visitor::on_double, &vis, _1));
116
117     BOOST_CHECK(disp.registered_types_count() == 2);
118
119     // Right now strings are not supported by the dispatcher
120     my_value< std::string > val1("Hello world!");
121     BOOST_CHECK(!val1.dispatch(disp));
122
123     // And now they are
124     disp.register_type< std::string >(boost::bind(&my_visitor::on_string, &vis, _1));
125     BOOST_CHECK(disp.registered_types_count() == 3);
126
127     vis.set_expected(val1.m_Value);
128     BOOST_CHECK(val1.dispatch(disp));
129
130     my_value< double > val2(1.2);
131     vis.set_expected(val2.m_Value);
132     BOOST_CHECK(val2.dispatch(disp));
133
134     // This one is not supported
135     my_value< float > val3(static_cast< float >(-4.3));
136     vis.set_expected();
137     BOOST_CHECK(!val3.dispatch(disp));
138 }