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 formatter.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 13.07.2012 Chris@16: * Chris@16: * The header contains a formatter function object definition. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_ Chris@16: Chris@101: #include Chris@16: #include Chris@16: #include Chris@101: #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: #include Chris@101: #include Chris@101: #include Chris@101: #endif 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@101: namespace expressions { Chris@101: Chris@101: namespace aux { Chris@101: Chris@101: // This reference class is a workaround for a Boost.Phoenix bug: https://svn.boost.org/trac/boost/ticket/9363 Chris@101: // It is needed to pass output streams by non-const reference to function objects wrapped in phoenix::bind and phoenix::function. Chris@101: // It's an implementation detail and will be removed when Boost.Phoenix is fixed. Chris@101: template< typename StreamT > Chris@101: class stream_ref : Chris@101: public reference_wrapper< StreamT > Chris@101: { Chris@101: public: Chris@101: BOOST_FORCEINLINE explicit stream_ref(StreamT& strm) : reference_wrapper< StreamT >(strm) Chris@101: { Chris@101: } Chris@101: Chris@101: template< typename T > Chris@101: BOOST_FORCEINLINE StreamT& operator<< (T& val) const Chris@101: { Chris@101: StreamT& strm = this->get(); Chris@101: strm << val; Chris@101: return strm; Chris@101: } Chris@101: Chris@101: template< typename T > Chris@101: BOOST_FORCEINLINE StreamT& operator<< (T const& val) const Chris@101: { Chris@101: StreamT& strm = this->get(); Chris@101: strm << val; Chris@101: return strm; Chris@101: } Chris@101: }; Chris@101: Chris@101: //! Default log record message formatter Chris@101: struct message_formatter Chris@101: { Chris@101: typedef void result_type; Chris@101: Chris@101: message_formatter() : m_MessageName(expressions::tag::message::get_name()) Chris@101: { Chris@101: } Chris@101: Chris@101: template< typename StreamT > Chris@101: result_type operator() (record_view const& rec, StreamT& strm) const Chris@101: { Chris@101: boost::log::visit< expressions::tag::message::value_type >(m_MessageName, rec, boost::log::bind_output(strm)); Chris@101: } Chris@101: Chris@101: private: Chris@101: const attribute_name m_MessageName; Chris@101: }; Chris@101: Chris@101: } // namespace aux Chris@101: Chris@101: } // namespace expressions Chris@101: Chris@16: /*! Chris@16: * Log record formatter function wrapper. Chris@16: */ Chris@16: template< typename CharT > Chris@16: class basic_formatter Chris@16: { Chris@16: typedef basic_formatter this_type; Chris@16: BOOST_COPYABLE_AND_MOVABLE(this_type) Chris@16: Chris@16: public: Chris@16: //! Result type Chris@16: typedef void result_type; Chris@16: Chris@16: //! Character type Chris@16: typedef CharT char_type; Chris@16: //! Output stream type Chris@16: typedef basic_formatting_ostream< char_type > stream_type; Chris@16: Chris@16: private: Chris@16: //! Filter function type Chris@101: typedef boost::log::aux::light_function< void (record_view const&, expressions::aux::stream_ref< stream_type >) > formatter_type; Chris@16: Chris@16: private: Chris@16: //! Formatter function Chris@16: formatter_type m_Formatter; Chris@16: Chris@16: public: Chris@16: /*! Chris@16: * Default constructor. Creates a formatter that only outputs log message. Chris@16: */ Chris@101: basic_formatter() : m_Formatter(expressions::aux::message_formatter()) Chris@16: { Chris@16: } Chris@16: /*! Chris@16: * Copy constructor Chris@16: */ Chris@16: basic_formatter(basic_formatter const& that) : m_Formatter(that.m_Formatter) Chris@16: { Chris@16: } Chris@16: /*! Chris@16: * Move constructor. The moved-from formatter is left in an unspecified state. Chris@16: */ Chris@16: basic_formatter(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_Formatter(boost::move(that.m_Formatter)) Chris@16: { Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Initializing constructor. Creates a formatter which will invoke the specified function object. Chris@16: */ Chris@16: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: template< typename FunT > Chris@101: basic_formatter(FunT&& fun) : m_Formatter(boost::forward< FunT >(fun)) Chris@16: { Chris@16: } Chris@101: #elif !defined(BOOST_MSVC) || BOOST_MSVC > 1400 Chris@101: template< typename FunT > Chris@101: basic_formatter(FunT const& fun, typename disable_if_c< move_detail::is_rv< FunT >::value, int >::type = 0) : m_Formatter(fun) Chris@101: { Chris@101: } Chris@101: #else Chris@101: // MSVC 8 blows up in unexpected ways if we use SFINAE to disable constructor instantiation Chris@101: template< typename FunT > Chris@101: basic_formatter(FunT const& fun) : m_Formatter(fun) Chris@101: { Chris@101: } Chris@101: template< typename FunT > Chris@101: basic_formatter(rv< FunT >& fun) : m_Formatter(fun) Chris@101: { Chris@101: } Chris@101: template< typename FunT > Chris@101: basic_formatter(rv< FunT > const& fun) : m_Formatter(static_cast< FunT const& >(fun)) Chris@101: { Chris@101: } Chris@101: basic_formatter(rv< this_type > const& that) : m_Formatter(that.m_Formatter) Chris@101: { Chris@101: } Chris@101: #endif Chris@16: Chris@16: /*! Chris@16: * Move assignment. The moved-from formatter is left in an unspecified state. Chris@16: */ Chris@16: basic_formatter& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT Chris@16: { Chris@16: m_Formatter.swap(that.m_Formatter); Chris@16: return *this; Chris@16: } Chris@16: /*! Chris@16: * Copy assignment. Chris@16: */ Chris@16: basic_formatter& operator= (BOOST_COPY_ASSIGN_REF(this_type) that) Chris@16: { Chris@16: m_Formatter = that.m_Formatter; Chris@16: return *this; Chris@16: } Chris@16: /*! Chris@16: * Initializing assignment. Sets the specified function object to the formatter. Chris@16: */ Chris@16: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: template< typename FunT > Chris@101: basic_formatter& operator= (FunT&& fun) Chris@101: { Chris@101: this_type(boost::forward< FunT >(fun)).swap(*this); Chris@101: return *this; Chris@101: } Chris@16: #else Chris@16: template< typename FunT > Chris@16: typename disable_if< is_same< typename remove_cv< FunT >::type, this_type >, this_type& >::type Chris@16: operator= (FunT const& fun) Chris@16: { Chris@16: this_type(fun).swap(*this); Chris@16: return *this; Chris@16: } Chris@101: #endif Chris@16: Chris@16: /*! Chris@16: * Formatting operator. Chris@16: * Chris@16: * \param rec A log record to format. Chris@16: * \param strm A stream to put the formatted characters to. Chris@16: */ Chris@16: result_type operator() (record_view const& rec, stream_type& strm) const Chris@16: { Chris@101: m_Formatter(rec, expressions::aux::stream_ref< stream_type >(strm)); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Resets the formatter to the default. The default formatter only outputs message text. Chris@16: */ Chris@16: void reset() Chris@16: { Chris@101: m_Formatter = expressions::aux::message_formatter(); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Swaps two formatters Chris@16: */ Chris@16: void swap(basic_formatter& that) BOOST_NOEXCEPT Chris@16: { Chris@16: m_Formatter.swap(that.m_Formatter); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< typename CharT > Chris@16: inline void swap(basic_formatter< CharT >& left, basic_formatter< CharT >& right) BOOST_NOEXCEPT Chris@16: { Chris@16: left.swap(right); Chris@16: } Chris@16: Chris@16: #ifdef BOOST_LOG_USE_CHAR Chris@16: typedef basic_formatter< char > formatter; Chris@16: #endif Chris@16: #ifdef BOOST_LOG_USE_WCHAR_T Chris@16: typedef basic_formatter< wchar_t > wformatter; Chris@16: #endif Chris@16: 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_EXPRESSIONS_FORMATTER_HPP_INCLUDED_