]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/log/test/run/util_manip_add_value.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / log / test / run / util_manip_add_value.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_manip_add_value.cpp
9 * \author Andrey Semashev
10 * \date 07.11.2013
11 *
12 * \brief This header contains tests for the \c add_value manipulator.
13 */
14
15 #define BOOST_TEST_MODULE util_manip_add_value
16
17 #include <iomanip>
18 #include <iostream>
19 #include <boost/move/core.hpp>
20 #include <boost/io/ios_state.hpp>
21 #include <boost/test/unit_test.hpp>
22 #include <boost/log/core.hpp>
23 #include <boost/log/sources/record_ostream.hpp>
24 #include <boost/log/attributes/attribute_set.hpp>
25 #include <boost/log/attributes/value_extraction.hpp>
26 #include <boost/log/expressions/keyword.hpp>
27 #include <boost/log/utility/manipulators/add_value.hpp>
28 #include "make_record.hpp"
29
30 namespace logging = boost::log;
31
32 struct my_type
33 {
34 BOOST_COPYABLE_AND_MOVABLE(my_type)
35
36 public:
37 unsigned int value;
38
39 explicit my_type(unsigned int n = 0) : value(n) {}
40 my_type(my_type const& that) : value(that.value) {}
41 my_type(BOOST_RV_REF(my_type) that) : value(that.value) { that.value = 0xbaadbaad; }
42 ~my_type() { value = 0xdeaddead; }
43
44 my_type& operator= (BOOST_COPY_ASSIGN_REF(my_type) that) { value = that.value; return *this; }
45 my_type& operator= (BOOST_RV_REF(my_type) that) { value = that.value; that.value = 0xbaadbaad; return *this; }
46 };
47
48 inline bool operator== (my_type const& left, my_type const& right)
49 {
50 return left.value == right.value;
51 }
52
53 inline bool operator!= (my_type const& left, my_type const& right)
54 {
55 return left.value != right.value;
56 }
57
58 template< typename CharT, typename TraitsT >
59 inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, my_type const& val)
60 {
61 if (strm.good())
62 {
63 boost::io::ios_flags_saver flags(strm);
64 boost::io::basic_ios_fill_saver< CharT, TraitsT > fill(strm);
65 strm << std::hex << std::internal << std::setfill(static_cast< CharT >('0')) << std::setw(10) << val.value;
66 }
67 return strm;
68 }
69
70 struct my_pod_type
71 {
72 unsigned int value;
73 };
74
75 inline bool operator== (my_pod_type const& left, my_pod_type const& right)
76 {
77 return left.value == right.value;
78 }
79
80 inline bool operator!= (my_pod_type const& left, my_pod_type const& right)
81 {
82 return left.value != right.value;
83 }
84
85 template< typename CharT, typename TraitsT >
86 inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, my_pod_type const& val)
87 {
88 if (strm.good())
89 {
90 boost::io::ios_flags_saver flags(strm);
91 boost::io::basic_ios_fill_saver< CharT, TraitsT > fill(strm);
92 strm << std::hex << std::internal << std::setfill(static_cast< CharT >('0')) << std::setw(10) << val.value;
93 }
94 return strm;
95 }
96
97 BOOST_AUTO_TEST_CASE(manual_add_attr)
98 {
99 logging::record rec = make_record(logging::attribute_set());
100 BOOST_REQUIRE(!!rec);
101 logging::record_ostream strm(rec);
102
103 my_type val(0xaaaaaaaa);
104 const my_type const_val(0xbbbbbbbb);
105 strm << logging::add_value("MyAttr1", val) << logging::add_value("MyAttr2", const_val) << logging::add_value("MyAttr3", my_type(0xcccccccc));
106
107 // Test for MSVC bug: if the value is a scalar type, it saves a dangling reference to the add_value_manip,
108 // which results in garbage in the attribute value
109 strm << logging::add_value("MyAttr4", 100u);
110 strm << logging::add_value("MyAttr5", my_pod_type());
111
112 strm.detach_from_record();
113
114 BOOST_CHECK_EQUAL(rec["MyAttr1"].extract< my_type >(), val);
115 BOOST_CHECK_EQUAL(rec["MyAttr2"].extract< my_type >(), const_val);
116 BOOST_CHECK_EQUAL(rec["MyAttr3"].extract< my_type >(), my_type(0xcccccccc));
117 BOOST_CHECK_EQUAL(rec["MyAttr4"].extract< unsigned int >(), 100u);
118 BOOST_CHECK_EQUAL(rec["MyAttr5"].extract< my_pod_type >(), my_pod_type());
119 }
120
121 BOOST_LOG_ATTRIBUTE_KEYWORD(a_my1, "MyAttr1", my_type)
122 BOOST_LOG_ATTRIBUTE_KEYWORD(a_my2, "MyAttr2", my_type)
123 BOOST_LOG_ATTRIBUTE_KEYWORD(a_my3, "MyAttr3", my_type)
124
125 BOOST_AUTO_TEST_CASE(keyword_add_attr)
126 {
127 logging::record rec = make_record(logging::attribute_set());
128 BOOST_REQUIRE(!!rec);
129 logging::record_ostream strm(rec);
130
131 my_type val(0xaaaaaaaa);
132 const my_type const_val(0xbbbbbbbb);
133 strm << logging::add_value(a_my1, val) << logging::add_value(a_my2, const_val) << logging::add_value(a_my3, my_type(0xcccccccc));
134 strm.detach_from_record();
135
136 BOOST_CHECK_EQUAL(rec[a_my1], val);
137 BOOST_CHECK_EQUAL(rec[a_my2], const_val);
138 BOOST_CHECK_EQUAL(rec[a_my3], my_type(0xcccccccc));
139 }