$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r84113 - in trunk: boost/log/detail boost/log/utility boost/log/utility/manipulators libs/log/doc
From: andrey.semashev_at_[hidden]
Date: 2013-05-02 13:28:28
Author: andysem
Date: 2013-05-02 13:28:27 EDT (Thu, 02 May 2013)
New Revision: 84113
URL: http://svn.boost.org/trac/boost/changeset/84113
Log:
basic_formatting_ostream no longer derives from std::basic_ostream, but rather reimplements its and its base classes interface closely. This solves problems with overloading operator<< for basic_formatting_ostream and user-defined types. This will break user's code if it relied on the inheritance from the standard stream types (such as passing basic_formatting_ostream object as an argument to a function receiving std::basic_ostream).
Text files modified: 
   trunk/boost/log/detail/decomposed_time.hpp      |     2                                         
   trunk/boost/log/utility/formatting_ostream.hpp  |   404 ++++++++++++++++++++++++++++++--------- 
   trunk/boost/log/utility/manipulators/to_log.hpp |     5                                         
   trunk/libs/log/doc/changelog.qbk                |    12 +                                       
   trunk/libs/log/doc/log.qbk                      |     1                                         
   5 files changed, 319 insertions(+), 105 deletions(-)
Modified: trunk/boost/log/detail/decomposed_time.hpp
==============================================================================
--- trunk/boost/log/detail/decomposed_time.hpp	(original)
+++ trunk/boost/log/detail/decomposed_time.hpp	2013-05-02 13:28:27 EDT (Thu, 02 May 2013)
@@ -214,7 +214,7 @@
         typedef std::time_put< char_type > facet_type;
         typedef typename facet_type::iter_type iter_type;
         std::tm t = to_tm(static_cast< decomposed_time const& >(ctx.value));
-        std::use_facet< facet_type >(ctx.strm.getloc()).put(iter_type(ctx.strm), ctx.strm, ' ', &t, FormatCharV);
+        std::use_facet< facet_type >(ctx.strm.getloc()).put(iter_type(ctx.strm.stream()), ctx.strm.stream(), ' ', &t, FormatCharV);
         ctx.strm.flush();
     }
 
Modified: trunk/boost/log/utility/formatting_ostream.hpp
==============================================================================
--- trunk/boost/log/utility/formatting_ostream.hpp	(original)
+++ trunk/boost/log/utility/formatting_ostream.hpp	2013-05-02 13:28:27 EDT (Thu, 02 May 2013)
@@ -19,16 +19,13 @@
 #include <string>
 #include <memory>
 #include <locale>
-#include <boost/ref.hpp>
 #include <boost/type_traits/remove_cv.hpp>
-#include <boost/utility/addressof.hpp>
-#include <boost/utility/base_from_member.hpp>
 #include <boost/log/detail/config.hpp>
 #include <boost/log/detail/attachable_sstream_buf.hpp>
 #include <boost/log/detail/code_conversion.hpp>
-#include <boost/log/detail/parameter_tools.hpp>
 #include <boost/log/utility/string_literal_fwd.hpp>
 #include <boost/log/utility/formatting_ostream_fwd.hpp>
+#include <boost/log/utility/explicit_operator_bool.hpp>
 #include <boost/log/detail/header.hpp>
 
 #ifdef BOOST_LOG_HAS_PRAGMA_ONCE
