]>
Commit | Line | Data |
---|---|---|
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 |