bind.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. #if !defined(BOOST_PP_IS_ITERATING)
  2. ///// header body
  3. #ifndef BOOST_MPL_BIND_HPP_INCLUDED
  4. #define BOOST_MPL_BIND_HPP_INCLUDED
  5. // Copyright Peter Dimov 2001
  6. // Copyright Aleksey Gurtovoy 2001-2004
  7. //
  8. // Distributed under the Boost Software License, Version 1.0.
  9. // (See accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. //
  12. // See http://www.boost.org/libs/mpl for documentation.
  13. // $Id$
  14. // $Date$
  15. // $Revision$
  16. #if !defined(BOOST_MPL_PREPROCESSING_MODE)
  17. # include <boost/mpl/bind_fwd.hpp>
  18. # include <boost/mpl/placeholders.hpp>
  19. # include <boost/mpl/next.hpp>
  20. # include <boost/mpl/protect.hpp>
  21. # include <boost/mpl/apply_wrap.hpp>
  22. # include <boost/mpl/limits/arity.hpp>
  23. # include <boost/mpl/aux_/na.hpp>
  24. # include <boost/mpl/aux_/arity_spec.hpp>
  25. # include <boost/mpl/aux_/type_wrapper.hpp>
  26. # include <boost/mpl/aux_/yes_no.hpp>
  27. # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  28. # include <boost/type_traits/is_reference.hpp>
  29. # endif
  30. #endif
  31. #include <boost/mpl/aux_/config/bind.hpp>
  32. #include <boost/mpl/aux_/config/static_constant.hpp>
  33. #include <boost/mpl/aux_/config/use_preprocessed.hpp>
  34. #if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
  35. && !defined(BOOST_MPL_PREPROCESSING_MODE)
  36. # if defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
  37. # define BOOST_MPL_PREPROCESSED_HEADER basic_bind.hpp
  38. # else
  39. # define BOOST_MPL_PREPROCESSED_HEADER bind.hpp
  40. # endif
  41. # include <boost/mpl/aux_/include_preprocessed.hpp>
  42. #else
  43. # include <boost/mpl/aux_/preprocessor/params.hpp>
  44. # include <boost/mpl/aux_/preprocessor/default_params.hpp>
  45. # include <boost/mpl/aux_/preprocessor/def_params_tail.hpp>
  46. # include <boost/mpl/aux_/preprocessor/partial_spec_params.hpp>
  47. # include <boost/mpl/aux_/preprocessor/ext_params.hpp>
  48. # include <boost/mpl/aux_/preprocessor/repeat.hpp>
  49. # include <boost/mpl/aux_/preprocessor/enum.hpp>
  50. # include <boost/mpl/aux_/preprocessor/add.hpp>
  51. # include <boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp>
  52. # include <boost/mpl/aux_/config/ctps.hpp>
  53. # include <boost/mpl/aux_/config/ttp.hpp>
  54. # include <boost/mpl/aux_/config/dtp.hpp>
  55. # include <boost/mpl/aux_/nttp_decl.hpp>
  56. # include <boost/preprocessor/iterate.hpp>
  57. # include <boost/preprocessor/comma_if.hpp>
  58. # include <boost/preprocessor/cat.hpp>
  59. # include <boost/preprocessor/inc.hpp>
  60. namespace boost { namespace mpl {
  61. // local macros, #undef-ined at the end of the header
  62. # define AUX778076_APPLY \
  63. BOOST_PP_CAT(apply_wrap,BOOST_MPL_LIMIT_METAFUNCTION_ARITY) \
  64. /**/
  65. # if defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS)
  66. # define AUX778076_DMC_PARAM() , int dummy_
  67. # else
  68. # define AUX778076_DMC_PARAM()
  69. # endif
  70. # define AUX778076_BIND_PARAMS(param) \
  71. BOOST_MPL_PP_PARAMS( \
  72. BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
  73. , param \
  74. ) \
  75. /**/
  76. # define AUX778076_BIND_DEFAULT_PARAMS(param, value) \
  77. BOOST_MPL_PP_DEFAULT_PARAMS( \
  78. BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
  79. , param \
  80. , value \
  81. ) \
  82. /**/
  83. # define AUX778076_BIND_N_PARAMS(n, param) \
  84. BOOST_PP_COMMA_IF(n) BOOST_MPL_PP_PARAMS(n, param) \
  85. /**/
  86. # define AUX778076_BIND_N_SPEC_PARAMS(n, param, def) \
  87. BOOST_PP_COMMA_IF(n) \
  88. BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(n, param, def) \
  89. /**/
  90. #if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
  91. # define AUX778076_BIND_NESTED_DEFAULT_PARAMS(param, value) \
  92. AUX778076_BIND_DEFAULT_PARAMS(param, value) \
  93. /**/
  94. #else
  95. # define AUX778076_BIND_NESTED_DEFAULT_PARAMS(param, value) \
  96. AUX778076_BIND_PARAMS(param) \
  97. /**/
  98. #endif
  99. namespace aux {
  100. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  101. template<
  102. typename T, AUX778076_BIND_PARAMS(typename U)
  103. >
  104. struct resolve_bind_arg
  105. {
  106. typedef T type;
  107. };
  108. # if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
  109. template<
  110. typename T
  111. , typename Arg
  112. >
  113. struct replace_unnamed_arg
  114. {
  115. typedef Arg next;
  116. typedef T type;
  117. };
  118. template<
  119. typename Arg
  120. >
  121. struct replace_unnamed_arg< arg<-1>,Arg >
  122. {
  123. typedef typename Arg::next next;
  124. typedef Arg type;
  125. };
  126. # endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT
  127. template<
  128. BOOST_MPL_AUX_NTTP_DECL(int, N), AUX778076_BIND_PARAMS(typename U)
  129. >
  130. struct resolve_bind_arg< arg<N>,AUX778076_BIND_PARAMS(U) >
  131. {
  132. typedef typename AUX778076_APPLY<mpl::arg<N>, AUX778076_BIND_PARAMS(U)>::type type;
  133. };
  134. #if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
  135. template<
  136. typename F, AUX778076_BIND_PARAMS(typename T), AUX778076_BIND_PARAMS(typename U)
  137. >
  138. struct resolve_bind_arg< bind<F,AUX778076_BIND_PARAMS(T)>,AUX778076_BIND_PARAMS(U) >
  139. {
  140. typedef bind<F,AUX778076_BIND_PARAMS(T)> f_;
  141. typedef typename AUX778076_APPLY<f_, AUX778076_BIND_PARAMS(U)>::type type;
  142. };
  143. #endif
  144. #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  145. // agurt, 15/jan/02: it's not a intended to be used as a function class, and
  146. // MSVC6.5 has problems with 'apply' name here (the code compiles, but doesn't
  147. // work), so I went with the 'result_' here, and in all other similar cases
  148. template< bool >
  149. struct resolve_arg_impl
  150. {
  151. template< typename T, AUX778076_BIND_PARAMS(typename U) > struct result_
  152. {
  153. typedef T type;
  154. };
  155. };
  156. template<>
  157. struct resolve_arg_impl<true>
  158. {
  159. template< typename T, AUX778076_BIND_PARAMS(typename U) > struct result_
  160. {
  161. typedef typename AUX778076_APPLY<
  162. T
  163. , AUX778076_BIND_PARAMS(U)
  164. >::type type;
  165. };
  166. };
  167. // for 'resolve_bind_arg'
  168. template< typename T > struct is_bind_template;
  169. template<
  170. typename T, AUX778076_BIND_PARAMS(typename U)
  171. >
  172. struct resolve_bind_arg
  173. : resolve_arg_impl< is_bind_template<T>::value >
  174. ::template result_< T,AUX778076_BIND_PARAMS(U) >
  175. {
  176. };
  177. # if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
  178. template< typename T >
  179. struct replace_unnamed_arg_impl
  180. {
  181. template< typename Arg > struct result_
  182. {
  183. typedef Arg next;
  184. typedef T type;
  185. };
  186. };
  187. template<>
  188. struct replace_unnamed_arg_impl< arg<-1> >
  189. {
  190. template< typename Arg > struct result_
  191. {
  192. typedef typename next<Arg>::type next;
  193. typedef Arg type;
  194. };
  195. };
  196. template< typename T, typename Arg >
  197. struct replace_unnamed_arg
  198. : replace_unnamed_arg_impl<T>::template result_<Arg>
  199. {
  200. };
  201. # endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT
  202. // agurt, 10/mar/02: the forward declaration has to appear before any of
  203. // 'is_bind_helper' overloads, otherwise MSVC6.5 issues an ICE on it
  204. template< BOOST_MPL_AUX_NTTP_DECL(int, arity_) > struct bind_chooser;
  205. aux::no_tag is_bind_helper(...);
  206. template< typename T > aux::no_tag is_bind_helper(protect<T>*);
  207. // overload for "main" form
  208. // agurt, 15/mar/02: MSVC 6.5 fails to properly resolve the overload
  209. // in case if we use 'aux::type_wrapper< bind<...> >' here, and all
  210. // 'bind' instantiations form a complete type anyway
  211. #if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
  212. template<
  213. typename F, AUX778076_BIND_PARAMS(typename T)
  214. >
  215. aux::yes_tag is_bind_helper(bind<F,AUX778076_BIND_PARAMS(T)>*);
  216. #endif
  217. template< BOOST_MPL_AUX_NTTP_DECL(int, N) >
  218. aux::yes_tag is_bind_helper(arg<N>*);
  219. template< bool is_ref_ = true >
  220. struct is_bind_template_impl
  221. {
  222. template< typename T > struct result_
  223. {
  224. BOOST_STATIC_CONSTANT(bool, value = false);
  225. };
  226. };
  227. template<>
  228. struct is_bind_template_impl<false>
  229. {
  230. template< typename T > struct result_
  231. {
  232. BOOST_STATIC_CONSTANT(bool, value =
  233. sizeof(aux::is_bind_helper(static_cast<T*>(0)))
  234. == sizeof(aux::yes_tag)
  235. );
  236. };
  237. };
  238. template< typename T > struct is_bind_template
  239. : is_bind_template_impl< ::boost::detail::is_reference_impl<T>::value >
  240. ::template result_<T>
  241. {
  242. };
  243. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  244. } // namespace aux
  245. #define BOOST_PP_ITERATION_PARAMS_1 \
  246. (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/bind.hpp>))
  247. #include BOOST_PP_ITERATE()
  248. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
  249. && !defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS)
  250. /// if_/eval_if specializations
  251. # define AUX778076_SPEC_NAME if_
  252. # define BOOST_PP_ITERATION_PARAMS_1 (3,(3, 3, <boost/mpl/bind.hpp>))
  253. # include BOOST_PP_ITERATE()
  254. #if !defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS)
  255. # define AUX778076_SPEC_NAME eval_if
  256. # define BOOST_PP_ITERATION_PARAMS_1 (3,(3, 3, <boost/mpl/bind.hpp>))
  257. # include BOOST_PP_ITERATE()
  258. #endif
  259. #endif
  260. // real C++ version is already taken care of
  261. #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
  262. && !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
  263. namespace aux {
  264. // apply_count_args
  265. #define AUX778076_COUNT_ARGS_PREFIX bind
  266. #define AUX778076_COUNT_ARGS_DEFAULT na
  267. #define AUX778076_COUNT_ARGS_ARITY BOOST_MPL_LIMIT_METAFUNCTION_ARITY
  268. #include <boost/mpl/aux_/count_args.hpp>
  269. }
  270. // bind
  271. template<
  272. typename F, AUX778076_BIND_PARAMS(typename T) AUX778076_DMC_PARAM()
  273. >
  274. struct bind
  275. : aux::bind_chooser<
  276. aux::bind_count_args<AUX778076_BIND_PARAMS(T)>::value
  277. >::template result_< F,AUX778076_BIND_PARAMS(T) >::type
  278. {
  279. };
  280. BOOST_MPL_AUX_ARITY_SPEC(
  281. BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
  282. , bind
  283. )
  284. BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(
  285. BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
  286. , bind
  287. )
  288. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  289. # undef AUX778076_BIND_NESTED_DEFAULT_PARAMS
  290. # undef AUX778076_BIND_N_SPEC_PARAMS
  291. # undef AUX778076_BIND_N_PARAMS
  292. # undef AUX778076_BIND_DEFAULT_PARAMS
  293. # undef AUX778076_BIND_PARAMS
  294. # undef AUX778076_DMC_PARAM
  295. # undef AUX778076_APPLY
  296. }}
  297. #endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
  298. #endif // BOOST_MPL_BIND_HPP_INCLUDED
  299. ///// iteration, depth == 1
  300. // For gcc 4.4 compatability, we must include the
  301. // BOOST_PP_ITERATION_DEPTH test inside an #else clause.
  302. #else // BOOST_PP_IS_ITERATING
  303. #if BOOST_PP_ITERATION_DEPTH() == 1
  304. # define i_ BOOST_PP_FRAME_ITERATION(1)
  305. #if defined(AUX778076_SPEC_NAME)
  306. // lazy metafunction specialization
  307. template< template< BOOST_MPL_PP_PARAMS(i_, typename T) > class F, typename Tag >
  308. struct BOOST_PP_CAT(quote,i_);
  309. template< BOOST_MPL_PP_PARAMS(i_, typename T) > struct AUX778076_SPEC_NAME;
  310. template<
  311. typename Tag AUX778076_BIND_N_PARAMS(i_, typename T)
  312. >
  313. struct BOOST_PP_CAT(bind,i_)<
  314. BOOST_PP_CAT(quote,i_)<AUX778076_SPEC_NAME,Tag>
  315. AUX778076_BIND_N_PARAMS(i_,T)
  316. >
  317. {
  318. template<
  319. AUX778076_BIND_NESTED_DEFAULT_PARAMS(typename U, na)
  320. >
  321. struct apply
  322. {
  323. private:
  324. typedef mpl::arg<1> n1;
  325. # define BOOST_PP_ITERATION_PARAMS_2 (3,(1, i_, <boost/mpl/bind.hpp>))
  326. # include BOOST_PP_ITERATE()
  327. typedef typename AUX778076_SPEC_NAME<
  328. typename t1::type
  329. , BOOST_MPL_PP_EXT_PARAMS(2, BOOST_PP_INC(i_), t)
  330. >::type f_;
  331. public:
  332. typedef typename f_::type type;
  333. };
  334. };
  335. #undef AUX778076_SPEC_NAME
  336. #else // AUX778076_SPEC_NAME
  337. template<
  338. typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM()
  339. >
  340. struct BOOST_PP_CAT(bind,i_)
  341. {
  342. template<
  343. AUX778076_BIND_NESTED_DEFAULT_PARAMS(typename U, na)
  344. >
  345. struct apply
  346. {
  347. private:
  348. # if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
  349. typedef aux::replace_unnamed_arg< F,mpl::arg<1> > r0;
  350. typedef typename r0::type a0;
  351. typedef typename r0::next n1;
  352. typedef typename aux::resolve_bind_arg<a0,AUX778076_BIND_PARAMS(U)>::type f_;
  353. ///
  354. # else
  355. typedef typename aux::resolve_bind_arg<F,AUX778076_BIND_PARAMS(U)>::type f_;
  356. # endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT
  357. # if i_ > 0
  358. # define BOOST_PP_ITERATION_PARAMS_2 (3,(1, i_, <boost/mpl/bind.hpp>))
  359. # include BOOST_PP_ITERATE()
  360. # endif
  361. public:
  362. # define AUX778076_ARG(unused, i_, t) \
  363. BOOST_PP_COMMA_IF(i_) \
  364. typename BOOST_PP_CAT(t,BOOST_PP_INC(i_))::type \
  365. /**/
  366. typedef typename BOOST_PP_CAT(apply_wrap,i_)<
  367. f_
  368. BOOST_PP_COMMA_IF(i_) BOOST_MPL_PP_REPEAT(i_, AUX778076_ARG, t)
  369. >::type type;
  370. # undef AUX778076_ARG
  371. };
  372. };
  373. namespace aux {
  374. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  375. template<
  376. typename F AUX778076_BIND_N_PARAMS(i_, typename T), AUX778076_BIND_PARAMS(typename U)
  377. >
  378. struct resolve_bind_arg<
  379. BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T)>,AUX778076_BIND_PARAMS(U)
  380. >
  381. {
  382. typedef BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T)> f_;
  383. typedef typename AUX778076_APPLY<f_, AUX778076_BIND_PARAMS(U)>::type type;
  384. };
  385. #else
  386. template<
  387. typename F AUX778076_BIND_N_PARAMS(i_, typename T)
  388. >
  389. aux::yes_tag
  390. is_bind_helper(BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T)>*);
  391. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  392. } // namespace aux
  393. BOOST_MPL_AUX_ARITY_SPEC(BOOST_PP_INC(i_), BOOST_PP_CAT(bind,i_))
  394. BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(BOOST_PP_INC(i_), BOOST_PP_CAT(bind,i_))
  395. # if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
  396. # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  397. #if i_ == BOOST_MPL_LIMIT_METAFUNCTION_ARITY
  398. /// primary template (not a specialization!)
  399. template<
  400. typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM()
  401. >
  402. struct bind
  403. : BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T) >
  404. {
  405. };
  406. #else
  407. template<
  408. typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM()
  409. >
  410. struct bind< F AUX778076_BIND_N_SPEC_PARAMS(i_, T, na) >
  411. : BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T) >
  412. {
  413. };
  414. #endif
  415. # else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  416. namespace aux {
  417. template<>
  418. struct bind_chooser<i_>
  419. {
  420. template<
  421. typename F, AUX778076_BIND_PARAMS(typename T)
  422. >
  423. struct result_
  424. {
  425. typedef BOOST_PP_CAT(bind,i_)< F AUX778076_BIND_N_PARAMS(i_,T) > type;
  426. };
  427. };
  428. } // namespace aux
  429. # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  430. # endif // BOOST_MPL_CFG_NO_BIND_TEMPLATE
  431. #endif // AUX778076_SPEC_NAME
  432. # undef i_
  433. ///// iteration, depth == 2
  434. #elif BOOST_PP_ITERATION_DEPTH() == 2
  435. # define j_ BOOST_PP_FRAME_ITERATION(2)
  436. # if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
  437. typedef aux::replace_unnamed_arg< BOOST_PP_CAT(T,j_),BOOST_PP_CAT(n,j_) > BOOST_PP_CAT(r,j_);
  438. typedef typename BOOST_PP_CAT(r,j_)::type BOOST_PP_CAT(a,j_);
  439. typedef typename BOOST_PP_CAT(r,j_)::next BOOST_PP_CAT(n,BOOST_PP_INC(j_));
  440. typedef aux::resolve_bind_arg<BOOST_PP_CAT(a,j_), AUX778076_BIND_PARAMS(U)> BOOST_PP_CAT(t,j_);
  441. ///
  442. # else
  443. typedef aux::resolve_bind_arg< BOOST_PP_CAT(T,j_),AUX778076_BIND_PARAMS(U)> BOOST_PP_CAT(t,j_);
  444. # endif
  445. # undef j_
  446. #endif // BOOST_PP_ITERATION_DEPTH()
  447. #endif // BOOST_PP_IS_ITERATING