• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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