Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file formatting_ostream.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 11.07.2012 Chris@16: * Chris@16: * The header contains implementation of a string stream used for log record formatting. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace aux { Chris@16: Chris@16: template< typename T, typename R > Chris@16: struct enable_if_char_type {}; Chris@16: template< typename R > Chris@16: struct enable_if_char_type< char, R > { typedef R type; }; Chris@16: template< typename R > Chris@16: struct enable_if_char_type< wchar_t, R > { typedef R type; }; Chris@16: #if !defined(BOOST_NO_CXX11_CHAR16_T) Chris@16: template< typename R > Chris@16: struct enable_if_char_type< char16_t, R > { typedef R type; }; Chris@16: #endif Chris@16: #if !defined(BOOST_NO_CXX11_CHAR32_T) Chris@16: template< typename R > Chris@16: struct enable_if_char_type< char32_t, R > { typedef R type; }; Chris@16: #endif Chris@16: Chris@16: } // namespace aux Chris@16: Chris@16: /*! Chris@16: * \brief Stream wrapper for log records formatting. Chris@16: * Chris@16: * This stream wrapper is used by the library for log record formatting. It implements the standard string stream interface Chris@16: * with a few differences: Chris@16: * Chris@16: * \li It does not derive from standard types std::basic_ostream, std::basic_ios and std::ios_base, Chris@16: * although it tries to implement their interfaces closely. There are a few small differences, mostly regarding rdbuf Chris@16: * and str signatures, as well as the supported insertion operator overloads. The actual wrapped stream can be accessed Chris@16: * through the stream methods. Chris@16: * \li By default, \c bool values are formatted using alphabetical representation rather than numeric. Chris@16: * \li The stream supports writing strings of character types different from the stream character type. The stream will perform Chris@16: * character code conversion as needed using the imbued locale. Chris@16: * \li The stream operates on an external string object rather than on the embedded one. The string can be attached or detached Chris@16: * from the stream dynamically. Chris@16: * Chris@16: * Although basic_formatting_ostream does not derive from std::basic_ostream, users are not required to add Chris@16: * special overloads of \c operator<< for it since the stream will by default reuse the operators for std::basic_ostream. Chris@16: * However, one can define special overloads of \c operator<< for basic_formatting_ostream if a certain type needs Chris@16: * special formatting when output to log. Chris@16: */ Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: class basic_formatting_ostream Chris@16: { Chris@16: public: Chris@16: //! Character type Chris@16: typedef CharT char_type; Chris@16: //! Character traits Chris@16: typedef TraitsT traits_type; Chris@16: //! Memory allocator Chris@16: typedef AllocatorT allocator_type; Chris@16: //! Stream buffer type Chris@16: typedef boost::log::aux::basic_ostringstreambuf< char_type, traits_type, allocator_type > streambuf_type; Chris@16: //! Target string type Chris@16: typedef typename streambuf_type::string_type string_type; Chris@16: Chris@16: //! Stream type Chris@16: typedef std::basic_ostream< char_type, traits_type > ostream_type; Chris@16: //! Stream position type Chris@16: typedef typename ostream_type::pos_type pos_type; Chris@16: //! Stream offset type Chris@16: typedef typename ostream_type::off_type off_type; Chris@16: //! Integer type for characters Chris@16: typedef typename ostream_type::int_type int_type; Chris@16: Chris@16: typedef typename ostream_type::failure failure; Chris@16: typedef typename ostream_type::fmtflags fmtflags; Chris@16: typedef typename ostream_type::iostate iostate; Chris@16: typedef typename ostream_type::openmode openmode; Chris@16: typedef typename ostream_type::seekdir seekdir; Chris@16: typedef typename ostream_type::Init Init; Chris@16: Chris@16: typedef typename ostream_type::event event; Chris@16: typedef typename ostream_type::event_callback event_callback; Chris@16: Chris@16: class sentry : Chris@16: public ostream_type::sentry Chris@16: { Chris@16: typedef typename ostream_type::sentry base_type; Chris@16: Chris@16: public: Chris@16: explicit sentry(basic_formatting_ostream& strm) : base_type(strm.stream()) Chris@16: { Chris@16: } Chris@16: Chris@16: BOOST_DELETED_FUNCTION(sentry(sentry const&)) Chris@16: BOOST_DELETED_FUNCTION(sentry& operator= (sentry const&)) Chris@16: }; Chris@16: Chris@16: private: Chris@16: // Function types Chris@16: typedef std::ios_base& (*ios_base_manip)(std::ios_base&); Chris@16: typedef std::basic_ios< char_type, traits_type >& (*basic_ios_manip)(std::basic_ios< char_type, traits_type >&); Chris@16: typedef ostream_type& (*stream_manip)(ostream_type&); Chris@16: Chris@16: public: Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags boolalpha = ostream_type::boolalpha; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags dec = ostream_type::dec; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags fixed = ostream_type::fixed; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags hex = ostream_type::hex; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags internal = ostream_type::internal; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags left = ostream_type::left; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags oct = ostream_type::oct; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags right = ostream_type::right; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags scientific = ostream_type::scientific; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags showbase = ostream_type::showbase; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags showpoint = ostream_type::showpoint; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags skipws = ostream_type::skipws; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags unitbuf = ostream_type::unitbuf; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags uppercase = ostream_type::uppercase; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags adjustfield = ostream_type::adjustfield; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags basefield = ostream_type::basefield; Chris@16: static BOOST_CONSTEXPR_OR_CONST fmtflags floatfield = ostream_type::floatfield; Chris@16: Chris@16: static BOOST_CONSTEXPR_OR_CONST iostate badbit = ostream_type::badbit; Chris@16: static BOOST_CONSTEXPR_OR_CONST iostate eofbit = ostream_type::eofbit; Chris@16: static BOOST_CONSTEXPR_OR_CONST iostate failbit = ostream_type::failbit; Chris@16: static BOOST_CONSTEXPR_OR_CONST iostate goodbit = ostream_type::goodbit; Chris@16: Chris@16: static BOOST_CONSTEXPR_OR_CONST openmode app = ostream_type::app; Chris@16: static BOOST_CONSTEXPR_OR_CONST openmode ate = ostream_type::ate; Chris@16: static BOOST_CONSTEXPR_OR_CONST openmode binary = ostream_type::binary; Chris@16: static BOOST_CONSTEXPR_OR_CONST openmode in = ostream_type::in; Chris@16: static BOOST_CONSTEXPR_OR_CONST openmode out = ostream_type::out; Chris@16: static BOOST_CONSTEXPR_OR_CONST openmode trunc = ostream_type::trunc; Chris@16: Chris@16: static BOOST_CONSTEXPR_OR_CONST seekdir beg = ostream_type::beg; Chris@16: static BOOST_CONSTEXPR_OR_CONST seekdir cur = ostream_type::cur; Chris@16: static BOOST_CONSTEXPR_OR_CONST seekdir end = ostream_type::end; Chris@16: Chris@16: static BOOST_CONSTEXPR_OR_CONST event erase_event = ostream_type::erase_event; Chris@16: static BOOST_CONSTEXPR_OR_CONST event imbue_event = ostream_type::imbue_event; Chris@16: static BOOST_CONSTEXPR_OR_CONST event copyfmt_event = ostream_type::copyfmt_event; Chris@16: Chris@16: private: Chris@16: mutable streambuf_type m_streambuf; Chris@16: ostream_type m_stream; Chris@16: Chris@16: public: Chris@16: /*! Chris@16: * Default constructor. Creates an empty record that is equivalent to the invalid record handle. Chris@16: * The stream capability is not available after construction. Chris@16: * Chris@16: * \post !*this == true Chris@16: */ Chris@16: basic_formatting_ostream() : m_stream(&m_streambuf) Chris@16: { Chris@16: init_stream(); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Initializing constructor. Attaches the string to the constructed stream. Chris@16: * The string will be used to store the formatted characters. Chris@16: * Chris@16: * \post !*this == false Chris@16: * \param str The string buffer to attach. Chris@16: */ Chris@16: explicit basic_formatting_ostream(string_type& str) : Chris@16: m_streambuf(str), Chris@16: m_stream(&m_streambuf) Chris@16: { Chris@16: init_stream(); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record. Chris@16: */ Chris@16: ~basic_formatting_ostream() Chris@16: { Chris@16: if (m_streambuf.storage()) Chris@16: flush(); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Attaches the stream to the string. The string will be used to store the formatted characters. Chris@16: * Chris@16: * \param str The string buffer to attach. Chris@16: */ Chris@16: void attach(string_type& str) Chris@16: { Chris@16: m_streambuf.attach(str); Chris@16: m_stream.clear(ostream_type::goodbit); Chris@16: } Chris@16: /*! Chris@16: * Detaches the stream from the string. Any buffered data is flushed to the string. Chris@16: */ Chris@16: void detach() Chris@16: { Chris@16: m_streambuf.detach(); Chris@16: m_stream.clear(ostream_type::badbit); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * \returns Reference to the attached string. The string must be attached before calling this method. Chris@16: */ Chris@16: string_type const& str() const Chris@16: { Chris@16: string_type* storage = m_streambuf.storage(); Chris@16: BOOST_ASSERT(storage != NULL); Chris@16: Chris@16: m_streambuf.pubsync(); Chris@16: Chris@16: return *storage; Chris@16: } Chris@16: Chris@16: /*! Chris@16: * \returns Reference to the wrapped stream Chris@16: */ Chris@16: ostream_type& stream() { return m_stream; } Chris@16: Chris@16: /*! Chris@16: * \returns Reference to the wrapped stream Chris@16: */ Chris@16: ostream_type const& stream() const { return m_stream; } Chris@16: Chris@16: // std::ios_base method forwarders Chris@16: fmtflags flags() const { return m_stream.flags(); } Chris@16: fmtflags flags(fmtflags f) { return m_stream.flags(f); } Chris@16: fmtflags setf(fmtflags f) { return m_stream.setf(f); } Chris@16: fmtflags setf(fmtflags f, fmtflags mask) { return m_stream.setf(f, mask); } Chris@16: void unsetf(fmtflags f) { m_stream.unsetf(f); } Chris@16: Chris@16: std::streamsize precision() const { return m_stream.precision(); } Chris@16: std::streamsize precision(std::streamsize p) { return m_stream.precision(p); } Chris@16: Chris@16: std::streamsize width() const { return m_stream.width(); } Chris@16: std::streamsize width(std::streamsize w) { return m_stream.width(w); } Chris@16: Chris@16: std::locale getloc() const { return m_stream.getloc(); } Chris@16: std::locale imbue(std::locale const& loc) { return m_stream.imbue(loc); } Chris@16: Chris@16: static int xalloc() { return ostream_type::xalloc(); } Chris@16: long& iword(int index) { return m_stream.iword(index); } Chris@16: void*& pword(int index) { return m_stream.pword(index); } Chris@16: Chris@16: void register_callback(event_callback fn, int index) { m_stream.register_callback(fn, index); } Chris@16: Chris@16: static bool sync_with_stdio(bool sync = true) { return ostream_type::sync_with_stdio(sync); } Chris@16: Chris@16: // std::basic_ios method forwarders Chris@16: BOOST_EXPLICIT_OPERATOR_BOOL() Chris@16: bool operator! () const { return !m_stream; } Chris@16: Chris@16: iostate rdstate() const { return m_stream.rdstate(); } Chris@16: void clear(iostate state = goodbit) { m_stream.clear(state); } Chris@16: void setstate(iostate state) { m_stream.setstate(state); } Chris@16: bool good() const { return m_stream.good(); } Chris@16: bool eof() const { return m_stream.eof(); } Chris@16: bool fail() const { return m_stream.fail(); } Chris@16: bool bad() const { return m_stream.bad(); } Chris@16: Chris@16: iostate exceptions() const { return m_stream.exceptions(); } Chris@16: void exceptions(iostate s) { m_stream.exceptions(s); } Chris@16: Chris@16: ostream_type* tie() const { return m_stream.tie(); } Chris@16: ostream_type* tie(ostream_type* strm) { return m_stream.tie(strm); } Chris@16: Chris@16: streambuf_type* rdbuf() const { return &m_streambuf; } Chris@16: Chris@16: basic_formatting_ostream& copyfmt(std::basic_ios< char_type, traits_type >& rhs) Chris@16: { Chris@16: m_stream.copyfmt(rhs); Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& copyfmt(basic_formatting_ostream& rhs) Chris@16: { Chris@16: m_stream.copyfmt(rhs.stream()); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: char_type fill() const { return m_stream.fill(); } Chris@16: char_type fill(char_type ch) { return m_stream.fill(ch); } Chris@16: Chris@16: char narrow(char_type ch, char def) const { return m_stream.narrow(ch, def); } Chris@16: char_type widen(char ch) const { return m_stream.widen(ch); } Chris@16: Chris@16: // std::basic_ostream method forwarders Chris@16: basic_formatting_ostream& flush() Chris@16: { Chris@16: m_stream.flush(); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: pos_type tellp() { return m_stream.tellp(); } Chris@16: basic_formatting_ostream& seekp(pos_type pos) Chris@16: { Chris@16: m_stream.seekp(pos); Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& seekp(off_type off, std::ios_base::seekdir dir) Chris@16: { Chris@16: m_stream.seekp(off, dir); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: basic_formatting_ostream& put(char_type c) Chris@16: { Chris@16: m_stream.put(c); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template< typename OtherCharT > Chris@16: typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type Chris@16: put(OtherCharT c) Chris@16: { Chris@16: write(&c, 1); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: basic_formatting_ostream& write(const char_type* p, std::streamsize size) Chris@16: { Chris@16: m_stream.write(p, size); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template< typename OtherCharT > Chris@16: typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type Chris@16: write(const OtherCharT* p, std::streamsize size) Chris@16: { Chris@16: sentry guard(*this); Chris@16: if (guard) Chris@16: { Chris@16: m_stream.flush(); Chris@16: Chris@16: string_type* storage = m_streambuf.storage(); Chris@16: aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_stream.getloc()); Chris@16: } Chris@16: Chris@16: return *this; Chris@16: } Chris@16: Chris@16: basic_formatting_ostream& operator<< (ios_base_manip manip) Chris@16: { Chris@16: m_stream << manip; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (basic_ios_manip manip) Chris@16: { Chris@16: m_stream << manip; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (stream_manip manip) Chris@16: { Chris@16: m_stream << manip; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: basic_formatting_ostream& operator<< (char c) Chris@16: { Chris@16: return this->formatted_write(&c, 1); Chris@16: } Chris@16: basic_formatting_ostream& operator<< (const char* p) Chris@16: { Chris@16: return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char >::length(p))); Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) Chris@16: basic_formatting_ostream& operator<< (wchar_t c) Chris@16: { Chris@16: return this->formatted_write(&c, 1); Chris@16: } Chris@16: basic_formatting_ostream& operator<< (const wchar_t* p) Chris@16: { Chris@16: return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< wchar_t >::length(p))); Chris@16: } Chris@16: #endif Chris@16: #if !defined(BOOST_NO_CXX11_CHAR16_T) Chris@16: basic_formatting_ostream& operator<< (char16_t c) Chris@16: { Chris@16: return this->formatted_write(&c, 1); Chris@16: } Chris@16: basic_formatting_ostream& operator<< (const char16_t* p) Chris@16: { Chris@16: return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char16_t >::length(p))); Chris@16: } Chris@16: #endif Chris@16: #if !defined(BOOST_NO_CXX11_CHAR32_T) Chris@16: basic_formatting_ostream& operator<< (char32_t c) Chris@16: { Chris@16: return this->formatted_write(&c, 1); Chris@16: } Chris@16: basic_formatting_ostream& operator<< (const char32_t* p) Chris@16: { Chris@16: return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char32_t >::length(p))); Chris@16: } Chris@16: #endif Chris@16: Chris@16: basic_formatting_ostream& operator<< (bool value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (signed char value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (unsigned char value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (short value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (unsigned short value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (int value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (unsigned int value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (long value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (unsigned long value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: #if !defined(BOOST_NO_LONG_LONG) Chris@16: basic_formatting_ostream& operator<< (long long value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (unsigned long long value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: Chris@16: basic_formatting_ostream& operator<< (float value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (double value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: basic_formatting_ostream& operator<< (long double value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: basic_formatting_ostream& operator<< (const void* value) Chris@16: { Chris@16: m_stream << value; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: basic_formatting_ostream& operator<< (std::basic_streambuf< char_type, traits_type >* buf) Chris@16: { Chris@16: m_stream << buf; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT > Chris@16: friend typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type Chris@16: operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str) Chris@16: { Chris@16: return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size())); Chris@16: } Chris@16: Chris@16: template< typename OtherCharT, typename OtherTraitsT > Chris@16: friend typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type Chris@16: operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str) Chris@16: { Chris@16: return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size())); Chris@16: } Chris@16: Chris@16: template< typename OtherCharT, typename OtherTraitsT > Chris@16: friend typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type Chris@16: operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str) Chris@16: { Chris@16: return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size())); Chris@16: } Chris@16: Chris@16: private: Chris@16: void init_stream() Chris@16: { Chris@16: m_stream.clear(m_streambuf.storage() ? ostream_type::goodbit : ostream_type::badbit); Chris@16: m_stream.flags Chris@16: ( Chris@16: ostream_type::dec | Chris@16: ostream_type::skipws | Chris@16: ostream_type::boolalpha // this differs from the default stream flags but makes logs look better Chris@16: ); Chris@16: m_stream.width(0); Chris@16: m_stream.precision(6); Chris@16: m_stream.fill(static_cast< char_type >(' ')); Chris@16: } Chris@16: Chris@16: basic_formatting_ostream& formatted_write(const char_type* p, std::streamsize size) Chris@16: { Chris@16: sentry guard(*this); Chris@16: if (guard) Chris@16: { Chris@16: m_stream.flush(); Chris@16: Chris@16: if (m_stream.width() <= size) Chris@16: m_streambuf.storage()->append(p, static_cast< std::size_t >(size)); Chris@16: else Chris@16: this->aligned_write(p, size); Chris@16: Chris@16: m_stream.width(0); Chris@16: } Chris@16: Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template< typename OtherCharT > Chris@16: basic_formatting_ostream& formatted_write(const OtherCharT* p, std::streamsize size) Chris@16: { Chris@16: sentry guard(*this); Chris@16: if (guard) Chris@16: { Chris@16: m_stream.flush(); Chris@16: Chris@16: if (m_stream.width() <= size) Chris@16: aux::code_convert(p, static_cast< std::size_t >(size), *m_streambuf.storage(), m_stream.getloc()); Chris@16: else Chris@16: this->aligned_write(p, size); Chris@16: Chris@16: m_stream.width(0); Chris@16: } Chris@16: Chris@16: return *this; Chris@16: } Chris@16: Chris@16: void aligned_write(const char_type* p, std::streamsize size); Chris@16: Chris@16: template< typename OtherCharT > Chris@16: void aligned_write(const OtherCharT* p, std::streamsize size); Chris@16: Chris@16: //! Copy constructor (closed) Chris@16: BOOST_DELETED_FUNCTION(basic_formatting_ostream(basic_formatting_ostream const& that)) Chris@16: //! Assignment (closed) Chris@16: BOOST_DELETED_FUNCTION(basic_formatting_ostream& operator= (basic_formatting_ostream const& that)) Chris@16: }; Chris@16: Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::boolalpha; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::dec; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fixed; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::hex; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::internal; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::left; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::oct; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::right; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::scientific; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showbase; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showpoint; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::skipws; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::unitbuf; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::uppercase; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::adjustfield; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::basefield; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::floatfield; Chris@16: Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::badbit; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::eofbit; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::failbit; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::goodbit; Chris@16: Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::app; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::ate; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::binary; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::in; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::out; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::trunc; Chris@16: Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::beg; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::cur; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::end; Chris@16: Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::erase_event; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::imbue_event; Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::copyfmt_event; Chris@16: Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const char_type* p, std::streamsize size) Chris@16: { Chris@16: string_type* const storage = m_streambuf.storage(); Chris@16: typename string_type::size_type const alignment_size = Chris@16: static_cast< typename string_type::size_type >(m_stream.width() - size); Chris@16: const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left; Chris@16: if (align_left) Chris@16: { Chris@16: storage->append(p, static_cast< std::size_t >(size)); Chris@16: storage->append(alignment_size, m_stream.fill()); Chris@16: } Chris@16: else Chris@16: { Chris@16: storage->append(alignment_size, m_stream.fill()); Chris@16: storage->append(p, static_cast< std::size_t >(size)); Chris@16: } Chris@16: } Chris@16: Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT > Chris@16: template< typename OtherCharT > Chris@16: void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const OtherCharT* p, std::streamsize size) Chris@16: { Chris@16: string_type* const storage = m_streambuf.storage(); Chris@16: typename string_type::size_type const alignment_size = Chris@16: static_cast< typename string_type::size_type >(m_stream.width() - size); Chris@16: const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left; Chris@16: if (align_left) Chris@16: { Chris@16: aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_stream.getloc()); Chris@16: storage->append(alignment_size, m_stream.fill()); Chris@16: } Chris@16: else Chris@16: { Chris@16: storage->append(alignment_size, m_stream.fill()); Chris@16: aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_stream.getloc()); Chris@16: } Chris@16: } Chris@16: Chris@16: template< typename CharT, typename TraitsT, typename AllocatorT, typename T > Chris@16: inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >& Chris@16: operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, T const& value) Chris@16: { Chris@16: strm.stream() << value; Chris@16: return strm; Chris@16: } Chris@16: Chris@101: template< typename CharT, typename TraitsT, typename AllocatorT, typename T > Chris@101: inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >& Chris@101: operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, T& value) Chris@101: { Chris@101: strm.stream() << value; Chris@101: return strm; Chris@101: } Chris@101: Chris@101: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@101: Chris@101: template< typename CharT, typename TraitsT, typename AllocatorT, typename T > Chris@101: inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >& Chris@101: operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >&& strm, T const& value) Chris@101: { Chris@101: static_cast< basic_formatting_ostream< CharT, TraitsT, AllocatorT >& >(strm) << value; Chris@101: return strm; Chris@101: } Chris@101: Chris@101: template< typename CharT, typename TraitsT, typename AllocatorT, typename T > Chris@101: inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >& Chris@101: operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >&& strm, T& value) Chris@101: { Chris@101: static_cast< basic_formatting_ostream< CharT, TraitsT, AllocatorT >& >(strm) << value; Chris@101: return strm; Chris@101: } Chris@101: Chris@101: #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@101: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_