preprocessor.hpp 41 KB

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