Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:29

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   formatting_ostream.hpp
0009  * \author Andrey Semashev
0010  * \date   11.07.2012
0011  *
0012  * The header contains implementation of a string stream used for log record formatting.
0013  */
0014 
0015 #ifndef BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
0016 #define BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
0017 
0018 #include <ostream>
0019 #include <string>
0020 #include <memory>
0021 #include <locale>
0022 #include <boost/core/enable_if.hpp>
0023 #include <boost/core/explicit_operator_bool.hpp>
0024 #include <boost/utility/string_ref_fwd.hpp>
0025 #include <boost/utility/string_view_fwd.hpp>
0026 #include <boost/type_traits/is_enum.hpp>
0027 #include <boost/type_traits/is_scalar.hpp>
0028 #include <boost/type_traits/remove_cv.hpp>
0029 #include <boost/log/detail/config.hpp>
0030 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0031 #include <string_view>
0032 #endif
0033 #include <boost/log/detail/attachable_sstream_buf.hpp>
0034 #include <boost/log/detail/code_conversion.hpp>
0035 #include <boost/log/utility/string_literal_fwd.hpp>
0036 #include <boost/log/utility/formatting_ostream_fwd.hpp>
0037 #include <boost/log/detail/header.hpp>
0038 
0039 #ifdef BOOST_HAS_PRAGMA_ONCE
0040 #pragma once
0041 #endif
0042 
0043 namespace boost {
0044 
0045 BOOST_LOG_OPEN_NAMESPACE
0046 
0047 namespace aux {
0048 
0049 template< typename T, typename R >
0050 struct enable_if_streamable_char_type {};
0051 template< typename T, typename R >
0052 struct disable_if_streamable_char_type { typedef R type; };
0053 template< typename R >
0054 struct enable_if_streamable_char_type< char, R > { typedef R type; };
0055 template< typename R >
0056 struct disable_if_streamable_char_type< char, R > {};
0057 template< typename R >
0058 struct enable_if_streamable_char_type< wchar_t, R > { typedef R type; };
0059 template< typename R >
0060 struct disable_if_streamable_char_type< wchar_t, R > {};
0061 #if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
0062 #if !defined(BOOST_NO_CXX11_CHAR16_T)
0063 template< typename R >
0064 struct enable_if_streamable_char_type< char16_t, R > { typedef R type; };
0065 template< typename R >
0066 struct disable_if_streamable_char_type< char16_t, R > {};
0067 #endif
0068 #if !defined(BOOST_NO_CXX11_CHAR32_T)
0069 template< typename R >
0070 struct enable_if_streamable_char_type< char32_t, R > { typedef R type; };
0071 template< typename R >
0072 struct disable_if_streamable_char_type< char32_t, R > {};
0073 #endif
0074 #endif
0075 
0076 template< typename StreamT, typename T, bool ByValueV, typename R >
0077 struct enable_formatting_ostream_generic_operator {};
0078 
0079 template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename R >
0080 struct enable_formatting_ostream_generic_operator< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, T, false, R > :
0081     public boost::disable_if_c< boost::is_scalar< typename boost::remove_cv< T >::type >::value, R >
0082 {
0083 };
0084 
0085 template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename R >
0086 struct enable_formatting_ostream_generic_operator< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, T, true, R > :
0087     public boost::enable_if_c< boost::is_enum< typename boost::remove_cv< T >::type >::value, R >
0088 {
0089 };
0090 
0091 template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename R >
0092 struct enable_formatting_ostream_generic_operator< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, T*, true, R > :
0093     public disable_if_streamable_char_type< typename boost::remove_cv< T >::type, R >
0094 {
0095 };
0096 
0097 } // namespace aux
0098 
0099 /*!
0100  * \brief Stream wrapper for log records formatting.
0101  *
0102  * This stream wrapper is used by the library for log record formatting. It implements the standard string stream interface
0103  * with a few differences:
0104  *
0105  * \li It does not derive from standard types <tt>std::basic_ostream</tt>, <tt>std::basic_ios</tt> and <tt>std::ios_base</tt>,
0106  *     although it tries to implement their interfaces closely. There are a few small differences, mostly regarding <tt>rdbuf</tt>
0107  *     and <tt>str</tt> signatures, as well as the supported insertion operator overloads. The actual wrapped stream can be accessed
0108  *     through the <tt>stream</tt> methods.
0109  * \li By default, \c bool values are formatted using alphabetical representation rather than numeric.
0110  * \li The stream supports writing strings of character types different from the stream character type. The stream will perform
0111  *     character code conversion as needed using the imbued locale.
0112  * \li The stream operates on an external string object rather than on the embedded one. The string can be attached or detached
0113  *     from the stream dynamically.
0114  *
0115  * Although <tt>basic_formatting_ostream</tt> does not derive from <tt>std::basic_ostream</tt>, users are not required to add
0116  * special overloads of \c operator<< for it since the stream will by default reuse the operators for <tt>std::basic_ostream</tt>.
0117  * However, one can define special overloads of \c operator<< for <tt>basic_formatting_ostream</tt> if a certain type needs
0118  * special formatting when output to log.
0119  */
0120 template< typename CharT, typename TraitsT, typename AllocatorT >
0121 class basic_formatting_ostream
0122 {
0123 public:
0124     //! Character type
0125     typedef CharT char_type;
0126     //! Character traits
0127     typedef TraitsT traits_type;
0128     //! Memory allocator
0129     typedef AllocatorT allocator_type;
0130     //! Stream buffer type
0131     typedef boost::log::aux::basic_ostringstreambuf< char_type, traits_type, allocator_type > streambuf_type;
0132     //! Target string type
0133     typedef typename streambuf_type::string_type string_type;
0134 
0135     //! Stream type
0136     typedef std::basic_ostream< char_type, traits_type > ostream_type;
0137     //! Stream position type
0138     typedef typename ostream_type::pos_type pos_type;
0139     //! Stream offset type
0140     typedef typename ostream_type::off_type off_type;
0141     //! Integer type for characters
0142     typedef typename ostream_type::int_type int_type;
0143 
0144     typedef typename ostream_type::failure failure;
0145     typedef typename ostream_type::fmtflags fmtflags;
0146     typedef typename ostream_type::iostate iostate;
0147     typedef typename ostream_type::openmode openmode;
0148     typedef typename ostream_type::seekdir seekdir;
0149     typedef typename ostream_type::Init Init;
0150 
0151     typedef typename ostream_type::event event;
0152     typedef typename ostream_type::event_callback event_callback;
0153 
0154     class sentry :
0155         public ostream_type::sentry
0156     {
0157         typedef typename ostream_type::sentry base_type;
0158 
0159     public:
0160         explicit sentry(basic_formatting_ostream& strm) : base_type(strm.stream())
0161         {
0162         }
0163 
0164         // A workaround for Solaris Studio 12.4 compiler, see: https://svn.boost.org/trac/boost/ticket/11545
0165         BOOST_EXPLICIT_OPERATOR_BOOL()
0166         bool operator! () const { return !static_cast< base_type const& >(*this); }
0167 
0168         BOOST_DELETED_FUNCTION(sentry(sentry const&))
0169         BOOST_DELETED_FUNCTION(sentry& operator= (sentry const&))
0170     };
0171 
0172 protected:
0173     //  Function types
0174     typedef std::ios_base& (*ios_base_manip)(std::ios_base&);
0175     typedef std::basic_ios< char_type, traits_type >& (*basic_ios_manip)(std::basic_ios< char_type, traits_type >&);
0176     typedef ostream_type& (*stream_manip)(ostream_type&);
0177 
0178 public:
0179     static BOOST_CONSTEXPR_OR_CONST fmtflags boolalpha = ostream_type::boolalpha;
0180     static BOOST_CONSTEXPR_OR_CONST fmtflags dec = ostream_type::dec;
0181     static BOOST_CONSTEXPR_OR_CONST fmtflags fixed = ostream_type::fixed;
0182     static BOOST_CONSTEXPR_OR_CONST fmtflags hex = ostream_type::hex;
0183     static BOOST_CONSTEXPR_OR_CONST fmtflags internal = ostream_type::internal;
0184     static BOOST_CONSTEXPR_OR_CONST fmtflags left = ostream_type::left;
0185     static BOOST_CONSTEXPR_OR_CONST fmtflags oct = ostream_type::oct;
0186     static BOOST_CONSTEXPR_OR_CONST fmtflags right = ostream_type::right;
0187     static BOOST_CONSTEXPR_OR_CONST fmtflags scientific = ostream_type::scientific;
0188     static BOOST_CONSTEXPR_OR_CONST fmtflags showbase = ostream_type::showbase;
0189     static BOOST_CONSTEXPR_OR_CONST fmtflags showpoint = ostream_type::showpoint;
0190     static BOOST_CONSTEXPR_OR_CONST fmtflags skipws = ostream_type::skipws;
0191     static BOOST_CONSTEXPR_OR_CONST fmtflags unitbuf = ostream_type::unitbuf;
0192     static BOOST_CONSTEXPR_OR_CONST fmtflags uppercase = ostream_type::uppercase;
0193     static BOOST_CONSTEXPR_OR_CONST fmtflags adjustfield = ostream_type::adjustfield;
0194     static BOOST_CONSTEXPR_OR_CONST fmtflags basefield = ostream_type::basefield;
0195     static BOOST_CONSTEXPR_OR_CONST fmtflags floatfield = ostream_type::floatfield;
0196 
0197     static BOOST_CONSTEXPR_OR_CONST iostate badbit = ostream_type::badbit;
0198     static BOOST_CONSTEXPR_OR_CONST iostate eofbit = ostream_type::eofbit;
0199     static BOOST_CONSTEXPR_OR_CONST iostate failbit = ostream_type::failbit;
0200     static BOOST_CONSTEXPR_OR_CONST iostate goodbit = ostream_type::goodbit;
0201 
0202     static BOOST_CONSTEXPR_OR_CONST openmode app = ostream_type::app;
0203     static BOOST_CONSTEXPR_OR_CONST openmode ate = ostream_type::ate;
0204     static BOOST_CONSTEXPR_OR_CONST openmode binary = ostream_type::binary;
0205     static BOOST_CONSTEXPR_OR_CONST openmode in = ostream_type::in;
0206     static BOOST_CONSTEXPR_OR_CONST openmode out = ostream_type::out;
0207     static BOOST_CONSTEXPR_OR_CONST openmode trunc = ostream_type::trunc;
0208 
0209     static BOOST_CONSTEXPR_OR_CONST seekdir beg = ostream_type::beg;
0210     static BOOST_CONSTEXPR_OR_CONST seekdir cur = ostream_type::cur;
0211     static BOOST_CONSTEXPR_OR_CONST seekdir end = ostream_type::end;
0212 
0213     static BOOST_CONSTEXPR_OR_CONST event erase_event = ostream_type::erase_event;
0214     static BOOST_CONSTEXPR_OR_CONST event imbue_event = ostream_type::imbue_event;
0215     static BOOST_CONSTEXPR_OR_CONST event copyfmt_event = ostream_type::copyfmt_event;
0216 
0217 private:
0218     mutable streambuf_type m_streambuf;
0219     ostream_type m_stream;
0220 
0221 public:
0222     /*!
0223      * Default constructor. Creates an empty record that is equivalent to the invalid record handle.
0224      * The stream capability is not available after construction.
0225      *
0226      * \post <tt>!*this == true</tt>
0227      */
0228     basic_formatting_ostream() : m_stream(&m_streambuf)
0229     {
0230         init_stream();
0231     }
0232 
0233     /*!
0234      * Initializing constructor. Attaches the string to the constructed stream.
0235      * The string will be used to store the formatted characters.
0236      *
0237      * \post <tt>!*this == false</tt>
0238      * \param str The string buffer to attach.
0239      */
0240     explicit basic_formatting_ostream(string_type& str) :
0241         m_streambuf(str),
0242         m_stream(&m_streambuf)
0243     {
0244         init_stream();
0245     }
0246 
0247     /*!
0248      * Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
0249      */
0250     ~basic_formatting_ostream()
0251     {
0252         if (m_streambuf.storage())
0253             flush();
0254     }
0255 
0256     /*!
0257      * Attaches the stream to the string. The string will be used to store the formatted characters.
0258      *
0259      * \param str The string buffer to attach.
0260      */
0261     void attach(string_type& str)
0262     {
0263         m_streambuf.attach(str);
0264         m_stream.clear(ostream_type::goodbit);
0265     }
0266     /*!
0267      * Detaches the stream from the string. Any buffered data is flushed to the string.
0268      */
0269     void detach()
0270     {
0271         m_streambuf.detach();
0272         m_stream.clear(ostream_type::badbit);
0273     }
0274 
0275     /*!
0276      * \returns Reference to the attached string. The string must be attached before calling this method.
0277      */
0278     string_type const& str() const
0279     {
0280         string_type* const storage = m_streambuf.storage();
0281         BOOST_ASSERT(storage != NULL);
0282 
0283         m_streambuf.pubsync();
0284 
0285         return *storage;
0286     }
0287 
0288     /*!
0289      * \returns Reference to the wrapped stream
0290      */
0291     ostream_type& stream() { return m_stream; }
0292 
0293     /*!
0294      * \returns Reference to the wrapped stream
0295      */
0296     ostream_type const& stream() const { return m_stream; }
0297 
0298     // std::ios_base method forwarders
0299     fmtflags flags() const { return m_stream.flags(); }
0300     fmtflags flags(fmtflags f) { return m_stream.flags(f); }
0301     fmtflags setf(fmtflags f) { return m_stream.setf(f); }
0302     fmtflags setf(fmtflags f, fmtflags mask) { return m_stream.setf(f, mask); }
0303     void unsetf(fmtflags f) { m_stream.unsetf(f); }
0304 
0305     std::streamsize precision() const { return m_stream.precision(); }
0306     std::streamsize precision(std::streamsize p) { return m_stream.precision(p); }
0307 
0308     std::streamsize width() const { return m_stream.width(); }
0309     std::streamsize width(std::streamsize w) { return m_stream.width(w); }
0310 
0311     std::locale getloc() const { return m_stream.getloc(); }
0312     std::locale imbue(std::locale const& loc) { return m_stream.imbue(loc); }
0313 
0314     static int xalloc() { return ostream_type::xalloc(); }
0315     long& iword(int index) { return m_stream.iword(index); }
0316     void*& pword(int index) { return m_stream.pword(index); }
0317 
0318     void register_callback(event_callback fn, int index) { m_stream.register_callback(fn, index); }
0319 
0320     static bool sync_with_stdio(bool sync = true) { return ostream_type::sync_with_stdio(sync); }
0321 
0322     // std::basic_ios method forwarders
0323     BOOST_EXPLICIT_OPERATOR_BOOL()
0324     bool operator! () const { return !m_stream; }
0325 
0326     iostate rdstate() const { return m_stream.rdstate(); }
0327     void clear(iostate state = goodbit) { m_stream.clear(state); }
0328     void setstate(iostate state) { m_stream.setstate(state); }
0329     bool good() const { return m_stream.good(); }
0330     bool eof() const { return m_stream.eof(); }
0331     bool fail() const { return m_stream.fail(); }
0332     bool bad() const { return m_stream.bad(); }
0333 
0334     iostate exceptions() const { return m_stream.exceptions(); }
0335     void exceptions(iostate s) { m_stream.exceptions(s); }
0336 
0337     ostream_type* tie() const { return m_stream.tie(); }
0338     ostream_type* tie(ostream_type* strm) { return m_stream.tie(strm); }
0339 
0340     streambuf_type* rdbuf() const { return &m_streambuf; }
0341 
0342     basic_formatting_ostream& copyfmt(std::basic_ios< char_type, traits_type >& rhs)
0343     {
0344         m_stream.copyfmt(rhs);
0345         return *this;
0346     }
0347     basic_formatting_ostream& copyfmt(basic_formatting_ostream& rhs)
0348     {
0349         m_stream.copyfmt(rhs.stream());
0350         return *this;
0351     }
0352 
0353     char_type fill() const { return m_stream.fill(); }
0354     char_type fill(char_type ch) { return m_stream.fill(ch); }
0355 
0356     char narrow(char_type ch, char def) const { return m_stream.narrow(ch, def); }
0357     char_type widen(char ch) const { return m_stream.widen(ch); }
0358 
0359     // std::basic_ostream method forwarders
0360     basic_formatting_ostream& flush()
0361     {
0362         m_stream.flush();
0363         return *this;
0364     }
0365 
0366     pos_type tellp() { return m_stream.tellp(); }
0367     basic_formatting_ostream& seekp(pos_type pos)
0368     {
0369         m_stream.seekp(pos);
0370         return *this;
0371     }
0372     basic_formatting_ostream& seekp(off_type off, std::ios_base::seekdir dir)
0373     {
0374         m_stream.seekp(off, dir);
0375         return *this;
0376     }
0377 
0378     basic_formatting_ostream& put(char_type c)
0379     {
0380         m_stream.put(c);
0381         return *this;
0382     }
0383 
0384     template< typename OtherCharT >
0385     typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0386     put(OtherCharT c)
0387     {
0388         write(&c, 1);
0389         return *this;
0390     }
0391 
0392     basic_formatting_ostream& write(const char_type* p, std::streamsize size)
0393     {
0394         m_stream.write(p, size);
0395         return *this;
0396     }
0397 
0398     template< typename OtherCharT >
0399     typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0400     write(const OtherCharT* p, std::streamsize size)
0401     {
0402         sentry guard(*this);
0403         if (!!guard)
0404         {
0405             m_stream.flush();
0406 
0407             if (!m_streambuf.storage_overflow())
0408             {
0409                 string_type* storage = m_streambuf.storage();
0410                 if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
0411                     m_streambuf.storage_overflow(true);
0412             }
0413         }
0414 
0415         return *this;
0416     }
0417 
0418     basic_formatting_ostream& operator<< (ios_base_manip manip)
0419     {
0420         m_stream << manip;
0421         return *this;
0422     }
0423     basic_formatting_ostream& operator<< (basic_ios_manip manip)
0424     {
0425         m_stream << manip;
0426         return *this;
0427     }
0428     basic_formatting_ostream& operator<< (stream_manip manip)
0429     {
0430         m_stream << manip;
0431         return *this;
0432     }
0433 
0434     basic_formatting_ostream& operator<< (char c)
0435     {
0436         return this->formatted_write(&c, 1);
0437     }
0438     basic_formatting_ostream& operator<< (const char* p)
0439     {
0440         return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char >::length(p)));
0441     }
0442 
0443     // When no native character type is supported, the following overloads are disabled as they have ambiguous meaning.
0444     // Use basic_string_view or basic_string to explicitly indicate that the data is a string.
0445 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
0446     basic_formatting_ostream& operator<< (wchar_t c)
0447     {
0448         return this->formatted_write(&c, 1);
0449     }
0450     basic_formatting_ostream& operator<< (const wchar_t* p)
0451     {
0452         return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< wchar_t >::length(p)));
0453     }
0454 #endif
0455 #if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
0456 #if !defined(BOOST_NO_CXX11_CHAR16_T)
0457     basic_formatting_ostream& operator<< (char16_t c)
0458     {
0459         return this->formatted_write(&c, 1);
0460     }
0461     basic_formatting_ostream& operator<< (const char16_t* p)
0462     {
0463         return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char16_t >::length(p)));
0464     }
0465 #endif
0466 #if !defined(BOOST_NO_CXX11_CHAR32_T)
0467     basic_formatting_ostream& operator<< (char32_t c)
0468     {
0469         return this->formatted_write(&c, 1);
0470     }
0471     basic_formatting_ostream& operator<< (const char32_t* p)
0472     {
0473         return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char32_t >::length(p)));
0474     }
0475 #endif
0476 #endif
0477 
0478     basic_formatting_ostream& operator<< (bool value)
0479     {
0480         m_stream << value;
0481         return *this;
0482     }
0483     basic_formatting_ostream& operator<< (signed char value)
0484     {
0485         m_stream << value;
0486         return *this;
0487     }
0488     basic_formatting_ostream& operator<< (unsigned char value)
0489     {
0490         m_stream << value;
0491         return *this;
0492     }
0493     basic_formatting_ostream& operator<< (short value)
0494     {
0495         m_stream << value;
0496         return *this;
0497     }
0498     basic_formatting_ostream& operator<< (unsigned short value)
0499     {
0500         m_stream << value;
0501         return *this;
0502     }
0503     basic_formatting_ostream& operator<< (int value)
0504     {
0505         m_stream << value;
0506         return *this;
0507     }
0508     basic_formatting_ostream& operator<< (unsigned int value)
0509     {
0510         m_stream << value;
0511         return *this;
0512     }
0513     basic_formatting_ostream& operator<< (long value)
0514     {
0515         m_stream << value;
0516         return *this;
0517     }
0518     basic_formatting_ostream& operator<< (unsigned long value)
0519     {
0520         m_stream << value;
0521         return *this;
0522     }
0523 #if !defined(BOOST_NO_LONG_LONG)
0524     basic_formatting_ostream& operator<< (long long value)
0525     {
0526         m_stream << value;
0527         return *this;
0528     }
0529     basic_formatting_ostream& operator<< (unsigned long long value)
0530     {
0531         m_stream << value;
0532         return *this;
0533     }
0534 #endif
0535 
0536     basic_formatting_ostream& operator<< (float value)
0537     {
0538         m_stream << value;
0539         return *this;
0540     }
0541     basic_formatting_ostream& operator<< (double value)
0542     {
0543         m_stream << value;
0544         return *this;
0545     }
0546     basic_formatting_ostream& operator<< (long double value)
0547     {
0548         m_stream << value;
0549         return *this;
0550     }
0551 
0552     basic_formatting_ostream& operator<< (std::basic_streambuf< char_type, traits_type >* buf)
0553     {
0554         m_stream << buf;
0555         return *this;
0556     }
0557 
0558     template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
0559     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0560     operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
0561     {
0562         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0563     }
0564 
0565 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0566     template< typename OtherCharT, typename OtherTraitsT >
0567     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0568     operator<< (basic_formatting_ostream& strm, std::basic_string_view< OtherCharT, OtherTraitsT > const& str)
0569     {
0570         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0571     }
0572 #endif
0573 
0574     template< typename OtherCharT, typename OtherTraitsT >
0575     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0576     operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
0577     {
0578         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0579     }
0580 
0581     template< typename OtherCharT, typename OtherTraitsT >
0582     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0583     operator<< (basic_formatting_ostream& strm, basic_string_view< OtherCharT, OtherTraitsT > const& str)
0584     {
0585         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0586     }
0587 
0588     // Deprecated overload
0589     template< typename OtherCharT, typename OtherTraitsT >
0590     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0591     operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
0592     {
0593         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0594     }
0595 
0596     template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
0597     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0598     operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
0599     {
0600         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0601     }
0602 
0603 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0604     template< typename OtherCharT, typename OtherTraitsT >
0605     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0606     operator<< (basic_formatting_ostream& strm, std::basic_string_view< OtherCharT, OtherTraitsT >& str)
0607     {
0608         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0609     }
0610 #endif
0611 
0612     template< typename OtherCharT, typename OtherTraitsT >
0613     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0614     operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
0615     {
0616         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0617     }
0618 
0619     template< typename OtherCharT, typename OtherTraitsT >
0620     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0621     operator<< (basic_formatting_ostream& strm, basic_string_view< OtherCharT, OtherTraitsT >& str)
0622     {
0623         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0624     }
0625 
0626     // Deprecated overload
0627     template< typename OtherCharT, typename OtherTraitsT >
0628     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0629     operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
0630     {
0631         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0632     }
0633 
0634 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0635     template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
0636     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0637     operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
0638     {
0639         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0640     }
0641 
0642 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0643     template< typename OtherCharT, typename OtherTraitsT >
0644     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0645     operator<< (basic_formatting_ostream&& strm, std::basic_string_view< OtherCharT, OtherTraitsT > const& str)
0646     {
0647         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0648     }
0649 #endif
0650 
0651     template< typename OtherCharT, typename OtherTraitsT >
0652     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0653     operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
0654     {
0655         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0656     }
0657 
0658     template< typename OtherCharT, typename OtherTraitsT >
0659     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0660     operator<< (basic_formatting_ostream&& strm, basic_string_view< OtherCharT, OtherTraitsT > const& str)
0661     {
0662         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0663     }
0664 
0665     // Deprecated overload
0666     template< typename OtherCharT, typename OtherTraitsT >
0667     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0668     operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
0669     {
0670         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0671     }
0672 
0673     template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
0674     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0675     operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
0676     {
0677         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0678     }
0679 
0680 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0681     template< typename OtherCharT, typename OtherTraitsT >
0682     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0683     operator<< (basic_formatting_ostream&& strm, std::basic_string_view< OtherCharT, OtherTraitsT >& str)
0684     {
0685         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0686     }
0687 #endif
0688 
0689     template< typename OtherCharT, typename OtherTraitsT >
0690     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0691     operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
0692     {
0693         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0694     }
0695 
0696     template< typename OtherCharT, typename OtherTraitsT >
0697     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0698     operator<< (basic_formatting_ostream&& strm, basic_string_view< OtherCharT, OtherTraitsT >& str)
0699     {
0700         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0701     }
0702 
0703     // Deprecated overload
0704     template< typename OtherCharT, typename OtherTraitsT >
0705     friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
0706     operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
0707     {
0708         return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
0709     }
0710 #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0711 
0712 protected:
0713     void init_stream()
0714     {
0715         m_stream.exceptions(ostream_type::goodbit);
0716         m_stream.clear(m_streambuf.storage() ? ostream_type::goodbit : ostream_type::badbit);
0717         m_stream.flags
0718         (
0719             ostream_type::dec |
0720             ostream_type::skipws |
0721             ostream_type::boolalpha // this differs from the default stream flags but makes logs look better
0722         );
0723         m_stream.width(0);
0724         m_stream.precision(6);
0725         m_stream.fill(static_cast< char_type >(' '));
0726     }
0727 
0728 private:
0729     basic_formatting_ostream& formatted_write(const char_type* p, std::streamsize size)
0730     {
0731         sentry guard(*this);
0732         if (!!guard)
0733         {
0734             m_stream.flush();
0735 
0736             if (m_stream.width() <= size)
0737                 m_streambuf.append(p, static_cast< std::size_t >(size));
0738             else
0739                 this->aligned_write(p, size);
0740 
0741             m_stream.width(0);
0742         }
0743 
0744         return *this;
0745     }
0746 
0747     template< typename OtherCharT >
0748     basic_formatting_ostream& formatted_write(const OtherCharT* p, std::streamsize size)
0749     {
0750         sentry guard(*this);
0751         if (!!guard)
0752         {
0753             m_stream.flush();
0754 
0755             if (m_stream.width() <= size)
0756             {
0757                 if (!m_streambuf.storage_overflow())
0758                 {
0759                     if (!aux::code_convert(p, static_cast< std::size_t >(size), *m_streambuf.storage(), m_streambuf.max_size(), m_stream.getloc()))
0760                         m_streambuf.storage_overflow(true);
0761                 }
0762             }
0763             else
0764                 this->aligned_write(p, size);
0765 
0766             m_stream.width(0);
0767         }
0768 
0769         return *this;
0770     }
0771 
0772     void aligned_write(const char_type* p, std::streamsize size);
0773 
0774     template< typename OtherCharT >
0775     void aligned_write(const OtherCharT* p, std::streamsize size);
0776 
0777     //! Copy constructor (closed)
0778     BOOST_DELETED_FUNCTION(basic_formatting_ostream(basic_formatting_ostream const& that))
0779     //! Assignment (closed)
0780     BOOST_DELETED_FUNCTION(basic_formatting_ostream& operator= (basic_formatting_ostream const& that))
0781 };
0782 
0783 template< typename CharT, typename TraitsT, typename AllocatorT >
0784 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::boolalpha;
0785 template< typename CharT, typename TraitsT, typename AllocatorT >
0786 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::dec;
0787 template< typename CharT, typename TraitsT, typename AllocatorT >
0788 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fixed;
0789 template< typename CharT, typename TraitsT, typename AllocatorT >
0790 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::hex;
0791 template< typename CharT, typename TraitsT, typename AllocatorT >
0792 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::internal;
0793 template< typename CharT, typename TraitsT, typename AllocatorT >
0794 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::left;
0795 template< typename CharT, typename TraitsT, typename AllocatorT >
0796 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::oct;
0797 template< typename CharT, typename TraitsT, typename AllocatorT >
0798 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::right;
0799 template< typename CharT, typename TraitsT, typename AllocatorT >
0800 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::scientific;
0801 template< typename CharT, typename TraitsT, typename AllocatorT >
0802 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showbase;
0803 template< typename CharT, typename TraitsT, typename AllocatorT >
0804 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showpoint;
0805 template< typename CharT, typename TraitsT, typename AllocatorT >
0806 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::skipws;
0807 template< typename CharT, typename TraitsT, typename AllocatorT >
0808 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::unitbuf;
0809 template< typename CharT, typename TraitsT, typename AllocatorT >
0810 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::uppercase;
0811 template< typename CharT, typename TraitsT, typename AllocatorT >
0812 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::adjustfield;
0813 template< typename CharT, typename TraitsT, typename AllocatorT >
0814 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::basefield;
0815 template< typename CharT, typename TraitsT, typename AllocatorT >
0816 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::floatfield;
0817 
0818 template< typename CharT, typename TraitsT, typename AllocatorT >
0819 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::badbit;
0820 template< typename CharT, typename TraitsT, typename AllocatorT >
0821 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::eofbit;
0822 template< typename CharT, typename TraitsT, typename AllocatorT >
0823 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::failbit;
0824 template< typename CharT, typename TraitsT, typename AllocatorT >
0825 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::goodbit;
0826 
0827 template< typename CharT, typename TraitsT, typename AllocatorT >
0828 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::app;
0829 template< typename CharT, typename TraitsT, typename AllocatorT >
0830 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::ate;
0831 template< typename CharT, typename TraitsT, typename AllocatorT >
0832 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::binary;
0833 template< typename CharT, typename TraitsT, typename AllocatorT >
0834 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::in;
0835 template< typename CharT, typename TraitsT, typename AllocatorT >
0836 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::out;
0837 template< typename CharT, typename TraitsT, typename AllocatorT >
0838 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::trunc;
0839 
0840 template< typename CharT, typename TraitsT, typename AllocatorT >
0841 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::beg;
0842 template< typename CharT, typename TraitsT, typename AllocatorT >
0843 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::cur;
0844 template< typename CharT, typename TraitsT, typename AllocatorT >
0845 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::end;
0846 
0847 template< typename CharT, typename TraitsT, typename AllocatorT >
0848 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::erase_event;
0849 template< typename CharT, typename TraitsT, typename AllocatorT >
0850 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::imbue_event;
0851 template< typename CharT, typename TraitsT, typename AllocatorT >
0852 BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::copyfmt_event;
0853 
0854 template< typename CharT, typename TraitsT, typename AllocatorT >
0855 void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const char_type* p, std::streamsize size)
0856 {
0857     typename string_type::size_type const alignment_size =
0858         static_cast< typename string_type::size_type >(m_stream.width() - size);
0859     const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
0860     if (align_left)
0861     {
0862         m_streambuf.append(p, static_cast< std::size_t >(size));
0863         m_streambuf.append(alignment_size, m_stream.fill());
0864     }
0865     else
0866     {
0867         m_streambuf.append(alignment_size, m_stream.fill());
0868         m_streambuf.append(p, static_cast< std::size_t >(size));
0869     }
0870 }
0871 
0872 template< typename CharT, typename TraitsT, typename AllocatorT >
0873 template< typename OtherCharT >
0874 void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const OtherCharT* p, std::streamsize size)
0875 {
0876     string_type* const storage = m_streambuf.storage();
0877     typename string_type::size_type const alignment_size =
0878         static_cast< typename string_type::size_type >(m_stream.width() - size);
0879     const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
0880     if (align_left)
0881     {
0882         if (!m_streambuf.storage_overflow())
0883         {
0884             if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
0885                 m_streambuf.storage_overflow(true);
0886         }
0887         m_streambuf.append(alignment_size, m_stream.fill());
0888     }
0889     else
0890     {
0891         m_streambuf.append(alignment_size, m_stream.fill());
0892         if (!m_streambuf.storage_overflow())
0893         {
0894             if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
0895                 m_streambuf.storage_overflow(true);
0896         }
0897     }
0898 }
0899 
0900 // Implementation note: these operators below should be the least attractive for the compiler
0901 // so that user's overloads are chosen, when present. We use function template partial ordering for this purpose.
0902 // We also don't use perfect forwarding for the right hand argument because in this case the generic overload
0903 // would be more preferred than the typical one written by users:
0904 //
0905 // formatting_ostream& operator<< (formatting_ostream& strm, my_type const& arg);
0906 //
0907 // This is because my_type rvalues require adding const to the type, which counts as a conversion that is not required
0908 // if there is a perfect forwarding overload.
0909 template< typename StreamT, typename T >
0910 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, true, StreamT& >::type
0911 operator<< (StreamT& strm, T value)
0912 {
0913     strm.stream() << value;
0914     return strm;
0915 }
0916 
0917 template< typename StreamT, typename T >
0918 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
0919 operator<< (StreamT& strm, T const& value)
0920 {
0921     strm.stream() << value;
0922     return strm;
0923 }
0924 
0925 template< typename StreamT, typename T >
0926 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
0927 operator<< (StreamT& strm, T& value)
0928 {
0929     strm.stream() << value;
0930     return strm;
0931 }
0932 
0933 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0934 
0935 template< typename StreamT, typename T >
0936 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, true, StreamT& >::type
0937 operator<< (StreamT&& strm, T value)
0938 {
0939     strm.stream() << value;
0940     return strm;
0941 }
0942 
0943 template< typename StreamT, typename T >
0944 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
0945 operator<< (StreamT&& strm, T const& value)
0946 {
0947     strm.stream() << value;
0948     return strm;
0949 }
0950 
0951 template< typename StreamT, typename T >
0952 inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
0953 operator<< (StreamT&& strm, T& value)
0954 {
0955     strm.stream() << value;
0956     return strm;
0957 }
0958 
0959 #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0960 
0961 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0962 
0963 } // namespace boost
0964 
0965 #include <boost/log/detail/footer.hpp>
0966 
0967 #endif // BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_