summaryrefslogtreecommitdiff
path: root/boost/log/sources/record_ostream.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/log/sources/record_ostream.hpp')
-rw-r--r--boost/log/sources/record_ostream.hpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/boost/log/sources/record_ostream.hpp b/boost/log/sources/record_ostream.hpp
index b3c58e2ab0..c1e80593aa 100644
--- a/boost/log/sources/record_ostream.hpp
+++ b/boost/log/sources/record_ostream.hpp
@@ -39,6 +39,18 @@ namespace boost {
BOOST_LOG_OPEN_NAMESPACE
+template< typename CharT >
+class basic_record_ostream;
+
+namespace aux {
+
+template< typename StreamT, typename R >
+struct enable_if_record_ostream {};
+template< typename CharT, typename R >
+struct enable_if_record_ostream< basic_record_ostream< CharT >, R > { typedef R type; };
+
+} // namespace aux
+
/*!
* \brief Logging record adapter with a streaming capability
*
@@ -174,6 +186,55 @@ typedef basic_record_ostream< char > record_ostream; //!< Convenience typ
typedef basic_record_ostream< wchar_t > wrecord_ostream; //!< Convenience typedef for wide-character logging
#endif
+// Implementation note: these operators below should be the least attractive for the compiler
+// so that user's overloads are chosen, when present. We use function template partial ordering for this purpose.
+// We also don't use perfect forwarding for the right hand argument because in ths case the generic overload
+// would be more preferred than the typical one written by users:
+//
+// record_ostream& operator<< (record_ostream& strm, my_type const& arg);
+//
+// This is because my_type rvalues require adding const to the type, which counts as a conversion that is not required
+// if there is a perfect forwarding overload.
+template< typename StreamT, typename T >
+inline typename boost::log::aux::enable_if_record_ostream< StreamT, StreamT& >::type
+operator<< (StreamT& strm, T const& value)
+{
+ typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
+ static_cast< formatting_ostream_type& >(strm) << value;
+ return strm;
+}
+
+template< typename StreamT, typename T >
+inline typename boost::log::aux::enable_if_record_ostream< StreamT, StreamT& >::type
+operator<< (StreamT& strm, T& value)
+{
+ typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
+ static_cast< formatting_ostream_type& >(strm) << value;
+ return strm;
+}
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+template< typename StreamT, typename T >
+inline typename boost::log::aux::enable_if_record_ostream< StreamT, StreamT& >::type
+operator<< (StreamT&& strm, T const& value)
+{
+ typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
+ static_cast< formatting_ostream_type& >(strm) << value;
+ return strm;
+}
+
+template< typename StreamT, typename T >
+inline typename boost::log::aux::enable_if_record_ostream< StreamT, StreamT& >::type
+operator<< (StreamT&& strm, T& value)
+{
+ typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
+ static_cast< formatting_ostream_type& >(strm) << value;
+ return strm;
+}
+
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
namespace aux {
//! Internal class that provides formatting streams for record pumps