@@ -37,21 +34,18 @@
 
 namespace boost {
 
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+// This forward is needed for operator<<
+template< typename CharT, typename TraitsT >
+class basic_string_ref;
+
+#endif
+
 BOOST_LOG_OPEN_NAMESPACE
 
 namespace aux {
 
-template< typename T, typename R, typename VoidT = void >
-struct enable_basic_formatting_ostream_generic_insert_operator { typedef R type; };
-template< typename T, typename R >
-struct enable_basic_formatting_ostream_generic_insert_operator< T, R, typename T::_has_basic_formatting_ostream_insert_operator > {};
-template< typename T, typename R >
-struct enable_basic_formatting_ostream_generic_insert_operator< T*, R > {};
-template< typename CharT, typename TraitsT, typename AllocatorT, typename R >
-struct enable_basic_formatting_ostream_generic_insert_operator< std::basic_string< CharT, TraitsT, AllocatorT >, R > {};
-template< typename CharT, typename TraitsT, typename R >
-struct enable_basic_formatting_ostream_generic_insert_operator< basic_string_literal< CharT, TraitsT >, R > {};
-
 template< typename T, typename R >
 struct enable_if_char_type {};
 template< typename R >
@@ -70,24 +64,29 @@
 } // namespace aux
 
 /*!
- * \brief Stream for log records formatting.
+ * \brief Stream wrapper for log records formatting.
  *
- * This stream type is used by the library for log record formatting. It implements the standard string stream interface
- * with a few extensions:
+ * This stream wrapper is used by the library for log record formatting. It implements the standard string stream interface
+ * with a few differences:
  *
+ * \li It does not derive from standard types <tt>std::basic_ostream</tt>, <tt>std::basic_ios</tt> and <tt>std::ios_base</tt>,
+ *     although it tries to implement their interfaces closely. There are a few small differences, mostly regarding <tt>rdbuf</tt>
+ *     and <tt>str</tt> signatures, as well as the supported insertion operator overloads. The actual wrapped stream can be accessed
+ *     through the <tt>stream</tt> methods.
  * \li By default, \c bool values are formatted using alphabetical representation rather than numeric.
  * \li The stream supports writing strings of character types different from the stream character type. The stream will perform
  *     character code conversion as needed using the imbued locale.
  * \li The stream operates on an external string object rather than on the embedded one. The string can be attached or detached
  *     from the stream dynamically.
+ *
+ * Although <tt>basic_formatting_ostream</tt> does not derive from <tt>std::basic_ostream</tt>, users are not required to add
+ * special overloads of \c operator<< for it since the stream will by default reuse the operators for <tt>std::basic_ostream</tt>.
+ * However, one can define special overloads of \c operator<< for <tt>basic_formatting_ostream</tt> if a certain type needs
+ * special formatting when output to log.
  */
 template< typename CharT, typename TraitsT, typename AllocatorT >
-class basic_formatting_ostream :
-    private base_from_member< boost::log::aux::basic_ostringstreambuf< CharT, TraitsT, AllocatorT > >,
-    public std::basic_ostream< CharT, TraitsT >
+class basic_formatting_ostream
 {
-    typedef base_from_member< boost::log::aux::basic_ostringstreambuf< CharT, TraitsT, AllocatorT > > streambuf_base_type;
-
 public:
     //! Character type
     typedef CharT char_type;
@@ -106,6 +105,29 @@
     typedef typename ostream_type::pos_type pos_type;
     //! Stream offset type
     typedef typename ostream_type::off_type off_type;
+    //! Integer type for characters
+    typedef typename ostream_type::int_type int_type;
+
+    typedef typename ostream_type::failure failure;
+    typedef typename ostream_type::fmtflags fmtflags;
+    typedef typename ostream_type::iostate iostate;
+    typedef typename ostream_type::openmode openmode;
+    typedef typename ostream_type::seekdir seekdir;
+    typedef typename ostream_type::Init Init;
+
+    typedef typename ostream_type::event event;
+    typedef typename ostream_type::event_callback event_callback;
+
+    class sentry :
+        public ostream_type::sentry
+    {
+        typedef typename ostream_type::sentry base_type;
+
+    public:
+        explicit sentry(basic_formatting_ostream& strm) : base_type(strm.stream())
+        {
+        }
+    };
 
 private:
     //  Function types
@@ -114,13 +136,56 @@
     typedef ostream_type& (*stream_manip)(ostream_type&);
 
 public:
+    static BOOST_CONSTEXPR_OR_CONST fmtflags boolalpha = ostream_type::boolalpha;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags dec = ostream_type::dec;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags fixed = ostream_type::fixed;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags hex = ostream_type::hex;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags internal = ostream_type::internal;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags left = ostream_type::left;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags oct = ostream_type::oct;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags right = ostream_type::right;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags scientific = ostream_type::scientific;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags showbase = ostream_type::showbase;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags showpoint = ostream_type::showpoint;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags skipws = ostream_type::skipws;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags unitbuf = ostream_type::unitbuf;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags uppercase = ostream_type::uppercase;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags adjustfield = ostream_type::adjustfield;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags basefield = ostream_type::basefield;
+    static BOOST_CONSTEXPR_OR_CONST fmtflags floatfield = ostream_type::floatfield;
+
+    static BOOST_CONSTEXPR_OR_CONST iostate badbit = ostream_type::badbit;
+    static BOOST_CONSTEXPR_OR_CONST iostate eofbit = ostream_type::eofbit;
+    static BOOST_CONSTEXPR_OR_CONST iostate failbit = ostream_type::failbit;
+    static BOOST_CONSTEXPR_OR_CONST iostate goodbit = ostream_type::goodbit;
+
+    static BOOST_CONSTEXPR_OR_CONST openmode app = ostream_type::app;
+    static BOOST_CONSTEXPR_OR_CONST openmode ate = ostream_type::ate;
+    static BOOST_CONSTEXPR_OR_CONST openmode binary = ostream_type::binary;
+    static BOOST_CONSTEXPR_OR_CONST openmode in = ostream_type::in;
+    static BOOST_CONSTEXPR_OR_CONST openmode out = ostream_type::out;
+    static BOOST_CONSTEXPR_OR_CONST openmode trunc = ostream_type::trunc;
+
+    static BOOST_CONSTEXPR_OR_CONST seekdir beg = ostream_type::beg;
+    static BOOST_CONSTEXPR_OR_CONST seekdir cur = ostream_type::cur;
+    static BOOST_CONSTEXPR_OR_CONST seekdir end = ostream_type::end;
+
+    static BOOST_CONSTEXPR_OR_CONST event erase_event = ostream_type::erase_event;
+    static BOOST_CONSTEXPR_OR_CONST event imbue_event = ostream_type::imbue_event;
+    static BOOST_CONSTEXPR_OR_CONST event copyfmt_event = ostream_type::copyfmt_event;
+
+private:
+    mutable streambuf_type m_streambuf;
+    ostream_type m_stream;
+
+public:
     /*!
      * Default constructor. Creates an empty record that is equivalent to the invalid record handle.
      * The stream capability is not available after construction.
      *
      * \post <tt>!*this == true</tt>
      */
-    basic_formatting_ostream() : ostream_type(&this->streambuf_base_type::member)
+    basic_formatting_ostream() : m_stream(&m_streambuf)
     {
         init_stream();
     }
@@ -133,8 +198,8 @@
      * \param str The string buffer to attach.
      */
     explicit basic_formatting_ostream(string_type& str) :
-        streambuf_base_type(boost::ref(str)),
-        ostream_type(&this->streambuf_base_type::member)
+        m_streambuf(str),
+        m_stream(&m_streambuf)
     {
         init_stream();
     }
@@ -144,7 +209,7 @@
      */
     ~basic_formatting_ostream()
     {
-        if (this->streambuf_base_type::member.storage())
+        if (m_streambuf.storage())
             flush();
     }
 
@@ -155,58 +220,124 @@
      */
     void attach(string_type& str)
     {
-        streambuf_base_type::member.attach(str);
-        ostream_type::clear(ostream_type::goodbit);
+        m_streambuf.attach(str);
+        m_stream.clear(ostream_type::goodbit);
     }
     /*!
      * Detaches the stream from the string. Any buffered data is flushed to the string.
      */
     void detach()
     {
-        streambuf_base_type::member.detach();
-        ostream_type::clear(ostream_type::badbit);
+        m_streambuf.detach();
+        m_stream.clear(ostream_type::badbit);
     }
 
     /*!
      * \returns Reference to the attached string. The string must be attached before calling this method.
      */
-    string_type const& str()
+    string_type const& str() const
     {
-        flush();
-
-        string_type* storage = this->streambuf_base_type::member.storage();
+        string_type* storage = m_streambuf.storage();
         BOOST_ASSERT(storage != NULL);
 
+        m_streambuf.pubsync();
+
         return *storage;
     }
 
-    //  Stream method overrides
-    basic_formatting_ostream& flush()
+    /*!
+     * \returns Reference to the wrapped stream
+     */
+    ostream_type& stream() { return m_stream; }
+
+    /*!
+     * \returns Reference to the wrapped stream
+     */
+    ostream_type const& stream() const { return m_stream; }
+
+    // std::ios_base method forwarders
+    fmtflags flags() const { return m_stream.flags(); }
+    fmtflags flags(fmtflags f) { return m_stream.flags(f); }
+    fmtflags setf(fmtflags f) { return m_stream.setf(f); }
+    fmtflags setf(fmtflags f, fmtflags mask) { return m_stream.setf(f, mask); }
+    void unsetf(fmtflags f) { m_stream.unsetf(f); }
+
+    std::streamsize precision() const { return m_stream.precision(); }
+    std::streamsize precision(std::streamsize p) { return m_stream.precision(p); }
+
+    std::streamsize width() const { return m_stream.width(); }
+    std::streamsize width(std::streamsize w) { return m_stream.width(w); }
+
+    std::locale getloc() const { return m_stream.getloc(); }
+    std::locale imbue(std::locale const& loc) { return m_stream.imbue(loc); }
+
+    static int xalloc() { return ostream_type::xalloc(); }
+    long& iword(int index) { return m_stream.iword(index); }
+    void*& pword(int index) { return m_stream.pword(index); }
+
+    void register_callback(event_callback fn, int index) { m_stream.register_callback(fn, index); }
+
+    static bool sync_with_stdio(bool sync = true) { return ostream_type::sync_with_stdio(sync); }
+
+    // std::basic_ios method forwarders
+    BOOST_LOG_EXPLICIT_OPERATOR_BOOL()
+    bool operator! () const { return !m_stream; }
+
+    iostate rdstate() const { return m_stream.rdstate(); }
+    void clear(iostate state = goodbit) { m_stream.clear(state); }
+    void setstate(iostate state) { m_stream.setstate(state); }
+    bool good() const { return m_stream.good(); }
+    bool eof() const { return m_stream.eof(); }
+    bool fail() const { return m_stream.fail(); }
+    bool bad() const { return m_stream.bad(); }
+
+    iostate exceptions() const { return m_stream.exceptions(); }
+    void exceptions(iostate s) { m_stream.exceptions(s); }
+
+    ostream_type* tie() const { return m_stream.tie(); }
+    ostream_type* tie(ostream_type* strm) { return m_stream.tie(strm); }
+
+    streambuf_type* rdbuf() const { return &m_streambuf; }
+
+    basic_formatting_ostream& copyfmt(std::basic_ios< char_type, traits_type >& rhs)
     {
-        ostream_type::flush();
+        m_stream.copyfmt(rhs);
         return *this;
     }
-
-    basic_formatting_ostream& seekp(pos_type pos)
+    basic_formatting_ostream& copyfmt(basic_formatting_ostream& rhs)
     {
-        ostream_type::seekp(pos);
+        m_stream.copyfmt(rhs.stream());
         return *this;
     }
 
-    basic_formatting_ostream& seekp(off_type off, std::ios_base::seekdir dir)
+    char_type fill() const { return m_stream.fill(); }
+    char_type fill(char_type ch) { return m_stream.fill(ch); }
+
+    char narrow(char_type ch, char def) const { return m_stream.narrow(ch, def); }
+    char_type widen(char ch) const { return m_stream.widen(ch); }
+
+    // std::basic_ostream method forwarders
+    basic_formatting_ostream& flush()
     {
-        ostream_type::seekp(off, dir);
+        m_stream.flush();
         return *this;
     }
 
-    streambuf_type* rdbuf()
+    pos_type tellp() { return m_stream.tellp(); }
+    basic_formatting_ostream& seekp(pos_type pos)
     {
-        return &this->streambuf_base_type::member;
+        m_stream.seekp(pos);
+        return *this;
+    }
+    basic_formatting_ostream& seekp(off_type off, std::ios_base::seekdir dir)
+    {
+        m_stream.seekp(off, dir);
+        return *this;
     }
 
     basic_formatting_ostream& put(char_type c)
     {
-        ostream_type::put(c);
+        m_stream.put(c);
         return *this;
     }
 
@@ -214,13 +345,13 @@
     typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
     put(OtherCharT c)
     {
-        write(boost::addressof(c), 1);
+        write(&c, 1);
         return *this;
     }
 
     basic_formatting_ostream& write(const char_type* p, std::streamsize size)
     {
-        ostream_type::write(p, size);
+        m_stream.write(p, size);
         return *this;
     }
 
@@ -230,26 +361,26 @@
     {
         flush();
 
-        string_type* storage = this->streambuf_base_type::member.storage();
+        string_type* storage = m_streambuf.storage();
         BOOST_ASSERT(storage != NULL);
-        aux::code_convert(p, static_cast< std::size_t >(size), *storage, this->getloc());
+        aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_stream.getloc());
 
         return *this;
     }
 
     basic_formatting_ostream& operator<< (ios_base_manip manip)
     {
-        *static_cast< ostream_type* >(this) << manip;
+        m_stream << manip;
         return *this;
     }
     basic_formatting_ostream& operator<< (basic_ios_manip manip)
     {
-        *static_cast< ostream_type* >(this) << manip;
+        m_stream << manip;
         return *this;
     }
     basic_formatting_ostream& operator<< (stream_manip manip)
     {
-        *static_cast< ostream_type* >(this) << manip;
+        m_stream << manip;
         return *this;
     }
 
@@ -303,127 +434,103 @@
 
     basic_formatting_ostream& operator<< (bool value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (signed char value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (unsigned char value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (short value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (unsigned short value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (int value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (unsigned int value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (long value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (unsigned long value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
 #if !defined(BOOST_NO_LONG_LONG)
     basic_formatting_ostream& operator<< (long long value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (unsigned long long value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
 #endif
 
     basic_formatting_ostream& operator<< (float value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (double value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
     basic_formatting_ostream& operator<< (long double value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
 
     basic_formatting_ostream& operator<< (const void* value)
     {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << value;
         return *this;
     }
 
     basic_formatting_ostream& operator<< (std::basic_streambuf< char_type, traits_type >* buf)
     {
-        *static_cast< ostream_type* >(this) << buf;
-        return *this;
-    }
-
-    template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
-    typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
-    operator<< (std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
-    {
-        this->write(str.c_str(), static_cast< std::streamsize >(str.size()));
-        return *this;
-    }
-
-    template< typename OtherCharT, typename OtherTraitsT >
-    typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream& >::type
-    operator<< (basic_string_literal< OtherCharT, OtherTraitsT > const& str)
-    {
-        this->write(str.c_str(), static_cast< std::streamsize >(str.size()));
-        return *this;
-    }
-
-    template< typename T >
-    typename aux::enable_basic_formatting_ostream_generic_insert_operator< T, basic_formatting_ostream& >::type
-    operator<< (T const& value)
-    {
-        *static_cast< ostream_type* >(this) << value;
+        m_stream << buf;
         return *this;
     }
 
 private:
     void init_stream()
     {
-        ostream_type::clear(this->streambuf_base_type::member.storage() ? ostream_type::goodbit : ostream_type::badbit);
-        ostream_type::flags
+        m_stream.clear(m_streambuf.storage() ? ostream_type::goodbit : ostream_type::badbit);
+        m_stream.flags
         (
             ostream_type::dec |
             ostream_type::skipws |
             ostream_type::boolalpha // this differs from the default stream flags but makes logs look better
         );
-        ostream_type::width(0);
-        ostream_type::precision(6);
-        ostream_type::fill(static_cast< char_type >(' '));
+        m_stream.width(0);
+        m_stream.precision(6);
+        m_stream.fill(static_cast< char_type >(' '));
     }
 
     //! Copy constructor (closed)
@@ -432,6 +539,107 @@
     BOOST_LOG_DELETED_FUNCTION(basic_formatting_ostream& operator= (basic_formatting_ostream const& that))
 };
 
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::boolalpha;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::dec;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fixed;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::hex;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::internal;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::left;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::oct;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::right;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::scientific;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showbase;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showpoint;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::skipws;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::unitbuf;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::uppercase;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::adjustfield;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::basefield;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::floatfield;
+
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::badbit;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::eofbit;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::failbit;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::goodbit;
+
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::app;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::ate;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::binary;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::in;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::out;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::trunc;
+
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::beg;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::cur;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::end;
+
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::erase_event;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::imbue_event;
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::copyfmt_event;
+
+
+template< typename CharT, typename TraitsT, typename AllocatorT, typename T >
+inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >&
+operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, T const& value)
+{
+    strm.stream() << value;
+    return strm;
+}
+
+template< typename CharT, typename TraitsT, typename AllocatorT, typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
+inline typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream< CharT, TraitsT, AllocatorT >& >::type
+operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
+{
+    return strm.write(str.c_str(), static_cast< std::streamsize >(str.size()));
+}
+
+template< typename CharT, typename TraitsT, typename AllocatorT, typename OtherCharT, typename OtherTraitsT >
+inline typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream< CharT, TraitsT, AllocatorT >& >::type
+operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
+{
+    return strm.write(str.c_str(), static_cast< std::streamsize >(str.size()));
+}
+
+template< typename CharT, typename TraitsT, typename AllocatorT, typename OtherCharT, typename OtherTraitsT >
+inline typename aux::enable_if_char_type< OtherCharT, basic_formatting_ostream< CharT, TraitsT, AllocatorT >& >::type
+operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
+{
+    return strm.write(str.data(), static_cast< std::streamsize >(str.size()));
+}
+
 BOOST_LOG_CLOSE_NAMESPACE // namespace log
 
 } // namespace boost
Modified: trunk/boost/log/utility/manipulators/to_log.hpp
==============================================================================
--- trunk/boost/log/utility/manipulators/to_log.hpp	(original)
+++ trunk/boost/log/utility/manipulators/to_log.hpp	2013-05-02 13:28:27 EDT (Thu, 02 May 2013)
@@ -35,11 +35,6 @@
 template< typename T, typename TagT = void >
 class to_log_manip
 {
-#ifndef BOOST_LOG_DOXYGEN_PASS
-public:
-    typedef void _has_basic_formatting_ostream_insert_operator;
-#endif
-
 public:
     //! Output value type
     typedef T value_type;
Modified: trunk/libs/log/doc/changelog.qbk
==============================================================================
--- trunk/libs/log/doc/changelog.qbk	(original)
+++ trunk/libs/log/doc/changelog.qbk	2013-05-02 13:28:27 EDT (Thu, 02 May 2013)
@@ -9,7 +9,17 @@
 
 [section:changelog Changelog]
 
-[heading 2.0]
+[heading 2.1]
+
+[*Breaking changes:]
+
+* [class_log_basic_formatting_ostream] no longer derives from `std::basic_ostream`, but rather reimplements its and its base classes interface closely. This solves problems with overloading `operator<<` for [class_log_basic_formatting_ostream] and user-defined types. This will break user's code if it relied on the inheritance from the standard stream types (such as passing [class_log_basic_formatting_ostream] object as an argument to a function receiving `std::basic_ostream`). Please, use the `stream()` member function to access the standard stream. This change will [*not] break the code that outputs user-defined types to a [class_log_basic_formatting_ostream] stream while there are only `operator<<` overloads for the standard stream types - the code will compile and use the standard operator overloads, as before.
+
+[*General changes:]
+
+* Removed the use of deprecated macros of __boost_config__.
+
+[heading 2.0, 13 April 2013]
 
 [*General changes:]
 
Modified: trunk/libs/log/doc/log.qbk
==============================================================================
--- trunk/libs/log/doc/log.qbk	(original)
+++ trunk/libs/log/doc/log.qbk	2013-05-02 13:28:27 EDT (Thu, 02 May 2013)
@@ -16,6 +16,7 @@
 [c++]
 
 [/ Links to external resources /]
+[def __boost_config__ [@http://www.boost.org/doc/libs/release/libs/config/doc/html/index.html Boost.Config]]
 [def __boost_smart_ptr__ [@http://www.boost.org/doc/libs/release/libs/smart_ptr/smart_ptr.htm Boost.SmartPtr]]
 [def __boost_function__ [@http://www.boost.org/doc/libs/release/doc/html/function.html Boost.Function]]
 [def __boost_filesystem__ [@http://www.boost.org/doc/libs/release/libs/filesystem/doc/index.htm Boost.Filesystem]]