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 9 #include <boost/mpl/void.hpp> 10 #include <boost/mpl/apply.hpp> 11 12 #include <boost/preprocessor/control/if.hpp> 13 #include <boost/preprocessor/cat.hpp> 14 #include <boost/preprocessor/punctuation/comma_if.hpp> 15 #include <boost/preprocessor/repetition/enum_params.hpp> 16 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> 17 #include <boost/preprocessor/repetition/repeat.hpp> 18 #include <boost/preprocessor/seq/fold_left.hpp> 19 #include <boost/preprocessor/seq/seq.hpp> 20 #include <boost/preprocessor/seq/for_each.hpp> 21 #include <boost/preprocessor/seq/for_each_i.hpp> 22 #include <boost/preprocessor/seq/for_each_product.hpp> 23 #include <boost/preprocessor/seq/size.hpp> 24 #include <boost/type_traits/add_const.hpp> 25 #include <boost/type_traits/remove_reference.hpp> 26 27 namespace boost { namespace detail { 28 29 # define BOOST_DETAIL_default_arg(z, n, _) \ 30 typedef mpl::void_ BOOST_PP_CAT(arg, n); 31 32 # define BOOST_DETAIL_function_arg(z, n, _) \ 33 typedef typename remove_reference< \ 34 typename add_const< BOOST_PP_CAT(A, n) >::type \ 35 >::type BOOST_PP_CAT(arg, n); 36 37 #define BOOST_DETAIL_cat_arg_counts(s, state, n) \ 38 BOOST_PP_IF( \ 39 n \ 40 , BOOST_PP_CAT(state, BOOST_PP_CAT(_, n)) \ 41 , state \ 42 ) \ 43 /**/ 44 45 #define function_name \ 46 BOOST_PP_SEQ_FOLD_LEFT( \ 47 BOOST_DETAIL_cat_arg_counts \ 48 , BOOST_PP_CAT(function, BOOST_PP_SEQ_HEAD(args)) \ 49 , BOOST_PP_SEQ_TAIL(args)(0) \ 50 ) \ 51 /**/ 52 53 template<typename F> 54 struct function_name 55 { 56 BOOST_PP_REPEAT( 57 BOOST_MPL_LIMIT_METAFUNCTION_ARITY 58 , BOOST_DETAIL_default_arg 59 , ~ 60 ) 61 62 template<typename Signature> 63 struct result {}; 64 65 #define BOOST_DETAIL_function_result(r, _, n) \ 66 template<typename This BOOST_PP_ENUM_TRAILING_PARAMS(n, typename A)> \ 67 struct result<This(BOOST_PP_ENUM_PARAMS(n, A))> \ 68 { \ 69 BOOST_PP_REPEAT(n, BOOST_DETAIL_function_arg, ~) \ 70 typedef \ 71 typename BOOST_PP_CAT(mpl::apply, BOOST_MPL_LIMIT_METAFUNCTION_ARITY)<\ 72 F \ 73 BOOST_PP_ENUM_TRAILING_PARAMS( \ 74 BOOST_MPL_LIMIT_METAFUNCTION_ARITY \ 75 , arg \ 76 ) \ 77 >::type \ 78 impl; \ 79 typedef typename impl::result_type type; \ 80 }; \ 81 /**/ 82 83 BOOST_PP_SEQ_FOR_EACH(BOOST_DETAIL_function_result, _, args) 84 85 # define arg_type(r, _, i, is_const) \ 86 BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A, i) BOOST_PP_CAT(const_if, is_const) & 87 88 # define result_(r, n, constness) \ 89 typename result< \ 90 function_name( \ 91 BOOST_PP_SEQ_FOR_EACH_I_R(r, arg_type, ~, constness) \ 92 ) \ 93 > \ 94 /**/ 95 96 # define param(r, _, i, is_const) BOOST_PP_COMMA_IF(i) \ 97 BOOST_PP_CAT(A, i) BOOST_PP_CAT(const_if, is_const) & BOOST_PP_CAT(x, i) 98 99 # define param_list(r, n, constness) \ 100 BOOST_PP_SEQ_FOR_EACH_I_R(r, param, ~, constness) 101 102 # define call_operator(r, constness) \ 103 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(constness), typename A)> \ 104 result_(r, BOOST_PP_SEQ_SIZE(constness), constness)::type \ 105 operator ()( param_list(r, BOOST_PP_SEQ_SIZE(constness), constness) ) const \ 106 { \ 107 typedef result_(r, BOOST_PP_SEQ_SIZE(constness), constness)::impl impl; \ 108 return impl()(BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(constness), x)); \ 109 } \ 110 /**/ 111 112 # define const_if0 113 # define const_if1 const 114 115 # define bits(z, n, _) ((0)(1)) 116 117 # define gen_operator(r, _, n) \ 118 BOOST_PP_SEQ_FOR_EACH_PRODUCT_R( \ 119 r \ 120 , call_operator \ 121 , BOOST_PP_REPEAT(n, bits, ~) \ 122 ) \ 123 /**/ 124 125 BOOST_PP_SEQ_FOR_EACH( 126 gen_operator 127 , ~ 128 , args 129 ) 130 131 # undef bits 132 # undef const_if1 133 # undef const_if0 134 # undef call_operator 135 # undef param_list 136 # undef param 137 # undef result_ 138 # undef default_ 139 # undef arg_type 140 # undef gen_operator 141 # undef function_name 142 143 # undef args 144 }; 145 146 }} // namespace boost::detail 147 148 //#endif // BOOST_DETAIL_FUNCTION_N_DWA2006514_HPP 149