invoke_function_object.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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/type_traits/remove_reference.hpp>
  18. #include <boost/type_traits/remove_const.hpp>
  19. #include <boost/utility/result_of.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 result_of
  30. {
  31. template <class Function, class Sequence> struct invoke_function_object;
  32. }
  33. template <class Function, class Sequence>
  34. inline typename result_of::invoke_function_object<Function, Sequence>::type
  35. invoke_function_object(Function, Sequence &);
  36. template <class Function, class Sequence>
  37. inline typename result_of::invoke_function_object<Function, Sequence const
  38. >::type invoke_function_object(Function, Sequence const &);
  39. //----- ---- --- -- - - - -
  40. namespace detail
  41. {
  42. template<
  43. class Function, class Sequence,
  44. int N = result_of::size<Sequence>::value,
  45. bool RandomAccess = traits::is_random_access<Sequence>::value
  46. >
  47. struct invoke_function_object_impl;
  48. template <class Sequence, int N>
  49. struct invoke_function_object_param_types;
  50. #define BOOST_PP_FILENAME_1 \
  51. <boost/fusion/functional/invocation/invoke_function_object.hpp>
  52. #define BOOST_PP_ITERATION_LIMITS \
  53. (0, BOOST_FUSION_INVOKE_FUNCTION_OBJECT_MAX_ARITY)
  54. #include BOOST_PP_ITERATE()
  55. }
  56. namespace result_of
  57. {
  58. template <class Function, class Sequence> struct invoke_function_object
  59. {
  60. typedef typename detail::invoke_function_object_impl<
  61. typename boost::remove_reference<Function>::type, Sequence
  62. >::result_type type;
  63. };
  64. }
  65. template <class Function, class Sequence>
  66. inline typename result_of::invoke_function_object<Function,Sequence>::type
  67. invoke_function_object(Function f, Sequence & s)
  68. {
  69. return detail::invoke_function_object_impl<
  70. typename boost::remove_reference<Function>::type,Sequence
  71. >::call(f,s);
  72. }
  73. template <class Function, class Sequence>
  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. template <class Function, class Sequence>
  91. struct invoke_function_object_impl<Function,Sequence,N,true>
  92. {
  93. public:
  94. typedef typename boost::result_of<
  95. #define M(z,j,data) \
  96. typename result_of::at_c<Sequence,j>::type
  97. Function (BOOST_PP_ENUM(N,M,~)) >::type result_type;
  98. #undef M
  99. #if N > 0
  100. template <class F>
  101. static inline result_type
  102. call(F & f, Sequence & s)
  103. {
  104. #define M(z,j,data) fusion::at_c<j>(s)
  105. return f( BOOST_PP_ENUM(N,M,~) );
  106. #undef M
  107. }
  108. #else
  109. template <class F>
  110. static inline result_type
  111. call(F & f, Sequence & /*s*/)
  112. {
  113. return f();
  114. }
  115. #endif
  116. };
  117. template <class Function, class Sequence>
  118. struct invoke_function_object_impl<Function,Sequence,N,false>
  119. {
  120. private:
  121. typedef invoke_function_object_param_types<Sequence,N> seq;
  122. public:
  123. typedef typename boost::result_of<
  124. Function (BOOST_PP_ENUM_PARAMS(N,typename seq::T))
  125. >::type result_type;
  126. #if N > 0
  127. template <class F>
  128. static inline result_type
  129. call(F & f, Sequence & s)
  130. {
  131. typename seq::I0 i0 = fusion::begin(s);
  132. #define M(z,j,data) \
  133. typename seq::I##j i##j = \
  134. fusion::next(BOOST_PP_CAT(i,BOOST_PP_DEC(j)));
  135. BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
  136. #undef M
  137. return f( BOOST_PP_ENUM_PARAMS(N,*i) );
  138. }
  139. #else
  140. template <class F>
  141. static inline result_type
  142. call(F & f, Sequence & /*s*/)
  143. {
  144. return f();
  145. }
  146. #endif
  147. };
  148. template <class Sequence>
  149. struct invoke_function_object_param_types<Sequence,N>
  150. {
  151. #if N > 0
  152. typedef typename result_of::begin<Sequence>::type I0;
  153. typedef typename result_of::deref<I0>::type T0;
  154. #define M(z,i,data) \
  155. typedef typename result_of::next< \
  156. BOOST_PP_CAT(I,BOOST_PP_DEC(i))>::type I##i; \
  157. typedef typename result_of::deref<I##i>::type T##i;
  158. BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
  159. #undef M
  160. #endif
  161. };
  162. #undef N
  163. #endif // defined(BOOST_PP_IS_ITERATING)
  164. #endif