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 formatters/if.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 17.11.2012 Chris@16: * Chris@16: * The header contains implementation of a conditional formatter. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_IF_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_EXPRESSIONS_FORMATTERS_IF_HPP_INCLUDED_ Chris@16: 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: #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@16: namespace expressions { Chris@16: Chris@16: namespace aux { Chris@16: Chris@16: template< typename LeftT, typename CondT, typename ThenT > Chris@16: class if_output_terminal Chris@16: { Chris@16: private: Chris@16: //! Self type Chris@16: typedef if_output_terminal this_type; Chris@16: Chris@16: public: Chris@16: //! Internal typedef for type categorization Chris@16: typedef void _is_boost_log_terminal; Chris@16: Chris@16: //! Result type definition Chris@16: template< typename > Chris@16: struct result; Chris@16: Chris@101: template< typename ThisT, typename ContextT > Chris@101: struct result< ThisT(ContextT) > Chris@16: { Chris@16: typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type; Chris@16: typedef typename phoenix::evaluator::impl< Chris@16: typename LeftT::proto_base_expr&, Chris@16: context_type, Chris@16: phoenix::unused Chris@16: >::result_type type; Chris@16: }; Chris@16: Chris@16: private: Chris@16: //! Left argument actor Chris@16: LeftT m_left; Chris@16: //! Condition expression Chris@16: CondT m_cond; Chris@16: //! Positive branch Chris@16: ThenT m_then; Chris@16: Chris@16: public: Chris@16: //! Initializing constructor Chris@16: if_output_terminal(LeftT const& left, CondT const& cond, ThenT const& then_) : m_left(left), m_cond(cond), m_then(then_) Chris@16: { Chris@16: } Chris@16: Chris@16: //! Invokation operator Chris@16: template< typename ContextT > Chris@16: typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx) Chris@16: { Chris@16: typedef typename result< this_type(ContextT const&) >::type result_type; Chris@16: result_type strm = phoenix::eval(m_left, ctx); Chris@16: if (phoenix::eval(m_cond, ctx)) Chris@16: phoenix::eval(m_then, ctx); Chris@16: return strm; Chris@16: } Chris@16: Chris@16: //! Invokation operator Chris@16: template< typename ContextT > Chris@16: typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const Chris@16: { Chris@16: typedef typename result< const this_type(ContextT const&) >::type result_type; Chris@16: result_type strm = phoenix::eval(m_left, ctx); Chris@16: if (phoenix::eval(m_cond, ctx)) Chris@16: phoenix::eval(m_then, ctx); Chris@16: return strm; Chris@16: } Chris@16: Chris@16: BOOST_DELETED_FUNCTION(if_output_terminal()) Chris@16: }; Chris@16: Chris@16: template< typename LeftT, typename CondT, typename ThenT, typename ElseT > Chris@16: class if_else_output_terminal Chris@16: { Chris@16: private: Chris@16: //! Self type Chris@16: typedef if_else_output_terminal this_type; Chris@16: Chris@16: public: Chris@16: //! Internal typedef for type categorization Chris@16: typedef void _is_boost_log_terminal; Chris@16: Chris@16: //! Result type definition Chris@16: template< typename > Chris@16: struct result; Chris@16: Chris@101: template< typename ThisT, typename ContextT > Chris@101: struct result< ThisT(ContextT) > Chris@16: { Chris@16: typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type; Chris@16: typedef typename phoenix::evaluator::impl< Chris@16: typename LeftT::proto_base_expr&, Chris@16: context_type, Chris@16: phoenix::unused Chris@16: >::result_type type; Chris@16: }; Chris@16: Chris@16: private: Chris@16: //! Left argument actor Chris@16: LeftT m_left; Chris@16: //! Condition expression Chris@16: CondT m_cond; Chris@16: //! Positive branch Chris@16: ThenT m_then; Chris@16: //! Negative branch Chris@16: ElseT m_else; Chris@16: Chris@16: public: Chris@16: //! Initializing constructor Chris@16: if_else_output_terminal(LeftT const& left, CondT const& cond, ThenT const& then_, ElseT const& else_) : m_left(left), m_cond(cond), m_then(then_), m_else(else_) Chris@16: { Chris@16: } Chris@16: Chris@16: //! Invokation operator Chris@16: template< typename ContextT > Chris@16: typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx) Chris@16: { Chris@16: typedef typename result< this_type(ContextT const&) >::type result_type; Chris@16: result_type strm = phoenix::eval(m_left, ctx); Chris@16: if (phoenix::eval(m_cond, ctx)) Chris@16: phoenix::eval(m_then, ctx); Chris@16: else Chris@16: phoenix::eval(m_else, ctx); Chris@16: return strm; Chris@16: } Chris@16: Chris@16: //! Invokation operator Chris@16: template< typename ContextT > Chris@16: typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const Chris@16: { Chris@16: typedef typename result< const this_type(ContextT const&) >::type result_type; Chris@16: result_type strm = phoenix::eval(m_left, ctx); Chris@16: if (phoenix::eval(m_cond, ctx)) Chris@16: phoenix::eval(m_then, ctx); Chris@16: else Chris@16: phoenix::eval(m_else, ctx); Chris@16: return strm; Chris@16: } Chris@16: Chris@16: BOOST_DELETED_FUNCTION(if_else_output_terminal()) Chris@16: }; Chris@16: Chris@16: Chris@16: template< typename CondT, typename ThenT, typename ElseT > Chris@16: struct if_then_else_gen Chris@16: { Chris@16: CondT m_cond; Chris@16: ThenT m_then; Chris@16: ElseT m_else; Chris@16: Chris@16: if_then_else_gen(CondT const& cond, ThenT const& then_, ElseT const& else_) : m_cond(cond), m_then(then_), m_else(else_) Chris@16: { Chris@16: } Chris@16: }; Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: #define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\ Chris@16: template< typename LeftExprT, typename CondT, typename ThenT, typename ElseT >\ Chris@16: BOOST_FORCEINLINE phoenix::actor< if_else_output_terminal< phoenix::actor< LeftExprT >, CondT, ThenT, ElseT > >\ Chris@16: operator<< (phoenix::actor< LeftExprT > left_ref left, if_then_else_gen< CondT, ThenT, ElseT > right_ref right)\ Chris@16: {\ Chris@16: typedef if_else_output_terminal< phoenix::actor< LeftExprT >, CondT, ThenT, ElseT > terminal_type;\ Chris@16: phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.m_cond, right.m_then, right.m_else) }};\ Chris@16: return actor;\ Chris@16: } Chris@16: Chris@16: #include Chris@16: Chris@16: #undef BOOST_LOG_AUX_OVERLOAD Chris@16: Chris@16: #endif // BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: template< typename CondT, typename ThenT > Chris@16: struct if_then_gen Chris@16: { Chris@16: struct else_gen Chris@16: { Chris@16: CondT m_cond; Chris@16: ThenT m_then; Chris@16: Chris@16: else_gen(CondT const& cond, ThenT const& then_) : m_cond(cond), m_then(then_) Chris@16: { Chris@16: } Chris@16: Chris@16: template< typename ElseT > Chris@16: BOOST_FORCEINLINE if_then_else_gen< CondT, ThenT, ElseT > operator[] (ElseT const& el) Chris@16: { Chris@16: return if_then_else_gen< CondT, ThenT, ElseT >(m_cond, m_then, el); Chris@16: } Chris@16: } Chris@16: else_; Chris@16: Chris@16: if_then_gen(CondT const& cond, ThenT const& then_) : else_(cond, then_) {} Chris@16: }; Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: #define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\ Chris@16: template< typename LeftExprT, typename CondT, typename ThenT >\ Chris@16: BOOST_FORCEINLINE phoenix::actor< if_output_terminal< phoenix::actor< LeftExprT >, CondT, ThenT > >\ Chris@16: operator<< (phoenix::actor< LeftExprT > left_ref left, if_then_gen< CondT, ThenT > right_ref right)\ Chris@16: {\ Chris@16: typedef if_output_terminal< phoenix::actor< LeftExprT >, CondT, ThenT > terminal_type;\ Chris@16: phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.else_.m_cond, right.else_.m_then) }};\ Chris@16: return actor;\ Chris@16: } Chris@16: Chris@16: #include Chris@16: Chris@16: #undef BOOST_LOG_AUX_OVERLOAD Chris@16: Chris@16: #endif // BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: template< typename CondT > Chris@16: class if_gen Chris@16: { Chris@16: private: Chris@16: CondT const& m_cond; Chris@16: Chris@16: public: Chris@16: explicit if_gen(CondT const& cond) : m_cond(cond) Chris@16: { Chris@16: } Chris@16: Chris@16: template< typename ThenT > Chris@16: BOOST_FORCEINLINE if_then_gen< CondT, ThenT > operator[] (ThenT const& then_) const Chris@16: { Chris@16: return if_then_gen< CondT, ThenT >(m_cond, then_); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace aux Chris@16: Chris@16: /*! Chris@16: * The function returns a conditional formatter generator object. The generator provides operator[] that can be used Chris@16: * to construct the actual formatter. The formatter must participate in a streaming expression. Chris@16: * Chris@16: * \param cond A filter expression that will be used as the condition Chris@16: */ Chris@16: template< typename CondT > Chris@16: BOOST_FORCEINLINE aux::if_gen< CondT > if_(CondT const& cond) Chris@16: { Chris@16: return aux::if_gen< CondT >(cond); Chris@16: } Chris@16: Chris@16: } // namespace expressions Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: namespace phoenix { Chris@16: Chris@16: namespace result_of { Chris@16: Chris@16: template< typename LeftT, typename CondT, typename ThenT > Chris@16: struct is_nullary< custom_terminal< boost::log::expressions::aux::if_output_terminal< LeftT, CondT, ThenT > > > : Chris@16: public mpl::false_ Chris@16: { Chris@16: }; Chris@16: Chris@16: template< typename LeftT, typename CondT, typename ThenT, typename ElseT > Chris@16: struct is_nullary< custom_terminal< boost::log::expressions::aux::if_else_output_terminal< LeftT, CondT, ThenT, ElseT > > > : Chris@16: public mpl::false_ Chris@16: { Chris@16: }; Chris@16: Chris@16: } // namespace result_of Chris@16: Chris@16: } // namespace phoenix Chris@16: Chris@16: #endif Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_IF_HPP_INCLUDED_