Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / log / test / run / attr_attribute_value_impl.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   attr_attribute_value_impl.cpp
9  * \author Andrey Semashev
10  * \date   25.01.2009
11  *
12  * \brief  This header contains tests for the basic attribute value class.
13  */
14
15 #define BOOST_TEST_MODULE attr_attribute_value_impl
16
17 #include <string>
18 #include <boost/smart_ptr/intrusive_ptr.hpp>
19 #include <boost/mpl/vector.hpp>
20 #include <boost/test/unit_test.hpp>
21 #include <boost/test/tools//floating_point_comparison.hpp>
22 #include <boost/log/attributes/attribute_value.hpp>
23 #include <boost/log/attributes/attribute_value_impl.hpp>
24 #include <boost/log/attributes/value_extraction.hpp>
25 #include <boost/log/attributes/value_visitation.hpp>
26 #include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp>
27 #include <boost/log/utility/functional/bind_assign.hpp>
28
29 namespace logging = boost::log;
30 namespace attrs = logging::attributes;
31
32 namespace {
33
34     // Type dispatcher for the supported types
35     struct my_dispatcher :
36         public logging::static_type_dispatcher<
37             boost::mpl::vector< int, double, std::string >
38         >
39     {
40         typedef logging::static_type_dispatcher<
41             boost::mpl::vector< int, double, std::string >
42         > base_type;
43
44         enum type_expected
45         {
46             none_expected,
47             int_expected,
48             double_expected,
49             string_expected
50         };
51
52         my_dispatcher() :
53             base_type(*this),
54             m_Expected(none_expected),
55             m_Int(0),
56             m_Double(0.0)
57         {
58         }
59
60         void set_expected()
61         {
62             m_Expected = none_expected;
63         }
64         void set_expected(int value)
65         {
66             m_Expected = int_expected;
67             m_Int = value;
68         }
69         void set_expected(double value)
70         {
71             m_Expected = double_expected;
72             m_Double = value;
73         }
74         void set_expected(std::string const& value)
75         {
76             m_Expected = string_expected;
77             m_String = value;
78         }
79
80         // Implement visitation logic for all supported types
81         void operator() (int const& value) const
82         {
83             BOOST_CHECK_EQUAL(m_Expected, int_expected);
84             BOOST_CHECK_EQUAL(m_Int, value);
85         }
86         void operator() (double const& value) const
87         {
88             BOOST_CHECK_EQUAL(m_Expected, double_expected);
89             BOOST_CHECK_CLOSE(m_Double, value, 0.001);
90         }
91         void operator() (std::string const& value) const
92         {
93             BOOST_CHECK_EQUAL(m_Expected, string_expected);
94             BOOST_CHECK_EQUAL(m_String, value);
95         }
96
97     private:
98         type_expected m_Expected;
99         int m_Int;
100         double m_Double;
101         std::string m_String;
102     };
103
104 } // namespace
105
106 // The test verifies that type dispatching works
107 BOOST_AUTO_TEST_CASE(type_dispatching)
108 {
109     my_dispatcher disp;
110     logging::attribute_value p1(attrs::make_attribute_value< int >(10));
111     logging::attribute_value p2(attrs::make_attribute_value< double > (5.5));
112     logging::attribute_value p3(attrs::make_attribute_value< std::string >(std::string("Hello, world!")));
113     logging::attribute_value p4(attrs::make_attribute_value< float >(static_cast< float >(-7.2)));
114
115     disp.set_expected(10);
116     BOOST_CHECK(p1.dispatch(disp));
117     BOOST_CHECK(p1.dispatch(disp)); // check that the contained value doesn't change over time or upon dispatching
118
119     disp.set_expected(5.5);
120     BOOST_CHECK(p2.dispatch(disp));
121
122     disp.set_expected("Hello, world!");
123     BOOST_CHECK(p3.dispatch(disp));
124
125     disp.set_expected();
126     BOOST_CHECK(!p4.dispatch(disp));
127 }
128
129 // The test verifies that value extraction works
130 BOOST_AUTO_TEST_CASE(value_extraction)
131 {
132     logging::attribute_value p1(attrs::make_attribute_value< int >(10));
133     logging::attribute_value p2(attrs::make_attribute_value< double >(5.5));
134
135     logging::value_ref< int > val1 = p1.extract< int >();
136     BOOST_CHECK(!!val1);
137     BOOST_CHECK_EQUAL(val1.get(), 10);
138
139     logging::value_ref< double > val2 = p1.extract< double >();
140     BOOST_CHECK(!val2);
141
142     double val3 = 0.0;
143     BOOST_CHECK(p2.visit< double >(logging::bind_assign(val3)));
144     BOOST_CHECK_CLOSE(val3, 5.5, 0.001);
145 }
146
147 // The test verifies that the detach_from_thread returns a valid pointer
148 BOOST_AUTO_TEST_CASE(detaching_from_thread)
149 {
150     boost::intrusive_ptr< logging::attribute_value::impl > p1(new attrs::attribute_value_impl< int >(10));
151     boost::intrusive_ptr< logging::attribute_value::impl > p2 = p1->detach_from_thread();
152     BOOST_CHECK(!!p2);
153 }