1 /* 2 * Copyright Andrey Semashev 2007 - 2015. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 /*! 8 * \file attribute_output_terminal.hpp 9 * \author Andrey Semashev 10 * \date 06.11.2012 11 * 12 * The header contains implementation of a generic output manipulator in template expressions. 13 */ 14 15 #ifndef BOOST_LOG_DETAIL_ATTR_OUTPUT_TERMINAL_HPP_INCLUDED_ 16 #define BOOST_LOG_DETAIL_ATTR_OUTPUT_TERMINAL_HPP_INCLUDED_ 17 18 #include <boost/mpl/bool.hpp> 19 #include <boost/phoenix/core/actor.hpp> 20 #include <boost/phoenix/core/meta_grammar.hpp> 21 #include <boost/phoenix/core/environment.hpp> 22 #include <boost/phoenix/core/terminal_fwd.hpp> 23 #include <boost/phoenix/core/is_nullary.hpp> 24 #include <boost/type_traits/remove_cv.hpp> 25 #include <boost/type_traits/remove_reference.hpp> 26 #include <boost/fusion/sequence/intrinsic/at.hpp> 27 #include <boost/log/detail/config.hpp> 28 #include <boost/log/detail/custom_terminal_spec.hpp> 29 #include <boost/log/attributes/attribute_name.hpp> 30 #include <boost/log/attributes/value_visitation.hpp> 31 #include <boost/log/utility/functional/bind.hpp> 32 #include <boost/log/detail/header.hpp> 33 34 #ifdef BOOST_HAS_PRAGMA_ONCE 35 #pragma once 36 #endif 37 38 namespace boost { 39 40 BOOST_LOG_OPEN_NAMESPACE 41 42 namespace expressions { 43 44 namespace aux { 45 46 //! Attribute stream output expression 47 template< typename LeftT, typename T, typename FallbackPolicyT, typename ImplT > 48 class attribute_output_terminal 49 { 50 private: 51 //! Self type 52 typedef attribute_output_terminal< LeftT, T, FallbackPolicyT, ImplT > this_type; 53 //! Attribute value visitor invoker 54 typedef value_visitor_invoker< T, FallbackPolicyT > visitor_invoker_type; 55 //! Manipulator implementation 56 typedef ImplT impl_type; 57 58 public: 59 //! Internal typedef for type categorization 60 typedef void _is_boost_log_terminal; 61 62 //! Result type definition 63 template< typename > 64 struct result; 65 66 template< typename ThisT, typename ContextT > 67 struct result< ThisT(ContextT) > 68 { 69 typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type; 70 typedef typename phoenix::evaluator::impl< 71 typename LeftT::proto_base_expr&, 72 context_type, 73 phoenix::unused 74 >::result_type type; 75 }; 76 77 private: 78 //! Left argument actor 79 LeftT m_left; 80 //! Attribute name 81 const attribute_name m_name; 82 //! Attribute value visitor invoker 83 visitor_invoker_type m_visitor_invoker; 84 //! Manipulator implementation 85 impl_type m_impl; 86 87 public: 88 //! Initializing constructor attribute_output_terminal(LeftT const & left,attribute_name const & name)89 attribute_output_terminal(LeftT const& left, attribute_name const& name) : m_left(left), m_name(name) 90 { 91 } 92 93 //! Initializing constructor attribute_output_terminal(LeftT const & left,attribute_name const & name,impl_type const & impl)94 attribute_output_terminal(LeftT const& left, attribute_name const& name, impl_type const& impl) : m_left(left), m_name(name), m_impl(impl) 95 { 96 } 97 98 //! Initializing constructor 99 template< typename U > attribute_output_terminal(LeftT const & left,attribute_name const & name,impl_type const & impl,U const & arg)100 attribute_output_terminal(LeftT const& left, attribute_name const& name, impl_type const& impl, U const& arg) : 101 m_left(left), m_name(name), m_visitor_invoker(arg), m_impl(impl) 102 { 103 } 104 105 //! Copy constructor attribute_output_terminal(attribute_output_terminal const & that)106 attribute_output_terminal(attribute_output_terminal const& that) : 107 m_left(that.m_left), m_name(that.m_name), m_visitor_invoker(that.m_visitor_invoker), m_impl(that.m_impl) 108 { 109 } 110 111 //! Invokation operator 112 template< typename ContextT > operator ()(ContextT const & ctx)113 typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx) 114 { 115 typedef typename result< this_type(ContextT const&) >::type result_type; 116 result_type strm = phoenix::eval(m_left, ctx); 117 m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< impl_type&, result_type >(m_impl, strm)); 118 return strm; 119 } 120 121 //! Invokation operator 122 template< typename ContextT > operator ()(ContextT const & ctx) const123 typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const 124 { 125 typedef typename result< const this_type(ContextT const&) >::type result_type; 126 result_type strm = phoenix::eval(m_left, ctx); 127 m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< impl_type const&, result_type >(m_impl, strm)); 128 return strm; 129 } 130 131 BOOST_DELETED_FUNCTION(attribute_output_terminal()) 132 }; 133 134 } // namespace aux 135 136 } // namespace expressions 137 138 BOOST_LOG_CLOSE_NAMESPACE // namespace log 139 140 #ifndef BOOST_LOG_DOXYGEN_PASS 141 142 namespace phoenix { 143 144 namespace result_of { 145 146 template< typename LeftT, typename T, typename FallbackPolicyT, typename ImplT > 147 struct is_nullary< custom_terminal< boost::log::expressions::aux::attribute_output_terminal< LeftT, T, FallbackPolicyT, ImplT > > > : 148 public mpl::false_ 149 { 150 }; 151 152 } // namespace result_of 153 154 } // namespace phoenix 155 156 #endif // !defined(BOOST_LOG_DOXYGEN_PASS) 157 158 } // namespace boost 159 160 #include <boost/log/detail/footer.hpp> 161 162 #endif // BOOST_LOG_DETAIL_ATTR_OUTPUT_TERMINAL_HPP_INCLUDED_ 163