]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/parameter/preprocessor.hpp
Improve Update::FitCursor when there is a selection
[lyx.git] / 3rdparty / boost / boost / parameter / preprocessor.hpp
1 // Copyright Daniel Wallin 2006. Use, modification and distribution is
2 // subject to the Boost 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 #ifndef BOOST_PARAMETER_PREPROCESSOR_060206_HPP
6 # define BOOST_PARAMETER_PREPROCESSOR_060206_HPP
7
8 # include <boost/parameter/parameters.hpp>
9 # include <boost/parameter/binding.hpp>
10 # include <boost/parameter/match.hpp>
11
12 # include <boost/parameter/aux_/parenthesized_type.hpp>
13 # include <boost/parameter/aux_/cast.hpp>
14 # include <boost/parameter/aux_/preprocessor/flatten.hpp>
15
16 # include <boost/preprocessor/repetition/repeat_from_to.hpp>
17 # include <boost/preprocessor/comparison/equal.hpp>
18 # include <boost/preprocessor/control/if.hpp>
19 # include <boost/preprocessor/control/iif.hpp>
20 # include <boost/preprocessor/control/expr_if.hpp>
21 # include <boost/preprocessor/repetition/enum_params.hpp>
22 # include <boost/preprocessor/repetition/enum_binary_params.hpp>
23 # include <boost/preprocessor/repetition/enum_trailing.hpp>
24 # include <boost/preprocessor/seq/first_n.hpp>
25 # include <boost/preprocessor/seq/for_each_product.hpp>
26 # include <boost/preprocessor/seq/for_each_i.hpp> 
27 # include <boost/preprocessor/tuple/elem.hpp> 
28 # include <boost/preprocessor/tuple/eat.hpp>
29 # include <boost/preprocessor/seq/fold_left.hpp>
30 # include <boost/preprocessor/seq/push_back.hpp>
31 # include <boost/preprocessor/seq/size.hpp>
32 # include <boost/preprocessor/seq/enum.hpp>
33 # include <boost/preprocessor/seq/push_back.hpp>
34
35 # include <boost/preprocessor/detail/is_nullary.hpp>
36
37 # include <boost/mpl/always.hpp>
38 # include <boost/mpl/apply_wrap.hpp>
39
40 namespace boost { namespace parameter { namespace aux {
41
42 #  if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
43
44 // Given Match, which is "void x" where x is an argument matching
45 // criterion, extract a corresponding MPL predicate.
46 template <class Match>
47 struct unwrap_predicate;
48
49 // Match anything
50 template <>
51 struct unwrap_predicate<void*>
52 {
53     typedef mpl::always<mpl::true_> type;
54 };
55
56 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
57
58 typedef void* voidstar;
59
60 // A matching predicate is explicitly specified
61 template <class Predicate>
62 struct unwrap_predicate<voidstar (Predicate)>
63 {
64     typedef Predicate type;
65 };
66
67 #else
68
69 // A matching predicate is explicitly specified
70 template <class Predicate>
71 struct unwrap_predicate<void *(Predicate)>
72 {
73     typedef Predicate type;
74 };
75
76 #endif 
77
78
79 // A type to which the argument is supposed to be convertible is
80 // specified
81 template <class Target>
82 struct unwrap_predicate<void (Target)>
83 {
84     typedef is_convertible<mpl::_, Target> type;
85 };
86
87 // Recast the ParameterSpec's nested match metafunction as a free metafunction
88 template <
89     class Parameters
90   , BOOST_PP_ENUM_BINARY_PARAMS(
91         BOOST_PARAMETER_MAX_ARITY, class A, = boost::parameter::void_ BOOST_PP_INTERCEPT
92     )
93 >
94 struct match
95   : Parameters::template match<
96         BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, A)
97     >
98 {};
99 # endif 
100
101 # undef false_
102
103 template <
104     class Parameters
105   , BOOST_PP_ENUM_BINARY_PARAMS(
106         BOOST_PARAMETER_MAX_ARITY, class A, = boost::parameter::void_ BOOST_PP_INTERCEPT
107     )
108 >
109 struct argument_pack
110 {
111     typedef typename make_arg_list<
112         typename BOOST_PARAMETER_build_arg_list(
113             BOOST_PARAMETER_MAX_ARITY, make_items, typename Parameters::parameter_spec, A
114         )::type
115       , typename Parameters::deduced_list
116       , tag_keyword_arg
117       , mpl::false_
118     >::type result;
119     typedef typename mpl::first<result>::type type;
120 };
121
122 // Works around VC6 problem where it won't accept rvalues.
123 template <class T>
124 T& as_lvalue(T& value, long)
125 {
126     return value;
127 }
128
129 template <class T>
130 T const& as_lvalue(T const& value, int)
131 {
132     return value;
133 }
134
135
136 # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
137
138 template <class Predicate, class T, class Args>
139 struct apply_predicate
140 {
141     BOOST_MPL_ASSERT((
142         mpl::and_<mpl::false_,T>
143     ));
144
145     typedef typename mpl::if_<
146         typename mpl::apply2<Predicate,T,Args>::type
147       , char
148       , int
149     >::type type;
150 };
151
152 template <class P>
153 struct funptr_predicate
154 {
155     static P p;
156
157     template <class T, class Args, class P0>
158     static typename apply_predicate<P0,T,Args>::type
159     check_predicate(type<T>, Args*, void**(*)(P0));
160
161     template <class T, class Args, class P0>
162     static typename mpl::if_<
163         is_convertible<T,P0>
164       , char
165       , int
166      >::type check_predicate(type<T>, Args*, void*(*)(P0));
167
168     template <class T, class Args>
169     struct apply
170     {
171         BOOST_STATIC_CONSTANT(bool, result = 
172             sizeof(check_predicate(boost::type<T>(), (Args*)0, &p)) == 1
173         );
174
175         typedef mpl::bool_<apply<T,Args>::result> type;
176     };
177 };
178
179 template <>
180 struct funptr_predicate<void**>
181   : mpl::always<mpl::true_>
182 {};
183
184 # endif
185
186 }}} // namespace boost::parameter::aux
187
188 # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
189 // From Paul Mensonides
190 #  define BOOST_PARAMETER_IS_NULLARY(x) \
191     BOOST_PP_SPLIT(1, BOOST_PARAMETER_IS_NULLARY_C x BOOST_PP_COMMA() 0) \
192     /**/
193 #  define BOOST_PARAMETER_IS_NULLARY_C() \
194     ~, 1 BOOST_PP_RPAREN() \
195     BOOST_PP_TUPLE_EAT(2) BOOST_PP_LPAREN() ~ \
196     /**/
197 # else
198 #  define BOOST_PARAMETER_IS_NULLARY(x) BOOST_PP_IS_NULLARY(x)
199 # endif
200
201 # define BOOST_PARAMETER_MEMBER_FUNCTION_CHECK_STATIC_static ()
202 # define BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \
203     BOOST_PARAMETER_IS_NULLARY( \
204         BOOST_PP_CAT(BOOST_PARAMETER_MEMBER_FUNCTION_CHECK_STATIC_,name) \
205     )
206
207 # if !defined(BOOST_MSVC)
208 #  define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_static
209 #  define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC(name) \
210     BOOST_PP_CAT(BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_, name)
211 # else
212 // Workaround for MSVC preprocessor.
213 //
214 // When stripping static from "static f", msvc will produce
215 // " f". The leading whitespace doesn't go away when pasting
216 // the token with something else, so this thing is a hack to
217 // strip the whitespace.
218 #  define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_static (
219 #  define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_AUX(name) \
220     BOOST_PP_CAT(BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_, name))
221 #  define BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC(name) \
222     BOOST_PP_SEQ_HEAD( \
223         BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_AUX(name) \
224     )
225 # endif
226
227 # define BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \
228     BOOST_PP_EXPR_IF( \
229         BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \
230       , static \
231     )
232
233 # define BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name) \
234     BOOST_PP_IF( \
235         BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \
236       , BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC \
237       , name BOOST_PP_TUPLE_EAT(1) \
238     )(name)
239
240 // Calculates [begin, end) arity range.
241
242 # define BOOST_PARAMETER_ARITY_RANGE_M_optional(state) state
243 # define BOOST_PARAMETER_ARITY_RANGE_M_deduced_optional(state) state
244 # define BOOST_PARAMETER_ARITY_RANGE_M_required(state) BOOST_PP_INC(state)
245 # define BOOST_PARAMETER_ARITY_RANGE_M_deduced_required(state) BOOST_PP_INC(state)
246
247 # define BOOST_PARAMETER_ARITY_RANGE_M(s, state, x) \
248     BOOST_PP_CAT( \
249         BOOST_PARAMETER_ARITY_RANGE_M_ \
250       , BOOST_PARAMETER_FN_ARG_QUALIFIER(x) \
251     )(state)
252 /**/
253
254 # define BOOST_PARAMETER_ARITY_RANGE(args) \
255     ( \
256         BOOST_PP_SEQ_FOLD_LEFT(BOOST_PARAMETER_ARITY_RANGE_M, 0, args) \
257       , BOOST_PP_INC(BOOST_PP_SEQ_SIZE(args)) \
258     )
259 /**/
260
261 // Accessor macros for the argument specs tuple.
262 # define BOOST_PARAMETER_FN_ARG_QUALIFIER(x) \
263     BOOST_PP_TUPLE_ELEM(4,0,x)
264 /**/
265
266 # define BOOST_PARAMETER_FN_ARG_NAME(x) \
267     BOOST_PP_TUPLE_ELEM(4,1,x)
268 /**/
269
270 # define BOOST_PARAMETER_FN_ARG_PRED(x) \
271     BOOST_PP_TUPLE_ELEM(4,2,x)
272 /**/
273
274 # define BOOST_PARAMETER_FN_ARG_DEFAULT(x) \
275     BOOST_PP_TUPLE_ELEM(4,3,x)
276 /**/
277
278 # define BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_out(x)
279 # define BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_in_out(x)
280
281 // Returns 1 if x is either "out(k)" or "in_out(k)".
282 # define BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER(x) \
283     BOOST_PP_IS_EMPTY( \
284         BOOST_PP_CAT(BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_, x) \
285     ) \
286 /**/
287
288 # define BOOST_PARAMETETER_FUNCTION_GET_KEYWORD_QUALIFIER_out(x) x
289 # define BOOST_PARAMETETER_FUNCTION_GET_KEYWORD_QUALIFIER_in_out(x) x
290 # define BOOST_PARAMETER_FUNCTION_KEYWORD_GET(x) \
291     BOOST_PP_CAT(BOOST_PARAMETETER_FUNCTION_GET_KEYWORD_QUALIFIER_, x)
292 /**/
293
294 // Returns the keyword of x, where x is either a keyword qualifier
295 // or a keyword.
296 //
297 //   k => k
298 //   out(k) => k
299 //   in_out(k) => k
300 //
301 # define BOOST_PARAMETER_FUNCTION_KEYWORD(x) \
302     BOOST_PP_IF( \
303         BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER(x) \
304       , BOOST_PARAMETER_FUNCTION_KEYWORD_GET \
305       , x BOOST_PP_TUPLE_EAT(1) \
306     )(x)
307 /**/
308
309 # define BOOST_PARAMETER_FN_ARG_KEYWORD(x) \
310     BOOST_PARAMETER_FUNCTION_KEYWORD( \
311         BOOST_PARAMETER_FN_ARG_NAME(x) \
312     )
313
314 // Builds forwarding functions.
315
316 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z(z, n) \
317     template<BOOST_PP_ENUM_PARAMS_Z(z, n, class ParameterArgumentType)>
318 /**/
319
320 # if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
321 #  define BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z(z, name, parameters, n) \
322     , typename boost::parameter::aux::match< \
323           parameters, BOOST_PP_ENUM_PARAMS(n, ParameterArgumentType) \
324       >::type = parameters()
325 # else
326 #  define BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z(z, name, parameters, n)
327 # endif
328 /**/
329
330 # define BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(base) \
331     BOOST_PP_CAT( \
332         boost_param_parameters_ \
333       , BOOST_PP_CAT(__LINE__, BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) \
334     )
335
336 // Produce a name for a result type metafunction for the function
337 // named base
338 # define BOOST_PARAMETER_FUNCTION_RESULT_NAME(base) \
339     BOOST_PP_CAT( \
340         boost_param_result_ \
341       , BOOST_PP_CAT(__LINE__,BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) \
342     )
343
344 // Can't do boost_param_impl_ ## basee because base might start with an underscore
345 // daniel: what? how is that relevant? the reason for using CAT() is to make sure
346 // base is expanded. i'm not sure we need to here, but it's more stable to do it.
347 # define BOOST_PARAMETER_IMPL(base) \
348     BOOST_PP_CAT(boost_param_impl,BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base))
349
350 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION00(z, n, r, data, elem) \
351     BOOST_PP_IF( \
352         n \
353       , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z, BOOST_PP_TUPLE_EAT(2) \
354     )(z,n) \
355     BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(7,3,data)) \
356     inline \
357     BOOST_PP_EXPR_IF(n, typename) \
358         BOOST_PARAMETER_FUNCTION_RESULT_NAME(BOOST_PP_TUPLE_ELEM(7,3,data))<   \
359         BOOST_PP_EXPR_IF(n, typename) \
360         boost::parameter::aux::argument_pack< \
361             BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(BOOST_PP_TUPLE_ELEM(7,3,data)) \
362             BOOST_PP_COMMA_IF(n) \
363             BOOST_PP_IF( \
364                 n, BOOST_PP_SEQ_ENUM, BOOST_PP_TUPLE_EAT(1) \
365             )(elem) \
366         >::type \
367     >::type \
368     BOOST_PARAMETER_MEMBER_FUNCTION_NAME(BOOST_PP_TUPLE_ELEM(7,3,data))( \
369         BOOST_PP_IF( \
370             n \
371           , BOOST_PP_SEQ_FOR_EACH_I_R \
372           , BOOST_PP_TUPLE_EAT(4) \
373         )( \
374             r \
375           , BOOST_PARAMETER_FUNCTION_ARGUMENT \
376           , ~ \
377           , elem \
378         ) \
379         BOOST_PP_IF(n, BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z, BOOST_PP_TUPLE_EAT(4))( \
380             z \
381           , BOOST_PP_TUPLE_ELEM(7,3,data) \
382           , BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(BOOST_PP_TUPLE_ELEM(7,3,data)) \
383           , n \
384         ) \
385     ) BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(7,4,data), const) \
386     { \
387         return BOOST_PARAMETER_IMPL(BOOST_PP_TUPLE_ELEM(7,3,data))( \
388             BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(BOOST_PP_TUPLE_ELEM(7,3,data))()( \
389                 BOOST_PP_ENUM_PARAMS_Z(z, n, a) \
390             ) \
391         ); \
392     }
393 /**/
394
395 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION0(r, data, elem) \
396     BOOST_PARAMETER_FUNCTION_FWD_FUNCTION00( \
397         BOOST_PP_TUPLE_ELEM(7,0,data) \
398       , BOOST_PP_TUPLE_ELEM(7,1,data) \
399       , r \
400       , data \
401       , elem \
402     )
403 /**/
404
405 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_0(z, n, data) \
406     BOOST_PARAMETER_FUNCTION_FWD_FUNCTION00( \
407         z, n, BOOST_PP_DEDUCE_R() \
408       , (z, n, BOOST_PP_TUPLE_REM(5) data) \
409       , ~ \
410     )
411 /**/
412
413 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_N(z, n, data) \
414     BOOST_PP_SEQ_FOR_EACH( \
415         BOOST_PARAMETER_FUNCTION_FWD_FUNCTION0 \
416       , (z, n, BOOST_PP_TUPLE_REM(5) data) \
417       , BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
418             BOOST_PARAMETER_FUNCTION_FWD_PRODUCT \
419           , BOOST_PP_SEQ_FIRST_N( \
420                 n, BOOST_PP_TUPLE_ELEM(5,3,data) \
421             ) \
422         ) \
423     )
424 /**/
425
426 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION(z, n, data) \
427     BOOST_PP_IF( \
428         n \
429       , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_N \
430       , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_0 \
431     )(z,n,data) \
432 /**/
433
434 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS0( \
435     result,name,args,const_,combinations,range \
436 ) \
437     BOOST_PP_REPEAT_FROM_TO( \
438         BOOST_PP_TUPLE_ELEM(2,0,range), BOOST_PP_TUPLE_ELEM(2,1,range) \
439       , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION \
440       , (result,name,const_,combinations,BOOST_PP_TUPLE_ELEM(2,1,range)) \
441     )
442 /**/
443
444 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS(result,name,args, const_, combinations) \
445     BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS0( \
446         result, name, args, const_, combinations, BOOST_PARAMETER_ARITY_RANGE(args) \
447     )
448 /**/
449
450 // Builds boost::parameter::parameters<> specialization
451 #  define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_optional(tag) \
452     optional<tag
453
454 #  define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_required(tag) \
455     required<tag
456
457 #  define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_deduced_optional(tag) \
458     optional<boost::parameter::deduced<tag>
459
460 #  define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_deduced_required(tag) \
461     required<boost::parameter::deduced<tag>
462
463 # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
464
465 #  define BOOST_PARAMETER_FUNCTION_PARAMETERS_M(r,tag_namespace,i,elem) \
466     BOOST_PP_COMMA_IF(i) \
467     boost::parameter::BOOST_PP_CAT( \
468         BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_ \
469       , BOOST_PARAMETER_FN_ARG_QUALIFIER(elem) \
470     )( \
471         tag_namespace::BOOST_PARAMETER_FUNCTION_KEYWORD( \
472             BOOST_PARAMETER_FN_ARG_KEYWORD(elem) \
473         ) \
474     ) \
475       , typename boost::parameter::aux::unwrap_predicate< \
476             void BOOST_PARAMETER_FN_ARG_PRED(elem) \
477         >::type \
478     >
479 # elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
480 #  define BOOST_PARAMETER_FUNCTION_PARAMETERS_M(r,tag_namespace,i,elem) \
481     BOOST_PP_COMMA_IF(i) \
482     boost::parameter::BOOST_PP_CAT( \
483         BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_ \
484       , BOOST_PARAMETER_FN_ARG_QUALIFIER(elem) \
485     )( \
486         tag_namespace::BOOST_PARAMETER_FUNCTION_KEYWORD( \
487             BOOST_PARAMETER_FN_ARG_KEYWORD(elem) \
488         ) \
489     ) \
490       , boost::mpl::always<boost::mpl::true_> \
491     >
492 # endif
493
494 # define BOOST_PARAMETER_FUNCTION_PARAMETERS(tag_namespace, base, args)             \
495     template <class BoostParameterDummy>                                            \
496     struct BOOST_PP_CAT(                                                            \
497             BOOST_PP_CAT(boost_param_params_, __LINE__)                             \
498           , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)                              \
499     ) : boost::parameter::parameters<                                               \
500             BOOST_PP_SEQ_FOR_EACH_I(                                                \
501                 BOOST_PARAMETER_FUNCTION_PARAMETERS_M, tag_namespace, args          \
502             )                                                                       \
503         >                                                                           \
504     {};                                                                             \
505                                                                                     \
506     typedef BOOST_PP_CAT( \
507             BOOST_PP_CAT(boost_param_params_, __LINE__) \
508           , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \
509     )<int>
510
511 // Defines result type metafunction
512 # define BOOST_PARAMETER_FUNCTION_RESULT_ARG(z, _, i, x) \
513     BOOST_PP_COMMA_IF(i) class BOOST_PP_TUPLE_ELEM(3,1,x)
514 /**/
515
516 # define BOOST_PARAMETER_FUNCTION_RESULT_(result, name, args)                                   \
517     template <class Args>                                                                       \
518     struct BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)                                           \
519     {                                                                                           \
520         typedef typename BOOST_PARAMETER_PARENTHESIZED_TYPE(result) type;                       \
521     };
522
523 // Defines implementation function
524 # define BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name)           \
525     template <class Args>                                   \
526     typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)<    \
527        Args                                                 \
528     >::type BOOST_PARAMETER_IMPL(name)(Args const& args)
529
530 # define BOOST_PARAMETER_FUNCTION_IMPL_FWD(name) \
531     BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name);
532 /**/
533
534 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_required(state, arg) \
535     ( \
536         BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4, 0, state)) \
537       , BOOST_PP_SEQ_PUSH_BACK(BOOST_PP_TUPLE_ELEM(4, 1, state), arg) \
538       , BOOST_PP_TUPLE_ELEM(4, 2, state) \
539       , BOOST_PP_TUPLE_ELEM(4, 3, state) \
540     )
541
542 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_deduced_required(state, arg) \
543     BOOST_PARAMETER_FUNCTION_SPLIT_ARG_required(state, arg)
544
545 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_optional(state, arg) \
546     ( \
547         BOOST_PP_TUPLE_ELEM(4, 0, state) \
548       , BOOST_PP_TUPLE_ELEM(4, 1, state) \
549       , BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4, 2, state)) \
550       , BOOST_PP_SEQ_PUSH_BACK(BOOST_PP_TUPLE_ELEM(4, 3, state), arg) \
551     )
552
553 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_deduced_optional(state, arg) \
554     BOOST_PARAMETER_FUNCTION_SPLIT_ARG_optional(state, arg)
555
556 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG(s, state, arg) \
557     BOOST_PP_CAT( \
558         BOOST_PARAMETER_FUNCTION_SPLIT_ARG_ \
559       , BOOST_PARAMETER_FN_ARG_QUALIFIER(arg) \
560     )(state, arg)
561
562 // Returns (required_count, required, optional_count, optionals) tuple
563 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARGS(args) \
564     BOOST_PP_SEQ_FOLD_LEFT( \
565         BOOST_PARAMETER_FUNCTION_SPLIT_ARG \
566       , (0,BOOST_PP_SEQ_NIL, 0,BOOST_PP_SEQ_NIL) \
567       , args \
568     )
569
570 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG_NAME(keyword) \
571     BOOST_PP_CAT(BOOST_PP_CAT(keyword,_),type)
572
573 // Helpers used as parameters to BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS.
574 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG(r, _, arg) \
575     , class BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG_NAME( \
576               BOOST_PARAMETER_FN_ARG_KEYWORD(arg) \
577       )
578
579 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG(r, _, arg) \
580     , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG_NAME( \
581               BOOST_PARAMETER_FN_ARG_KEYWORD(arg) \
582       )& BOOST_PARAMETER_FN_ARG_KEYWORD(arg)
583
584 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_PARAMETER(r, _, arg) \
585     , BOOST_PARAMETER_FN_ARG_KEYWORD(arg)
586
587 // Produces a name for the dispatch functions.
588 # define BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name) \
589     BOOST_PP_CAT( \
590         boost_param_default_ \
591       , BOOST_PP_CAT(__LINE__, BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name)) \
592     )
593
594 // Helper macro used below to produce lists based on the keyword argument
595 // names. macro is applied to every element. n is the number of
596 // optional arguments that should be included.
597 # define BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS(macro, n, split_args) \
598     BOOST_PP_SEQ_FOR_EACH( \
599         macro \
600       , ~ \
601       , BOOST_PP_TUPLE_ELEM(4,1,split_args) \
602     ) \
603     BOOST_PP_SEQ_FOR_EACH( \
604         macro \
605       , ~ \
606       , BOOST_PP_SEQ_FIRST_N( \
607           BOOST_PP_SUB(BOOST_PP_TUPLE_ELEM(4,2,split_args), n) \
608         , BOOST_PP_TUPLE_ELEM(4,3,split_args) \
609         ) \
610     )
611
612 // Generates a keyword | default expression.
613 # define BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT(arg, tag_namespace) \
614     boost::parameter::keyword< \
615         tag_namespace::BOOST_PARAMETER_FN_ARG_KEYWORD(arg) \
616     >::instance | boost::parameter::aux::use_default_tag()
617
618 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_GET_ARG(arg, tag_ns) \
619     BOOST_PARAMETER_FUNCTION_CAST( \
620         args[ \
621             BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT( \
622                 arg, tag_ns \
623             ) \
624         ] \
625       , BOOST_PARAMETER_FN_ARG_PRED(arg) \
626       , Args \
627     )
628
629 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_BODY(name, n, split_args, tag_namespace) \
630     { \
631         return BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
632             (ResultType(*)())0 \
633           , args \
634           , 0L \
635             BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
636                 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_PARAMETER \
637               , n \
638               , split_args \
639             ) \
640           , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_GET_ARG( \
641                 BOOST_PP_SEQ_ELEM( \
642                     BOOST_PP_SUB(BOOST_PP_TUPLE_ELEM(4,2,split_args), n) \
643                   , BOOST_PP_TUPLE_ELEM(4,3,split_args) \
644                 ) \
645               , tag_namespace \
646             ) \
647         ); \
648     }
649
650 # define BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_ACTUAL_DEFAULT(arg) \
651     BOOST_PARAMETER_FUNCTION_CAST( \
652         boost::parameter::aux::as_lvalue(BOOST_PARAMETER_FN_ARG_DEFAULT(arg), 0L) \
653       , BOOST_PARAMETER_FN_ARG_PRED(arg) \
654       , Args \
655     )
656
657 # define BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT_BODY(name, n, split_args, tag_ns, const_) \
658     template < \
659         class ResultType \
660       , class Args \
661         BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
662             BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG \
663           , BOOST_PP_INC(n) \
664           , split_args \
665         ) \
666     > \
667     BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \
668     ResultType BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
669         ResultType(*)() \
670       , Args const& args \
671       , long \
672         BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
673             BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \
674           , BOOST_PP_INC(n) \
675           , split_args \
676         ) \
677       , boost::parameter::aux::use_default_tag \
678     ) BOOST_PP_EXPR_IF(const_, const) \
679     { \
680         return BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
681             (ResultType(*)())0 \
682           , args \
683           , 0L \
684             BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
685                 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_PARAMETER \
686               , BOOST_PP_INC(n) \
687               , split_args \
688             ) \
689           , BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_ACTUAL_DEFAULT( \
690                 BOOST_PP_SEQ_ELEM( \
691                     BOOST_PP_SUB(BOOST_PP_TUPLE_ELEM(4,2,split_args), BOOST_PP_INC(n)) \
692                   , BOOST_PP_TUPLE_ELEM(4,3,split_args) \
693                 ) \
694             ) \
695         ); \
696     }
697
698 // Produces a forwarding layer in the default evaluation machine.
699 //
700 // data is a tuple:
701 //
702 //   (name, split_args)
703 //
704 // Where name is the base name of the function, and split_args is a tuple:
705 //
706 //   (required_count, required_args, optional_count, required_args)
707 //
708
709
710 // defines the actual function body for BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION below.
711 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION0(z, n, data) \
712     template < \
713         class ResultType \
714       , class Args \
715         BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
716             BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG \
717           , n \
718           , BOOST_PP_TUPLE_ELEM(5,1,data) \
719         ) \
720     > \
721     BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(5,0,data)) \
722     ResultType BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(BOOST_PP_TUPLE_ELEM(5,0,data))( \
723         ResultType(*)() \
724       , Args const& args \
725       , int \
726         BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
727             BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \
728           , n \
729           , BOOST_PP_TUPLE_ELEM(5,1,data) \
730         ) \
731     ) BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(5,2,data), const) \
732     BOOST_PP_IF( \
733         n \
734       , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_BODY \
735       , ; BOOST_PP_TUPLE_EAT(4) \
736     )( \
737         BOOST_PP_TUPLE_ELEM(5,0,data) \
738       , n \
739       , BOOST_PP_TUPLE_ELEM(5,1,data) \
740       , BOOST_PP_TUPLE_ELEM(5,3,data) \
741     )
742
743 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION(z, n, data) \
744     BOOST_PP_IF( \
745         BOOST_PP_AND( \
746             BOOST_PP_NOT(n) \
747           , BOOST_PP_TUPLE_ELEM(5,4,data) \
748         ) \
749       , BOOST_PP_TUPLE_EAT(3) \
750       , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION0 \
751     )(z, n, data) \
752     BOOST_PP_IF( \
753         BOOST_PP_EQUAL(n, BOOST_PP_TUPLE_ELEM(4,2,BOOST_PP_TUPLE_ELEM(5,1,data))) \
754       , BOOST_PP_TUPLE_EAT(5) \
755       , BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT_BODY \
756     )( \
757         BOOST_PP_TUPLE_ELEM(5,0,data) \
758       , n \
759       , BOOST_PP_TUPLE_ELEM(5,1,data) \
760       , BOOST_PP_TUPLE_ELEM(5,3,data) \
761       , BOOST_PP_TUPLE_ELEM(5,2,data) \
762     )
763
764 # define BOOST_PARAMETER_FUNCTION_DEFAULT_GET_ARG(r, tag_ns, arg) \
765     , BOOST_PARAMETER_FUNCTION_CAST( \
766           args[ \
767               boost::parameter::keyword<tag_ns::BOOST_PARAMETER_FN_ARG_KEYWORD(arg)>::instance \
768           ] \
769         , BOOST_PARAMETER_FN_ARG_PRED(arg) \
770         , Args \
771       )
772
773 // Generates the function template that recives a ArgumentPack, and then
774 // goes on to call the layers of overloads generated by 
775 // BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER.
776 # define BOOST_PARAMETER_FUNCTION_INITIAL_DISPATCH_FUNCTION(name, split_args, const_, tag_ns) \
777     template <class Args> \
778     typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)<Args>::type \
779     BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \
780     BOOST_PARAMETER_IMPL(name)(Args const& args) BOOST_PP_EXPR_IF(const_, const) \
781     { \
782         return BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
783             (typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)<Args>::type(*)())0 \
784           , args \
785           , 0L \
786  \
787             BOOST_PP_SEQ_FOR_EACH( \
788                 BOOST_PARAMETER_FUNCTION_DEFAULT_GET_ARG \
789               , tag_ns \
790               , BOOST_PP_TUPLE_ELEM(4,1,split_args) \
791             ) \
792  \
793         ); \
794     }
795
796 // Helper for BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER below.
797 # define BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER_AUX( \
798     name, split_args, skip_fwd_decl, const_, tag_namespace \
799   ) \
800     BOOST_PP_REPEAT_FROM_TO( \
801         0 \
802       , BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(4, 2, split_args)) \
803       , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION \
804       , (name, split_args, const_, tag_namespace, skip_fwd_decl) \
805     ) \
806  \
807     BOOST_PARAMETER_FUNCTION_INITIAL_DISPATCH_FUNCTION(name, split_args, const_, tag_namespace) \
808 \
809     template < \
810         class ResultType \
811       , class Args \
812         BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
813             BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG \
814           , 0 \
815           , split_args \
816         ) \
817     > \
818     BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \
819     ResultType BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
820         ResultType(*)() \
821       , Args const& \
822       , int \
823         BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
824             BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \
825           , 0 \
826           , split_args \
827         ) \
828     ) BOOST_PP_EXPR_IF(const_, const)
829
830 // Generates a bunch of forwarding functions that each extract
831 // one more argument.
832 # define BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER(name, args, skip_fwd_decl, const_, tag_ns) \
833     BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER_AUX( \
834         name, BOOST_PARAMETER_FUNCTION_SPLIT_ARGS(args), skip_fwd_decl, const_, tag_ns \
835     )
836 /**/
837
838 // Defines the result metafunction and the parameters specialization.
839 # define BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args)   \
840       BOOST_PARAMETER_FUNCTION_RESULT_(result, name, args)                   \
841                                                                             \
842           BOOST_PARAMETER_FUNCTION_PARAMETERS(tag_namespace, name, args)    \
843           BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(name);                   \
844
845 // Helper for BOOST_PARAMETER_FUNCTION below.
846 # define BOOST_PARAMETER_FUNCTION_AUX(result, name, tag_namespace, args)    \
847     BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args)         \
848     BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name); \
849 \
850     BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS(                                  \
851         result, name, args, 0                                                \
852       , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args)                      \
853     )                                                                        \
854                                                                              \
855     BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER(name, args, 0, 0, tag_namespace)
856
857 // Defines a Boost.Parameter enabled function with the new syntax.
858 # define BOOST_PARAMETER_FUNCTION(result, name, tag_namespace, args)    \
859     BOOST_PARAMETER_FUNCTION_AUX(                                       \
860         result, name, tag_namespace                                      \
861       , BOOST_PARAMETER_FLATTEN(3, 2, 3, args)                           \
862     )                                                                    \
863 /**/
864
865 // Defines a Boost.Parameter enabled function.
866 # define BOOST_PARAMETER_BASIC_FUNCTION_AUX(result, name, tag_namespace, args)    \
867     BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args)        \
868                                                                             \
869     BOOST_PARAMETER_FUNCTION_IMPL_FWD(name)                                 \
870                                                                             \
871     BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS(                                 \
872         result, name, args, 0                                               \
873       , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args)                     \
874     )                                                                       \
875                                                                             \
876     BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name)
877
878 # define BOOST_PARAMETER_BASIC_FUNCTION(result, name, tag_namespace, args)  \
879     BOOST_PARAMETER_BASIC_FUNCTION_AUX(                                     \
880         result, name, tag_namespace                                     \
881       , BOOST_PARAMETER_FLATTEN(2, 2, 3, args)                          \
882     )                                                                   \
883 /**/
884
885 // Defines a Boost.Parameter enabled member function.
886 # define BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX(result, name, tag_namespace, args, const_) \
887     BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args)                    \
888                                                                                         \
889     BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS(                                             \
890         result, name, args, const_                                                      \
891       , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args)                                 \
892     )                                                                                   \
893                                                                                         \
894     BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) BOOST_PP_EXPR_IF(const_, const)            \
895 /**/
896
897 # define BOOST_PARAMETER_BASIC_MEMBER_FUNCTION(result, name, tag_namespace, args) \
898     BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX( \
899         result, name, tag_namespace \
900       , BOOST_PARAMETER_FLATTEN(2, 2, 3, args) \
901       , 0 \
902     )
903 /**/
904
905 # define BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION(result, name, tag_namespace, args) \
906     BOOST_PARAMETER_BASIC_MEMBER_FUNCTION_AUX( \
907         result, name, tag_namespace \
908       , BOOST_PARAMETER_FLATTEN(2, 2, 3, args) \
909       , 1 \
910     )
911 /**/
912
913
914
915 # define BOOST_PARAMETER_MEMBER_FUNCTION_AUX(result, name, tag_namespace, const_, args)    \
916     BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args)         \
917 \
918     BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS(                                  \
919         result, name, args, const_                                           \
920       , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args)                      \
921     )                                                                        \
922                                                                              \
923     BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER(name, args, 1, const_, tag_namespace)
924
925 // Defines a Boost.Parameter enabled function with the new syntax.
926 # define BOOST_PARAMETER_MEMBER_FUNCTION(result, name, tag_namespace, args)    \
927     BOOST_PARAMETER_MEMBER_FUNCTION_AUX(                                       \
928         result, name, tag_namespace, 0                                     \
929       , BOOST_PARAMETER_FLATTEN(3, 2, 3, args)                           \
930     )                                                                    \
931 /**/
932
933 # define BOOST_PARAMETER_CONST_MEMBER_FUNCTION(result, name, tag_namespace, args)    \
934     BOOST_PARAMETER_MEMBER_FUNCTION_AUX(                                       \
935         result, name, tag_namespace, 1                                     \
936       , BOOST_PARAMETER_FLATTEN(3, 2, 3, args)                           \
937     )                                                                    \
938 /**/
939
940 // Defines a Boost.Parameter enabled constructor.
941
942 # define BOOST_PARAMETER_FUNCTION_ARGUMENT(r, _, i, elem) \
943     BOOST_PP_COMMA_IF(i) elem& BOOST_PP_CAT(a, i)
944 /**/
945
946 # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR00(z, n, r, data, elem) \
947     BOOST_PP_IF( \
948         n \
949       , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z, BOOST_PP_TUPLE_EAT(2) \
950     )(z, n) \
951     BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n,1), explicit) \
952     BOOST_PP_TUPLE_ELEM(6,2,data)( \
953         BOOST_PP_IF( \
954             n \
955           , BOOST_PP_SEQ_FOR_EACH_I_R \
956           , BOOST_PP_TUPLE_EAT(4) \
957         )( \
958             r \
959           , BOOST_PARAMETER_FUNCTION_ARGUMENT \
960           , ~ \
961           , elem \
962         ) \
963         BOOST_PP_IF(n, BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z, BOOST_PP_TUPLE_EAT(4))( \
964             z \
965           , BOOST_PP_TUPLE_ELEM(6,3,data) \
966           , BOOST_PP_CAT(constructor_parameters, __LINE__) \
967           , n \
968         ) \
969     ) \
970       : BOOST_PARAMETER_PARENTHESIZED_TYPE(BOOST_PP_TUPLE_ELEM(6,3,data)) ( \
971             BOOST_PP_CAT(constructor_parameters, __LINE__)()( \
972                 BOOST_PP_ENUM_PARAMS_Z(z, n, a) \
973             ) \
974         ) \
975     {}
976 /**/
977
978 # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR0(r, data, elem) \
979     BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR00( \
980         BOOST_PP_TUPLE_ELEM(6,0,data) \
981       , BOOST_PP_TUPLE_ELEM(6,1,data) \
982       , r \
983       , data \
984       , elem \
985     )
986 /**/
987
988 # define BOOST_PARAMETER_FUNCTION_FWD_PRODUCT(r, product) \
989     (product)
990 /**/
991
992 # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_0(z, n, data) \
993     BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR00( \
994         z, n, BOOST_PP_DEDUCE_R() \
995       , (z, n, BOOST_PP_TUPLE_REM(4) data) \
996       , ~ \
997     )
998 /**/
999
1000 # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_N(z, n, data) \
1001     BOOST_PP_SEQ_FOR_EACH( \
1002         BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR0 \
1003       , (z, n, BOOST_PP_TUPLE_REM(4) data) \
1004       , BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
1005             BOOST_PARAMETER_FUNCTION_FWD_PRODUCT \
1006           , BOOST_PP_SEQ_FIRST_N( \
1007                 n, BOOST_PP_TUPLE_ELEM(4,2,data) \
1008             ) \
1009         ) \
1010     )
1011 /**/
1012
1013 # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR(z, n, data) \
1014     BOOST_PP_IF( \
1015         n \
1016       , BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_N \
1017       , BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_0 \
1018     )(z,n,data) \
1019 /**/
1020
1021 # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTORS0(class_,base,args,combinations,range) \
1022     BOOST_PP_REPEAT_FROM_TO( \
1023         BOOST_PP_TUPLE_ELEM(2,0,range), BOOST_PP_TUPLE_ELEM(2,1,range) \
1024       , BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR \
1025       , (class_,base,combinations,BOOST_PP_TUPLE_ELEM(2,1,range)) \
1026     )
1027 /**/
1028
1029 # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTORS(class_,base,args,combinations) \
1030     BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTORS0( \
1031         class_, base, args, combinations, BOOST_PARAMETER_ARITY_RANGE(args) \
1032     )
1033 /**/
1034
1035 # define BOOST_PARAMETER_CONSTRUCTOR_AUX(class_, base, tag_namespace, args) \
1036     BOOST_PARAMETER_FUNCTION_PARAMETERS(tag_namespace, ctor, args)          \
1037         BOOST_PP_CAT(constructor_parameters, __LINE__); \
1038 \
1039     BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTORS( \
1040         class_, base, args \
1041       , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \
1042     ) \
1043 /**/
1044
1045 # define BOOST_PARAMETER_CONSTRUCTOR(class_, base, tag_namespace, args) \
1046     BOOST_PARAMETER_CONSTRUCTOR_AUX( \
1047         class_, base, tag_namespace \
1048       , BOOST_PARAMETER_FLATTEN(2, 2, 3, args) \
1049     )
1050 /**/
1051
1052 # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
1053 #  define BOOST_PARAMETER_FUNCTION_FWD_COMBINATION(r, _, i, elem) \
1054     (BOOST_PP_IF( \
1055         BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER( \
1056             BOOST_PARAMETER_FN_ARG_NAME(elem) \
1057         ) \
1058       , (const ParameterArgumentType ## i)(ParameterArgumentType ## i) \
1059       , (const ParameterArgumentType ## i) \
1060     ))
1061 // No partial ordering. This feature doesn't work.
1062 # else
1063 #  define BOOST_PARAMETER_FUNCTION_FWD_COMBINATION(r, _, i, elem) \
1064     (BOOST_PP_IF( \
1065         BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER( \
1066             BOOST_PARAMETER_FN_ARG_NAME(elem) \
1067         ) \
1068       , (ParameterArgumentType ## i) \
1069       , (const ParameterArgumentType ## i) \
1070     ))
1071 # endif
1072
1073 # define BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \
1074     BOOST_PP_SEQ_FOR_EACH_I(BOOST_PARAMETER_FUNCTION_FWD_COMBINATION, ~, args)
1075
1076 #endif // BOOST_PARAMETER_PREPROCESSOR_060206_HPP
1077