• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   unary_function_terminal.hpp
9  * \author Andrey Semashev
10  * \date   21.07.2012
11  *
12  * The header contains attribute value extractor adapter for constructing expression template terminals.
13  */
14 
15 #ifndef BOOST_LOG_DETAIL_UNARY_FUNCTION_TERMINAL_HPP_INCLUDED_
16 #define BOOST_LOG_DETAIL_UNARY_FUNCTION_TERMINAL_HPP_INCLUDED_
17 
18 #include <boost/mpl/bool.hpp>
19 #include <boost/utility/result_of.hpp>
20 #include <boost/fusion/sequence/intrinsic/at_c.hpp>
21 #include <boost/phoenix/core/is_nullary.hpp>
22 #include <boost/phoenix/core/environment.hpp>
23 #include <boost/type_traits/remove_cv.hpp>
24 #include <boost/type_traits/remove_reference.hpp>
25 #include <boost/log/detail/config.hpp>
26 #include <boost/log/detail/copy_cv.hpp>
27 #include <boost/log/detail/custom_terminal_spec.hpp>
28 #include <boost/log/detail/header.hpp>
29 
30 #ifdef BOOST_HAS_PRAGMA_ONCE
31 #pragma once
32 #endif
33 
34 namespace boost {
35 
36 BOOST_LOG_OPEN_NAMESPACE
37 
38 namespace expressions {
39 
40 namespace aux {
41 
42 /*!
43  * \brief An adapter for a unary function to be used as a terminal in a Boost.Phoenix expression
44  *
45  * This class is an adapter between Boost.Phoenix expression invocation protocol and
46  * a unary function. It forwards the call to the base function, passing only the first argument
47  * from the original call. This allows to embed value extractors in template expressions.
48  */
49 template< typename FunT >
50 class unary_function_terminal
51 {
52 private:
53     //! Adopted function type
54     typedef FunT function_type;
55     //! Self type
56     typedef unary_function_terminal< function_type > this_type;
57 
58 public:
59     //! Internal typedef for type categorization
60     typedef void _is_boost_log_terminal;
61 
62     //! Function result type
63     template< typename >
64     struct result;
65 
66     template< typename ThisT, typename ContextT >
67     struct result< ThisT(ContextT) >
68     {
69         typedef typename remove_cv<
70             typename remove_reference< typename phoenix::result_of::env< ContextT >::type >::type
71         >::type env_type;
72         typedef typename env_type::args_type args_type;
73         typedef typename boost::log::aux::copy_cv< ThisT, function_type >::type cv_function_type;
74 
75         typedef typename boost::result_of< cv_function_type(typename fusion::result_of::at_c< args_type, 0 >::type) >::type type;
76     };
77 
78 private:
79     //! Adopted function
80     function_type m_fun;
81 
82 public:
83     //! Default constructor
unary_function_terminal()84     BOOST_DEFAULTED_FUNCTION(unary_function_terminal(), {})
85     //! Copy constructor
86     unary_function_terminal(unary_function_terminal const& that) : m_fun(that.m_fun) {}
87     //! Initializing constructor
88     template< typename ArgT1 >
unary_function_terminal(ArgT1 const & arg1)89     explicit unary_function_terminal(ArgT1 const& arg1) : m_fun(arg1) {}
90     //! Initializing constructor
91     template< typename ArgT1, typename ArgT2 >
unary_function_terminal(ArgT1 const & arg1,ArgT2 const & arg2)92     unary_function_terminal(ArgT1 const& arg1, ArgT2 const& arg2) : m_fun(arg1, arg2) {}
93     //! Initializing constructor
94     template< typename ArgT1, typename ArgT2, typename ArgT3 >
unary_function_terminal(ArgT1 const & arg1,ArgT2 const & arg2,ArgT3 const & arg3)95     unary_function_terminal(ArgT1 const& arg1, ArgT2 const& arg2, ArgT3 const& arg3) : m_fun(arg1, arg2, arg3) {}
96 
97     //! The operator forwards the call to the base function
98     template< typename ContextT >
99     typename result< this_type(ContextT const&) >::type
operator ()(ContextT const & ctx)100     operator() (ContextT const& ctx)
101     {
102         return m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()));
103     }
104 
105     //! The operator forwards the call to the base function
106     template< typename ContextT >
107     typename result< const this_type(ContextT const&) >::type
operator ()(ContextT const & ctx) const108     operator() (ContextT const& ctx) const
109     {
110         return m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()));
111     }
112 };
113 
114 } // namespace aux
115 
116 } // namespace expressions
117 
118 BOOST_LOG_CLOSE_NAMESPACE // namespace log
119 
120 #ifndef BOOST_LOG_DOXYGEN_PASS
121 
122 namespace phoenix {
123 
124 namespace result_of {
125 
126 template< typename FunT >
127 struct is_nullary< custom_terminal< boost::log::expressions::aux::unary_function_terminal< FunT > > > :
128     public mpl::false_
129 {
130 };
131 
132 } // namespace result_of
133 
134 } // namespace phoenix
135 
136 #endif // BOOST_LOG_DOXYGEN_PASS
137 
138 } // namespace boost
139 
140 #include <boost/log/detail/footer.hpp>
141 
142 #endif // BOOST_LOG_DETAIL_UNARY_FUNCTION_TERMINAL_HPP_INCLUDED_
143