invoke_function_object.hpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*=============================================================================
  2. Copyright (c) 2005-2006 Joao Abecasis
  3. Copyright (c) 2006-2007 Tobias Schwinger
  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. #if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_FUNCTION_OBJECT_HPP_INCLUDED)
  9. #if !defined(BOOST_PP_IS_ITERATING)
  10. #include <boost/preprocessor/cat.hpp>
  11. #include <boost/preprocessor/iteration/iterate.hpp>
  12. #include <boost/preprocessor/arithmetic/dec.hpp>
  13. #include <boost/preprocessor/repetition/repeat_from_to.hpp>
  14. #include <boost/preprocessor/repetition/enum.hpp>
  15. #include <boost/preprocessor/repetition/enum_params.hpp>
  16. #include <boost/utility/result_of.hpp>
  17. #include <boost/core/enable_if.hpp>
  18. #include <boost/type_traits/remove_reference.hpp>
  19. #include <boost/type_traits/remove_const.hpp>
  20. #include <boost/fusion/support/category_of.hpp>
  21. #include <boost/fusion/sequence/intrinsic/size.hpp>
  22. #include <boost/fusion/sequence/intrinsic/at.hpp>
  23. #include <boost/fusion/sequence/intrinsic/begin.hpp>
  24. #include <boost/fusion/iterator/next.hpp>
  25. #include <boost/fusion/iterator/deref.hpp>
  26. #include <boost/fusion/functional/invocation/limits.hpp>
  27. namespace boost { namespace fusion
  28. {
  29. namespace detail
  30. {
  31. template<
  32. class Function, class Sequence,
  33. int N = result_of::size<Sequence>::value,
  34. bool RandomAccess = traits::is_random_access<Sequence>::value,
  35. typename Enable = void
  36. >
  37. struct invoke_function_object_impl;
  38. template <class Sequence, int N>
  39. struct invoke_function_object_param_types;
  40. #define BOOST_PP_FILENAME_1 \
  41. <boost/fusion/functional/invocation/invoke_function_object.hpp>
  42. #define BOOST_PP_ITERATION_LIMITS \
  43. (0, BOOST_FUSION_INVOKE_FUNCTION_OBJECT_MAX_ARITY)
  44. #include BOOST_PP_ITERATE()
  45. }
  46. namespace result_of
  47. {
  48. template <class Function, class Sequence, class Enable = void>
  49. struct invoke_function_object;
  50. template <class Function, class Sequence>
  51. struct invoke_function_object<Function, Sequence,
  52. typename enable_if_has_type<
  53. typename detail::invoke_function_object_impl<
  54. typename boost::remove_reference<Function>::type, Sequence
  55. >::result_type
  56. >::type>
  57. {
  58. typedef typename detail::invoke_function_object_impl<
  59. typename boost::remove_reference<Function>::type, Sequence
  60. >::result_type type;
  61. };
  62. }
  63. template <class Function, class Sequence>
  64. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  65. inline typename result_of::invoke_function_object<Function,Sequence>::type
  66. invoke_function_object(Function f, Sequence & s)
  67. {
  68. return detail::invoke_function_object_impl<
  69. typename boost::remove_reference<Function>::type,Sequence
  70. >::call(f,s);
  71. }
  72. template <class Function, class Sequence>
  73. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  74. inline typename result_of::invoke_function_object<Function,Sequence const>::type
  75. invoke_function_object(Function f, Sequence const & s)
  76. {
  77. return detail::invoke_function_object_impl<
  78. typename boost::remove_reference<Function>::type,Sequence const
  79. >::call(f,s);
  80. }
  81. }}
  82. #define BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_FUNCTION_OBJECT_HPP_INCLUDED
  83. #else // defined(BOOST_PP_IS_ITERATING)
  84. ///////////////////////////////////////////////////////////////////////////////
  85. //
  86. // Preprocessor vertical repetition code
  87. //
  88. ///////////////////////////////////////////////////////////////////////////////
  89. #define N BOOST_PP_ITERATION()
  90. #define M(z,j,data) \
  91. typename result_of::at_c<Sequence,j>::type
  92. template <class Function, class Sequence>
  93. struct invoke_function_object_impl<Function,Sequence,N,true,
  94. typename enable_if_has_type<
  95. typename boost::result_of<Function (BOOST_PP_ENUM(N,M,~)) >::type
  96. >::type>
  97. {
  98. public:
  99. typedef typename boost::result_of<
  100. Function (BOOST_PP_ENUM(N,M,~)) >::type result_type;
  101. #undef M
  102. #if N > 0
  103. template <class F>
  104. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  105. static inline result_type
  106. call(F & f, Sequence & s)
  107. {
  108. #define M(z,j,data) fusion::at_c<j>(s)
  109. return f( BOOST_PP_ENUM(N,M,~) );
  110. #undef M
  111. }
  112. #else
  113. template <class F>
  114. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  115. static inline result_type
  116. call(F & f, Sequence & /*s*/)
  117. {
  118. return f();
  119. }
  120. #endif
  121. };
  122. #define M(z,j,data) \
  123. typename invoke_function_object_param_types<Sequence,N>::T ## j
  124. template <class Function, class Sequence>
  125. struct invoke_function_object_impl<Function,Sequence,N,false,
  126. typename enable_if_has_type<
  127. typename boost::result_of<Function (BOOST_PP_ENUM(N,M,~)) >::type
  128. >::type>
  129. #undef M
  130. {
  131. private:
  132. typedef invoke_function_object_param_types<Sequence,N> seq;
  133. public:
  134. typedef typename boost::result_of<
  135. Function (BOOST_PP_ENUM_PARAMS(N,typename seq::T))
  136. >::type result_type;
  137. #if N > 0
  138. template <class F>
  139. BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  140. static inline result_type
  141. call(F & f, Sequence & s)
  142. {
  143. typename seq::I0 i0 = fusion::begin(s);
  144. #define M(z,j,data) \
  145. typename seq::I##j i##j = \
  146. fusion::next(BOOST_PP_CAT(i,BOOST_PP_DEC(j)));
  147. BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
  148. #undef M
  149. return f( BOOST_PP_ENUM_PARAMS(N,*i) );
  150. }
  151. #else
  152. template <class F>
  153. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  154. static inline result_type
  155. call(F & f, Sequence & /*s*/)
  156. {
  157. return f();
  158. }
  159. #endif
  160. };
  161. template <class Sequence>
  162. struct invoke_function_object_param_types<Sequence,N>
  163. {
  164. #if N > 0
  165. typedef typename result_of::begin<Sequence>::type I0;
  166. typedef typename result_of::deref<I0>::type T0;
  167. #define M(z,i,data) \
  168. typedef typename result_of::next< \
  169. BOOST_PP_CAT(I,BOOST_PP_DEC(i))>::type I##i; \
  170. typedef typename result_of::deref<I##i>::type T##i;
  171. BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
  172. #undef M
  173. #endif
  174. };
  175. #undef N
  176. #endif // defined(BOOST_PP_IS_ITERATING)
  177. #endif