summaryrefslogtreecommitdiff
path: root/boost/log/expressions/formatter.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/log/expressions/formatter.hpp')
-rw-r--r--boost/log/expressions/formatter.hpp257
1 files changed, 257 insertions, 0 deletions
diff --git a/boost/log/expressions/formatter.hpp b/boost/log/expressions/formatter.hpp
new file mode 100644
index 0000000000..05692ec287
--- /dev/null
+++ b/boost/log/expressions/formatter.hpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file formatter.hpp
+ * \author Andrey Semashev
+ * \date 13.07.2012
+ *
+ * The header contains a formatter function object definition.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
+
+#include <boost/ref.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/light_function.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/attributes/value_visitation.hpp>
+#include <boost/log/core/record_view.hpp>
+#include <boost/log/utility/formatting_ostream.hpp>
+#include <boost/log/utility/functional/bind_output.hpp>
+#include <boost/log/expressions/message.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+// This reference class is a workaround for a Boost.Phoenix bug: https://svn.boost.org/trac/boost/ticket/9363
+// It is needed to pass output streams by non-const reference to function objects wrapped in phoenix::bind and phoenix::function.
+// It's an implementation detail and will be removed when Boost.Phoenix is fixed.
+template< typename StreamT >
+class stream_ref :
+ public reference_wrapper< StreamT >
+{
+public:
+ BOOST_FORCEINLINE explicit stream_ref(StreamT& strm) : reference_wrapper< StreamT >(strm)
+ {
+ }
+
+ template< typename T >
+ BOOST_FORCEINLINE StreamT& operator<< (T& val) const
+ {
+ StreamT& strm = this->get();
+ strm << val;
+ return strm;
+ }
+
+ template< typename T >
+ BOOST_FORCEINLINE StreamT& operator<< (T const& val) const
+ {
+ StreamT& strm = this->get();
+ strm << val;
+ return strm;
+ }
+};
+
+//! Default log record message formatter
+struct message_formatter
+{
+ typedef void result_type;
+
+ message_formatter() : m_MessageName(expressions::tag::message::get_name())
+ {
+ }
+
+ template< typename StreamT >
+ result_type operator() (record_view const& rec, StreamT& strm) const
+ {
+ boost::log::visit< expressions::tag::message::value_type >(m_MessageName, rec, boost::log::bind_output(strm));
+ }
+
+private:
+ const attribute_name m_MessageName;
+};
+
+} // namespace aux
+
+} // namespace expressions
+
+/*!
+ * Log record formatter function wrapper.
+ */
+template< typename CharT >
+class basic_formatter
+{
+ typedef basic_formatter this_type;
+ BOOST_COPYABLE_AND_MOVABLE(this_type)
+
+public:
+ //! Result type
+ typedef void result_type;
+
+ //! Character type
+ typedef CharT char_type;
+ //! Output stream type
+ typedef basic_formatting_ostream< char_type > stream_type;
+
+private:
+ //! Filter function type
+ typedef boost::log::aux::light_function< void (record_view const&, expressions::aux::stream_ref< stream_type >) > formatter_type;
+
+private:
+ //! Formatter function
+ formatter_type m_Formatter;
+
+public:
+ /*!
+ * Default constructor. Creates a formatter that only outputs log message.
+ */
+ basic_formatter() : m_Formatter(expressions::aux::message_formatter())
+ {
+ }
+ /*!
+ * Copy constructor
+ */
+ basic_formatter(basic_formatter const& that) : m_Formatter(that.m_Formatter)
+ {
+ }
+ /*!
+ * Move constructor. The moved-from formatter is left in an unspecified state.
+ */
+ basic_formatter(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_Formatter(boost::move(that.m_Formatter))
+ {
+ }
+
+ /*!
+ * Initializing constructor. Creates a formatter which will invoke the specified function object.
+ */
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ basic_formatter(FunT&& fun) : m_Formatter(boost::forward< FunT >(fun))
+ {
+ }
+#elif !defined(BOOST_MSVC) || BOOST_MSVC > 1400
+ template< typename FunT >
+ basic_formatter(FunT const& fun, typename disable_if_c< move_detail::is_rv< FunT >::value, int >::type = 0) : m_Formatter(fun)
+ {
+ }
+#else
+ // MSVC 8 blows up in unexpected ways if we use SFINAE to disable constructor instantiation
+ template< typename FunT >
+ basic_formatter(FunT const& fun) : m_Formatter(fun)
+ {
+ }
+ template< typename FunT >
+ basic_formatter(rv< FunT >& fun) : m_Formatter(fun)
+ {
+ }
+ template< typename FunT >
+ basic_formatter(rv< FunT > const& fun) : m_Formatter(static_cast< FunT const& >(fun))
+ {
+ }
+ basic_formatter(rv< this_type > const& that) : m_Formatter(that.m_Formatter)
+ {
+ }
+#endif
+
+ /*!
+ * Move assignment. The moved-from formatter is left in an unspecified state.
+ */
+ basic_formatter& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ m_Formatter.swap(that.m_Formatter);
+ return *this;
+ }
+ /*!
+ * Copy assignment.
+ */
+ basic_formatter& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
+ {
+ m_Formatter = that.m_Formatter;
+ return *this;
+ }
+ /*!
+ * Initializing assignment. Sets the specified function object to the formatter.
+ */
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ basic_formatter& operator= (FunT&& fun)
+ {
+ this_type(boost::forward< FunT >(fun)).swap(*this);
+ return *this;
+ }
+#else
+ template< typename FunT >
+ typename disable_if< is_same< typename remove_cv< FunT >::type, this_type >, this_type& >::type
+ operator= (FunT const& fun)
+ {
+ this_type(fun).swap(*this);
+ return *this;
+ }
+#endif
+
+ /*!
+ * Formatting operator.
+ *
+ * \param rec A log record to format.
+ * \param strm A stream to put the formatted characters to.
+ */
+ result_type operator() (record_view const& rec, stream_type& strm) const
+ {
+ m_Formatter(rec, expressions::aux::stream_ref< stream_type >(strm));
+ }
+
+ /*!
+ * Resets the formatter to the default. The default formatter only outputs message text.
+ */
+ void reset()
+ {
+ m_Formatter = expressions::aux::message_formatter();
+ }
+
+ /*!
+ * Swaps two formatters
+ */
+ void swap(basic_formatter& that) BOOST_NOEXCEPT
+ {
+ m_Formatter.swap(that.m_Formatter);
+ }
+};
+
+template< typename CharT >
+inline void swap(basic_formatter< CharT >& left, basic_formatter< CharT >& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+#ifdef BOOST_LOG_USE_CHAR
+typedef basic_formatter< char > formatter;
+#endif
+#ifdef BOOST_LOG_USE_WCHAR_T
+typedef basic_formatter< wchar_t > wformatter;
+#endif
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_