Chris@16
|
1 /*
|
Chris@101
|
2 * Copyright Andrey Semashev 2007 - 2015.
|
Chris@16
|
3 * Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
4 * (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
5 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 */
|
Chris@16
|
7 /*!
|
Chris@16
|
8 * \file formatter.hpp
|
Chris@16
|
9 * \author Andrey Semashev
|
Chris@16
|
10 * \date 13.07.2012
|
Chris@16
|
11 *
|
Chris@16
|
12 * The header contains a formatter function object definition.
|
Chris@16
|
13 */
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
|
Chris@16
|
16 #define BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
|
Chris@16
|
17
|
Chris@101
|
18 #include <boost/ref.hpp>
|
Chris@16
|
19 #include <boost/move/core.hpp>
|
Chris@16
|
20 #include <boost/move/utility.hpp>
|
Chris@101
|
21 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@16
|
22 #include <boost/utility/enable_if.hpp>
|
Chris@101
|
23 #include <boost/type_traits/is_same.hpp>
|
Chris@101
|
24 #include <boost/type_traits/remove_cv.hpp>
|
Chris@101
|
25 #endif
|
Chris@16
|
26 #include <boost/log/detail/config.hpp>
|
Chris@16
|
27 #include <boost/log/detail/light_function.hpp>
|
Chris@16
|
28 #include <boost/log/attributes/attribute_value_set.hpp>
|
Chris@16
|
29 #include <boost/log/attributes/value_visitation.hpp>
|
Chris@16
|
30 #include <boost/log/core/record_view.hpp>
|
Chris@16
|
31 #include <boost/log/utility/formatting_ostream.hpp>
|
Chris@16
|
32 #include <boost/log/utility/functional/bind_output.hpp>
|
Chris@16
|
33 #include <boost/log/expressions/message.hpp>
|
Chris@16
|
34 #include <boost/log/detail/header.hpp>
|
Chris@16
|
35
|
Chris@16
|
36 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@16
|
37 #pragma once
|
Chris@16
|
38 #endif
|
Chris@16
|
39
|
Chris@16
|
40 namespace boost {
|
Chris@16
|
41
|
Chris@16
|
42 BOOST_LOG_OPEN_NAMESPACE
|
Chris@16
|
43
|
Chris@101
|
44 namespace expressions {
|
Chris@101
|
45
|
Chris@101
|
46 namespace aux {
|
Chris@101
|
47
|
Chris@101
|
48 // This reference class is a workaround for a Boost.Phoenix bug: https://svn.boost.org/trac/boost/ticket/9363
|
Chris@101
|
49 // It is needed to pass output streams by non-const reference to function objects wrapped in phoenix::bind and phoenix::function.
|
Chris@101
|
50 // It's an implementation detail and will be removed when Boost.Phoenix is fixed.
|
Chris@101
|
51 template< typename StreamT >
|
Chris@101
|
52 class stream_ref :
|
Chris@101
|
53 public reference_wrapper< StreamT >
|
Chris@101
|
54 {
|
Chris@101
|
55 public:
|
Chris@101
|
56 BOOST_FORCEINLINE explicit stream_ref(StreamT& strm) : reference_wrapper< StreamT >(strm)
|
Chris@101
|
57 {
|
Chris@101
|
58 }
|
Chris@101
|
59
|
Chris@101
|
60 template< typename T >
|
Chris@101
|
61 BOOST_FORCEINLINE StreamT& operator<< (T& val) const
|
Chris@101
|
62 {
|
Chris@101
|
63 StreamT& strm = this->get();
|
Chris@101
|
64 strm << val;
|
Chris@101
|
65 return strm;
|
Chris@101
|
66 }
|
Chris@101
|
67
|
Chris@101
|
68 template< typename T >
|
Chris@101
|
69 BOOST_FORCEINLINE StreamT& operator<< (T const& val) const
|
Chris@101
|
70 {
|
Chris@101
|
71 StreamT& strm = this->get();
|
Chris@101
|
72 strm << val;
|
Chris@101
|
73 return strm;
|
Chris@101
|
74 }
|
Chris@101
|
75 };
|
Chris@101
|
76
|
Chris@101
|
77 //! Default log record message formatter
|
Chris@101
|
78 struct message_formatter
|
Chris@101
|
79 {
|
Chris@101
|
80 typedef void result_type;
|
Chris@101
|
81
|
Chris@101
|
82 message_formatter() : m_MessageName(expressions::tag::message::get_name())
|
Chris@101
|
83 {
|
Chris@101
|
84 }
|
Chris@101
|
85
|
Chris@101
|
86 template< typename StreamT >
|
Chris@101
|
87 result_type operator() (record_view const& rec, StreamT& strm) const
|
Chris@101
|
88 {
|
Chris@101
|
89 boost::log::visit< expressions::tag::message::value_type >(m_MessageName, rec, boost::log::bind_output(strm));
|
Chris@101
|
90 }
|
Chris@101
|
91
|
Chris@101
|
92 private:
|
Chris@101
|
93 const attribute_name m_MessageName;
|
Chris@101
|
94 };
|
Chris@101
|
95
|
Chris@101
|
96 } // namespace aux
|
Chris@101
|
97
|
Chris@101
|
98 } // namespace expressions
|
Chris@101
|
99
|
Chris@16
|
100 /*!
|
Chris@16
|
101 * Log record formatter function wrapper.
|
Chris@16
|
102 */
|
Chris@16
|
103 template< typename CharT >
|
Chris@16
|
104 class basic_formatter
|
Chris@16
|
105 {
|
Chris@16
|
106 typedef basic_formatter this_type;
|
Chris@16
|
107 BOOST_COPYABLE_AND_MOVABLE(this_type)
|
Chris@16
|
108
|
Chris@16
|
109 public:
|
Chris@16
|
110 //! Result type
|
Chris@16
|
111 typedef void result_type;
|
Chris@16
|
112
|
Chris@16
|
113 //! Character type
|
Chris@16
|
114 typedef CharT char_type;
|
Chris@16
|
115 //! Output stream type
|
Chris@16
|
116 typedef basic_formatting_ostream< char_type > stream_type;
|
Chris@16
|
117
|
Chris@16
|
118 private:
|
Chris@16
|
119 //! Filter function type
|
Chris@101
|
120 typedef boost::log::aux::light_function< void (record_view const&, expressions::aux::stream_ref< stream_type >) > formatter_type;
|
Chris@16
|
121
|
Chris@16
|
122 private:
|
Chris@16
|
123 //! Formatter function
|
Chris@16
|
124 formatter_type m_Formatter;
|
Chris@16
|
125
|
Chris@16
|
126 public:
|
Chris@16
|
127 /*!
|
Chris@16
|
128 * Default constructor. Creates a formatter that only outputs log message.
|
Chris@16
|
129 */
|
Chris@101
|
130 basic_formatter() : m_Formatter(expressions::aux::message_formatter())
|
Chris@16
|
131 {
|
Chris@16
|
132 }
|
Chris@16
|
133 /*!
|
Chris@16
|
134 * Copy constructor
|
Chris@16
|
135 */
|
Chris@16
|
136 basic_formatter(basic_formatter const& that) : m_Formatter(that.m_Formatter)
|
Chris@16
|
137 {
|
Chris@16
|
138 }
|
Chris@16
|
139 /*!
|
Chris@16
|
140 * Move constructor. The moved-from formatter is left in an unspecified state.
|
Chris@16
|
141 */
|
Chris@16
|
142 basic_formatter(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_Formatter(boost::move(that.m_Formatter))
|
Chris@16
|
143 {
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 /*!
|
Chris@16
|
147 * Initializing constructor. Creates a formatter which will invoke the specified function object.
|
Chris@16
|
148 */
|
Chris@16
|
149 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@16
|
150 template< typename FunT >
|
Chris@101
|
151 basic_formatter(FunT&& fun) : m_Formatter(boost::forward< FunT >(fun))
|
Chris@16
|
152 {
|
Chris@16
|
153 }
|
Chris@101
|
154 #elif !defined(BOOST_MSVC) || BOOST_MSVC > 1400
|
Chris@101
|
155 template< typename FunT >
|
Chris@101
|
156 basic_formatter(FunT const& fun, typename disable_if_c< move_detail::is_rv< FunT >::value, int >::type = 0) : m_Formatter(fun)
|
Chris@101
|
157 {
|
Chris@101
|
158 }
|
Chris@101
|
159 #else
|
Chris@101
|
160 // MSVC 8 blows up in unexpected ways if we use SFINAE to disable constructor instantiation
|
Chris@101
|
161 template< typename FunT >
|
Chris@101
|
162 basic_formatter(FunT const& fun) : m_Formatter(fun)
|
Chris@101
|
163 {
|
Chris@101
|
164 }
|
Chris@101
|
165 template< typename FunT >
|
Chris@101
|
166 basic_formatter(rv< FunT >& fun) : m_Formatter(fun)
|
Chris@101
|
167 {
|
Chris@101
|
168 }
|
Chris@101
|
169 template< typename FunT >
|
Chris@101
|
170 basic_formatter(rv< FunT > const& fun) : m_Formatter(static_cast< FunT const& >(fun))
|
Chris@101
|
171 {
|
Chris@101
|
172 }
|
Chris@101
|
173 basic_formatter(rv< this_type > const& that) : m_Formatter(that.m_Formatter)
|
Chris@101
|
174 {
|
Chris@101
|
175 }
|
Chris@101
|
176 #endif
|
Chris@16
|
177
|
Chris@16
|
178 /*!
|
Chris@16
|
179 * Move assignment. The moved-from formatter is left in an unspecified state.
|
Chris@16
|
180 */
|
Chris@16
|
181 basic_formatter& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
Chris@16
|
182 {
|
Chris@16
|
183 m_Formatter.swap(that.m_Formatter);
|
Chris@16
|
184 return *this;
|
Chris@16
|
185 }
|
Chris@16
|
186 /*!
|
Chris@16
|
187 * Copy assignment.
|
Chris@16
|
188 */
|
Chris@16
|
189 basic_formatter& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
|
Chris@16
|
190 {
|
Chris@16
|
191 m_Formatter = that.m_Formatter;
|
Chris@16
|
192 return *this;
|
Chris@16
|
193 }
|
Chris@16
|
194 /*!
|
Chris@16
|
195 * Initializing assignment. Sets the specified function object to the formatter.
|
Chris@16
|
196 */
|
Chris@16
|
197 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
Chris@16
|
198 template< typename FunT >
|
Chris@101
|
199 basic_formatter& operator= (FunT&& fun)
|
Chris@101
|
200 {
|
Chris@101
|
201 this_type(boost::forward< FunT >(fun)).swap(*this);
|
Chris@101
|
202 return *this;
|
Chris@101
|
203 }
|
Chris@16
|
204 #else
|
Chris@16
|
205 template< typename FunT >
|
Chris@16
|
206 typename disable_if< is_same< typename remove_cv< FunT >::type, this_type >, this_type& >::type
|
Chris@16
|
207 operator= (FunT const& fun)
|
Chris@16
|
208 {
|
Chris@16
|
209 this_type(fun).swap(*this);
|
Chris@16
|
210 return *this;
|
Chris@16
|
211 }
|
Chris@101
|
212 #endif
|
Chris@16
|
213
|
Chris@16
|
214 /*!
|
Chris@16
|
215 * Formatting operator.
|
Chris@16
|
216 *
|
Chris@16
|
217 * \param rec A log record to format.
|
Chris@16
|
218 * \param strm A stream to put the formatted characters to.
|
Chris@16
|
219 */
|
Chris@16
|
220 result_type operator() (record_view const& rec, stream_type& strm) const
|
Chris@16
|
221 {
|
Chris@101
|
222 m_Formatter(rec, expressions::aux::stream_ref< stream_type >(strm));
|
Chris@16
|
223 }
|
Chris@16
|
224
|
Chris@16
|
225 /*!
|
Chris@16
|
226 * Resets the formatter to the default. The default formatter only outputs message text.
|
Chris@16
|
227 */
|
Chris@16
|
228 void reset()
|
Chris@16
|
229 {
|
Chris@101
|
230 m_Formatter = expressions::aux::message_formatter();
|
Chris@16
|
231 }
|
Chris@16
|
232
|
Chris@16
|
233 /*!
|
Chris@16
|
234 * Swaps two formatters
|
Chris@16
|
235 */
|
Chris@16
|
236 void swap(basic_formatter& that) BOOST_NOEXCEPT
|
Chris@16
|
237 {
|
Chris@16
|
238 m_Formatter.swap(that.m_Formatter);
|
Chris@16
|
239 }
|
Chris@16
|
240 };
|
Chris@16
|
241
|
Chris@16
|
242 template< typename CharT >
|
Chris@16
|
243 inline void swap(basic_formatter< CharT >& left, basic_formatter< CharT >& right) BOOST_NOEXCEPT
|
Chris@16
|
244 {
|
Chris@16
|
245 left.swap(right);
|
Chris@16
|
246 }
|
Chris@16
|
247
|
Chris@16
|
248 #ifdef BOOST_LOG_USE_CHAR
|
Chris@16
|
249 typedef basic_formatter< char > formatter;
|
Chris@16
|
250 #endif
|
Chris@16
|
251 #ifdef BOOST_LOG_USE_WCHAR_T
|
Chris@16
|
252 typedef basic_formatter< wchar_t > wformatter;
|
Chris@16
|
253 #endif
|
Chris@16
|
254
|
Chris@16
|
255 BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
Chris@16
|
256
|
Chris@16
|
257 } // namespace boost
|
Chris@16
|
258
|
Chris@16
|
259 #include <boost/log/detail/footer.hpp>
|
Chris@16
|
260
|
Chris@16
|
261 #endif // BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
|