1 /*============================================================================= 2 Copyright (c) 2006-2007 Tobias Schwinger 3 4 Use modification and distribution are subject to the Boost Software 5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 http://www.boost.org/LICENSE_1_0.txt). 7 ==============================================================================*/ 8 9 #if !defined(BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_TYPED_HPP_INCLUDED) 10 #if !defined(BOOST_PP_IS_ITERATING) 11 12 #include <boost/preprocessor/cat.hpp> 13 #include <boost/preprocessor/iteration/iterate.hpp> 14 #include <boost/preprocessor/repetition/enum.hpp> 15 #include <boost/preprocessor/repetition/enum_params.hpp> 16 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> 17 18 #include <boost/config.hpp> 19 20 #include <boost/utility/result_of.hpp> 21 22 #include <boost/fusion/support/detail/access.hpp> 23 #include <boost/fusion/sequence/intrinsic/value_at.hpp> 24 #include <boost/fusion/sequence/intrinsic/size.hpp> 25 #include <boost/fusion/container/vector/vector.hpp> 26 #include <boost/fusion/container/vector/convert.hpp> 27 28 #include <boost/fusion/functional/adapter/limits.hpp> 29 #include <boost/fusion/functional/adapter/detail/access.hpp> 30 31 #if defined (BOOST_MSVC) 32 # pragma warning(push) 33 # pragma warning (disable: 4512) // assignment operator could not be generated. 34 #endif 35 36 37 namespace boost { namespace fusion 38 { 39 40 template <class Function, class Sequence> class unfused_typed; 41 42 //----- ---- --- -- - - - - 43 44 namespace detail 45 { 46 template <class Derived, class Function, 47 class Sequence, long Arity> 48 struct unfused_typed_impl; 49 } 50 51 template <class Function, class Sequence> 52 class unfused_typed 53 : public detail::unfused_typed_impl 54 < unfused_typed<Function,Sequence>, Function, Sequence, 55 result_of::size<Sequence>::value > 56 { 57 Function fnc_transformed; 58 59 template <class D, class F, class S, long A> 60 friend struct detail::unfused_typed_impl; 61 62 typedef typename detail::call_param<Function>::type func_const_fwd_t; 63 64 public: 65 66 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED unfused_typed(func_const_fwd_t f=Function ())67 inline explicit unfused_typed(func_const_fwd_t f = Function()) 68 : fnc_transformed(f) 69 { } 70 }; 71 72 #define BOOST_PP_FILENAME_1 <boost/fusion/functional/adapter/unfused_typed.hpp> 73 #define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUSION_UNFUSED_TYPED_MAX_ARITY) 74 #include BOOST_PP_ITERATE() 75 76 }} 77 78 #if defined (BOOST_MSVC) 79 # pragma warning(pop) 80 #endif 81 82 namespace boost 83 { 84 #if !defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_NO_CXX11_DECLTYPE) 85 template<class F, class Seq> 86 struct result_of< boost::fusion::unfused_typed<F,Seq> const () > 87 : boost::fusion::unfused_typed<F,Seq>::template result< 88 boost::fusion::unfused_typed<F,Seq> const () > 89 { }; 90 template<class F, class Seq> 91 struct result_of< boost::fusion::unfused_typed<F,Seq>() > 92 : boost::fusion::unfused_typed<F,Seq>::template result< 93 boost::fusion::unfused_typed<F,Seq> () > 94 { }; 95 #endif 96 template<class F, class Seq> 97 struct tr1_result_of< boost::fusion::unfused_typed<F,Seq> const () > 98 : boost::fusion::unfused_typed<F,Seq>::template result< 99 boost::fusion::unfused_typed<F,Seq> const () > 100 { }; 101 template<class F, class Seq> 102 struct tr1_result_of< boost::fusion::unfused_typed<F,Seq>() > 103 : boost::fusion::unfused_typed<F,Seq>::template result< 104 boost::fusion::unfused_typed<F,Seq> () > 105 { }; 106 } 107 108 109 #define BOOST_FUSION_FUNCTIONAL_ADAPTER_UNFUSED_TYPED_HPP_INCLUDED 110 #else // defined(BOOST_PP_IS_ITERATING) 111 /////////////////////////////////////////////////////////////////////////////// 112 // 113 // Preprocessor vertical repetition code 114 // 115 /////////////////////////////////////////////////////////////////////////////// 116 #define N BOOST_PP_ITERATION() 117 118 namespace detail 119 { 120 121 template <class Derived, class Function, class Sequence> 122 struct unfused_typed_impl<Derived,Function,Sequence,N> 123 { 124 typedef typename detail::qf_c<Function>::type function_c; 125 typedef typename detail::qf<Function>::type function; 126 typedef typename result_of::as_vector<Sequence>::type arg_vector_t; 127 128 public: 129 130 #define M(z,i,s) \ 131 typename call_param<typename result_of::value_at_c<s,i>::type>::type a##i 132 133 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED 134 inline typename boost::result_of< 135 function_c(arg_vector_t &) >::type operator ()detail::unfused_typed_impl136 operator()(BOOST_PP_ENUM(N,M,arg_vector_t)) const 137 { 138 #if N > 0 139 arg_vector_t arg(BOOST_PP_ENUM_PARAMS(N,a)); 140 #else 141 arg_vector_t arg; 142 #endif 143 return static_cast<Derived const *>(this)->fnc_transformed(arg); 144 } 145 146 BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED 147 inline typename boost::result_of< 148 function(arg_vector_t &) >::type operator ()detail::unfused_typed_impl149 operator()(BOOST_PP_ENUM(N,M,arg_vector_t)) 150 { 151 #if N > 0 152 arg_vector_t arg(BOOST_PP_ENUM_PARAMS(N,a)); 153 #else 154 arg_vector_t arg; 155 #endif 156 return static_cast<Derived *>(this)->fnc_transformed(arg); 157 } 158 159 #undef M 160 161 template <typename Sig> struct result { typedef void type; }; 162 163 template <class Self BOOST_PP_ENUM_TRAILING_PARAMS(N,typename T)> 164 struct result< Self const (BOOST_PP_ENUM_PARAMS(N,T)) > 165 : boost::result_of< function_c(arg_vector_t &) > 166 { }; 167 168 template <class Self BOOST_PP_ENUM_TRAILING_PARAMS(N,typename T)> 169 struct result< Self (BOOST_PP_ENUM_PARAMS(N,T)) > 170 : boost::result_of< function(arg_vector_t &) > 171 { }; 172 }; 173 174 } // namespace detail 175 176 #undef N 177 #endif // defined(BOOST_PP_IS_ITERATING) 178 #endif 179 180