diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:41:18 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:43:11 +0900 |
commit | f763a99a501650eff2c60288aa6f10ef916d769e (patch) | |
tree | 02af7e13f9a38c888ebf340fe764cbe7dae99da9 /boost/log/expressions | |
parent | 5cde13f21d36c7224b0e13d11c4b49379ae5210d (diff) | |
download | boost-f763a99a501650eff2c60288aa6f10ef916d769e.tar.gz boost-f763a99a501650eff2c60288aa6f10ef916d769e.tar.bz2 boost-f763a99a501650eff2c60288aa6f10ef916d769e.zip |
Imported Upstream version 1.62.0upstream/1.62.0
Change-Id: I9d4c1ddb7b7d8f0069217ecc582700f9fda6dd4c
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/log/expressions')
-rw-r--r-- | boost/log/expressions/attr.hpp | 2 | ||||
-rw-r--r-- | boost/log/expressions/filter.hpp | 12 | ||||
-rw-r--r-- | boost/log/expressions/formatter.hpp | 10 | ||||
-rw-r--r-- | boost/log/expressions/formatters.hpp | 1 | ||||
-rw-r--r-- | boost/log/expressions/formatters/char_decorator.hpp | 20 | ||||
-rw-r--r-- | boost/log/expressions/formatters/date_time.hpp | 8 | ||||
-rw-r--r-- | boost/log/expressions/formatters/format.hpp | 2 | ||||
-rw-r--r-- | boost/log/expressions/formatters/if.hpp | 4 | ||||
-rw-r--r-- | boost/log/expressions/formatters/max_size_decorator.hpp | 561 | ||||
-rw-r--r-- | boost/log/expressions/formatters/named_scope.hpp | 8 | ||||
-rw-r--r-- | boost/log/expressions/formatters/wrap_formatter.hpp | 10 | ||||
-rw-r--r-- | boost/log/expressions/predicates/channel_severity_filter.hpp | 2 |
12 files changed, 612 insertions, 28 deletions
diff --git a/boost/log/expressions/attr.hpp b/boost/log/expressions/attr.hpp index aca0447cff..60540e7d77 100644 --- a/boost/log/expressions/attr.hpp +++ b/boost/log/expressions/attr.hpp @@ -56,8 +56,10 @@ private: typedef attribute_terminal< T, FallbackPolicyT, TagT > this_type; public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Attribute tag type typedef TagT tag_type; diff --git a/boost/log/expressions/filter.hpp b/boost/log/expressions/filter.hpp index ae43abe150..1e53f5c3bd 100644 --- a/boost/log/expressions/filter.hpp +++ b/boost/log/expressions/filter.hpp @@ -16,11 +16,11 @@ #define BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_ #include <boost/move/core.hpp> -#include <boost/move/utility.hpp> +#include <boost/move/utility_core.hpp> #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -#include <boost/utility/enable_if.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/remove_cv.hpp> +#include <boost/log/detail/sfinae_tools.hpp> #endif #include <boost/log/detail/config.hpp> #include <boost/log/attributes/attribute_value_set.hpp> @@ -89,13 +89,13 @@ public: filter(FunT&& fun) : m_Filter(boost::forward< FunT >(fun)) { } -#elif !defined(BOOST_MSVC) || BOOST_MSVC > 1400 +#elif !defined(BOOST_MSVC) || BOOST_MSVC >= 1600 template< typename FunT > - filter(FunT const& fun, typename disable_if_c< move_detail::is_rv< FunT >::value, int >::type = 0) : m_Filter(fun) + filter(FunT const& fun, typename boost::disable_if_c< move_detail::is_rv< FunT >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) : m_Filter(fun) { } #else - // MSVC 8 blows up in unexpected ways if we use SFINAE to disable constructor instantiation + // MSVC 9 and older blows up in unexpected ways if we use SFINAE to disable constructor instantiation template< typename FunT > filter(FunT const& fun) : m_Filter(fun) { @@ -137,7 +137,7 @@ public: filter& operator= (FunT const& fun) #else template< typename FunT > - typename disable_if< is_same< typename remove_cv< FunT >::type, filter >, filter& >::type + typename boost::disable_if_c< is_same< typename remove_cv< FunT >::type, filter >::value, filter& >::type operator= (FunT const& fun) #endif { diff --git a/boost/log/expressions/formatter.hpp b/boost/log/expressions/formatter.hpp index bdbabb504e..bc80dfa250 100644 --- a/boost/log/expressions/formatter.hpp +++ b/boost/log/expressions/formatter.hpp @@ -19,11 +19,11 @@ #include <ostream> #include <boost/ref.hpp> #include <boost/move/core.hpp> -#include <boost/move/utility.hpp> +#include <boost/move/utility_core.hpp> #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -#include <boost/utility/enable_if.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/remove_cv.hpp> +#include <boost/log/detail/sfinae_tools.hpp> #endif #include <boost/log/detail/config.hpp> #include <boost/log/detail/light_function.hpp> @@ -376,11 +376,11 @@ public: } #elif !defined(BOOST_MSVC) || BOOST_MSVC >= 1600 template< typename FunT > - basic_formatter(FunT const& fun, typename disable_if_c< move_detail::is_rv< FunT >::value, int >::type = 0) : m_Formatter(fun) + basic_formatter(FunT const& fun, typename boost::disable_if_c< move_detail::is_rv< FunT >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) : m_Formatter(fun) { } #else - // MSVC 9 blows up in unexpected ways if we use SFINAE to disable constructor instantiation + // MSVC 9 and older blows up in unexpected ways if we use SFINAE to disable constructor instantiation template< typename FunT > basic_formatter(FunT const& fun) : m_Formatter(fun) { @@ -426,7 +426,7 @@ public: } #else template< typename FunT > - typename disable_if< is_same< typename remove_cv< FunT >::type, this_type >, this_type& >::type + typename boost::disable_if_c< is_same< typename remove_cv< FunT >::type, this_type >::value, this_type& >::type operator= (FunT const& fun) { this_type(fun).swap(*this); diff --git a/boost/log/expressions/formatters.hpp b/boost/log/expressions/formatters.hpp index 1d3f4edd54..f85cb7903b 100644 --- a/boost/log/expressions/formatters.hpp +++ b/boost/log/expressions/formatters.hpp @@ -27,6 +27,7 @@ #include <boost/log/expressions/formatters/xml_decorator.hpp> #include <boost/log/expressions/formatters/csv_decorator.hpp> #include <boost/log/expressions/formatters/c_decorator.hpp> +#include <boost/log/expressions/formatters/max_size_decorator.hpp> #include <boost/log/expressions/formatters/if.hpp> #include <boost/log/expressions/formatters/wrap_formatter.hpp> diff --git a/boost/log/expressions/formatters/char_decorator.hpp b/boost/log/expressions/formatters/char_decorator.hpp index e3188810ff..229e72ae89 100644 --- a/boost/log/expressions/formatters/char_decorator.hpp +++ b/boost/log/expressions/formatters/char_decorator.hpp @@ -27,9 +27,8 @@ #include <boost/range/const_iterator.hpp> #include <boost/range/value_type.hpp> #include <boost/move/core.hpp> -#include <boost/move/utility.hpp> -#include <boost/core/enable_if.hpp> -#include <boost/utility/addressof.hpp> +#include <boost/move/utility_core.hpp> +#include <boost/core/addressof.hpp> #include <boost/phoenix/core/actor.hpp> #include <boost/phoenix/core/meta_grammar.hpp> #include <boost/phoenix/core/terminal_fwd.hpp> @@ -43,6 +42,7 @@ #include <boost/log/detail/config.hpp> #include <boost/log/detail/custom_terminal_spec.hpp> #include <boost/log/detail/deduce_char_type.hpp> +#include <boost/log/detail/sfinae_tools.hpp> #include <boost/log/utility/formatting_ostream.hpp> #include <boost/log/detail/header.hpp> @@ -113,7 +113,7 @@ public: explicit pattern_replacer(RangeT const& decorations #ifndef BOOST_LOG_DOXYGEN_PASS // This is needed for a workaround against an MSVC-10 and older bug in constructor overload resolution - , typename boost::enable_if_has_type< typename range_const_iterator< RangeT >::type, int >::type = 0 + , typename boost::enable_if_has_type< typename range_const_iterator< RangeT >::type, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy() #endif ) { @@ -235,8 +235,10 @@ private: typedef char_decorator_output_terminal< LeftT, SubactorT, ImplT > this_type; public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Implementation type typedef ImplT impl_type; @@ -300,12 +302,12 @@ public: typename string_type::size_type const start_pos = strm.rdbuf()->storage()->size(); // Invoke the adopted formatter - typedef typename result< this_type(ContextT const&) >::type result_type; phoenix::eval(m_subactor, ctx); // Flush the buffered characters and apply decorations strm.flush(); m_impl(*strm.rdbuf()->storage(), start_pos); + strm.rdbuf()->ensure_max_size(); return strm; } @@ -323,12 +325,12 @@ public: typename string_type::size_type const start_pos = strm.rdbuf()->storage()->size(); // Invoke the adopted formatter - typedef typename result< const this_type(ContextT const&) >::type result_type; phoenix::eval(m_subactor, ctx); // Flush the buffered characters and apply decorations strm.flush(); m_impl(*strm.rdbuf()->storage(), start_pos); + strm.rdbuf()->ensure_max_size(); return strm; } @@ -357,8 +359,10 @@ private: typedef char_decorator_terminal< SubactorT, ImplT > this_type; public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Implementation type typedef ImplT impl_type; @@ -439,7 +443,7 @@ public: strm.flush(); m_impl(*strm.rdbuf()->storage()); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } /*! @@ -471,7 +475,7 @@ public: strm.flush(); m_impl(*strm.rdbuf()->storage()); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } BOOST_DELETED_FUNCTION(char_decorator_terminal()) diff --git a/boost/log/expressions/formatters/date_time.hpp b/boost/log/expressions/formatters/date_time.hpp index 45091fc206..b8de0b4cb7 100644 --- a/boost/log/expressions/formatters/date_time.hpp +++ b/boost/log/expressions/formatters/date_time.hpp @@ -17,7 +17,7 @@ #include <string> #include <boost/move/core.hpp> -#include <boost/move/utility.hpp> +#include <boost/move/utility_core.hpp> #include <boost/phoenix/core/actor.hpp> #include <boost/phoenix/core/terminal_fwd.hpp> #include <boost/phoenix/core/is_nullary.hpp> @@ -54,8 +54,10 @@ template< typename T, typename FallbackPolicyT, typename CharT > class format_date_time_terminal { public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Attribute value type typedef T value_type; @@ -126,7 +128,7 @@ public: stream_type strm(str); m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type&, stream_type& >(m_formatter, strm)); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } //! Invokation operator @@ -137,7 +139,7 @@ public: stream_type strm(str); m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type const&, stream_type& >(m_formatter, strm)); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } BOOST_DELETED_FUNCTION(format_date_time_terminal()) diff --git a/boost/log/expressions/formatters/format.hpp b/boost/log/expressions/formatters/format.hpp index ceccae942e..d312d8e36d 100644 --- a/boost/log/expressions/formatters/format.hpp +++ b/boost/log/expressions/formatters/format.hpp @@ -44,8 +44,10 @@ template< typename CharT > class format_terminal { public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Character type typedef CharT char_type; diff --git a/boost/log/expressions/formatters/if.hpp b/boost/log/expressions/formatters/if.hpp index 360622f843..3e1e1abc5a 100644 --- a/boost/log/expressions/formatters/if.hpp +++ b/boost/log/expressions/formatters/if.hpp @@ -48,8 +48,10 @@ private: typedef if_output_terminal this_type; public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Result type definition template< typename > @@ -113,8 +115,10 @@ private: typedef if_else_output_terminal this_type; public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Result type definition template< typename > diff --git a/boost/log/expressions/formatters/max_size_decorator.hpp b/boost/log/expressions/formatters/max_size_decorator.hpp new file mode 100644 index 0000000000..0ab44d6fa4 --- /dev/null +++ b/boost/log/expressions/formatters/max_size_decorator.hpp @@ -0,0 +1,561 @@ +/* + * Copyright Andrey Semashev 2016. + * 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 formatters/max_size_decorator.hpp + * \author Andrey Semashev + * \date 06.07.2016 + * + * The header contains implementation of a string length limiting decorator. + */ + +#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_MAX_SIZE_DECORATOR_HPP_INCLUDED_ +#define BOOST_LOG_EXPRESSIONS_FORMATTERS_MAX_SIZE_DECORATOR_HPP_INCLUDED_ + +#include <cstddef> +#include <string> +#include <boost/assert.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/move/core.hpp> +#include <boost/move/utility_core.hpp> +#include <boost/core/addressof.hpp> +#include <boost/phoenix/core/actor.hpp> +#include <boost/phoenix/core/meta_grammar.hpp> +#include <boost/phoenix/core/terminal_fwd.hpp> +#include <boost/phoenix/core/is_nullary.hpp> +#include <boost/phoenix/core/environment.hpp> +#include <boost/phoenix/support/vector.hpp> +#include <boost/fusion/sequence/intrinsic/at_c.hpp> +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/log/detail/config.hpp> +#include <boost/log/detail/custom_terminal_spec.hpp> +#include <boost/log/utility/formatting_ostream.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 { + +//! String size limiting decorator stream output terminal +template< typename LeftT, typename SubactorT, typename CharT > +class max_size_decorator_output_terminal +{ +private: + //! Self type + typedef max_size_decorator_output_terminal< LeftT, SubactorT, CharT > this_type; + +public: +#ifndef BOOST_LOG_DOXYGEN_PASS + //! Internal typedef for type categorization + typedef void _is_boost_log_terminal; +#endif + + //! Character type + typedef CharT char_type; + //! String type + typedef std::basic_string< char_type > string_type; + //! String size type + typedef std::size_t size_type; + //! Adopted actor type + typedef SubactorT subactor_type; + + //! Result type definition + template< typename > + struct result; + + template< typename ThisT, typename ContextT > + struct result< ThisT(ContextT) > + { + typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type; + typedef typename phoenix::evaluator::impl< + typename LeftT::proto_base_expr&, + context_type, + phoenix::unused + >::result_type type; + }; + +private: + //! Left argument actor + LeftT m_left; + //! Adopted formatter actor + subactor_type m_subactor; + //! Max size of the formatted string produced by the adopted formatter + size_type m_max_size; + //! Overflow marker + string_type m_overflow_marker; + +public: + /*! + * Initializing constructor. Creates decorator of the \a fmt formatter with the specified \a decorations. + */ + max_size_decorator_output_terminal(LeftT const& left, subactor_type const& sub, size_type max_size, string_type const& overflow_marker = string_type()) : + m_left(left), m_subactor(sub), m_max_size(max_size), m_overflow_marker(overflow_marker) + { + BOOST_ASSERT(overflow_marker.size() <= max_size); + } + /*! + * Copy constructor + */ + max_size_decorator_output_terminal(max_size_decorator_output_terminal const& that) : + m_left(that.m_left), m_subactor(that.m_subactor), m_max_size(that.m_max_size), m_overflow_marker(that.m_overflow_marker) + { + } + + /*! + * Invokation operator + */ + template< typename ContextT > + typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx) + { + // Flush the stream and keep the current write position in the target string + typedef typename result< this_type(ContextT const&) >::type result_type; + result_type strm = phoenix::eval(m_left, ctx); + strm.flush(); + + if (!strm.rdbuf()->storage_overflow()) + { + const size_type old_max_size = strm.rdbuf()->max_size(); + const size_type start_pos = strm.rdbuf()->storage()->size(), max_size_left = strm.rdbuf()->storage()->max_size() - start_pos; + strm.rdbuf()->max_size(start_pos + (m_max_size <= max_size_left ? m_max_size : max_size_left)); + + try + { + // Invoke the adopted formatter + phoenix::eval(m_subactor, ctx); + + // Flush the buffered characters and apply decorations + strm.flush(); + + if (strm.rdbuf()->storage_overflow()) + { + if (!m_overflow_marker.empty()) + { + // Free up space for the overflow marker + strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size()); + + // Append the marker + strm.rdbuf()->max_size(strm.rdbuf()->storage()->max_size()); + strm.rdbuf()->storage_overflow(false); + strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); + } + else + { + strm.rdbuf()->storage_overflow(false); + } + } + + // Restore the original size limit + strm.rdbuf()->max_size(old_max_size); + } + catch (...) + { + strm.rdbuf()->storage_overflow(false); + strm.rdbuf()->max_size(old_max_size); + throw; + } + } + + return strm; + } + + /*! + * Invokation operator + */ + template< typename ContextT > + typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const + { + // Flush the stream and keep the current write position in the target string + typedef typename result< const this_type(ContextT const&) >::type result_type; + result_type strm = phoenix::eval(m_left, ctx); + strm.flush(); + + if (!strm.rdbuf()->storage_overflow()) + { + const size_type old_max_size = strm.rdbuf()->max_size(); + const size_type start_pos = strm.rdbuf()->storage()->size(), max_size_left = strm.rdbuf()->storage()->max_size() - start_pos; + strm.rdbuf()->max_size(start_pos + (m_max_size <= max_size_left ? m_max_size : max_size_left)); + + try + { + // Invoke the adopted formatter + phoenix::eval(m_subactor, ctx); + + // Flush the buffered characters and apply decorations + strm.flush(); + + if (strm.rdbuf()->storage_overflow()) + { + if (!m_overflow_marker.empty()) + { + // Free up space for the overflow marker + strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size()); + + // Append the marker + strm.rdbuf()->max_size(strm.rdbuf()->storage()->max_size()); + strm.rdbuf()->storage_overflow(false); + strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); + } + else + { + strm.rdbuf()->storage_overflow(false); + } + } + + // Restore the original size limit + strm.rdbuf()->max_size(old_max_size); + } + catch (...) + { + strm.rdbuf()->storage_overflow(false); + strm.rdbuf()->max_size(old_max_size); + throw; + } + } + + return strm; + } + + BOOST_DELETED_FUNCTION(max_size_decorator_output_terminal()) +}; + +} // namespace aux + +/*! + * String size limiting decorator terminal class. This formatter allows to limit the maximum total length + * of the strings generated by other formatters. + * + * The \c max_size_decorator_terminal class aggregates the formatter being decorated, the maximum string length + * it can produce and an optional truncation marker string, which will be put at the end of the output if the limit is exceeded. Note that + * the marker length is included in the limit and as such must not exceed it. + * The \c max_size_decorator_terminal class is a formatter itself, so it can be used to construct + * more complex formatters, including nesting decorators. + */ +template< typename SubactorT, typename CharT > +class max_size_decorator_terminal +{ +private: + //! Self type + typedef max_size_decorator_terminal< SubactorT, CharT > this_type; + +public: +#ifndef BOOST_LOG_DOXYGEN_PASS + //! Internal typedef for type categorization + typedef void _is_boost_log_terminal; +#endif + + //! Character type + typedef CharT char_type; + //! String type + typedef std::basic_string< char_type > string_type; + //! String size type + typedef std::size_t size_type; + //! Stream type + typedef basic_formatting_ostream< char_type > stream_type; + //! Adopted actor type + typedef SubactorT subactor_type; + + //! Result type definition + typedef string_type result_type; + +private: + //! Adopted formatter actor + subactor_type m_subactor; + //! Max size of the formatted string produced by the adopted formatter + size_type m_max_size; + //! Overflow marker + string_type m_overflow_marker; + +public: + /*! + * Initializing constructor. + */ + max_size_decorator_terminal(subactor_type const& sub, size_type max_size, string_type const& overflow_marker = string_type()) : + m_subactor(sub), m_max_size(max_size), m_overflow_marker(overflow_marker) + { + BOOST_ASSERT(overflow_marker.size() <= max_size); + } + /*! + * Copy constructor + */ + max_size_decorator_terminal(max_size_decorator_terminal const& that) : + m_subactor(that.m_subactor), m_max_size(that.m_max_size), m_overflow_marker(that.m_overflow_marker) + { + } + + /*! + * \returns Adopted subactor + */ + subactor_type const& get_subactor() const + { + return m_subactor; + } + + /*! + * \returns Max string size limit + */ + size_type get_max_size() const + { + return m_max_size; + } + + /*! + * \returns Max string size limit + */ + string_type const& get_overflow_marker() const + { + return m_overflow_marker; + } + + /*! + * Invokation operator + */ + template< typename ContextT > + result_type operator() (ContextT const& ctx) + { + string_type str; + stream_type strm(str); + strm.rdbuf()->max_size(m_max_size); + + // Invoke the adopted formatter + typedef phoenix::vector3< + subactor_type*, + typename fusion::result_of::at_c< + typename remove_cv< + typename remove_reference< + typename phoenix::result_of::env< ContextT const& >::type + >::type + >::type::args_type, + 0 + >::type, + stream_type& + > env_type; + env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm }; + phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx))); + + // Flush the buffered characters and see of overflow happened + strm.flush(); + + if (strm.rdbuf()->storage_overflow() && !m_overflow_marker.empty()) + { + strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size()); + strm.rdbuf()->max_size(str.max_size()); + strm.rdbuf()->storage_overflow(false); + strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); + strm.flush(); + } + + return BOOST_LOG_NRVO_RESULT(str); + } + + /*! + * Invokation operator + */ + template< typename ContextT > + result_type operator() (ContextT const& ctx) const + { + string_type str; + stream_type strm(str); + strm.rdbuf()->max_size(m_max_size); + + // Invoke the adopted formatter + typedef phoenix::vector3< + const subactor_type*, + typename fusion::result_of::at_c< + typename remove_cv< + typename remove_reference< + typename phoenix::result_of::env< ContextT const& >::type + >::type + >::type::args_type, + 0 + >::type, + stream_type& + > env_type; + env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm }; + phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx))); + + // Flush the buffered characters and see of overflow happened + strm.flush(); + + if (strm.rdbuf()->storage_overflow()) + { + strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size()); + strm.rdbuf()->max_size(str.max_size()); + strm.rdbuf()->storage_overflow(false); + strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size()); + strm.flush(); + } + + return BOOST_LOG_NRVO_RESULT(str); + } + + BOOST_DELETED_FUNCTION(max_size_decorator_terminal()) +}; + +/*! + * Character decorator actor + */ +template< typename SubactorT, typename CharT, template< typename > class ActorT = phoenix::actor > +class max_size_decorator_actor : + public ActorT< max_size_decorator_terminal< SubactorT, CharT > > +{ +public: + //! Base terminal type + typedef max_size_decorator_terminal< SubactorT, CharT > terminal_type; + //! Character type + typedef typename terminal_type::char_type char_type; + + //! Base actor type + typedef ActorT< terminal_type > base_type; + +public: + //! Initializing constructor + explicit max_size_decorator_actor(base_type const& act) : base_type(act) + { + } + + //! Returns reference to the terminal + terminal_type const& get_terminal() const + { + return this->proto_expr_.child0; + } +}; + +#ifndef BOOST_LOG_DOXYGEN_PASS + +#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\ + template< typename LeftExprT, typename SubactorT, typename CharT, template< typename > class ActorT >\ + BOOST_FORCEINLINE phoenix::actor< aux::max_size_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, CharT > >\ + operator<< (phoenix::actor< LeftExprT > left_ref left, max_size_decorator_actor< SubactorT, CharT, ActorT > right_ref right)\ + {\ + typedef aux::max_size_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, CharT > terminal_type;\ + phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.get_terminal().get_subactor(), right.get_terminal().get_max_size(), right.get_terminal().get_overflow_marker()) }};\ + return actor;\ + } + +#include <boost/log/detail/generate_overloads.hpp> + +#undef BOOST_LOG_AUX_OVERLOAD + +#endif // BOOST_LOG_DOXYGEN_PASS + +namespace aux { + +template< typename CharT > +class max_size_decorator_gen +{ +private: + typedef CharT char_type; + typedef std::basic_string< char_type > string_type; + typedef std::size_t size_type; + +private: + size_type m_max_size; + string_type m_overflow_marker; + +public: + explicit max_size_decorator_gen(size_type max_size, string_type const& overflow_marker = string_type()) : + m_max_size(max_size), m_overflow_marker(overflow_marker) + { + BOOST_ASSERT(overflow_marker.size() <= max_size); + } + + template< typename SubactorT > + BOOST_FORCEINLINE max_size_decorator_actor< SubactorT, char_type > operator[] (SubactorT const& subactor) const + { + typedef max_size_decorator_actor< SubactorT, char_type > result_type; + typedef typename result_type::terminal_type terminal_type; + typename result_type::base_type act = {{ terminal_type(subactor, m_max_size, m_overflow_marker) }}; + return result_type(act); + } +}; + +} // namespace aux + +/*! + * The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used + * to construct the actual decorator. + * + * \param max_size The maximum number of characters (i.e. string element objects) that the decorated formatter can produce. + */ +template< typename CharT > +BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_t max_size) +{ + return aux::max_size_decorator_gen< CharT >(max_size); +} + +/*! + * The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used + * to construct the actual decorator. + * + * \param max_size The maximum number of characters (i.e. string element objects) that the decorated formatter can produce. + * \param overflow_marker The marker string which is appended to the output if the \a max_size limit is exceeded. Must be + * a non-null pointer to a zero-terminated string. + * + * \pre The \a overflow_marker length must not exceed the \a max_size limit. + */ +template< typename CharT > +BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_t max_size, const CharT* overflow_marker) +{ + return aux::max_size_decorator_gen< CharT >(max_size, overflow_marker); +} + +/*! + * The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used + * to construct the actual decorator. + * + * \param max_size The maximum number of characters (i.e. string element objects) that the decorated formatter can produce. + * \param overflow_marker The marker string which is appended to the output if the \a max_size limit is exceeded. + * + * \pre The \a overflow_marker length must not exceed the \a max_size limit. + */ +template< typename CharT > +BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_t max_size, std::basic_string< CharT > const& overflow_marker) +{ + return aux::max_size_decorator_gen< CharT >(max_size, overflow_marker); +} + +} // namespace expressions + +BOOST_LOG_CLOSE_NAMESPACE // namespace log + +#ifndef BOOST_LOG_DOXYGEN_PASS + +namespace phoenix { + +namespace result_of { + +template< typename SubactorT, typename CharT > +struct is_nullary< custom_terminal< boost::log::expressions::max_size_decorator_terminal< SubactorT, CharT > > > : + public mpl::false_ +{ +}; + +template< typename LeftT, typename SubactorT, typename CharT > +struct is_nullary< custom_terminal< boost::log::expressions::aux::max_size_decorator_output_terminal< LeftT, SubactorT, CharT > > > : + public mpl::false_ +{ +}; + +} // namespace result_of + +} // namespace phoenix + +#endif + +} // namespace boost + +#include <boost/log/detail/footer.hpp> + +#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_MAX_SIZE_DECORATOR_HPP_INCLUDED_ diff --git a/boost/log/expressions/formatters/named_scope.hpp b/boost/log/expressions/formatters/named_scope.hpp index cc45dc6e81..ae140b1956 100644 --- a/boost/log/expressions/formatters/named_scope.hpp +++ b/boost/log/expressions/formatters/named_scope.hpp @@ -21,7 +21,7 @@ #include <boost/static_assert.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/move/core.hpp> -#include <boost/move/utility.hpp> +#include <boost/move/utility_core.hpp> #include <boost/parameter/binding.hpp> #include <boost/preprocessor/iteration/iterate.hpp> #include <boost/preprocessor/repetition/enum_params.hpp> @@ -257,8 +257,10 @@ template< typename FallbackPolicyT, typename CharT > class format_named_scope_terminal { public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Attribute value type typedef attributes::named_scope::value_type value_type; @@ -337,7 +339,7 @@ public: stream_type strm(str); m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type&, stream_type& >(m_formatter, strm)); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } //! Invokation operator @@ -348,7 +350,7 @@ public: stream_type strm(str); m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type const&, stream_type& >(m_formatter, strm)); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } BOOST_DELETED_FUNCTION(format_named_scope_terminal()) diff --git a/boost/log/expressions/formatters/wrap_formatter.hpp b/boost/log/expressions/formatters/wrap_formatter.hpp index 612be28d70..29c19c2f80 100644 --- a/boost/log/expressions/formatters/wrap_formatter.hpp +++ b/boost/log/expressions/formatters/wrap_formatter.hpp @@ -17,7 +17,7 @@ #include <string> #include <boost/move/core.hpp> -#include <boost/move/utility.hpp> +#include <boost/move/utility_core.hpp> #include <boost/mpl/has_xxx.hpp> #include <boost/phoenix/core/actor.hpp> #include <boost/phoenix/core/terminal_fwd.hpp> @@ -53,8 +53,10 @@ private: typedef wrapped_formatter_output_terminal< LeftT, FunT > this_type; public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Wrapped function type typedef FunT function_type; @@ -156,8 +158,10 @@ template< typename FunT, typename CharT > class wrapped_formatter_terminal { public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Character type typedef CharT char_type; @@ -199,7 +203,7 @@ public: stream_type strm(str); m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()), strm); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } //! Invokation operator @@ -210,7 +214,7 @@ public: stream_type strm(str); m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()), strm); strm.flush(); - return boost::move(str); + return BOOST_LOG_NRVO_RESULT(str); } }; diff --git a/boost/log/expressions/predicates/channel_severity_filter.hpp b/boost/log/expressions/predicates/channel_severity_filter.hpp index 079b79233d..c7430a1bd7 100644 --- a/boost/log/expressions/predicates/channel_severity_filter.hpp +++ b/boost/log/expressions/predicates/channel_severity_filter.hpp @@ -57,8 +57,10 @@ template< class channel_severity_filter_terminal { public: +#ifndef BOOST_LOG_DOXYGEN_PASS //! Internal typedef for type categorization typedef void _is_boost_log_terminal; +#endif //! Function result type typedef bool result_type; |