function_n.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright David Abrahams 2006. Distributed under the Boost
  2. // Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. //
  5. // #include guards intentionally disabled.
  6. // #ifndef BOOST_DETAIL_FUNCTION_N_DWA2006514_HPP
  7. // # define BOOST_DETAIL_FUNCTION_N_DWA2006514_HPP
  8. #include <boost/mpl/void.hpp>
  9. #include <boost/mpl/apply.hpp>
  10. #include <boost/preprocessor/control/if.hpp>
  11. #include <boost/preprocessor/cat.hpp>
  12. #include <boost/preprocessor/punctuation/comma_if.hpp>
  13. #include <boost/preprocessor/repetition/enum_params.hpp>
  14. #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
  15. #include <boost/preprocessor/repetition/repeat.hpp>
  16. #include <boost/preprocessor/seq/fold_left.hpp>
  17. #include <boost/preprocessor/seq/seq.hpp>
  18. #include <boost/preprocessor/seq/for_each.hpp>
  19. #include <boost/preprocessor/seq/for_each_i.hpp>
  20. #include <boost/preprocessor/seq/for_each_product.hpp>
  21. #include <boost/preprocessor/seq/size.hpp>
  22. #include <boost/type_traits/add_const.hpp>
  23. #include <boost/type_traits/remove_reference.hpp>
  24. namespace boost { namespace detail {
  25. # define BOOST_DETAIL_default_arg(z, n, _) \
  26. typedef mpl::void_ BOOST_PP_CAT(arg, n);
  27. # define BOOST_DETAIL_function_arg(z, n, _) \
  28. typedef typename remove_reference< \
  29. typename add_const< BOOST_PP_CAT(A, n) >::type \
  30. >::type BOOST_PP_CAT(arg, n);
  31. #define BOOST_DETAIL_cat_arg_counts(s, state, n) \
  32. BOOST_PP_IF( \
  33. n \
  34. , BOOST_PP_CAT(state, BOOST_PP_CAT(_, n)) \
  35. , state \
  36. ) \
  37. /**/
  38. #define function_name \
  39. BOOST_PP_SEQ_FOLD_LEFT( \
  40. BOOST_DETAIL_cat_arg_counts \
  41. , BOOST_PP_CAT(function, BOOST_PP_SEQ_HEAD(args)) \
  42. , BOOST_PP_SEQ_TAIL(args)(0) \
  43. ) \
  44. /**/
  45. template<typename F>
  46. struct function_name
  47. {
  48. BOOST_PP_REPEAT(
  49. BOOST_MPL_LIMIT_METAFUNCTION_ARITY
  50. , BOOST_DETAIL_default_arg
  51. , ~
  52. )
  53. template<typename Signature>
  54. struct result {};
  55. #define BOOST_DETAIL_function_result(r, _, n) \
  56. template<typename This BOOST_PP_ENUM_TRAILING_PARAMS(n, typename A)> \
  57. struct result<This(BOOST_PP_ENUM_PARAMS(n, A))> \
  58. { \
  59. BOOST_PP_REPEAT(n, BOOST_DETAIL_function_arg, ~) \
  60. typedef \
  61. typename BOOST_PP_CAT(mpl::apply, BOOST_MPL_LIMIT_METAFUNCTION_ARITY)<\
  62. F \
  63. BOOST_PP_ENUM_TRAILING_PARAMS( \
  64. BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
  65. , arg \
  66. ) \
  67. >::type \
  68. impl; \
  69. typedef typename impl::result_type type; \
  70. }; \
  71. /**/
  72. BOOST_PP_SEQ_FOR_EACH(BOOST_DETAIL_function_result, _, args)
  73. # define arg_type(r, _, i, is_const) \
  74. BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A, i) BOOST_PP_CAT(const_if, is_const) &
  75. # define result_(r, n, constness) \
  76. typename result< \
  77. function_name( \
  78. BOOST_PP_SEQ_FOR_EACH_I_R(r, arg_type, ~, constness) \
  79. ) \
  80. > \
  81. /**/
  82. # define param(r, _, i, is_const) BOOST_PP_COMMA_IF(i) \
  83. BOOST_PP_CAT(A, i) BOOST_PP_CAT(const_if, is_const) & BOOST_PP_CAT(x, i)
  84. # define param_list(r, n, constness) \
  85. BOOST_PP_SEQ_FOR_EACH_I_R(r, param, ~, constness)
  86. # define call_operator(r, constness) \
  87. template<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(constness), typename A)> \
  88. result_(r, BOOST_PP_SEQ_SIZE(constness), constness)::type \
  89. operator ()( param_list(r, BOOST_PP_SEQ_SIZE(constness), constness) ) const \
  90. { \
  91. typedef result_(r, BOOST_PP_SEQ_SIZE(constness), constness)::impl impl; \
  92. return impl()(BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(constness), x)); \
  93. } \
  94. /**/
  95. # define const_if0
  96. # define const_if1 const
  97. # define bits(z, n, _) ((0)(1))
  98. # define gen_operator(r, _, n) \
  99. BOOST_PP_SEQ_FOR_EACH_PRODUCT_R( \
  100. r \
  101. , call_operator \
  102. , BOOST_PP_REPEAT(n, bits, ~) \
  103. ) \
  104. /**/
  105. BOOST_PP_SEQ_FOR_EACH(
  106. gen_operator
  107. , ~
  108. , args
  109. )
  110. # undef bits
  111. # undef const_if1
  112. # undef const_if0
  113. # undef call_operator
  114. # undef param_list
  115. # undef param
  116. # undef result_
  117. # undef default_
  118. # undef arg_type
  119. # undef gen_operator
  120. # undef function_name
  121. # undef args
  122. };
  123. }} // namespace boost::detail
  124. //#endif // BOOST_DETAIL_FUNCTION_N_DWA2006514_HPP