1 // Copyright David Abrahams, Daniel Wallin 2003.
2 // Copyright Cromwell D. Enage 2017.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 #ifndef BOOST_PARAMETER_MACROS_050412_HPP
8 #define BOOST_PARAMETER_MACROS_050412_HPP
9 
10 #include <boost/parameter/config.hpp>
11 #include <boost/preprocessor/repetition/enum_params.hpp>
12 
13 #if !defined(BOOST_NO_SFINAE) && \
14     !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592))
15 
16 #define BOOST_PARAMETER_MATCH_TYPE(n, param)                                 \
17   , typename param::match<BOOST_PP_ENUM_PARAMS(n, T)>::type kw = param()
18 /**/
19 
20 #define BOOST_PARAMETER_MATCH_TYPE_Z(z, n, param)                            \
21   , typename param::match<BOOST_PP_ENUM_PARAMS_Z(z, n, T)>::type kw = param()
22 /**/
23 
24 #else   // SFINAE disbled, or Borland workarounds needed.
25 
26 #define BOOST_PARAMETER_MATCH_TYPE(n, param) , param kw = param()
27 /**/
28 
29 #define BOOST_PARAMETER_MATCH_TYPE_Z(z, n, param) , param kw = param()
30 /**/
31 
32 #endif  // SFINAE enabled, not Borland.
33 
34 #include <boost/preprocessor/control/if.hpp>
35 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
36 #include <boost/preprocessor/tuple/elem.hpp>
37 #include <boost/preprocessor/cat.hpp>
38 
39 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
40 
41 #define BOOST_PARAMETER_FUN_0(z, n, params)                                  \
42     BOOST_PP_TUPLE_ELEM(3, 0, params) BOOST_PP_TUPLE_ELEM(3, 1, params)()    \
43     {                                                                        \
44         return BOOST_PP_CAT(                                                 \
45             BOOST_PP_TUPLE_ELEM(3, 1, params)                                \
46           , _with_named_params                                               \
47         )(BOOST_PP_TUPLE_ELEM(3, 2, params)()());                            \
48     }
49 /**/
50 
51 #include <utility>
52 
53 #define BOOST_PARAMETER_FUN_DECL_PARAM(z, n, p)                              \
54     ::std::forward<BOOST_PP_CAT(T, n)>(BOOST_PP_CAT(p, n))
55 /**/
56 
57 #include <boost/preprocessor/repetition/enum.hpp>
58 
59 #define BOOST_PARAMETER_FUN_DEFN_1(z, n, params)                             \
60     template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename T)>                      \
61     BOOST_PP_TUPLE_ELEM(3, 0, params)                                        \
62         BOOST_PP_TUPLE_ELEM(3, 1, params)(                                   \
63             BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, && p)                     \
64             BOOST_PARAMETER_MATCH_TYPE_Z(                                    \
65                 z, n, BOOST_PP_TUPLE_ELEM(3, 2, params)                      \
66             )                                                                \
67         )                                                                    \
68     {                                                                        \
69         return BOOST_PP_CAT(                                                 \
70             BOOST_PP_TUPLE_ELEM(3, 1, params)                                \
71           , _with_named_params                                               \
72         )(                                                                   \
73             kw(                                                              \
74                 BOOST_PP_CAT(BOOST_PP_ENUM_, z)(                             \
75                     n, BOOST_PARAMETER_FUN_DECL_PARAM, p                     \
76                 )                                                            \
77             )                                                                \
78         );                                                                   \
79     }
80 /**/
81 
82 #define BOOST_PARAMETER_FUN_DECL(z, n, params)                               \
83     BOOST_PP_IF(                                                             \
84         n                                                                    \
85       , BOOST_PARAMETER_FUN_DEFN_1                                           \
86       , BOOST_PARAMETER_FUN_0                                                \
87     )(z, n, params)
88 /**/
89 
90 #else   // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
91 
92 #define BOOST_PARAMETER_FUN_DEFN_0(z, n, params)                             \
93     template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename T)>                      \
94     BOOST_PP_TUPLE_ELEM(3, 0, params)                                        \
95         BOOST_PP_TUPLE_ELEM(3, 1, params)(                                   \
96             BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, const& p)                 \
97             BOOST_PARAMETER_MATCH_TYPE_Z(                                    \
98                 z, n, BOOST_PP_TUPLE_ELEM(3, 2, params)                      \
99             )                                                                \
100         )                                                                    \
101     {                                                                        \
102         return BOOST_PP_CAT(                                                 \
103             BOOST_PP_TUPLE_ELEM(3, 1, params)                                \
104           , _with_named_params                                               \
105         )(kw(BOOST_PP_ENUM_PARAMS_Z(z, n, p)));                              \
106     }
107 /**/
108 
109 #include <boost/preprocessor/seq/seq.hpp>
110 
111 #define BOOST_PARAMETER_FUN_0(z, n, seq)                                     \
112     BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)))     \
113     BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq)))()   \
114     {                                                                        \
115         return BOOST_PP_CAT(                                                 \
116             BOOST_PP_TUPLE_ELEM(                                             \
117                 3, 1, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq))              \
118             )                                                                \
119           , _with_named_params                                               \
120         )(                                                                   \
121         BOOST_PP_TUPLE_ELEM(3, 2, BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_TAIL(seq))) \
122         ()()                                                                 \
123         );                                                                   \
124     }
125 /**/
126 
127 #include <boost/parameter/aux_/preprocessor/binary_seq_to_args.hpp>
128 #include <boost/preprocessor/seq/size.hpp>
129 
130 #define BOOST_PARAMETER_FUN_DEFN_R(r, seq)                                   \
131     template <                                                               \
132         BOOST_PP_ENUM_PARAMS(                                                \
133             BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_TAIL(seq))                        \
134           , typename T                                                       \
135         )                                                                    \
136     > BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_SEQ_HEAD(seq))                      \
137         BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_SEQ_HEAD(seq))(                   \
138             BOOST_PARAMETER_AUX_PP_BINARY_SEQ_TO_ARGS(                       \
139                 BOOST_PP_SEQ_TAIL(seq), (T)(p)                               \
140             )                                                                \
141             BOOST_PARAMETER_MATCH_TYPE(                                      \
142                 BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_TAIL(seq))                    \
143               , BOOST_PP_TUPLE_ELEM(3, 2, BOOST_PP_SEQ_HEAD(seq))            \
144             )                                                                \
145         )                                                                    \
146     {                                                                        \
147         return BOOST_PP_CAT(                                                 \
148             BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_SEQ_HEAD(seq))                \
149           , _with_named_params                                               \
150         )(                                                                   \
151             kw(                                                              \
152                 BOOST_PP_ENUM_PARAMS(                                        \
153                     BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_TAIL(seq)), p             \
154                 )                                                            \
155             )                                                                \
156         );                                                                   \
157     }
158 /**/
159 
160 #include <boost/parameter/aux_/preprocessor/binary_seq_for_each.hpp>
161 #include <boost/preprocessor/tuple/eat.hpp>
162 
163 #define BOOST_PARAMETER_FUN_DEFN_1(z, n, params)                             \
164     BOOST_PP_IF(                                                             \
165         n                                                                    \
166       , BOOST_PARAMETER_AUX_PP_BINARY_SEQ_FOR_EACH_Z                         \
167       , BOOST_PARAMETER_FUN_0                                                \
168     )(z, n, (BOOST_PARAMETER_FUN_DEFN_R)(params))
169 /**/
170 
171 #include <boost/preprocessor/comparison/less.hpp>
172 
173 #define BOOST_PARAMETER_FUN_DECL(z, n, params)                               \
174     BOOST_PP_CAT(                                                            \
175         BOOST_PARAMETER_FUN_DEFN_                                            \
176       , BOOST_PP_LESS(                                                       \
177             n                                                                \
178           , BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY             \
179         )                                                                    \
180     )(z, n, params)
181 /**/
182 
183 #endif  // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
184 
185 #include <boost/preprocessor/arithmetic/inc.hpp>
186 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
187 
188 // Generates:
189 //
190 // template <typename Params>
191 // ret name ## _with_named_params(Params const&);
192 //
193 // template <typename T0>
194 // ret name(
195 //     T0 && p0
196 //   , typename parameters::match<T0>::type kw = parameters()
197 // )
198 // {
199 //     return name ## _with_named_params(kw(p0));
200 // }
201 //
202 // template <typename T0, ..., typename T ## N>
203 // ret name(
204 //     T0 && p0, ..., TN && p ## N
205 //   , typename parameters::match<T0, ..., T ## N>::type kw = parameters()
206 // )
207 // {
208 //     return name ## _with_named_params(kw(p0, ..., p ## N));
209 // }
210 //
211 // template <typename Params>
212 // ret name ## _with_named_params(Params const&)
213 //
214 // lo and hi determine the min and max arities of the generated functions.
215 
216 #define BOOST_PARAMETER_MEMFUN(ret, name, lo, hi, parameters)                \
217     BOOST_PP_REPEAT_FROM_TO(                                                 \
218         lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL                       \
219       , (ret, name, parameters)                                              \
220     )                                                                        \
221     template <typename Params>                                               \
222     ret BOOST_PP_CAT(name, _with_named_params)(Params const& p)
223 /**/
224 
225 #define BOOST_PARAMETER_FUN(ret, name, lo, hi, parameters)                   \
226     template <typename Params>                                               \
227     ret BOOST_PP_CAT(name, _with_named_params)(Params const& p);             \
228     BOOST_PARAMETER_MEMFUN(ret, name, lo, hi, parameters)
229 /**/
230 
231 #endif  // include guard
232 
233