File indexing completed on 2025-01-18 09:28:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/mpl/void.hpp>
0010 #include <boost/mpl/apply.hpp>
0011
0012 #include <boost/preprocessor/control/if.hpp>
0013 #include <boost/preprocessor/cat.hpp>
0014 #include <boost/preprocessor/punctuation/comma_if.hpp>
0015 #include <boost/preprocessor/repetition/enum_params.hpp>
0016 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0017 #include <boost/preprocessor/repetition/repeat.hpp>
0018 #include <boost/preprocessor/seq/fold_left.hpp>
0019 #include <boost/preprocessor/seq/seq.hpp>
0020 #include <boost/preprocessor/seq/for_each.hpp>
0021 #include <boost/preprocessor/seq/for_each_i.hpp>
0022 #include <boost/preprocessor/seq/for_each_product.hpp>
0023 #include <boost/preprocessor/seq/size.hpp>
0024 #include <boost/type_traits/add_const.hpp>
0025 #include <boost/type_traits/remove_reference.hpp>
0026
0027 namespace boost { namespace detail {
0028
0029 # define BOOST_DETAIL_default_arg(z, n, _) \
0030 typedef mpl::void_ BOOST_PP_CAT(arg, n);
0031
0032 # define BOOST_DETAIL_function_arg(z, n, _) \
0033 typedef typename remove_reference< \
0034 typename add_const< BOOST_PP_CAT(A, n) >::type \
0035 >::type BOOST_PP_CAT(arg, n);
0036
0037 #define BOOST_DETAIL_cat_arg_counts(s, state, n) \
0038 BOOST_PP_IF( \
0039 n \
0040 , BOOST_PP_CAT(state, BOOST_PP_CAT(_, n)) \
0041 , state \
0042 ) \
0043
0044
0045 #define function_name \
0046 BOOST_PP_SEQ_FOLD_LEFT( \
0047 BOOST_DETAIL_cat_arg_counts \
0048 , BOOST_PP_CAT(function, BOOST_PP_SEQ_HEAD(args)) \
0049 , BOOST_PP_SEQ_TAIL(args)(0) \
0050 ) \
0051
0052
0053 template<typename F>
0054 struct function_name
0055 {
0056 BOOST_PP_REPEAT(
0057 BOOST_MPL_LIMIT_METAFUNCTION_ARITY
0058 , BOOST_DETAIL_default_arg
0059 , ~
0060 )
0061
0062 template<typename Signature>
0063 struct result {};
0064
0065 #define BOOST_DETAIL_function_result(r, _, n) \
0066 template<typename This BOOST_PP_ENUM_TRAILING_PARAMS(n, typename A)> \
0067 struct result<This(BOOST_PP_ENUM_PARAMS(n, A))> \
0068 { \
0069 BOOST_PP_REPEAT(n, BOOST_DETAIL_function_arg, ~) \
0070 typedef \
0071 typename BOOST_PP_CAT(mpl::apply, BOOST_MPL_LIMIT_METAFUNCTION_ARITY)<\
0072 F \
0073 BOOST_PP_ENUM_TRAILING_PARAMS( \
0074 BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
0075 , arg \
0076 ) \
0077 >::type \
0078 impl; \
0079 typedef typename impl::result_type type; \
0080 }; \
0081
0082
0083 BOOST_PP_SEQ_FOR_EACH(BOOST_DETAIL_function_result, _, args)
0084
0085 # define arg_type(r, _, i, is_const) \
0086 BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A, i) BOOST_PP_CAT(const_if, is_const) &
0087
0088 # define result_(r, n, constness) \
0089 typename result< \
0090 function_name( \
0091 BOOST_PP_SEQ_FOR_EACH_I_R(r, arg_type, ~, constness) \
0092 ) \
0093 > \
0094
0095
0096 # define param(r, _, i, is_const) BOOST_PP_COMMA_IF(i) \
0097 BOOST_PP_CAT(A, i) BOOST_PP_CAT(const_if, is_const) & BOOST_PP_CAT(x, i)
0098
0099 # define param_list(r, n, constness) \
0100 BOOST_PP_SEQ_FOR_EACH_I_R(r, param, ~, constness)
0101
0102 # define call_operator(r, constness) \
0103 template<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(constness), typename A)> \
0104 result_(r, BOOST_PP_SEQ_SIZE(constness), constness)::type \
0105 operator ()( param_list(r, BOOST_PP_SEQ_SIZE(constness), constness) ) const \
0106 { \
0107 typedef result_(r, BOOST_PP_SEQ_SIZE(constness), constness)::impl impl; \
0108 return impl()(BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(constness), x)); \
0109 } \
0110
0111
0112 # define const_if0
0113 # define const_if1 const
0114
0115 # define bits(z, n, _) ((0)(1))
0116
0117 # define gen_operator(r, _, n) \
0118 BOOST_PP_SEQ_FOR_EACH_PRODUCT_R( \
0119 r \
0120 , call_operator \
0121 , BOOST_PP_REPEAT(n, bits, ~) \
0122 ) \
0123
0124
0125 BOOST_PP_SEQ_FOR_EACH(
0126 gen_operator
0127 , ~
0128 , args
0129 )
0130
0131 # undef bits
0132 # undef const_if1
0133 # undef const_if0
0134 # undef call_operator
0135 # undef param_list
0136 # undef param
0137 # undef result_
0138 # undef default_
0139 # undef arg_type
0140 # undef gen_operator
0141 # undef function_name
0142
0143 # undef args
0144 };
0145
0146 }}
0147
0148