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 | |