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 formatting_ostream.hpp
9 * \author Andrey Semashev
12 * The header contains implementation of a string stream used for log record formatting.
15 #ifndef BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
16 #define BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
22 #include <boost/core/enable_if.hpp>
23 #include <boost/core/explicit_operator_bool.hpp>
24 #include <boost/utility/string_ref_fwd.hpp>
25 #include <boost/utility/string_view_fwd.hpp>
26 #include <boost/type_traits/is_enum.hpp>
27 #include <boost/type_traits/is_scalar.hpp>
28 #include <boost/type_traits/remove_cv.hpp>
29 #include <boost/log/detail/config.hpp>
30 #include <boost/log/detail/attachable_sstream_buf.hpp>
31 #include <boost/log/detail/code_conversion.hpp>
32 #include <boost/log/utility/string_literal_fwd.hpp>
33 #include <boost/log/utility/formatting_ostream_fwd.hpp>
34 #include <boost/log/detail/header.hpp>
36 #ifdef BOOST_HAS_PRAGMA_ONCE
42 BOOST_LOG_OPEN_NAMESPACE
46 template< typename T, typename R >
47 struct enable_if_streamable_char_type {};
48 template< typename R >
49 struct enable_if_streamable_char_type< char, R > { typedef R type; };
50 template< typename R >
51 struct enable_if_streamable_char_type< wchar_t, R > { typedef R type; };
52 #if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
53 #if !defined(BOOST_NO_CXX11_CHAR16_T)
54 template< typename R >
55 struct enable_if_streamable_char_type< char16_t, R > { typedef R type; };
57 #if !defined(BOOST_NO_CXX11_CHAR32_T)
58 template< typename R >
59 struct enable_if_streamable_char_type< char32_t, R > { typedef R type; };
63 template< typename StreamT, typename T, bool ByValueV, typename R >
64 struct enable_formatting_ostream_generic_operator {};
65 template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename R >
66 struct enable_formatting_ostream_generic_operator< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, T, false, R > :
67 public boost::disable_if_c< boost::is_scalar< typename boost::remove_cv< T >::type >::value, R >
70 template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename R >
71 struct enable_formatting_ostream_generic_operator< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, T, true, R > :
72 public boost::enable_if_c< boost::is_enum< typename boost::remove_cv< T >::type >::value, R >
79 * \brief Stream wrapper for log records formatting.
81 * This stream wrapper is used by the library for log record formatting. It implements the standard string stream interface
82 * with a few differences:
84 * \li It does not derive from standard types <tt>std::basic_ostream</tt>, <tt>std::basic_ios</tt> and <tt>std::ios_base</tt>,
85 * although it tries to implement their interfaces closely. There are a few small differences, mostly regarding <tt>rdbuf</tt>
86 * and <tt>str</tt> signatures, as well as the supported insertion operator overloads. The actual wrapped stream can be accessed
87 * through the <tt>stream</tt> methods.
88 * \li By default, \c bool values are formatted using alphabetical representation rather than numeric.
89 * \li The stream supports writing strings of character types different from the stream character type. The stream will perform
90 * character code conversion as needed using the imbued locale.
91 * \li The stream operates on an external string object rather than on the embedded one. The string can be attached or detached
92 * from the stream dynamically.
94 * Although <tt>basic_formatting_ostream</tt> does not derive from <tt>std::basic_ostream</tt>, users are not required to add
95 * special overloads of \c operator<< for it since the stream will by default reuse the operators for <tt>std::basic_ostream</tt>.
96 * However, one can define special overloads of \c operator<< for <tt>basic_formatting_ostream</tt> if a certain type needs
97 * special formatting when output to log.
99 template< typename CharT, typename TraitsT, typename AllocatorT >
100 class basic_formatting_ostream
104 typedef CharT char_type;
106 typedef TraitsT traits_type;
108 typedef AllocatorT allocator_type;
109 //! Stream buffer type
110 typedef boost::log::aux::basic_ostringstreambuf< char_type, traits_type, allocator_type > streambuf_type;
111 //! Target string type
112 typedef typename streambuf_type::string_type string_type;
115 typedef std::basic_ostream< char_type, traits_type > ostream_type;
116 //! Stream position type
117 typedef typename ostream_type::pos_type pos_type;
118 //! Stream offset type
119 typedef typename ostream_type::off_type off_type;
120 //! Integer type for characters
121 typedef typename ostream_type::int_type int_type;
123 typedef typename ostream_type::failure failure;
124 typedef typename ostream_type::fmtflags fmtflags;
125 typedef typename ostream_type::iostate iostate;
126 typedef typename ostream_type::openmode openmode;
127 typedef typename ostream_type::seekdir seekdir;
128 typedef typename ostream_type::Init Init;
130 typedef typename ostream_type::event event;
131 typedef typename ostream_type::event_callback event_callback;
134 public ostream_type::sentry
136 typedef typename ostream_type::sentry base_type;
139 explicit sentry(basic_formatting_ostream& strm) : base_type(strm.stream())
143 // A workaround for Solaris Studio 12.4 compiler, see: https://svn.boost.org/trac/boost/ticket/11545
144 BOOST_EXPLICIT_OPERATOR_BOOL()
145 bool operator! () const { return !static_cast< base_type const& >(*this); }
147 BOOST_DELETED_FUNCTION(sentry(sentry const&))
148 BOOST_DELETED_FUNCTION(sentry& operator= (sentry const&))
153 typedef std::ios_base& (*ios_base_manip)(std::ios_base&);
154 typedef std::basic_ios< char_type, traits_type >& (*basic_ios_manip)(std::basic_ios< char_type, traits_type >&);
155 typedef ostream_type& (*stream_manip)(ostream_type&);
158 static BOOST_CONSTEXPR_OR_CONST fmtflags boolalpha = ostream_type::boolalpha;
159 static BOOST_CONSTEXPR_OR_CONST fmtflags dec = ostream_type::dec;
160 static BOOST_CONSTEXPR_OR_CONST fmtflags fixed = ostream_type::fixed;
161 static BOOST_CONSTEXPR_OR_CONST fmtflags hex = ostream_type::hex;
162 static BOOST_CONSTEXPR_OR_CONST fmtflags internal = ostream_type::internal;
163 static BOOST_CONSTEXPR_OR_CONST fmtflags left = ostream_type::left;
164 static BOOST_CONSTEXPR_OR_CONST fmtflags oct = ostream_type::oct;
165 static BOOST_CONSTEXPR_OR_CONST fmtflags right = ostream_type::right;
166 static BOOST_CONSTEXPR_OR_CONST fmtflags scientific = ostream_type::scientific;
167 static BOOST_CONSTEXPR_OR_CONST fmtflags showbase = ostream_type::showbase;
168 static BOOST_CONSTEXPR_OR_CONST fmtflags showpoint = ostream_type::showpoint;
169 static BOOST_CONSTEXPR_OR_CONST fmtflags skipws = ostream_type::skipws;
170 static BOOST_CONSTEXPR_OR_CONST fmtflags unitbuf = ostream_type::unitbuf;
171 static BOOST_CONSTEXPR_OR_CONST fmtflags uppercase = ostream_type::uppercase;
172 static BOOST_CONSTEXPR_OR_CONST fmtflags adjustfield = ostream_type::adjustfield;
173 static BOOST_CONSTEXPR_OR_CONST fmtflags basefield = ostream_type::basefield;
174 static BOOST_CONSTEXPR_OR_CONST fmtflags floatfield = ostream_type::floatfield;
176 static BOOST_CONSTEXPR_OR_CONST iostate badbit = ostream_type::badbit;
177 static BOOST_CONSTEXPR_OR_CONST iostate eofbit = ostream_type::eofbit;
178 static BOOST_CONSTEXPR_OR_CONST iostate failbit = ostream_type::failbit;
179 static BOOST_CONSTEXPR_OR_CONST iostate goodbit = ostream_type::goodbit;
181 static BOOST_CONSTEXPR_OR_CONST openmode app = ostream_type::app;
182 static BOOST_CONSTEXPR_OR_CONST openmode ate = ostream_type::ate;
183 static BOOST_CONSTEXPR_OR_CONST openmode binary = ostream_type::binary;
184 static BOOST_CONSTEXPR_OR_CONST openmode in = ostream_type::in;
185 static BOOST_CONSTEXPR_OR_CONST openmode out = ostream_type::out;
186 static BOOST_CONSTEXPR_OR_CONST openmode trunc = ostream_type::trunc;
188 static BOOST_CONSTEXPR_OR_CONST seekdir beg = ostream_type::beg;
189 static BOOST_CONSTEXPR_OR_CONST seekdir cur = ostream_type::cur;
190 static BOOST_CONSTEXPR_OR_CONST seekdir end = ostream_type::end;
192 static BOOST_CONSTEXPR_OR_CONST event erase_event = ostream_type::erase_event;
193 static BOOST_CONSTEXPR_OR_CONST event imbue_event = ostream_type::imbue_event;
194 static BOOST_CONSTEXPR_OR_CONST event copyfmt_event = ostream_type::copyfmt_event;
197 mutable streambuf_type m_streambuf;
198 ostream_type m_stream;
202 * Default constructor. Creates an empty record that is equivalent to the invalid record handle.
203 * The stream capability is not available after construction.
205 * \post <tt>!*this == true</tt>
207 basic_formatting_ostream() : m_stream(&m_streambuf)
213 * Initializing constructor. Attaches the string to the constructed stream.
214 * The string will be used to store the formatted characters.
216 * \post <tt>!*this == false</tt>
217 * \param str The string buffer to attach.
219 explicit basic_formatting_ostream(string_type& str) :
221 m_stream(&m_streambuf)
227 * Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
229 ~basic_formatting_ostream()
231 if (m_streambuf.storage())
236 * Attaches the stream to the string. The string will be used to store the formatted characters.
238 * \param str The string buffer to attach.
240 void attach(string_type& str)
242 m_streambuf.attach(str);
243 m_stream.clear(ostream_type::goodbit);
246 * Detaches the stream from the string. Any buffered data is flushed to the string.
250 m_streambuf.detach();
251 m_stream.clear(ostream_type::badbit);
255 * \returns Reference to the attached string. The string must be attached before calling this method.
257 string_type const& str() const
259 string_type* const storage = m_streambuf.storage();
260 BOOST_ASSERT(storage != NULL);
262 m_streambuf.pubsync();
268 * \returns Reference to the wrapped stream
270 ostream_type& stream() { return m_stream; }
273 * \returns Reference to the wrapped stream
275 ostream_type const& stream() const { return m_stream; }
277 // std::ios_base method forwarders
278 fmtflags flags() const { return m_stream.flags(); }
279 fmtflags flags(fmtflags f) { return m_stream.flags(f); }
280 fmtflags setf(fmtflags f) { return m_stream.setf(f); }
281 fmtflags setf(fmtflags f, fmtflags mask) { return m_stream.setf(f, mask); }
282 void unsetf(fmtflags f) { m_stream.unsetf(f); }
284 std::streamsize precision() const { return m_stream.precision(); }
285 std::streamsize precision(std::streamsize p) { return m_stream.precision(p); }
287 std::streamsize width() const { return m_stream.width(); }
288 std::streamsize width(std::streamsize w) { return m_stream.width(w); }
290 std::locale getloc() const { return m_stream.getloc(); }
291 std::locale imbue(std::locale const& loc) { return m_stream.imbue(loc); }
293 static int xalloc() { return ostream_type::xalloc(); }
294 long& iword(int index) { return m_stream.iword(index); }
295 void*& pword(int index) { return m_stream.pword(index); }
297 void register_callback(event_callback fn, int index) { m_stream.register_callback(fn, index); }
299 static bool sync_with_stdio(bool sync = true) { return ostream_type::sync_with_stdio(sync); }
301 // std::basic_ios method forwarders
302 BOOST_EXPLICIT_OPERATOR_BOOL()
303 bool operator! () const { return !m_stream; }
305 iostate rdstate() const { return m_stream.rdstate(); }
306 void clear(iostate state = goodbit) { m_stream.clear(state); }
307 void setstate(iostate state) { m_stream.setstate(state); }
308 bool good() const { return m_stream.good(); }
309 bool eof() const { return m_stream.eof(); }
310 bool fail() const { return m_stream.fail(); }
311 bool bad() const { return m_stream.bad(); }
313 iostate exceptions() const { return m_stream.exceptions(); }
314 void exceptions(iostate s) { m_stream.exceptions(s); }
316 ostream_type* tie() const { return m_stream.tie(); }
317 ostream_type* tie(ostream_type* strm) { return m_stream.tie(strm); }
319 streambuf_type* rdbuf() const { return &m_streambuf; }
321 basic_formatting_ostream& copyfmt(std::basic_ios< char_type, traits_type >& rhs)
323 m_stream.copyfmt(rhs);
326 basic_formatting_ostream& copyfmt(basic_formatting_ostream& rhs)
328 m_stream.copyfmt(rhs.stream());
332 char_type fill() const { return m_stream.fill(); }
333 char_type fill(char_type ch) { return m_stream.fill(ch); }
335 char narrow(char_type ch, char def) const { return m_stream.narrow(ch, def); }
336 char_type widen(char ch) const { return m_stream.widen(ch); }
338 // std::basic_ostream method forwarders
339 basic_formatting_ostream& flush()
345 pos_type tellp() { return m_stream.tellp(); }
346 basic_formatting_ostream& seekp(pos_type pos)
351 basic_formatting_ostream& seekp(off_type off, std::ios_base::seekdir dir)
353 m_stream.seekp(off, dir);
357 basic_formatting_ostream& put(char_type c)
363 template< typename OtherCharT >
364 typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
371 basic_formatting_ostream& write(const char_type* p, std::streamsize size)
373 m_stream.write(p, size);
377 template< typename OtherCharT >
378 typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
379 write(const OtherCharT* p, std::streamsize size)
386 if (!m_streambuf.storage_overflow())
388 string_type* storage = m_streambuf.storage();
389 if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
390 m_streambuf.storage_overflow(true);
397 basic_formatting_ostream& operator<< (ios_base_manip manip)
402 basic_formatting_ostream& operator<< (basic_ios_manip manip)
407 basic_formatting_ostream& operator<< (stream_manip manip)
413 basic_formatting_ostream& operator<< (char c)
415 return this->formatted_write(&c, 1);
417 basic_formatting_ostream& operator<< (const char* p)
419 return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char >::length(p)));
422 // When no native character type is supported, the following overloads are disabled as they have ambiguous meaning.
423 // Use basic_string_view or basic_string to explicitly indicate that the data is a string.
424 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
425 basic_formatting_ostream& operator<< (wchar_t c)
427 return this->formatted_write(&c, 1);
429 basic_formatting_ostream& operator<< (const wchar_t* p)
431 return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< wchar_t >::length(p)));
434 #if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
435 #if !defined(BOOST_NO_CXX11_CHAR16_T)
436 basic_formatting_ostream& operator<< (char16_t c)
438 return this->formatted_write(&c, 1);
440 basic_formatting_ostream& operator<< (const char16_t* p)
442 return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char16_t >::length(p)));
445 #if !defined(BOOST_NO_CXX11_CHAR32_T)
446 basic_formatting_ostream& operator<< (char32_t c)
448 return this->formatted_write(&c, 1);
450 basic_formatting_ostream& operator<< (const char32_t* p)
452 return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char32_t >::length(p)));
457 basic_formatting_ostream& operator<< (bool value)
462 basic_formatting_ostream& operator<< (signed char value)
467 basic_formatting_ostream& operator<< (unsigned char value)
472 basic_formatting_ostream& operator<< (short value)
477 basic_formatting_ostream& operator<< (unsigned short value)
482 basic_formatting_ostream& operator<< (int value)
487 basic_formatting_ostream& operator<< (unsigned int value)
492 basic_formatting_ostream& operator<< (long value)
497 basic_formatting_ostream& operator<< (unsigned long value)
502 #if !defined(BOOST_NO_LONG_LONG)
503 basic_formatting_ostream& operator<< (long long value)
508 basic_formatting_ostream& operator<< (unsigned long long value)
515 basic_formatting_ostream& operator<< (float value)
520 basic_formatting_ostream& operator<< (double value)
525 basic_formatting_ostream& operator<< (long double value)
531 basic_formatting_ostream& operator<< (const void* value)
537 basic_formatting_ostream& operator<< (std::basic_streambuf< char_type, traits_type >* buf)
543 template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
544 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
545 operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
547 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
550 template< typename OtherCharT, typename OtherTraitsT >
551 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
552 operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
554 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
557 template< typename OtherCharT, typename OtherTraitsT >
558 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
559 operator<< (basic_formatting_ostream& strm, basic_string_view< OtherCharT, OtherTraitsT > const& str)
561 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
564 // Deprecated overload
565 template< typename OtherCharT, typename OtherTraitsT >
566 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
567 operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
569 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
572 template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
573 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
574 operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
576 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
579 template< typename OtherCharT, typename OtherTraitsT >
580 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
581 operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
583 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
586 template< typename OtherCharT, typename OtherTraitsT >
587 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
588 operator<< (basic_formatting_ostream& strm, basic_string_view< OtherCharT, OtherTraitsT >& str)
590 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
593 // Deprecated overload
594 template< typename OtherCharT, typename OtherTraitsT >
595 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
596 operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
598 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
601 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
602 template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
603 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
604 operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
606 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
609 template< typename OtherCharT, typename OtherTraitsT >
610 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
611 operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
613 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
616 template< typename OtherCharT, typename OtherTraitsT >
617 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
618 operator<< (basic_formatting_ostream&& strm, basic_string_view< OtherCharT, OtherTraitsT > const& str)
620 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
623 // Deprecated overload
624 template< typename OtherCharT, typename OtherTraitsT >
625 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
626 operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
628 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
631 template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
632 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
633 operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
635 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
638 template< typename OtherCharT, typename OtherTraitsT >
639 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
640 operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
642 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
645 template< typename OtherCharT, typename OtherTraitsT >
646 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
647 operator<< (basic_formatting_ostream&& strm, basic_string_view< OtherCharT, OtherTraitsT >& str)
649 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
652 // Deprecated overload
653 template< typename OtherCharT, typename OtherTraitsT >
654 friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
655 operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
657 return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
664 m_stream.exceptions(ostream_type::goodbit);
665 m_stream.clear(m_streambuf.storage() ? ostream_type::goodbit : ostream_type::badbit);
669 ostream_type::skipws |
670 ostream_type::boolalpha // this differs from the default stream flags but makes logs look better
673 m_stream.precision(6);
674 m_stream.fill(static_cast< char_type >(' '));
678 basic_formatting_ostream& formatted_write(const char_type* p, std::streamsize size)
685 if (m_stream.width() <= size)
686 m_streambuf.append(p, static_cast< std::size_t >(size));
688 this->aligned_write(p, size);
696 template< typename OtherCharT >
697 basic_formatting_ostream& formatted_write(const OtherCharT* p, std::streamsize size)
704 if (m_stream.width() <= size)
706 if (!m_streambuf.storage_overflow())
708 if (!aux::code_convert(p, static_cast< std::size_t >(size), *m_streambuf.storage(), m_streambuf.max_size(), m_stream.getloc()))
709 m_streambuf.storage_overflow(true);
713 this->aligned_write(p, size);
721 void aligned_write(const char_type* p, std::streamsize size);
723 template< typename OtherCharT >
724 void aligned_write(const OtherCharT* p, std::streamsize size);
726 //! Copy constructor (closed)
727 BOOST_DELETED_FUNCTION(basic_formatting_ostream(basic_formatting_ostream const& that))
728 //! Assignment (closed)
729 BOOST_DELETED_FUNCTION(basic_formatting_ostream& operator= (basic_formatting_ostream const& that))
732 template< typename CharT, typename TraitsT, typename AllocatorT >
733 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::boolalpha;
734 template< typename CharT, typename TraitsT, typename AllocatorT >
735 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::dec;
736 template< typename CharT, typename TraitsT, typename AllocatorT >
737 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fixed;
738 template< typename CharT, typename TraitsT, typename AllocatorT >
739 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::hex;
740 template< typename CharT, typename TraitsT, typename AllocatorT >
741 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::internal;
742 template< typename CharT, typename TraitsT, typename AllocatorT >
743 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::left;
744 template< typename CharT, typename TraitsT, typename AllocatorT >
745 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::oct;
746 template< typename CharT, typename TraitsT, typename AllocatorT >
747 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::right;
748 template< typename CharT, typename TraitsT, typename AllocatorT >
749 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::scientific;
750 template< typename CharT, typename TraitsT, typename AllocatorT >
751 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showbase;
752 template< typename CharT, typename TraitsT, typename AllocatorT >
753 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showpoint;
754 template< typename CharT, typename TraitsT, typename AllocatorT >
755 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::skipws;
756 template< typename CharT, typename TraitsT, typename AllocatorT >
757 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::unitbuf;
758 template< typename CharT, typename TraitsT, typename AllocatorT >
759 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::uppercase;
760 template< typename CharT, typename TraitsT, typename AllocatorT >
761 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::adjustfield;
762 template< typename CharT, typename TraitsT, typename AllocatorT >
763 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::basefield;
764 template< typename CharT, typename TraitsT, typename AllocatorT >
765 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::floatfield;
767 template< typename CharT, typename TraitsT, typename AllocatorT >
768 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::badbit;
769 template< typename CharT, typename TraitsT, typename AllocatorT >
770 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::eofbit;
771 template< typename CharT, typename TraitsT, typename AllocatorT >
772 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::failbit;
773 template< typename CharT, typename TraitsT, typename AllocatorT >
774 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::goodbit;
776 template< typename CharT, typename TraitsT, typename AllocatorT >
777 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::app;
778 template< typename CharT, typename TraitsT, typename AllocatorT >
779 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::ate;
780 template< typename CharT, typename TraitsT, typename AllocatorT >
781 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::binary;
782 template< typename CharT, typename TraitsT, typename AllocatorT >
783 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::in;
784 template< typename CharT, typename TraitsT, typename AllocatorT >
785 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::out;
786 template< typename CharT, typename TraitsT, typename AllocatorT >
787 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::trunc;
789 template< typename CharT, typename TraitsT, typename AllocatorT >
790 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::beg;
791 template< typename CharT, typename TraitsT, typename AllocatorT >
792 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::cur;
793 template< typename CharT, typename TraitsT, typename AllocatorT >
794 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::end;
796 template< typename CharT, typename TraitsT, typename AllocatorT >
797 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::erase_event;
798 template< typename CharT, typename TraitsT, typename AllocatorT >
799 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::imbue_event;
800 template< typename CharT, typename TraitsT, typename AllocatorT >
801 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::copyfmt_event;
803 template< typename CharT, typename TraitsT, typename AllocatorT >
804 void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const char_type* p, std::streamsize size)
806 typename string_type::size_type const alignment_size =
807 static_cast< typename string_type::size_type >(m_stream.width() - size);
808 const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
811 m_streambuf.append(p, static_cast< std::size_t >(size));
812 m_streambuf.append(alignment_size, m_stream.fill());
816 m_streambuf.append(alignment_size, m_stream.fill());
817 m_streambuf.append(p, static_cast< std::size_t >(size));
821 template< typename CharT, typename TraitsT, typename AllocatorT >
822 template< typename OtherCharT >
823 void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const OtherCharT* p, std::streamsize size)
825 string_type* const storage = m_streambuf.storage();
826 typename string_type::size_type const alignment_size =
827 static_cast< typename string_type::size_type >(m_stream.width() - size);
828 const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
831 if (!m_streambuf.storage_overflow())
833 if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
834 m_streambuf.storage_overflow(true);
836 m_streambuf.append(alignment_size, m_stream.fill());
840 m_streambuf.append(alignment_size, m_stream.fill());
841 if (!m_streambuf.storage_overflow())
843 if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
844 m_streambuf.storage_overflow(true);
849 // Implementation note: these operators below should be the least attractive for the compiler
850 // so that user's overloads are chosen, when present. We use function template partial ordering for this purpose.
851 // We also don't use perfect forwarding for the right hand argument because in this case the generic overload
852 // would be more preferred than the typical one written by users:
854 // formatting_ostream& operator<< (formatting_ostream& strm, my_type const& arg);
856 // This is because my_type rvalues require adding const to the type, which counts as a conversion that is not required
857 // if there is a perfect forwarding overload.
858 template< typename StreamT, typename T >
859 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, true, StreamT& >::type
860 operator<< (StreamT& strm, T value)
862 strm.stream() << value;
866 template< typename StreamT, typename T >
867 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
868 operator<< (StreamT& strm, T const& value)
870 strm.stream() << value;
874 template< typename StreamT, typename T >
875 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
876 operator<< (StreamT& strm, T& value)
878 strm.stream() << value;
882 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
884 template< typename StreamT, typename T >
885 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, true, StreamT& >::type
886 operator<< (StreamT&& strm, T value)
888 strm.stream() << value;
892 template< typename StreamT, typename T >
893 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
894 operator<< (StreamT&& strm, T const& value)
896 strm.stream() << value;
900 template< typename StreamT, typename T >
901 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
902 operator<< (StreamT&& strm, T& value)
904 strm.stream() << value;
908 #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
910 BOOST_LOG_CLOSE_NAMESPACE // namespace log
914 #include <boost/log/detail/footer.hpp>
916 #endif // BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_