1 /*============================================================================== 2 Copyright (c) 2001-2010 Joel de Guzman 3 Copyright (c) 2010 Eric Niebler 4 Copyright (c) 2015 John Fletcher 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 ==============================================================================*/ 9 #ifndef BOOST_PHOENIX_FUNCTION_FUNCTION_HPP 10 #define BOOST_PHOENIX_FUNCTION_FUNCTION_HPP 11 12 #include <boost/phoenix/config.hpp> 13 #include <boost/phoenix/core/limits.hpp> 14 #include <boost/phoenix/core/detail/function_eval.hpp> 15 #include <boost/utility/result_of.hpp> 16 17 namespace boost { namespace phoenix 18 { 19 ///////////////////////////////////////////////////////////////////////////// 20 // Functions 21 ///////////////////////////////////////////////////////////////////////////// 22 23 namespace expression 24 { 25 #if defined(BOOST_PHOENIX_NO_VARIADIC_FUNCTION) 26 template <typename F, BOOST_PHOENIX_typename_A_void(BOOST_PHOENIX_ACTOR_LIMIT)> 27 struct function 28 : detail::expression::function_eval<F, BOOST_PHOENIX_A(BOOST_PHOENIX_ACTOR_LIMIT)> 29 {}; 30 #else 31 // TODO: 32 #endif 33 } 34 35 // functor which returns our lazy function call extension 36 template<typename F> 37 struct function 38 { functionboost::phoenix::function39 BOOST_CONSTEXPR function() 40 : f() 41 {} 42 functionboost::phoenix::function43 BOOST_CONSTEXPR function(F f_) 44 : f(f_) 45 {} 46 47 template <typename Sig> 48 struct result; 49 50 #if defined(BOOST_PHOENIX_NO_VARIADIC_FUNCTION) 51 typename detail::expression::function_eval<F>::type const operator ()boost::phoenix::function52 operator()() const 53 { 54 return detail::expression::function_eval<F>::make(f); 55 } 56 57 // Bring in the rest 58 #include <boost/phoenix/function/detail/cpp03/function_operator.hpp> 59 60 // Solves the result problem for F(X) 61 template <typename This, typename A0> 62 struct result<This(A0)> 63 : detail::expression::function_eval<F, 64 typename boost::remove_reference<A0>::type> 65 {}; 66 // Solves the result problem for F(X,Y) 67 template <typename This, typename A0, typename A1> 68 struct result<This(A0,A1)> 69 : detail::expression::function_eval<F, 70 typename boost::remove_reference<A0>::type, 71 typename boost::remove_reference<A1>::type> 72 {}; 73 // Solves the result problem for F(X,Y,Z) 74 template <typename This, typename A0, typename A1, typename A2> 75 struct result<This(A0,A1,A2)> 76 : detail::expression::function_eval<F, 77 typename boost::remove_reference<A0>::type, 78 typename boost::remove_reference<A1>::type, 79 typename boost::remove_reference<A2>::type> 80 {}; 81 82 // Solves the result problem for F(W,X,Y,Z) 83 template <typename This, typename A0, typename A1, 84 typename A2, typename A3> 85 struct result<This(A0,A1,A2,A3)> 86 : detail::expression::function_eval<F, 87 typename boost::remove_reference<A0>::type, 88 typename boost::remove_reference<A1>::type, 89 typename boost::remove_reference<A2>::type, 90 typename boost::remove_reference<A3>::type> 91 {}; 92 93 // Solves the result problem for F(V,W,X,Y,Z) 94 template <typename This, typename A0, typename A1, 95 typename A2, typename A3,typename A4> 96 struct result<This(A0,A1,A2,A3,A4)> 97 : detail::expression::function_eval<F, 98 typename boost::remove_reference<A0>::type, 99 typename boost::remove_reference<A1>::type, 100 typename boost::remove_reference<A2>::type, 101 typename boost::remove_reference<A3>::type, 102 typename boost::remove_reference<A4>::type> 103 {}; 104 105 // Solves the result problem for F(U,V,W,X,Y,Z) 106 template <typename This, typename A0, typename A1, 107 typename A2, typename A3,typename A4, 108 typename A5> 109 struct result<This(A0,A1,A2,A3,A4,A5)> 110 : detail::expression::function_eval<F, 111 typename boost::remove_reference<A0>::type, 112 typename boost::remove_reference<A1>::type, 113 typename boost::remove_reference<A2>::type, 114 typename boost::remove_reference<A3>::type, 115 typename boost::remove_reference<A4>::type, 116 typename boost::remove_reference<A5>::type> 117 {}; 118 119 // Solves the result problem for F(T,U,V,W,X,Y,Z) 120 template <typename This, typename A0, typename A1, 121 typename A2, typename A3,typename A4, 122 typename A5, typename A6> 123 struct result<This(A0,A1,A2,A3,A4,A5,A6)> 124 : detail::expression::function_eval<F, 125 typename boost::remove_reference<A0>::type, 126 typename boost::remove_reference<A1>::type, 127 typename boost::remove_reference<A2>::type, 128 typename boost::remove_reference<A3>::type, 129 typename boost::remove_reference<A4>::type, 130 typename boost::remove_reference<A5>::type, 131 typename boost::remove_reference<A6>::type> 132 {}; 133 #else 134 // TODO: 135 #endif 136 137 F f; 138 }; 139 } 140 141 template<typename F> 142 struct result_of<phoenix::function<F>()> 143 : phoenix::detail::expression::function_eval<F> 144 {}; 145 146 } 147 148 #endif 149 150