Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/parameter/preprocessor.hpp @ 47

Last change on this file since 47 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

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