]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/log/expressions/formatter.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / log / expressions / formatter.hpp
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 formatter.hpp
9 * \author Andrey Semashev
10 * \date 13.07.2012
11 *
12 * The header contains a formatter function object definition.
13 */
14
15 #ifndef BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
16 #define BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
17
18 #include <locale>
19 #include <ostream>
20 #include <boost/ref.hpp>
21 #include <boost/move/core.hpp>
22 #include <boost/move/utility_core.hpp>
23 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
24 #include <boost/type_traits/is_same.hpp>
25 #include <boost/type_traits/remove_cv.hpp>
26 #include <boost/log/detail/sfinae_tools.hpp>
27 #endif
28 #include <boost/log/detail/config.hpp>
29 #include <boost/log/detail/light_function.hpp>
30 #include <boost/log/attributes/attribute_value_set.hpp>
31 #include <boost/log/attributes/value_visitation.hpp>
32 #include <boost/log/core/record_view.hpp>
33 #include <boost/log/utility/formatting_ostream.hpp>
34 #include <boost/log/utility/functional/bind_output.hpp>
35 #include <boost/log/expressions/message.hpp>
36 #include <boost/log/detail/header.hpp>
37
38 #ifdef BOOST_HAS_PRAGMA_ONCE
39 #pragma once
40 #endif
41
42 namespace boost {
43
44 BOOST_LOG_OPEN_NAMESPACE
45
46 namespace expressions {
47
48 namespace aux {
49
50 // This reference class is a workaround for a Boost.Phoenix bug: https://svn.boost.org/trac/boost/ticket/9363
51 // It is needed to pass output streams by non-const reference to function objects wrapped in phoenix::bind and phoenix::function.
52 // It's an implementation detail and will be removed when Boost.Phoenix is fixed.
53 template< typename StreamT >
54 class stream_ref :
55 public reference_wrapper< StreamT >
56 {
57 public:
58 typedef typename StreamT::char_type char_type;
59 typedef typename StreamT::traits_type traits_type;
60 typedef typename StreamT::allocator_type allocator_type;
61 typedef typename StreamT::streambuf_type streambuf_type;
62 typedef typename StreamT::string_type string_type;
63 typedef typename StreamT::ostream_type ostream_type;
64 typedef typename StreamT::pos_type pos_type;
65 typedef typename StreamT::off_type off_type;
66 typedef typename StreamT::int_type int_type;
67
68 typedef typename StreamT::failure failure;
69 typedef typename StreamT::fmtflags fmtflags;
70 typedef typename StreamT::iostate iostate;
71 typedef typename StreamT::openmode openmode;
72 typedef typename StreamT::seekdir seekdir;
73 typedef typename StreamT::Init Init;
74
75 typedef typename StreamT::event event;
76 typedef typename StreamT::event_callback event_callback;
77
78 typedef typename StreamT::sentry sentry;
79
80 static BOOST_CONSTEXPR_OR_CONST fmtflags boolalpha = StreamT::boolalpha;
81 static BOOST_CONSTEXPR_OR_CONST fmtflags dec = StreamT::dec;
82 static BOOST_CONSTEXPR_OR_CONST fmtflags fixed = StreamT::fixed;
83 static BOOST_CONSTEXPR_OR_CONST fmtflags hex = StreamT::hex;
84 static BOOST_CONSTEXPR_OR_CONST fmtflags internal = StreamT::internal;
85 static BOOST_CONSTEXPR_OR_CONST fmtflags left = StreamT::left;
86 static BOOST_CONSTEXPR_OR_CONST fmtflags oct = StreamT::oct;
87 static BOOST_CONSTEXPR_OR_CONST fmtflags right = StreamT::right;
88 static BOOST_CONSTEXPR_OR_CONST fmtflags scientific = StreamT::scientific;
89 static BOOST_CONSTEXPR_OR_CONST fmtflags showbase = StreamT::showbase;
90 static BOOST_CONSTEXPR_OR_CONST fmtflags showpoint = StreamT::showpoint;
91 static BOOST_CONSTEXPR_OR_CONST fmtflags skipws = StreamT::skipws;
92 static BOOST_CONSTEXPR_OR_CONST fmtflags unitbuf = StreamT::unitbuf;
93 static BOOST_CONSTEXPR_OR_CONST fmtflags uppercase = StreamT::uppercase;
94 static BOOST_CONSTEXPR_OR_CONST fmtflags adjustfield = StreamT::adjustfield;
95 static BOOST_CONSTEXPR_OR_CONST fmtflags basefield = StreamT::basefield;
96 static BOOST_CONSTEXPR_OR_CONST fmtflags floatfield = StreamT::floatfield;
97
98 static BOOST_CONSTEXPR_OR_CONST iostate badbit = StreamT::badbit;
99 static BOOST_CONSTEXPR_OR_CONST iostate eofbit = StreamT::eofbit;
100 static BOOST_CONSTEXPR_OR_CONST iostate failbit = StreamT::failbit;
101 static BOOST_CONSTEXPR_OR_CONST iostate goodbit = StreamT::goodbit;
102
103 static BOOST_CONSTEXPR_OR_CONST openmode app = StreamT::app;
104 static BOOST_CONSTEXPR_OR_CONST openmode ate = StreamT::ate;
105 static BOOST_CONSTEXPR_OR_CONST openmode binary = StreamT::binary;
106 static BOOST_CONSTEXPR_OR_CONST openmode in = StreamT::in;
107 static BOOST_CONSTEXPR_OR_CONST openmode out = StreamT::out;
108 static BOOST_CONSTEXPR_OR_CONST openmode trunc = StreamT::trunc;
109
110 static BOOST_CONSTEXPR_OR_CONST seekdir beg = StreamT::beg;
111 static BOOST_CONSTEXPR_OR_CONST seekdir cur = StreamT::cur;
112 static BOOST_CONSTEXPR_OR_CONST seekdir end = StreamT::end;
113
114 static BOOST_CONSTEXPR_OR_CONST event erase_event = StreamT::erase_event;
115 static BOOST_CONSTEXPR_OR_CONST event imbue_event = StreamT::imbue_event;
116 static BOOST_CONSTEXPR_OR_CONST event copyfmt_event = StreamT::copyfmt_event;
117
118
119 BOOST_FORCEINLINE explicit stream_ref(StreamT& strm) : reference_wrapper< StreamT >(strm)
120 {
121 }
122
123 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
124 template< typename T >
125 BOOST_FORCEINLINE StreamT& operator<< (T&& val) const
126 {
127 StreamT& strm = this->get();
128 strm << static_cast< T&& >(val);
129 return strm;
130 }
131 #if defined(BOOST_MSVC) && BOOST_MSVC < 1800
132 // MSVC 10 and 11 generate broken code for the perfect forwarding version above if T is an array type (e.g. a string literal)
133 template< typename T, unsigned int N >
134 BOOST_FORCEINLINE StreamT& operator<< (T (&val)[N]) const
135 {
136 StreamT& strm = this->get();
137 strm << val;
138 return strm;
139 }
140 #endif
141 #else
142 template< typename T >
143 BOOST_FORCEINLINE StreamT& operator<< (T& val) const
144 {
145 StreamT& strm = this->get();
146 strm << val;
147 return strm;
148 }
149
150 template< typename T >
151 BOOST_FORCEINLINE StreamT& operator<< (T const& val) const
152 {
153 StreamT& strm = this->get();
154 strm << val;
155 return strm;
156 }
157 #endif
158
159 BOOST_FORCEINLINE void attach(string_type& str) const { this->get().attach(str); }
160 BOOST_FORCEINLINE void detach() const { this->get().detach(); }
161 BOOST_FORCEINLINE string_type const& str() const { return this->get().str(); }
162 BOOST_FORCEINLINE ostream_type& stream() const { return this->get().stream(); }
163 BOOST_FORCEINLINE fmtflags flags() const { return this->get().flags(); }
164 BOOST_FORCEINLINE fmtflags flags(fmtflags f) const { return this->get().flags(f); }
165 BOOST_FORCEINLINE fmtflags setf(fmtflags f) const { return this->get().setf(f); }
166 BOOST_FORCEINLINE fmtflags setf(fmtflags f, fmtflags mask) const { return this->get().setf(f, mask); }
167 BOOST_FORCEINLINE void unsetf(fmtflags f) const { this->get().unsetf(f); }
168
169 BOOST_FORCEINLINE std::streamsize precision() const { return this->get().precision(); }
170 BOOST_FORCEINLINE std::streamsize precision(std::streamsize p) const { return this->get().precision(p); }
171
172 BOOST_FORCEINLINE std::streamsize width() const { return this->get().width(); }
173 BOOST_FORCEINLINE std::streamsize width(std::streamsize w) const { return this->get().width(w); }
174
175 BOOST_FORCEINLINE std::locale getloc() const { return this->get().getloc(); }
176 BOOST_FORCEINLINE std::locale imbue(std::locale const& loc) const { return this->get().imbue(loc); }
177
178 static BOOST_FORCEINLINE int xalloc() { return StreamT::xalloc(); }
179 BOOST_FORCEINLINE long& iword(int index) const { return this->get().iword(index); }
180 BOOST_FORCEINLINE void*& pword(int index) const { return this->get().pword(index); }
181
182 BOOST_FORCEINLINE void register_callback(event_callback fn, int index) const { this->get().register_callback(fn, index); }
183
184 static BOOST_FORCEINLINE bool sync_with_stdio(bool sync = true) { return StreamT::sync_with_stdio(sync); }
185
186 BOOST_EXPLICIT_OPERATOR_BOOL()
187 BOOST_FORCEINLINE bool operator! () const { return !this->get(); }
188
189 BOOST_FORCEINLINE iostate rdstate() const { return this->get().rdstate(); }
190 BOOST_FORCEINLINE void clear(iostate state = goodbit) const { this->get().clear(state); }
191 BOOST_FORCEINLINE void setstate(iostate state) const { this->get().setstate(state); }
192 BOOST_FORCEINLINE bool good() const { return this->get().good(); }
193 BOOST_FORCEINLINE bool eof() const { return this->get().eof(); }
194 BOOST_FORCEINLINE bool fail() const { return this->get().fail(); }
195 BOOST_FORCEINLINE bool bad() const { return this->get().bad(); }
196
197 BOOST_FORCEINLINE iostate exceptions() const { return this->get().exceptions(); }
198 BOOST_FORCEINLINE void exceptions(iostate s) const { this->get().exceptions(s); }
199
200 BOOST_FORCEINLINE ostream_type* tie() const { return this->get().tie(); }
201 BOOST_FORCEINLINE ostream_type* tie(ostream_type* strm) const { return this->get().tie(strm); }
202
203 BOOST_FORCEINLINE streambuf_type* rdbuf() const { return this->get().rdbuf(); }
204
205 BOOST_FORCEINLINE StreamT& copyfmt(std::basic_ios< char_type, traits_type >& rhs) const { return this->get().copyfmt(rhs); }
206 BOOST_FORCEINLINE StreamT& copyfmt(StreamT& rhs) const { return this->get().copyfmt(rhs); }
207
208 BOOST_FORCEINLINE char_type fill() const { return this->get().fill(); }
209 BOOST_FORCEINLINE char_type fill(char_type ch) const { return this->get().fill(ch); }
210
211 BOOST_FORCEINLINE char narrow(char_type ch, char def) const { return this->get().narrow(ch, def); }
212 BOOST_FORCEINLINE char_type widen(char ch) const { return this->get().widen(ch); }
213
214 BOOST_FORCEINLINE StreamT& flush() const { return this->get().flush(); }
215
216 BOOST_FORCEINLINE pos_type tellp() const { return this->get().tellp(); }
217 BOOST_FORCEINLINE StreamT& seekp(pos_type pos) const { return this->get().seekp(pos); }
218 BOOST_FORCEINLINE StreamT& seekp(off_type off, std::ios_base::seekdir dir) const { return this->get().seekp(off, dir); }
219
220 template< typename CharT >
221 BOOST_FORCEINLINE typename boost::log::aux::enable_if_streamable_char_type< CharT, StreamT& >::type
222 put(CharT c) const { return this->get().put(c); }
223
224 template< typename CharT >
225 BOOST_FORCEINLINE typename boost::log::aux::enable_if_streamable_char_type< CharT, StreamT& >::type
226 write(const CharT* p, std::streamsize size) const { return this->get().write(p, size); }
227 };
228
229 template< typename StreamT >
230 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::boolalpha;
231 template< typename StreamT >
232 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::dec;
233 template< typename StreamT >
234 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::fixed;
235 template< typename StreamT >
236 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::hex;
237 template< typename StreamT >
238 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::internal;
239 template< typename StreamT >
240 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::left;
241 template< typename StreamT >
242 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::oct;
243 template< typename StreamT >
244 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::right;
245 template< typename StreamT >
246 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::scientific;
247 template< typename StreamT >
248 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::showbase;
249 template< typename StreamT >
250 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::showpoint;
251 template< typename StreamT >
252 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::skipws;
253 template< typename StreamT >
254 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::unitbuf;
255 template< typename StreamT >
256 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::uppercase;
257 template< typename StreamT >
258 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::adjustfield;
259 template< typename StreamT >
260 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::basefield;
261 template< typename StreamT >
262 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::floatfield;
263
264 template< typename StreamT >
265 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::iostate stream_ref< StreamT >::badbit;
266 template< typename StreamT >
267 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::iostate stream_ref< StreamT >::eofbit;
268 template< typename StreamT >
269 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::iostate stream_ref< StreamT >::failbit;
270 template< typename StreamT >
271 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::iostate stream_ref< StreamT >::goodbit;
272
273 template< typename StreamT >
274 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::app;
275 template< typename StreamT >
276 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::ate;
277 template< typename StreamT >
278 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::binary;
279 template< typename StreamT >
280 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::in;
281 template< typename StreamT >
282 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::out;
283 template< typename StreamT >
284 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::trunc;
285
286 template< typename StreamT >
287 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::seekdir stream_ref< StreamT >::beg;
288 template< typename StreamT >
289 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::seekdir stream_ref< StreamT >::cur;
290 template< typename StreamT >
291 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::seekdir stream_ref< StreamT >::end;
292
293 template< typename StreamT >
294 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::event stream_ref< StreamT >::erase_event;
295 template< typename StreamT >
296 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::event stream_ref< StreamT >::imbue_event;
297 template< typename StreamT >
298 BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::event stream_ref< StreamT >::copyfmt_event;
299
300 //! Default log record message formatter
301 struct message_formatter
302 {
303 typedef void result_type;
304
305 message_formatter() : m_MessageName(expressions::tag::message::get_name())
306 {
307 }
308
309 template< typename StreamT >
310 BOOST_FORCEINLINE result_type operator() (record_view const& rec, StreamT& strm) const
311 {
312 boost::log::visit< expressions::tag::message::value_type >(m_MessageName, rec, boost::log::bind_output(strm));
313 }
314
315 private:
316 const attribute_name m_MessageName;
317 };
318
319 } // namespace aux
320
321 } // namespace expressions
322
323 /*!
324 * Log record formatter function wrapper.
325 */
326 template< typename CharT >
327 class basic_formatter
328 {
329 typedef basic_formatter this_type;
330 BOOST_COPYABLE_AND_MOVABLE(this_type)
331
332 public:
333 //! Result type
334 typedef void result_type;
335
336 //! Character type
337 typedef CharT char_type;
338 //! Output stream type
339 typedef basic_formatting_ostream< char_type > stream_type;
340
341 private:
342 //! Filter function type
343 typedef boost::log::aux::light_function< void (record_view const&, expressions::aux::stream_ref< stream_type >) > formatter_type;
344
345 private:
346 //! Formatter function
347 formatter_type m_Formatter;
348
349 public:
350 /*!
351 * Default constructor. Creates a formatter that only outputs log message.
352 */
353 basic_formatter() : m_Formatter(expressions::aux::message_formatter())
354 {
355 }
356 /*!
357 * Copy constructor
358 */
359 basic_formatter(basic_formatter const& that) : m_Formatter(that.m_Formatter)
360 {
361 }
362 /*!
363 * Move constructor. The moved-from formatter is left in an unspecified state.
364 */
365 basic_formatter(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_Formatter(boost::move(that.m_Formatter))
366 {
367 }
368
369 /*!
370 * Initializing constructor. Creates a formatter which will invoke the specified function object.
371 */
372 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
373 template< typename FunT >
374 basic_formatter(FunT&& fun) : m_Formatter(boost::forward< FunT >(fun))
375 {
376 }
377 #elif !defined(BOOST_MSVC) || BOOST_MSVC >= 1600
378 template< typename FunT >
379 basic_formatter(FunT const& fun, typename boost::disable_if_c< move_detail::is_rv< FunT >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) : m_Formatter(fun)
380 {
381 }
382 #else
383 // MSVC 9 and older blows up in unexpected ways if we use SFINAE to disable constructor instantiation
384 template< typename FunT >
385 basic_formatter(FunT const& fun) : m_Formatter(fun)
386 {
387 }
388 template< typename FunT >
389 basic_formatter(rv< FunT >& fun) : m_Formatter(fun)
390 {
391 }
392 template< typename FunT >
393 basic_formatter(rv< FunT > const& fun) : m_Formatter(static_cast< FunT const& >(fun))
394 {
395 }
396 basic_formatter(rv< this_type > const& that) : m_Formatter(that.m_Formatter)
397 {
398 }
399 #endif
400
401 /*!
402 * Move assignment. The moved-from formatter is left in an unspecified state.
403 */
404 basic_formatter& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
405 {
406 m_Formatter.swap(that.m_Formatter);
407 return *this;
408 }
409 /*!
410 * Copy assignment.
411 */
412 basic_formatter& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
413 {
414 m_Formatter = that.m_Formatter;
415 return *this;
416 }
417 /*!
418 * Initializing assignment. Sets the specified function object to the formatter.
419 */
420 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
421 template< typename FunT >
422 basic_formatter& operator= (FunT&& fun)
423 {
424 this_type(boost::forward< FunT >(fun)).swap(*this);
425 return *this;
426 }
427 #else
428 template< typename FunT >
429 typename boost::disable_if_c< is_same< typename remove_cv< FunT >::type, this_type >::value, this_type& >::type
430 operator= (FunT const& fun)
431 {
432 this_type(fun).swap(*this);
433 return *this;
434 }
435 #endif
436
437 /*!
438 * Formatting operator.
439 *
440 * \param rec A log record to format.
441 * \param strm A stream to put the formatted characters to.
442 */
443 result_type operator() (record_view const& rec, stream_type& strm) const
444 {
445 m_Formatter(rec, expressions::aux::stream_ref< stream_type >(strm));
446 }
447
448 /*!
449 * Resets the formatter to the default. The default formatter only outputs message text.
450 */
451 void reset()
452 {
453 m_Formatter = expressions::aux::message_formatter();
454 }
455
456 /*!
457 * Swaps two formatters
458 */
459 void swap(basic_formatter& that) BOOST_NOEXCEPT
460 {
461 m_Formatter.swap(that.m_Formatter);
462 }
463 };
464
465 template< typename CharT >
466 inline void swap(basic_formatter< CharT >& left, basic_formatter< CharT >& right) BOOST_NOEXCEPT
467 {
468 left.swap(right);
469 }
470
471 #ifdef BOOST_LOG_USE_CHAR
472 typedef basic_formatter< char > formatter;
473 #endif
474 #ifdef BOOST_LOG_USE_WCHAR_T
475 typedef basic_formatter< wchar_t > wformatter;
476 #endif
477
478 BOOST_LOG_CLOSE_NAMESPACE // namespace log
479
480 } // namespace boost
481
482 #include <boost/log/detail/footer.hpp>
483
484 #endif // BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_