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)
5 #ifndef BOOST_PARAMETER_PREPROCESSOR_060206_HPP
6 # define BOOST_PARAMETER_PREPROCESSOR_060206_HPP
8 # include <boost/parameter/parameters.hpp>
9 # include <boost/parameter/binding.hpp>
10 # include <boost/parameter/match.hpp>
12 # include <boost/parameter/aux_/parenthesized_type.hpp>
13 # include <boost/parameter/aux_/cast.hpp>
14 # include <boost/parameter/aux_/preprocessor/flatten.hpp>
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>
35 # include <boost/preprocessor/detail/is_nullary.hpp>
37 # include <boost/mpl/always.hpp>
38 # include <boost/mpl/apply_wrap.hpp>
40 namespace boost { namespace parameter { namespace aux {
42 # if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
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;
51 struct unwrap_predicate<void*>
53 typedef mpl::always<mpl::true_> type;
56 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
58 typedef void* voidstar;
60 // A matching predicate is explicitly specified
61 template <class Predicate>
62 struct unwrap_predicate<voidstar (Predicate)>
64 typedef Predicate type;
69 // A matching predicate is explicitly specified
70 template <class Predicate>
71 struct unwrap_predicate<void *(Predicate)>
73 typedef Predicate type;
79 // A type to which the argument is supposed to be convertible is
81 template <class Target>
82 struct unwrap_predicate<void (Target)>
84 typedef is_convertible<mpl::_, Target> type;
87 // Recast the ParameterSpec's nested match metafunction as a free metafunction
90 , BOOST_PP_ENUM_BINARY_PARAMS(
91 BOOST_PARAMETER_MAX_ARITY, class A, = boost::parameter::void_ BOOST_PP_INTERCEPT
95 : Parameters::template match<
96 BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, A)
105 , BOOST_PP_ENUM_BINARY_PARAMS(
106 BOOST_PARAMETER_MAX_ARITY, class A, = boost::parameter::void_ BOOST_PP_INTERCEPT
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
115 , typename Parameters::deduced_list
119 typedef typename mpl::first<result>::type type;
122 // Works around VC6 problem where it won't accept rvalues.
124 T& as_lvalue(T& value, long)
130 T const& as_lvalue(T const& value, int)
136 # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
138 template <class Predicate, class T, class Args>
139 struct apply_predicate
142 mpl::and_<mpl::false_,T>
145 typedef typename mpl::if_<
146 typename mpl::apply2<Predicate,T,Args>::type
153 struct funptr_predicate
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));
161 template <class T, class Args, class P0>
162 static typename mpl::if_<
166 >::type check_predicate(type<T>, Args*, void*(*)(P0));
168 template <class T, class Args>
171 BOOST_STATIC_CONSTANT(bool, result =
172 sizeof(check_predicate(boost::type<T>(), (Args*)0, &p)) == 1
175 typedef mpl::bool_<apply<T,Args>::result> type;
180 struct funptr_predicate<void**>
181 : mpl::always<mpl::true_>
186 }}} // namespace boost::parameter::aux
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) \
193 # define BOOST_PARAMETER_IS_NULLARY_C() \
194 ~, 1 BOOST_PP_RPAREN() \
195 BOOST_PP_TUPLE_EAT(2) BOOST_PP_LPAREN() ~ \
198 # define BOOST_PARAMETER_IS_NULLARY(x) BOOST_PP_IS_NULLARY(x)
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) \
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)
212 // Workaround for MSVC preprocessor.
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) \
223 BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC_AUX(name) \
227 # define BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \
229 BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \
233 # define BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name) \
235 BOOST_PARAMETER_MEMBER_FUNCTION_IS_STATIC(name) \
236 , BOOST_PARAMETER_MEMBER_FUNCTION_STRIP_STATIC \
237 , name BOOST_PP_TUPLE_EAT(1) \
240 // Calculates [begin, end) arity range.
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)
247 # define BOOST_PARAMETER_ARITY_RANGE_M(s, state, x) \
249 BOOST_PARAMETER_ARITY_RANGE_M_ \
250 , BOOST_PARAMETER_FN_ARG_QUALIFIER(x) \
254 # define BOOST_PARAMETER_ARITY_RANGE(args) \
256 BOOST_PP_SEQ_FOLD_LEFT(BOOST_PARAMETER_ARITY_RANGE_M, 0, args) \
257 , BOOST_PP_INC(BOOST_PP_SEQ_SIZE(args)) \
261 // Accessor macros for the argument specs tuple.
262 # define BOOST_PARAMETER_FN_ARG_QUALIFIER(x) \
263 BOOST_PP_TUPLE_ELEM(4,0,x)
266 # define BOOST_PARAMETER_FN_ARG_NAME(x) \
267 BOOST_PP_TUPLE_ELEM(4,1,x)
270 # define BOOST_PARAMETER_FN_ARG_PRED(x) \
271 BOOST_PP_TUPLE_ELEM(4,2,x)
274 # define BOOST_PARAMETER_FN_ARG_DEFAULT(x) \
275 BOOST_PP_TUPLE_ELEM(4,3,x)
278 # define BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_out(x)
279 # define BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_in_out(x)
281 // Returns 1 if x is either "out(k)" or "in_out(k)".
282 # define BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER(x) \
284 BOOST_PP_CAT(BOOST_PARAMETETER_FUNCTION_EAT_KEYWORD_QUALIFIER_, x) \
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)
294 // Returns the keyword of x, where x is either a keyword qualifier
301 # define BOOST_PARAMETER_FUNCTION_KEYWORD(x) \
303 BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER(x) \
304 , BOOST_PARAMETER_FUNCTION_KEYWORD_GET \
305 , x BOOST_PP_TUPLE_EAT(1) \
309 # define BOOST_PARAMETER_FN_ARG_KEYWORD(x) \
310 BOOST_PARAMETER_FUNCTION_KEYWORD( \
311 BOOST_PARAMETER_FN_ARG_NAME(x) \
314 // Builds forwarding functions.
316 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z(z, n) \
317 template<BOOST_PP_ENUM_PARAMS_Z(z, n, class ParameterArgumentType)>
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()
326 # define BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z(z, name, parameters, n)
330 # define BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(base) \
332 boost_param_parameters_ \
333 , BOOST_PP_CAT(__LINE__, BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) \
336 // Produce a name for a result type metafunction for the function
338 # define BOOST_PARAMETER_FUNCTION_RESULT_NAME(base) \
340 boost_param_result_ \
341 , BOOST_PP_CAT(__LINE__,BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base)) \
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))
350 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION00(z, n, r, data, elem) \
353 , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z, BOOST_PP_TUPLE_EAT(2) \
355 BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(7,3,data)) \
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) \
364 n, BOOST_PP_SEQ_ENUM, BOOST_PP_TUPLE_EAT(1) \
368 BOOST_PARAMETER_MEMBER_FUNCTION_NAME(BOOST_PP_TUPLE_ELEM(7,3,data))( \
371 , BOOST_PP_SEQ_FOR_EACH_I_R \
372 , BOOST_PP_TUPLE_EAT(4) \
375 , BOOST_PARAMETER_FUNCTION_ARGUMENT \
379 BOOST_PP_IF(n, BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z, BOOST_PP_TUPLE_EAT(4))( \
381 , BOOST_PP_TUPLE_ELEM(7,3,data) \
382 , BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(BOOST_PP_TUPLE_ELEM(7,3,data)) \
385 ) BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(7,4,data), const) \
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) \
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) \
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) \
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) \
426 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTION(z, n, data) \
429 , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_N \
430 , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_ARITY_0 \
434 # define BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS0( \
435 result,name,args,const_,combinations,range \
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)) \
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) \
450 // Builds boost::parameter::parameters<> specialization
451 # define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_optional(tag) \
454 # define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_required(tag) \
457 # define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_deduced_optional(tag) \
458 optional<boost::parameter::deduced<tag>
460 # define BOOST_PARAMETER_FUNCTION_PARAMETERS_QUALIFIER_deduced_required(tag) \
461 required<boost::parameter::deduced<tag>
463 # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
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) \
471 tag_namespace::BOOST_PARAMETER_FUNCTION_KEYWORD( \
472 BOOST_PARAMETER_FN_ARG_KEYWORD(elem) \
475 , typename boost::parameter::aux::unwrap_predicate< \
476 void BOOST_PARAMETER_FN_ARG_PRED(elem) \
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) \
486 tag_namespace::BOOST_PARAMETER_FUNCTION_KEYWORD( \
487 BOOST_PARAMETER_FN_ARG_KEYWORD(elem) \
490 , boost::mpl::always<boost::mpl::true_> \
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 \
506 typedef BOOST_PP_CAT( \
507 BOOST_PP_CAT(boost_param_params_, __LINE__) \
508 , BOOST_PARAMETER_MEMBER_FUNCTION_NAME(base) \
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)
516 # define BOOST_PARAMETER_FUNCTION_RESULT_(result, name, args) \
517 template <class Args> \
518 struct BOOST_PARAMETER_FUNCTION_RESULT_NAME(name) \
520 typedef typename BOOST_PARAMETER_PARENTHESIZED_TYPE(result) type; \
523 // Defines implementation function
524 # define BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) \
525 template <class Args> \
526 typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)< \
528 >::type BOOST_PARAMETER_IMPL(name)(Args const& args)
530 # define BOOST_PARAMETER_FUNCTION_IMPL_FWD(name) \
531 BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name);
534 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_required(state, arg) \
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) \
542 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_deduced_required(state, arg) \
543 BOOST_PARAMETER_FUNCTION_SPLIT_ARG_required(state, arg)
545 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_optional(state, arg) \
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) \
553 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG_deduced_optional(state, arg) \
554 BOOST_PARAMETER_FUNCTION_SPLIT_ARG_optional(state, arg)
556 # define BOOST_PARAMETER_FUNCTION_SPLIT_ARG(s, state, arg) \
558 BOOST_PARAMETER_FUNCTION_SPLIT_ARG_ \
559 , BOOST_PARAMETER_FN_ARG_QUALIFIER(arg) \
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) \
570 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG_NAME(keyword) \
571 BOOST_PP_CAT(BOOST_PP_CAT(keyword,_),type)
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) \
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)
584 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_PARAMETER(r, _, arg) \
585 , BOOST_PARAMETER_FN_ARG_KEYWORD(arg)
587 // Produces a name for the dispatch functions.
588 # define BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name) \
590 boost_param_default_ \
591 , BOOST_PP_CAT(__LINE__, BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name)) \
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( \
601 , BOOST_PP_TUPLE_ELEM(4,1,split_args) \
603 BOOST_PP_SEQ_FOR_EACH( \
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) \
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()
618 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_GET_ARG(arg, tag_ns) \
619 BOOST_PARAMETER_FUNCTION_CAST( \
621 BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT( \
625 , BOOST_PARAMETER_FN_ARG_PRED(arg) \
629 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_BODY(name, n, split_args, tag_namespace) \
631 return BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
635 BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
636 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_PARAMETER \
640 , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_GET_ARG( \
642 BOOST_PP_SUB(BOOST_PP_TUPLE_ELEM(4,2,split_args), n) \
643 , BOOST_PP_TUPLE_ELEM(4,3,split_args) \
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) \
657 # define BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_DEFAULT_BODY(name, n, split_args, tag_ns, const_) \
661 BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
662 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG \
667 BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \
668 ResultType BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
672 BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
673 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \
677 , boost::parameter::aux::use_default_tag \
678 ) BOOST_PP_EXPR_IF(const_, const) \
680 return BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
684 BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
685 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_PARAMETER \
689 , BOOST_PARAMETER_FUNCTION_DEFAULT_EVAL_ACTUAL_DEFAULT( \
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) \
698 // Produces a forwarding layer in the default evaluation machine.
702 // (name, split_args)
704 // Where name is the base name of the function, and split_args is a tuple:
706 // (required_count, required_args, optional_count, required_args)
710 // defines the actual function body for BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION below.
711 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION0(z, n, data) \
715 BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
716 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG \
718 , BOOST_PP_TUPLE_ELEM(5,1,data) \
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))( \
726 BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
727 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \
729 , BOOST_PP_TUPLE_ELEM(5,1,data) \
731 ) BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(5,2,data), const) \
734 , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_BODY \
735 , ; BOOST_PP_TUPLE_EAT(4) \
737 BOOST_PP_TUPLE_ELEM(5,0,data) \
739 , BOOST_PP_TUPLE_ELEM(5,1,data) \
740 , BOOST_PP_TUPLE_ELEM(5,3,data) \
743 # define BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION(z, n, data) \
747 , BOOST_PP_TUPLE_ELEM(5,4,data) \
749 , BOOST_PP_TUPLE_EAT(3) \
750 , BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION0 \
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 \
757 BOOST_PP_TUPLE_ELEM(5,0,data) \
759 , BOOST_PP_TUPLE_ELEM(5,1,data) \
760 , BOOST_PP_TUPLE_ELEM(5,3,data) \
761 , BOOST_PP_TUPLE_ELEM(5,2,data) \
764 # define BOOST_PARAMETER_FUNCTION_DEFAULT_GET_ARG(r, tag_ns, arg) \
765 , BOOST_PARAMETER_FUNCTION_CAST( \
767 boost::parameter::keyword<tag_ns::BOOST_PARAMETER_FN_ARG_KEYWORD(arg)>::instance \
769 , BOOST_PARAMETER_FN_ARG_PRED(arg) \
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) \
782 return BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
783 (typename BOOST_PARAMETER_FUNCTION_RESULT_NAME(name)<Args>::type(*)())0 \
787 BOOST_PP_SEQ_FOR_EACH( \
788 BOOST_PARAMETER_FUNCTION_DEFAULT_GET_ARG \
790 , BOOST_PP_TUPLE_ELEM(4,1,split_args) \
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 \
800 BOOST_PP_REPEAT_FROM_TO( \
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) \
807 BOOST_PARAMETER_FUNCTION_INITIAL_DISPATCH_FUNCTION(name, split_args, const_, tag_namespace) \
812 BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
813 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_TEMPLATE_ARG \
818 BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) \
819 ResultType BOOST_PARAMETER_FUNCTION_DEFAULT_NAME(name)( \
823 BOOST_PARAMETER_FUNCTION_DEFAULT_ARGUMENTS( \
824 BOOST_PARAMETER_FUNCTION_DEFAULT_FUNCTION_ARG \
828 ) BOOST_PP_EXPR_IF(const_, const)
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 \
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) \
842 BOOST_PARAMETER_FUNCTION_PARAMETERS(tag_namespace, name, args) \
843 BOOST_PARAMETER_FUNCTION_PARAMETERS_NAME(name); \
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); \
850 BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS( \
851 result, name, args, 0 \
852 , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \
855 BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER(name, args, 0, 0, tag_namespace)
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) \
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) \
869 BOOST_PARAMETER_FUNCTION_IMPL_FWD(name) \
871 BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS( \
872 result, name, args, 0 \
873 , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \
876 BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name)
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) \
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) \
889 BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS( \
890 result, name, args, const_ \
891 , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \
894 BOOST_PARAMETER_FUNCTION_IMPL_HEAD(name) BOOST_PP_EXPR_IF(const_, const) \
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) \
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) \
915 # define BOOST_PARAMETER_MEMBER_FUNCTION_AUX(result, name, tag_namespace, const_, args) \
916 BOOST_PARAMETER_FUNCTION_HEAD(result, name, tag_namespace, args) \
918 BOOST_PARAMETER_FUNCTION_FWD_FUNCTIONS( \
919 result, name, args, const_ \
920 , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \
923 BOOST_PARAMETER_FUNCTION_DEFAULT_LAYER(name, args, 1, const_, tag_namespace)
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) \
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) \
940 // Defines a Boost.Parameter enabled constructor.
942 # define BOOST_PARAMETER_FUNCTION_ARGUMENT(r, _, i, elem) \
943 BOOST_PP_COMMA_IF(i) elem& BOOST_PP_CAT(a, i)
946 # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR00(z, n, r, data, elem) \
949 , BOOST_PARAMETER_FUNCTION_FWD_FUNCTION_TEMPLATE_Z, BOOST_PP_TUPLE_EAT(2) \
951 BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n,1), explicit) \
952 BOOST_PP_TUPLE_ELEM(6,2,data)( \
955 , BOOST_PP_SEQ_FOR_EACH_I_R \
956 , BOOST_PP_TUPLE_EAT(4) \
959 , BOOST_PARAMETER_FUNCTION_ARGUMENT \
963 BOOST_PP_IF(n, BOOST_PARAMETER_FUNCTION_FWD_MATCH_Z, BOOST_PP_TUPLE_EAT(4))( \
965 , BOOST_PP_TUPLE_ELEM(6,3,data) \
966 , BOOST_PP_CAT(constructor_parameters, __LINE__) \
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) \
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) \
988 # define BOOST_PARAMETER_FUNCTION_FWD_PRODUCT(r, product) \
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) \
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) \
1013 # define BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR(z, n, data) \
1016 , BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_N \
1017 , BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTOR_ARITY_0 \
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)) \
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) \
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__); \
1039 BOOST_PARAMETER_FUNCTION_FWD_CONSTRUCTORS( \
1040 class_, base, args \
1041 , BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \
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) \
1052 # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
1053 # define BOOST_PARAMETER_FUNCTION_FWD_COMBINATION(r, _, i, elem) \
1055 BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER( \
1056 BOOST_PARAMETER_FN_ARG_NAME(elem) \
1058 , (const ParameterArgumentType ## i)(ParameterArgumentType ## i) \
1059 , (const ParameterArgumentType ## i) \
1061 // No partial ordering. This feature doesn't work.
1063 # define BOOST_PARAMETER_FUNCTION_FWD_COMBINATION(r, _, i, elem) \
1065 BOOST_PARAMETER_FUNCTION_IS_KEYWORD_QUALIFIER( \
1066 BOOST_PARAMETER_FN_ARG_NAME(elem) \
1068 , (ParameterArgumentType ## i) \
1069 , (const ParameterArgumentType ## i) \
1073 # define BOOST_PARAMETER_FUNCTION_FWD_COMBINATIONS(args) \
1074 BOOST_PP_SEQ_FOR_EACH_I(BOOST_PARAMETER_FUNCTION_FWD_COMBINATION, ~, args)
1076 #endif // BOOST_PARAMETER_PREPROCESSOR_060206_HPP