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)
8 * \file attr_attribute_value_set.cpp
9 * \author Andrey Semashev
12 * \brief This header contains tests for the attribute value set.
15 #define BOOST_TEST_MODULE attr_attribute_value_set
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"
32 namespace logging = boost::log;
33 namespace attrs = logging::attributes;
37 //! A simple attribute value receiver functional object
38 template< typename T >
41 typedef void result_type;
42 receiver(T& val) : m_Val(val) {}
43 result_type operator() (T const& val) const
52 //! The function extracts attribute value
53 template< typename T >
54 inline bool get_attr_value(logging::attribute_value const& val, T& res)
57 logging::static_type_dispatcher< T > disp(r);
58 return val.dispatch(disp);
63 // The test checks construction and assignment
64 BOOST_AUTO_TEST_CASE(construction)
66 typedef logging::attribute_set attr_set;
67 typedef logging::attribute_value_set attr_values;
68 typedef test_data< char > data;
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');
76 attr_set set1, set2, set3;
77 set1[data::attr1()] = attr1;
78 set1[data::attr2()] = attr2;
79 set1[data::attr3()] = attr3;
81 attr_values view1(set1, set2, set3);
84 BOOST_CHECK(!view1.empty());
85 BOOST_CHECK_EQUAL(view1.size(), 3UL);
88 attr_set set1, set2, set3;
89 set1[data::attr1()] = attr1;
90 set2[data::attr2()] = attr2;
91 set3[data::attr3()] = attr3;
93 attr_values view1(set1, set2, set3);
96 BOOST_CHECK(!view1.empty());
97 BOOST_CHECK_EQUAL(view1.size(), 3UL);
99 attr_values view2 = view1;
100 BOOST_CHECK(!view2.empty());
101 BOOST_CHECK_EQUAL(view2.size(), 3UL);
104 // Check that the more prioritized attributes replace the less ones
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);
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;
117 set2[data::attr2()] = attr2_2;
118 set2[data::attr4()] = attr4_2;
120 set1[data::attr3()] = attr3_3;
121 set1[data::attr4()] = attr4_3;
123 attr_values view1(set1, set2, set3);
126 BOOST_CHECK(!view1.empty());
127 BOOST_CHECK_EQUAL(view1.size(), 4UL);
130 BOOST_CHECK(logging::visit< int >(data::attr1(), view1, receiver< int >(n)));
131 BOOST_CHECK_EQUAL(n, 10);
133 BOOST_CHECK(logging::visit< int >(data::attr2(), view1, receiver< int >(n)));
134 BOOST_CHECK_EQUAL(n, 20);
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));
141 BOOST_CHECK(logging::visit< unsigned int >(data::attr4(), view1, receiver< unsigned int >(m)));
142 BOOST_CHECK_EQUAL(m, 5U);
146 // The test checks lookup methods
147 BOOST_AUTO_TEST_CASE(lookup)
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;
154 attrs::constant< int > attr1(10);
155 attrs::constant< double > attr2(5.5);
156 attrs::constant< std::string > attr3("Hello, world!");
158 attr_set set1, set2, set3;
159 set1[data::attr1()] = attr1;
160 set1[data::attr2()] = attr2;
161 set1[data::attr3()] = attr3;
163 attr_values view1(set1, set2, set3);
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());
171 BOOST_CHECK(get_attr_value(it->second, val1));
172 BOOST_CHECK_EQUAL(val1, 10);
174 string s1 = data::attr2();
176 BOOST_CHECK(it != view1.end());
177 BOOST_CHECK(it->first == data::attr2());
179 BOOST_CHECK(get_attr_value(it->second, val2));
180 BOOST_CHECK_CLOSE(val2, 5.5, 0.001);
182 it = view1.find(data::attr3());
183 BOOST_CHECK(it != view1.end());
184 BOOST_CHECK(it->first == data::attr3());
186 BOOST_CHECK(get_attr_value(it->second, val3));
187 BOOST_CHECK_EQUAL(val3, "Hello, world!");
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));
192 it = view1.find(data::attr4());
193 BOOST_CHECK(it == view1.end());
195 // Subscript operator
196 logging::attribute_value p = view1[data::attr1()];
197 BOOST_CHECK_EQUAL(view1.size(), 3UL);
199 BOOST_CHECK(get_attr_value(p, val1));
200 BOOST_CHECK_EQUAL(val1, 10);
203 BOOST_CHECK_EQUAL(view1.size(), 3UL);
205 BOOST_CHECK(get_attr_value(p, val2));
206 BOOST_CHECK_CLOSE(val2, 5.5, 0.001);
208 p = view1[data::attr3()];
209 BOOST_CHECK_EQUAL(view1.size(), 3UL);
211 BOOST_CHECK(get_attr_value(p, val3));
212 BOOST_CHECK_EQUAL(val3, "Hello, world!");
214 p = view1[data::attr4()];
216 BOOST_CHECK_EQUAL(view1.size(), 3UL);
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);
225 // The test checks size method
226 BOOST_AUTO_TEST_CASE(size)
228 typedef logging::attribute_value_set attr_values;
229 attrs::constant< int > attr1(10);
237 std::ostringstream strm;
240 view.insert(attr_values::key_type(strm.str()), attr1.get_value());
243 BOOST_CHECK_EQUAL(view.size(), i);