Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / log / test / run / attr_attribute_value_set.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_set.cpp
9  * \author Andrey Semashev
10  * \date   24.01.2009
11  *
12  * \brief  This header contains tests for the attribute value set.
13  */
14
15 #define BOOST_TEST_MODULE attr_attribute_value_set
16
17 #include <vector>
18 #include <string>
19 #include <sstream>
20 #include <utility>
21 #include <iterator>
22 #include <boost/config.hpp>
23 #include <boost/test/unit_test.hpp>
24 #include <boost/test/tools//floating_point_comparison.hpp>
25 #include <boost/log/attributes/constant.hpp>
26 #include <boost/log/attributes/attribute_set.hpp>
27 #include <boost/log/attributes/attribute_value_set.hpp>
28 #include <boost/log/attributes/value_visitation.hpp>
29 #include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp>
30 #include "char_definitions.hpp"
31
32 namespace logging = boost::log;
33 namespace attrs = logging::attributes;
34
35 namespace {
36
37     //! A simple attribute value receiver functional object
38     template< typename T >
39     struct receiver
40     {
41         typedef void result_type;
42         receiver(T& val) : m_Val(val) {}
43         result_type operator() (T const& val) const
44         {
45             m_Val = val;
46         }
47
48     private:
49         T& m_Val;
50     };
51
52     //! The function extracts attribute value
53     template< typename T >
54     inline bool get_attr_value(logging::attribute_value const& val, T& res)
55     {
56         receiver< T > r(res);
57         logging::static_type_dispatcher< T > disp(r);
58         return val.dispatch(disp);
59     }
60
61 } // namespace
62
63 // The test checks construction and assignment
64 BOOST_AUTO_TEST_CASE(construction)
65 {
66     typedef logging::attribute_set attr_set;
67     typedef logging::attribute_value_set attr_values;
68     typedef test_data< char > data;
69
70     attrs::constant< int > attr1(10);
71     attrs::constant< double > attr2(5.5);
72     attrs::constant< std::string > attr3("Hello, world!");
73     attrs::constant< char > attr4('L');
74
75     {
76         attr_set set1, set2, set3;
77         set1[data::attr1()] = attr1;
78         set1[data::attr2()] = attr2;
79         set1[data::attr3()] = attr3;
80
81         attr_values view1(set1, set2, set3);
82         view1.freeze();
83
84         BOOST_CHECK(!view1.empty());
85         BOOST_CHECK_EQUAL(view1.size(), 3UL);
86     }
87     {
88         attr_set set1, set2, set3;
89         set1[data::attr1()] = attr1;
90         set2[data::attr2()] = attr2;
91         set3[data::attr3()] = attr3;
92
93         attr_values view1(set1, set2, set3);
94         view1.freeze();
95
96         BOOST_CHECK(!view1.empty());
97         BOOST_CHECK_EQUAL(view1.size(), 3UL);
98
99         attr_values view2 = view1;
100         BOOST_CHECK(!view2.empty());
101         BOOST_CHECK_EQUAL(view2.size(), 3UL);
102     }
103
104     // Check that the more prioritized attributes replace the less ones
105     {
106         attrs::constant< int > attr2_2(20);
107         attrs::constant< double > attr4_2(10.3);
108         attrs::constant< float > attr3_3(static_cast< float >(-7.2));
109         attrs::constant< unsigned int > attr4_3(5);
110
111         attr_set set1, set2, set3;
112         set3[data::attr1()] = attr1;
113         set3[data::attr2()] = attr2;
114         set3[data::attr3()] = attr3;
115         set3[data::attr4()] = attr4;
116
117         set2[data::attr2()] = attr2_2;
118         set2[data::attr4()] = attr4_2;
119
120         set1[data::attr3()] = attr3_3;
121         set1[data::attr4()] = attr4_3;
122
123         attr_values view1(set1, set2, set3);
124         view1.freeze();
125
126         BOOST_CHECK(!view1.empty());
127         BOOST_CHECK_EQUAL(view1.size(), 4UL);
128
129         int n = 0;
130         BOOST_CHECK(logging::visit< int >(data::attr1(), view1, receiver< int >(n)));
131         BOOST_CHECK_EQUAL(n, 10);
132
133         BOOST_CHECK(logging::visit< int >(data::attr2(), view1, receiver< int >(n)));
134         BOOST_CHECK_EQUAL(n, 20);
135
136         float f = static_cast< float >(0.0);
137         BOOST_CHECK(logging::visit< float >(data::attr3(), view1, receiver< float >(f)));
138         BOOST_CHECK_CLOSE(f, static_cast< float >(-7.2), static_cast< float >(0.001));
139
140         unsigned int m = 0;
141         BOOST_CHECK(logging::visit< unsigned int >(data::attr4(), view1, receiver< unsigned int >(m)));
142         BOOST_CHECK_EQUAL(m, 5U);
143     }
144 }
145
146 // The test checks lookup methods
147 BOOST_AUTO_TEST_CASE(lookup)
148 {
149     typedef logging::attribute_set attr_set;
150     typedef logging::attribute_value_set attr_values;
151     typedef test_data< char > data;
152     typedef std::basic_string< char > string;
153
154     attrs::constant< int > attr1(10);
155     attrs::constant< double > attr2(5.5);
156     attrs::constant< std::string > attr3("Hello, world!");
157
158     attr_set set1, set2, set3;
159     set1[data::attr1()] = attr1;
160     set1[data::attr2()] = attr2;
161     set1[data::attr3()] = attr3;
162
163     attr_values view1(set1, set2, set3);
164     view1.freeze();
165
166     // Traditional find methods
167     attr_values::const_iterator it = view1.find(data::attr1());
168     BOOST_CHECK(it != view1.end());
169     BOOST_CHECK(it->first == data::attr1());
170     int val1 = 0;
171     BOOST_CHECK(get_attr_value(it->second, val1));
172     BOOST_CHECK_EQUAL(val1, 10);
173
174     string s1 = data::attr2();
175     it = view1.find(s1);
176     BOOST_CHECK(it != view1.end());
177     BOOST_CHECK(it->first == data::attr2());
178     double val2 = 0;
179     BOOST_CHECK(get_attr_value(it->second, val2));
180     BOOST_CHECK_CLOSE(val2, 5.5, 0.001);
181
182     it = view1.find(data::attr3());
183     BOOST_CHECK(it != view1.end());
184     BOOST_CHECK(it->first == data::attr3());
185     std::string val3;
186     BOOST_CHECK(get_attr_value(it->second, val3));
187     BOOST_CHECK_EQUAL(val3, "Hello, world!");
188
189     // make an additional check that the result is absent if the value type does not match the requested type
190     BOOST_CHECK(!get_attr_value(it->second, val2));
191
192     it = view1.find(data::attr4());
193     BOOST_CHECK(it == view1.end());
194
195     // Subscript operator
196     logging::attribute_value p = view1[data::attr1()];
197     BOOST_CHECK_EQUAL(view1.size(), 3UL);
198     BOOST_CHECK(!!p);
199     BOOST_CHECK(get_attr_value(p, val1));
200     BOOST_CHECK_EQUAL(val1, 10);
201
202     p = view1[s1];
203     BOOST_CHECK_EQUAL(view1.size(), 3UL);
204     BOOST_CHECK(!!p);
205     BOOST_CHECK(get_attr_value(p, val2));
206     BOOST_CHECK_CLOSE(val2, 5.5, 0.001);
207
208     p = view1[data::attr3()];
209     BOOST_CHECK_EQUAL(view1.size(), 3UL);
210     BOOST_CHECK(!!p);
211     BOOST_CHECK(get_attr_value(p, val3));
212     BOOST_CHECK_EQUAL(val3, "Hello, world!");
213
214     p = view1[data::attr4()];
215     BOOST_CHECK(!p);
216     BOOST_CHECK_EQUAL(view1.size(), 3UL);
217
218     // Counting elements
219     BOOST_CHECK_EQUAL(view1.count(data::attr1()), 1UL);
220     BOOST_CHECK_EQUAL(view1.count(s1), 1UL);
221     BOOST_CHECK_EQUAL(view1.count(data::attr3()), 1UL);
222     BOOST_CHECK_EQUAL(view1.count(data::attr4()), 0UL);
223 }
224
225 // The test checks size method
226 BOOST_AUTO_TEST_CASE(size)
227 {
228     typedef logging::attribute_value_set attr_values;
229     attrs::constant< int > attr1(10);
230
231     attr_values view;
232     view.freeze();
233
234     unsigned int i = 0;
235     for (; i < 100; ++i)
236     {
237         std::ostringstream strm;
238         strm << "Attr" << i;
239
240         view.insert(attr_values::key_type(strm.str()), attr1.get_value());
241     }
242
243     BOOST_CHECK_EQUAL(view.size(), i);
244 }