Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:23

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   formatters/wrap_formatter.hpp
0009  * \author Andrey Semashev
0010  * \date   24.11.2012
0011  *
0012  * The header contains a formatter function wrapper that enables third-party functions to participate in formatting expressions.
0013  */
0014 
0015 #ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_WRAP_FORMATTER_HPP_INCLUDED_
0016 #define BOOST_LOG_EXPRESSIONS_FORMATTERS_WRAP_FORMATTER_HPP_INCLUDED_
0017 
0018 #include <string>
0019 #include <boost/move/core.hpp>
0020 #include <boost/move/utility_core.hpp>
0021 #include <boost/mpl/has_xxx.hpp>
0022 #include <boost/phoenix/core/actor.hpp>
0023 #include <boost/phoenix/core/terminal_fwd.hpp>
0024 #include <boost/phoenix/core/is_nullary.hpp>
0025 #include <boost/phoenix/core/environment.hpp>
0026 #include <boost/type_traits/remove_cv.hpp>
0027 #include <boost/type_traits/remove_reference.hpp>
0028 #include <boost/fusion/sequence/intrinsic/at_c.hpp>
0029 #include <boost/log/detail/config.hpp>
0030 #include <boost/log/detail/custom_terminal_spec.hpp>
0031 #include <boost/log/detail/function_traits.hpp>
0032 #include <boost/log/utility/formatting_ostream.hpp>
0033 #include <boost/log/detail/header.hpp>
0034 
0035 #ifdef BOOST_HAS_PRAGMA_ONCE
0036 #pragma once
0037 #endif
0038 
0039 namespace boost {
0040 
0041 BOOST_LOG_OPEN_NAMESPACE
0042 
0043 namespace expressions {
0044 
0045 namespace aux {
0046 
0047 //! Wrapped formatter stream output terminal
0048 template< typename LeftT, typename FunT >
0049 class wrapped_formatter_output_terminal
0050 {
0051 private:
0052     //! Self type
0053     typedef wrapped_formatter_output_terminal< LeftT, FunT > this_type;
0054 
0055 public:
0056 #ifndef BOOST_LOG_DOXYGEN_PASS
0057     //! Internal typedef for type categorization
0058     typedef void _is_boost_log_terminal;
0059 #endif
0060 
0061     //! Wrapped function type
0062     typedef FunT function_type;
0063 
0064     //! Result type definition
0065     template< typename >
0066     struct result;
0067 
0068     template< typename ThisT, typename ContextT >
0069     struct result< ThisT(ContextT) >
0070     {
0071         typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
0072         typedef typename phoenix::evaluator::impl<
0073             typename LeftT::proto_base_expr&,
0074             context_type,
0075             phoenix::unused
0076         >::result_type type;
0077     };
0078 
0079 private:
0080     //! Left argument actor
0081     LeftT m_left;
0082     //! Wrapped function
0083     function_type m_fun;
0084 
0085 public:
0086     //! Initializing constructor
0087     wrapped_formatter_output_terminal(LeftT const& left, function_type const& fun) : m_left(left), m_fun(fun)
0088     {
0089     }
0090     //! Copy constructor
0091     wrapped_formatter_output_terminal(wrapped_formatter_output_terminal const& that) : m_left(that.m_left), m_fun(that.m_fun)
0092     {
0093     }
0094 
0095     //! Invokation operator
0096     template< typename ContextT >
0097     typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx)
0098     {
0099         typedef typename result< this_type(ContextT const&) >::type result_type;
0100         result_type strm = phoenix::eval(m_left, ctx);
0101         m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()), strm);
0102         return strm;
0103     }
0104 
0105     //! Invokation operator
0106     template< typename ContextT >
0107     typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const
0108     {
0109         typedef typename result< const this_type(ContextT const&) >::type result_type;
0110         result_type strm = phoenix::eval(m_left, ctx);
0111         m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()), strm);
0112         return strm;
0113     }
0114 
0115     BOOST_DELETED_FUNCTION(wrapped_formatter_output_terminal())
0116 };
0117 
0118 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_char_type, char_type, false)
0119 
0120 template<
0121     typename FunT,
0122     bool HasCharTypeV = has_char_type< FunT >::value,
0123     bool HasSecondArgumentV = boost::log::aux::has_second_argument_type< FunT >::value,
0124     bool HasArg2V = boost::log::aux::has_arg2_type< FunT >::value
0125 >
0126 struct default_char_type
0127 {
0128     // Use this char type if all detection fails
0129     typedef char type;
0130 };
0131 
0132 template< typename FunT, bool HasSecondArgumentV, bool HasArg2V >
0133 struct default_char_type< FunT, true, HasSecondArgumentV, HasArg2V >
0134 {
0135     typedef typename FunT::char_type type;
0136 };
0137 
0138 template< typename FunT, bool HasArg2V >
0139 struct default_char_type< FunT, false, true, HasArg2V >
0140 {
0141     typedef typename remove_cv< typename remove_reference< typename FunT::second_argument_type >::type >::type argument_type;
0142     typedef typename argument_type::char_type type;
0143 };
0144 
0145 template< typename FunT >
0146 struct default_char_type< FunT, false, false, true >
0147 {
0148     typedef typename remove_cv< typename remove_reference< typename FunT::arg2_type >::type >::type argument_type;
0149     typedef typename argument_type::char_type type;
0150 };
0151 
0152 } // namespace aux
0153 
0154 /*!
0155  * Formatter function wrapper terminal.
0156  */
0157 template< typename FunT, typename CharT >
0158 class wrapped_formatter_terminal
0159 {
0160 public:
0161 #ifndef BOOST_LOG_DOXYGEN_PASS
0162     //! Internal typedef for type categorization
0163     typedef void _is_boost_log_terminal;
0164 #endif
0165 
0166     //! Character type
0167     typedef CharT char_type;
0168     //! String type
0169     typedef std::basic_string< char_type > string_type;
0170     //! Formatting stream type
0171     typedef basic_formatting_ostream< char_type > stream_type;
0172     //! Wrapped function type
0173     typedef FunT function_type;
0174 
0175     //! Formatter result type
0176     typedef string_type result_type;
0177 
0178 private:
0179     //! Wrapped function
0180     function_type m_fun;
0181 
0182 public:
0183     //! Initializing construction
0184     explicit wrapped_formatter_terminal(function_type const& fun) : m_fun(fun)
0185     {
0186     }
0187     //! Copy constructor
0188     wrapped_formatter_terminal(wrapped_formatter_terminal const& that) : m_fun(that.m_fun)
0189     {
0190     }
0191 
0192     //! Returns the wrapped function
0193     function_type const& get_function() const
0194     {
0195         return m_fun;
0196     }
0197 
0198     //! Invokation operator
0199     template< typename ContextT >
0200     result_type operator() (ContextT const& ctx)
0201     {
0202         string_type str;
0203         stream_type strm(str);
0204         m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()), strm);
0205         strm.flush();
0206         return BOOST_LOG_NRVO_RESULT(str);
0207     }
0208 
0209     //! Invokation operator
0210     template< typename ContextT >
0211     result_type operator() (ContextT const& ctx) const
0212     {
0213         string_type str;
0214         stream_type strm(str);
0215         m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()), strm);
0216         strm.flush();
0217         return BOOST_LOG_NRVO_RESULT(str);
0218     }
0219 };
0220 
0221 /*!
0222  * Wrapped formatter function actor.
0223  */
0224 template< typename FunT, typename CharT, template< typename > class ActorT = phoenix::actor >
0225 class wrapped_formatter_actor :
0226     public ActorT< wrapped_formatter_terminal< FunT, CharT > >
0227 {
0228 public:
0229     //! Character type
0230     typedef CharT char_type;
0231     //! Wrapped function type
0232     typedef FunT function_type;
0233     //! Base terminal type
0234     typedef wrapped_formatter_terminal< function_type, char_type > terminal_type;
0235 
0236     //! Base actor type
0237     typedef ActorT< terminal_type > base_type;
0238 
0239 public:
0240     //! Initializing constructor
0241     explicit wrapped_formatter_actor(base_type const& act) : base_type(act)
0242     {
0243     }
0244 
0245     /*!
0246      * \returns The wrapped function
0247      */
0248     function_type const& get_function() const
0249     {
0250         return this->proto_expr_.child0.get_function();
0251     }
0252 };
0253 
0254 #ifndef BOOST_LOG_DOXYGEN_PASS
0255 
0256 #define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
0257     template< typename LeftExprT, typename FunT, typename CharT >\
0258     BOOST_FORCEINLINE phoenix::actor< aux::wrapped_formatter_output_terminal< phoenix::actor< LeftExprT >, FunT > >\
0259     operator<< (phoenix::actor< LeftExprT > left_ref left, wrapped_formatter_actor< FunT, CharT > right_ref right)\
0260     {\
0261         typedef aux::wrapped_formatter_output_terminal< phoenix::actor< LeftExprT >, FunT > terminal_type;\
0262         phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.get_function()) }};\
0263         return actor;\
0264     }
0265 
0266 #include <boost/log/detail/generate_overloads.hpp>
0267 
0268 #undef BOOST_LOG_AUX_OVERLOAD
0269 
0270 #endif // BOOST_LOG_DOXYGEN_PASS
0271 
0272 /*!
0273  * The function wraps a function object in order it to be able to participate in formatting expressions. The wrapped
0274  * function object must be compatible with the following signature:
0275  *
0276  * <pre>
0277  * void (record_view const&, basic_formatting_ostream< CharT >&)
0278  * </pre>
0279  *
0280  * where \c CharT is the character type of the formatting expression.
0281  */
0282 template< typename FunT >
0283 BOOST_FORCEINLINE wrapped_formatter_actor< FunT, typename aux::default_char_type< FunT >::type > wrap_formatter(FunT const& fun)
0284 {
0285     typedef wrapped_formatter_actor< FunT, typename aux::default_char_type< FunT >::type > actor_type;
0286     typedef typename actor_type::terminal_type terminal_type;
0287     typename actor_type::base_type act = {{ terminal_type(fun) }};
0288     return actor_type(act);
0289 }
0290 
0291 /*!
0292  * The function wraps a function object in order it to be able to participate in formatting expressions. The wrapped
0293  * function object must be compatible with the following signature:
0294  *
0295  * <pre>
0296  * void (record_view const&, basic_formatting_ostream< CharT >&)
0297  * </pre>
0298  *
0299  * where \c CharT is the character type of the formatting expression.
0300  */
0301 template< typename CharT, typename FunT >
0302 BOOST_FORCEINLINE wrapped_formatter_actor< FunT, CharT > wrap_formatter(FunT const& fun)
0303 {
0304     typedef wrapped_formatter_actor< FunT, CharT > actor_type;
0305     typedef typename actor_type::terminal_type terminal_type;
0306     typename actor_type::base_type act = {{ terminal_type(fun) }};
0307     return actor_type(act);
0308 }
0309 
0310 } // namespace expressions
0311 
0312 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0313 
0314 #ifndef BOOST_LOG_DOXYGEN_PASS
0315 
0316 namespace phoenix {
0317 
0318 namespace result_of {
0319 
0320 template< typename LeftT, typename FunT >
0321 struct is_nullary< custom_terminal< boost::log::expressions::aux::wrapped_formatter_output_terminal< LeftT, FunT > > > :
0322     public mpl::false_
0323 {
0324 };
0325 
0326 template< typename FunT, typename CharT >
0327 struct is_nullary< custom_terminal< boost::log::expressions::wrapped_formatter_terminal< FunT, CharT > > > :
0328     public mpl::false_
0329 {
0330 };
0331 
0332 } // namespace result_of
0333 
0334 } // namespace phoenix
0335 
0336 #endif
0337 
0338 } // namespace boost
0339 
0340 #include <boost/log/detail/footer.hpp>
0341 
0342 #endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_WRAP_FORMATTER_HPP_INCLUDED_