]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
7c673cae | 19 | #include <boost/test/unit_test.hpp> |
92f5a8d4 | 20 | #include <boost/test/tools/floating_point_comparison.hpp> |
7c673cae FG |
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 | } |