function_template.hpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158
  1. // Boost.Function library
  2. // Copyright Douglas Gregor 2001-2006
  3. // Copyright Emil Dotchevski 2007
  4. // Use, modification and distribution is subject to the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // For more information, see http://www.boost.org
  8. // Note: this header is a header template and must NOT have multiple-inclusion
  9. // protection.
  10. #include <boost/function/detail/prologue.hpp>
  11. #include <boost/detail/no_exceptions_support.hpp>
  12. #if defined(BOOST_MSVC)
  13. # pragma warning( push )
  14. # pragma warning( disable : 4127 ) // "conditional expression is constant"
  15. #endif
  16. #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
  17. #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
  18. #define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
  19. #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
  20. #define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
  21. #define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
  22. typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
  23. #define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
  24. // Comma if nonzero number of arguments
  25. #if BOOST_FUNCTION_NUM_ARGS == 0
  26. # define BOOST_FUNCTION_COMMA
  27. #else
  28. # define BOOST_FUNCTION_COMMA ,
  29. #endif // BOOST_FUNCTION_NUM_ARGS > 0
  30. // Class names used in this version of the code
  31. #define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
  32. #define BOOST_FUNCTION_FUNCTION_INVOKER \
  33. BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
  34. #define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
  35. BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
  36. #define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
  37. BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
  38. #define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
  39. BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
  40. #define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
  41. BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
  42. #define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
  43. BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
  44. #define BOOST_FUNCTION_MEMBER_INVOKER \
  45. BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
  46. #define BOOST_FUNCTION_VOID_MEMBER_INVOKER \
  47. BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
  48. #define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
  49. BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
  50. #define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
  51. BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
  52. #define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
  53. BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
  54. #define BOOST_FUNCTION_GET_MEMBER_INVOKER \
  55. BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS)
  56. #define BOOST_FUNCTION_GET_INVOKER \
  57. BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS)
  58. #define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
  59. #ifndef BOOST_NO_VOID_RETURNS
  60. # define BOOST_FUNCTION_VOID_RETURN_TYPE void
  61. # define BOOST_FUNCTION_RETURN(X) X
  62. #else
  63. # define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
  64. # define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
  65. #endif
  66. namespace boost {
  67. namespace detail {
  68. namespace function {
  69. template<
  70. typename FunctionPtr,
  71. typename R BOOST_FUNCTION_COMMA
  72. BOOST_FUNCTION_TEMPLATE_PARMS
  73. >
  74. struct BOOST_FUNCTION_FUNCTION_INVOKER
  75. {
  76. static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
  77. BOOST_FUNCTION_PARMS)
  78. {
  79. FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
  80. return f(BOOST_FUNCTION_ARGS);
  81. }
  82. };
  83. template<
  84. typename FunctionPtr,
  85. typename R BOOST_FUNCTION_COMMA
  86. BOOST_FUNCTION_TEMPLATE_PARMS
  87. >
  88. struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
  89. {
  90. static BOOST_FUNCTION_VOID_RETURN_TYPE
  91. invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
  92. BOOST_FUNCTION_PARMS)
  93. {
  94. FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
  95. BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
  96. }
  97. };
  98. template<
  99. typename FunctionObj,
  100. typename R BOOST_FUNCTION_COMMA
  101. BOOST_FUNCTION_TEMPLATE_PARMS
  102. >
  103. struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
  104. {
  105. static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
  106. BOOST_FUNCTION_PARMS)
  107. {
  108. FunctionObj* f;
  109. if (function_allows_small_object_optimization<FunctionObj>::value)
  110. f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
  111. else
  112. f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
  113. return (*f)(BOOST_FUNCTION_ARGS);
  114. }
  115. };
  116. template<
  117. typename FunctionObj,
  118. typename R BOOST_FUNCTION_COMMA
  119. BOOST_FUNCTION_TEMPLATE_PARMS
  120. >
  121. struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
  122. {
  123. static BOOST_FUNCTION_VOID_RETURN_TYPE
  124. invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
  125. BOOST_FUNCTION_PARMS)
  126. {
  127. FunctionObj* f;
  128. if (function_allows_small_object_optimization<FunctionObj>::value)
  129. f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
  130. else
  131. f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
  132. BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
  133. }
  134. };
  135. template<
  136. typename FunctionObj,
  137. typename R BOOST_FUNCTION_COMMA
  138. BOOST_FUNCTION_TEMPLATE_PARMS
  139. >
  140. struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
  141. {
  142. static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
  143. BOOST_FUNCTION_PARMS)
  144. {
  145. FunctionObj* f =
  146. reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
  147. return (*f)(BOOST_FUNCTION_ARGS);
  148. }
  149. };
  150. template<
  151. typename FunctionObj,
  152. typename R BOOST_FUNCTION_COMMA
  153. BOOST_FUNCTION_TEMPLATE_PARMS
  154. >
  155. struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
  156. {
  157. static BOOST_FUNCTION_VOID_RETURN_TYPE
  158. invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
  159. BOOST_FUNCTION_PARMS)
  160. {
  161. FunctionObj* f =
  162. reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
  163. BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
  164. }
  165. };
  166. #if BOOST_FUNCTION_NUM_ARGS > 0
  167. /* Handle invocation of member pointers. */
  168. template<
  169. typename MemberPtr,
  170. typename R BOOST_FUNCTION_COMMA
  171. BOOST_FUNCTION_TEMPLATE_PARMS
  172. >
  173. struct BOOST_FUNCTION_MEMBER_INVOKER
  174. {
  175. static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
  176. BOOST_FUNCTION_PARMS)
  177. {
  178. MemberPtr* f =
  179. reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
  180. return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
  181. }
  182. };
  183. template<
  184. typename MemberPtr,
  185. typename R BOOST_FUNCTION_COMMA
  186. BOOST_FUNCTION_TEMPLATE_PARMS
  187. >
  188. struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
  189. {
  190. static BOOST_FUNCTION_VOID_RETURN_TYPE
  191. invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
  192. BOOST_FUNCTION_PARMS)
  193. {
  194. MemberPtr* f =
  195. reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
  196. BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
  197. }
  198. };
  199. #endif
  200. template<
  201. typename FunctionPtr,
  202. typename R BOOST_FUNCTION_COMMA
  203. BOOST_FUNCTION_TEMPLATE_PARMS
  204. >
  205. struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
  206. {
  207. typedef typename mpl::if_c<(is_void<R>::value),
  208. BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
  209. FunctionPtr,
  210. R BOOST_FUNCTION_COMMA
  211. BOOST_FUNCTION_TEMPLATE_ARGS
  212. >,
  213. BOOST_FUNCTION_FUNCTION_INVOKER<
  214. FunctionPtr,
  215. R BOOST_FUNCTION_COMMA
  216. BOOST_FUNCTION_TEMPLATE_ARGS
  217. >
  218. >::type type;
  219. };
  220. template<
  221. typename FunctionObj,
  222. typename R BOOST_FUNCTION_COMMA
  223. BOOST_FUNCTION_TEMPLATE_PARMS
  224. >
  225. struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
  226. {
  227. typedef typename mpl::if_c<(is_void<R>::value),
  228. BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
  229. FunctionObj,
  230. R BOOST_FUNCTION_COMMA
  231. BOOST_FUNCTION_TEMPLATE_ARGS
  232. >,
  233. BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
  234. FunctionObj,
  235. R BOOST_FUNCTION_COMMA
  236. BOOST_FUNCTION_TEMPLATE_ARGS
  237. >
  238. >::type type;
  239. };
  240. template<
  241. typename FunctionObj,
  242. typename R BOOST_FUNCTION_COMMA
  243. BOOST_FUNCTION_TEMPLATE_PARMS
  244. >
  245. struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
  246. {
  247. typedef typename mpl::if_c<(is_void<R>::value),
  248. BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
  249. FunctionObj,
  250. R BOOST_FUNCTION_COMMA
  251. BOOST_FUNCTION_TEMPLATE_ARGS
  252. >,
  253. BOOST_FUNCTION_FUNCTION_REF_INVOKER<
  254. FunctionObj,
  255. R BOOST_FUNCTION_COMMA
  256. BOOST_FUNCTION_TEMPLATE_ARGS
  257. >
  258. >::type type;
  259. };
  260. #if BOOST_FUNCTION_NUM_ARGS > 0
  261. /* Retrieve the appropriate invoker for a member pointer. */
  262. template<
  263. typename MemberPtr,
  264. typename R BOOST_FUNCTION_COMMA
  265. BOOST_FUNCTION_TEMPLATE_PARMS
  266. >
  267. struct BOOST_FUNCTION_GET_MEMBER_INVOKER
  268. {
  269. typedef typename mpl::if_c<(is_void<R>::value),
  270. BOOST_FUNCTION_VOID_MEMBER_INVOKER<
  271. MemberPtr,
  272. R BOOST_FUNCTION_COMMA
  273. BOOST_FUNCTION_TEMPLATE_ARGS
  274. >,
  275. BOOST_FUNCTION_MEMBER_INVOKER<
  276. MemberPtr,
  277. R BOOST_FUNCTION_COMMA
  278. BOOST_FUNCTION_TEMPLATE_ARGS
  279. >
  280. >::type type;
  281. };
  282. #endif
  283. /* Given the tag returned by get_function_tag, retrieve the
  284. actual invoker that will be used for the given function
  285. object.
  286. Each specialization contains an "apply" nested class template
  287. that accepts the function object, return type, function
  288. argument types, and allocator. The resulting "apply" class
  289. contains two typedefs, "invoker_type" and "manager_type",
  290. which correspond to the invoker and manager types. */
  291. template<typename Tag>
  292. struct BOOST_FUNCTION_GET_INVOKER { };
  293. /* Retrieve the invoker for a function pointer. */
  294. template<>
  295. struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
  296. {
  297. template<typename FunctionPtr,
  298. typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
  299. struct apply
  300. {
  301. typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
  302. FunctionPtr,
  303. R BOOST_FUNCTION_COMMA
  304. BOOST_FUNCTION_TEMPLATE_ARGS
  305. >::type
  306. invoker_type;
  307. typedef functor_manager<FunctionPtr> manager_type;
  308. };
  309. template<typename FunctionPtr,
  310. typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
  311. typename Allocator>
  312. struct apply_a
  313. {
  314. typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
  315. FunctionPtr,
  316. R BOOST_FUNCTION_COMMA
  317. BOOST_FUNCTION_TEMPLATE_ARGS
  318. >::type
  319. invoker_type;
  320. typedef functor_manager<FunctionPtr> manager_type;
  321. };
  322. };
  323. #if BOOST_FUNCTION_NUM_ARGS > 0
  324. /* Retrieve the invoker for a member pointer. */
  325. template<>
  326. struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
  327. {
  328. template<typename MemberPtr,
  329. typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
  330. struct apply
  331. {
  332. typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
  333. MemberPtr,
  334. R BOOST_FUNCTION_COMMA
  335. BOOST_FUNCTION_TEMPLATE_ARGS
  336. >::type
  337. invoker_type;
  338. typedef functor_manager<MemberPtr> manager_type;
  339. };
  340. template<typename MemberPtr,
  341. typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
  342. typename Allocator>
  343. struct apply_a
  344. {
  345. typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
  346. MemberPtr,
  347. R BOOST_FUNCTION_COMMA
  348. BOOST_FUNCTION_TEMPLATE_ARGS
  349. >::type
  350. invoker_type;
  351. typedef functor_manager<MemberPtr> manager_type;
  352. };
  353. };
  354. #endif
  355. /* Retrieve the invoker for a function object. */
  356. template<>
  357. struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
  358. {
  359. template<typename FunctionObj,
  360. typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
  361. struct apply
  362. {
  363. typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
  364. FunctionObj,
  365. R BOOST_FUNCTION_COMMA
  366. BOOST_FUNCTION_TEMPLATE_ARGS
  367. >::type
  368. invoker_type;
  369. typedef functor_manager<FunctionObj> manager_type;
  370. };
  371. template<typename FunctionObj,
  372. typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
  373. typename Allocator>
  374. struct apply_a
  375. {
  376. typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
  377. FunctionObj,
  378. R BOOST_FUNCTION_COMMA
  379. BOOST_FUNCTION_TEMPLATE_ARGS
  380. >::type
  381. invoker_type;
  382. typedef functor_manager_a<FunctionObj, Allocator> manager_type;
  383. };
  384. };
  385. /* Retrieve the invoker for a reference to a function object. */
  386. template<>
  387. struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
  388. {
  389. template<typename RefWrapper,
  390. typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
  391. struct apply
  392. {
  393. typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
  394. typename RefWrapper::type,
  395. R BOOST_FUNCTION_COMMA
  396. BOOST_FUNCTION_TEMPLATE_ARGS
  397. >::type
  398. invoker_type;
  399. typedef reference_manager<typename RefWrapper::type> manager_type;
  400. };
  401. template<typename RefWrapper,
  402. typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
  403. typename Allocator>
  404. struct apply_a
  405. {
  406. typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
  407. typename RefWrapper::type,
  408. R BOOST_FUNCTION_COMMA
  409. BOOST_FUNCTION_TEMPLATE_ARGS
  410. >::type
  411. invoker_type;
  412. typedef reference_manager<typename RefWrapper::type> manager_type;
  413. };
  414. };
  415. /**
  416. * vtable for a specific boost::function instance. This
  417. * structure must be an aggregate so that we can use static
  418. * initialization in boost::function's assign_to and assign_to_a
  419. * members. It therefore cannot have any constructors,
  420. * destructors, base classes, etc.
  421. */
  422. template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
  423. struct BOOST_FUNCTION_VTABLE
  424. {
  425. #ifndef BOOST_NO_VOID_RETURNS
  426. typedef R result_type;
  427. #else
  428. typedef typename function_return_type<R>::type result_type;
  429. #endif // BOOST_NO_VOID_RETURNS
  430. typedef result_type (*invoker_type)(function_buffer&
  431. BOOST_FUNCTION_COMMA
  432. BOOST_FUNCTION_TEMPLATE_ARGS);
  433. template<typename F>
  434. bool assign_to(F f, function_buffer& functor)
  435. {
  436. typedef typename get_function_tag<F>::type tag;
  437. return assign_to(f, functor, tag());
  438. }
  439. template<typename F,typename Allocator>
  440. bool assign_to_a(F f, function_buffer& functor, Allocator a)
  441. {
  442. typedef typename get_function_tag<F>::type tag;
  443. return assign_to_a(f, functor, a, tag());
  444. }
  445. void clear(function_buffer& functor)
  446. {
  447. if (base.manager)
  448. base.manager(functor, functor, destroy_functor_tag);
  449. }
  450. private:
  451. // Function pointers
  452. template<typename FunctionPtr>
  453. bool
  454. assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag)
  455. {
  456. this->clear(functor);
  457. if (f) {
  458. // should be a reinterpret cast, but some compilers insist
  459. // on giving cv-qualifiers to free functions
  460. functor.func_ptr = (void (*)())(f);
  461. return true;
  462. } else {
  463. return false;
  464. }
  465. }
  466. template<typename FunctionPtr,typename Allocator>
  467. bool
  468. assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag)
  469. {
  470. return assign_to(f,functor,function_ptr_tag());
  471. }
  472. // Member pointers
  473. #if BOOST_FUNCTION_NUM_ARGS > 0
  474. template<typename MemberPtr>
  475. bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
  476. {
  477. // DPG TBD: Add explicit support for member function
  478. // objects, so we invoke through mem_fn() but we retain the
  479. // right target_type() values.
  480. if (f) {
  481. this->assign_to(mem_fn(f), functor);
  482. return true;
  483. } else {
  484. return false;
  485. }
  486. }
  487. template<typename MemberPtr,typename Allocator>
  488. bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag)
  489. {
  490. // DPG TBD: Add explicit support for member function
  491. // objects, so we invoke through mem_fn() but we retain the
  492. // right target_type() values.
  493. if (f) {
  494. this->assign_to_a(mem_fn(f), functor, a);
  495. return true;
  496. } else {
  497. return false;
  498. }
  499. }
  500. #endif // BOOST_FUNCTION_NUM_ARGS > 0
  501. // Function objects
  502. // Assign to a function object using the small object optimization
  503. template<typename FunctionObj>
  504. void
  505. assign_functor(FunctionObj f, function_buffer& functor, mpl::true_)
  506. {
  507. new ((void*)&functor.data) FunctionObj(f);
  508. }
  509. template<typename FunctionObj,typename Allocator>
  510. void
  511. assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_)
  512. {
  513. assign_functor(f,functor,mpl::true_());
  514. }
  515. // Assign to a function object allocated on the heap.
  516. template<typename FunctionObj>
  517. void
  518. assign_functor(FunctionObj f, function_buffer& functor, mpl::false_)
  519. {
  520. functor.obj_ptr = new FunctionObj(f);
  521. }
  522. template<typename FunctionObj,typename Allocator>
  523. void
  524. assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_)
  525. {
  526. typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
  527. typedef typename Allocator::template rebind<functor_wrapper_type>::other
  528. wrapper_allocator_type;
  529. typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
  530. wrapper_allocator_type wrapper_allocator(a);
  531. wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
  532. wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
  533. functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
  534. functor.obj_ptr = new_f;
  535. }
  536. template<typename FunctionObj>
  537. bool
  538. assign_to(FunctionObj f, function_buffer& functor, function_obj_tag)
  539. {
  540. if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
  541. assign_functor(f, functor,
  542. mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
  543. return true;
  544. } else {
  545. return false;
  546. }
  547. }
  548. template<typename FunctionObj,typename Allocator>
  549. bool
  550. assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag)
  551. {
  552. if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
  553. assign_functor_a(f, functor, a,
  554. mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
  555. return true;
  556. } else {
  557. return false;
  558. }
  559. }
  560. // Reference to a function object
  561. template<typename FunctionObj>
  562. bool
  563. assign_to(const reference_wrapper<FunctionObj>& f,
  564. function_buffer& functor, function_obj_ref_tag)
  565. {
  566. functor.obj_ref.obj_ptr = (void *)f.get_pointer();
  567. functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
  568. functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
  569. return true;
  570. }
  571. template<typename FunctionObj,typename Allocator>
  572. bool
  573. assign_to_a(const reference_wrapper<FunctionObj>& f,
  574. function_buffer& functor, Allocator, function_obj_ref_tag)
  575. {
  576. return assign_to(f,functor,function_obj_ref_tag());
  577. }
  578. public:
  579. vtable_base base;
  580. invoker_type invoker;
  581. };
  582. } // end namespace function
  583. } // end namespace detail
  584. template<
  585. typename R BOOST_FUNCTION_COMMA
  586. BOOST_FUNCTION_TEMPLATE_PARMS
  587. >
  588. class BOOST_FUNCTION_FUNCTION : public function_base
  589. #if BOOST_FUNCTION_NUM_ARGS == 1
  590. , public std::unary_function<T0,R>
  591. #elif BOOST_FUNCTION_NUM_ARGS == 2
  592. , public std::binary_function<T0,T1,R>
  593. #endif
  594. {
  595. public:
  596. #ifndef BOOST_NO_VOID_RETURNS
  597. typedef R result_type;
  598. #else
  599. typedef typename boost::detail::function::function_return_type<R>::type
  600. result_type;
  601. #endif // BOOST_NO_VOID_RETURNS
  602. private:
  603. typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
  604. R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
  605. vtable_type;
  606. vtable_type* get_vtable() const {
  607. return reinterpret_cast<vtable_type*>(
  608. reinterpret_cast<std::size_t>(vtable) & ~(std::size_t)0x01);
  609. }
  610. struct clear_type {};
  611. public:
  612. BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
  613. // add signature for boost::lambda
  614. template<typename Args>
  615. struct sig
  616. {
  617. typedef result_type type;
  618. };
  619. #if BOOST_FUNCTION_NUM_ARGS == 1
  620. typedef T0 argument_type;
  621. #elif BOOST_FUNCTION_NUM_ARGS == 2
  622. typedef T0 first_argument_type;
  623. typedef T1 second_argument_type;
  624. #endif
  625. BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
  626. BOOST_FUNCTION_ARG_TYPES
  627. typedef BOOST_FUNCTION_FUNCTION self_type;
  628. BOOST_FUNCTION_FUNCTION() : function_base() { }
  629. // MSVC chokes if the following two constructors are collapsed into
  630. // one with a default parameter.
  631. template<typename Functor>
  632. BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
  633. #ifndef BOOST_NO_SFINAE
  634. ,typename enable_if_c<
  635. (boost::type_traits::ice_not<
  636. (is_integral<Functor>::value)>::value),
  637. int>::type = 0
  638. #endif // BOOST_NO_SFINAE
  639. ) :
  640. function_base()
  641. {
  642. this->assign_to(f);
  643. }
  644. template<typename Functor,typename Allocator>
  645. BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
  646. #ifndef BOOST_NO_SFINAE
  647. ,typename enable_if_c<
  648. (boost::type_traits::ice_not<
  649. (is_integral<Functor>::value)>::value),
  650. int>::type = 0
  651. #endif // BOOST_NO_SFINAE
  652. ) :
  653. function_base()
  654. {
  655. this->assign_to_a(f,a);
  656. }
  657. #ifndef BOOST_NO_SFINAE
  658. BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
  659. #else
  660. BOOST_FUNCTION_FUNCTION(int zero) : function_base()
  661. {
  662. BOOST_ASSERT(zero == 0);
  663. }
  664. #endif
  665. BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
  666. {
  667. this->assign_to_own(f);
  668. }
  669. ~BOOST_FUNCTION_FUNCTION() { clear(); }
  670. #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  671. // MSVC 6.0 and prior require all definitions to be inline, but
  672. // these definitions can become very costly.
  673. result_type operator()(BOOST_FUNCTION_PARMS) const
  674. {
  675. if (this->empty())
  676. boost::throw_exception(bad_function_call());
  677. return get_vtable()->invoker
  678. (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
  679. }
  680. #else
  681. result_type operator()(BOOST_FUNCTION_PARMS) const;
  682. #endif
  683. // The distinction between when to use BOOST_FUNCTION_FUNCTION and
  684. // when to use self_type is obnoxious. MSVC cannot handle self_type as
  685. // the return type of these assignment operators, but Borland C++ cannot
  686. // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
  687. // construct.
  688. template<typename Functor>
  689. #ifndef BOOST_NO_SFINAE
  690. typename enable_if_c<
  691. (boost::type_traits::ice_not<
  692. (is_integral<Functor>::value)>::value),
  693. BOOST_FUNCTION_FUNCTION&>::type
  694. #else
  695. BOOST_FUNCTION_FUNCTION&
  696. #endif
  697. operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
  698. {
  699. this->clear();
  700. BOOST_TRY {
  701. this->assign_to(f);
  702. } BOOST_CATCH (...) {
  703. vtable = 0;
  704. BOOST_RETHROW;
  705. }
  706. BOOST_CATCH_END
  707. return *this;
  708. }
  709. template<typename Functor,typename Allocator>
  710. void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
  711. {
  712. this->clear();
  713. BOOST_TRY{
  714. this->assign_to_a(f,a);
  715. } BOOST_CATCH (...) {
  716. vtable = 0;
  717. BOOST_RETHROW;
  718. }
  719. BOOST_CATCH_END
  720. }
  721. #ifndef BOOST_NO_SFINAE
  722. BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
  723. {
  724. this->clear();
  725. return *this;
  726. }
  727. #else
  728. BOOST_FUNCTION_FUNCTION& operator=(int zero)
  729. {
  730. BOOST_ASSERT(zero == 0);
  731. this->clear();
  732. return *this;
  733. }
  734. #endif
  735. // Assignment from another BOOST_FUNCTION_FUNCTION
  736. BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
  737. {
  738. if (&f == this)
  739. return *this;
  740. this->clear();
  741. BOOST_TRY {
  742. this->assign_to_own(f);
  743. } BOOST_CATCH (...) {
  744. vtable = 0;
  745. BOOST_RETHROW;
  746. }
  747. BOOST_CATCH_END
  748. return *this;
  749. }
  750. void swap(BOOST_FUNCTION_FUNCTION& other)
  751. {
  752. if (&other == this)
  753. return;
  754. BOOST_FUNCTION_FUNCTION tmp;
  755. tmp.move_assign(*this);
  756. this->move_assign(other);
  757. other.move_assign(tmp);
  758. }
  759. // Clear out a target, if there is one
  760. void clear()
  761. {
  762. if (vtable) {
  763. if (!this->has_trivial_copy_and_destroy())
  764. get_vtable()->clear(this->functor);
  765. vtable = 0;
  766. }
  767. }
  768. #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
  769. // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
  770. operator bool () const { return !this->empty(); }
  771. #else
  772. private:
  773. struct dummy {
  774. void nonnull() {};
  775. };
  776. typedef void (dummy::*safe_bool)();
  777. public:
  778. operator safe_bool () const
  779. { return (this->empty())? 0 : &dummy::nonnull; }
  780. bool operator!() const
  781. { return this->empty(); }
  782. #endif
  783. private:
  784. void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
  785. {
  786. if (!f.empty()) {
  787. this->vtable = f.vtable;
  788. if (this->has_trivial_copy_and_destroy())
  789. this->functor = f.functor;
  790. else
  791. get_vtable()->base.manager(f.functor, this->functor,
  792. boost::detail::function::clone_functor_tag);
  793. }
  794. }
  795. template<typename Functor>
  796. void assign_to(Functor f)
  797. {
  798. using detail::function::vtable_base;
  799. typedef typename detail::function::get_function_tag<Functor>::type tag;
  800. typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
  801. typedef typename get_invoker::
  802. template apply<Functor, R BOOST_FUNCTION_COMMA
  803. BOOST_FUNCTION_TEMPLATE_ARGS>
  804. handler_type;
  805. typedef typename handler_type::invoker_type invoker_type;
  806. typedef typename handler_type::manager_type manager_type;
  807. // Note: it is extremely important that this initialization use
  808. // static initialization. Otherwise, we will have a race
  809. // condition here in multi-threaded code. See
  810. // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
  811. static vtable_type stored_vtable =
  812. { { &manager_type::manage }, &invoker_type::invoke };
  813. if (stored_vtable.assign_to(f, functor)) {
  814. std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
  815. if (boost::has_trivial_copy_constructor<Functor>::value &&
  816. boost::has_trivial_destructor<Functor>::value &&
  817. detail::function::function_allows_small_object_optimization<Functor>::value)
  818. value |= (std::size_t)0x01;
  819. vtable = reinterpret_cast<detail::function::vtable_base *>(value);
  820. } else
  821. vtable = 0;
  822. }
  823. template<typename Functor,typename Allocator>
  824. void assign_to_a(Functor f,Allocator a)
  825. {
  826. using detail::function::vtable_base;
  827. typedef typename detail::function::get_function_tag<Functor>::type tag;
  828. typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
  829. typedef typename get_invoker::
  830. template apply_a<Functor, R BOOST_FUNCTION_COMMA
  831. BOOST_FUNCTION_TEMPLATE_ARGS,
  832. Allocator>
  833. handler_type;
  834. typedef typename handler_type::invoker_type invoker_type;
  835. typedef typename handler_type::manager_type manager_type;
  836. // Note: it is extremely important that this initialization use
  837. // static initialization. Otherwise, we will have a race
  838. // condition here in multi-threaded code. See
  839. // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
  840. static vtable_type stored_vtable =
  841. { { &manager_type::manage }, &invoker_type::invoke };
  842. if (stored_vtable.assign_to_a(f, functor, a)) {
  843. std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
  844. if (boost::has_trivial_copy_constructor<Functor>::value &&
  845. boost::has_trivial_destructor<Functor>::value &&
  846. detail::function::function_allows_small_object_optimization<Functor>::value)
  847. value |= (std::size_t)0x01;
  848. vtable = reinterpret_cast<detail::function::vtable_base *>(value);
  849. } else
  850. vtable = 0;
  851. }
  852. // Moves the value from the specified argument to *this. If the argument
  853. // has its function object allocated on the heap, move_assign will pass
  854. // its buffer to *this, and set the argument's buffer pointer to NULL.
  855. void move_assign(BOOST_FUNCTION_FUNCTION& f)
  856. {
  857. if (&f == this)
  858. return;
  859. BOOST_TRY {
  860. if (!f.empty()) {
  861. this->vtable = f.vtable;
  862. if (this->has_trivial_copy_and_destroy())
  863. this->functor = f.functor;
  864. else
  865. get_vtable()->base.manager(f.functor, this->functor,
  866. boost::detail::function::move_functor_tag);
  867. f.vtable = 0;
  868. } else {
  869. clear();
  870. }
  871. } BOOST_CATCH (...) {
  872. vtable = 0;
  873. BOOST_RETHROW;
  874. }
  875. BOOST_CATCH_END
  876. }
  877. };
  878. template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
  879. inline void swap(BOOST_FUNCTION_FUNCTION<
  880. R BOOST_FUNCTION_COMMA
  881. BOOST_FUNCTION_TEMPLATE_ARGS
  882. >& f1,
  883. BOOST_FUNCTION_FUNCTION<
  884. R BOOST_FUNCTION_COMMA
  885. BOOST_FUNCTION_TEMPLATE_ARGS
  886. >& f2)
  887. {
  888. f1.swap(f2);
  889. }
  890. #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
  891. template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
  892. typename BOOST_FUNCTION_FUNCTION<
  893. R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type
  894. inline
  895. BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
  896. ::operator()(BOOST_FUNCTION_PARMS) const
  897. {
  898. if (this->empty())
  899. boost::throw_exception(bad_function_call());
  900. return get_vtable()->invoker
  901. (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
  902. }
  903. #endif
  904. // Poison comparisons between boost::function objects of the same type.
  905. template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
  906. void operator==(const BOOST_FUNCTION_FUNCTION<
  907. R BOOST_FUNCTION_COMMA
  908. BOOST_FUNCTION_TEMPLATE_ARGS>&,
  909. const BOOST_FUNCTION_FUNCTION<
  910. R BOOST_FUNCTION_COMMA
  911. BOOST_FUNCTION_TEMPLATE_ARGS>&);
  912. template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
  913. void operator!=(const BOOST_FUNCTION_FUNCTION<
  914. R BOOST_FUNCTION_COMMA
  915. BOOST_FUNCTION_TEMPLATE_ARGS>&,
  916. const BOOST_FUNCTION_FUNCTION<
  917. R BOOST_FUNCTION_COMMA
  918. BOOST_FUNCTION_TEMPLATE_ARGS>& );
  919. #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
  920. #if BOOST_FUNCTION_NUM_ARGS == 0
  921. #define BOOST_FUNCTION_PARTIAL_SPEC R (void)
  922. #else
  923. #define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
  924. #endif
  925. template<typename R BOOST_FUNCTION_COMMA
  926. BOOST_FUNCTION_TEMPLATE_PARMS>
  927. class function<BOOST_FUNCTION_PARTIAL_SPEC>
  928. : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
  929. {
  930. typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
  931. typedef function self_type;
  932. struct clear_type {};
  933. public:
  934. function() : base_type() {}
  935. template<typename Functor>
  936. function(Functor f
  937. #ifndef BOOST_NO_SFINAE
  938. ,typename enable_if_c<
  939. (boost::type_traits::ice_not<
  940. (is_integral<Functor>::value)>::value),
  941. int>::type = 0
  942. #endif
  943. ) :
  944. base_type(f)
  945. {
  946. }
  947. template<typename Functor,typename Allocator>
  948. function(Functor f, Allocator a
  949. #ifndef BOOST_NO_SFINAE
  950. ,typename enable_if_c<
  951. (boost::type_traits::ice_not<
  952. (is_integral<Functor>::value)>::value),
  953. int>::type = 0
  954. #endif
  955. ) :
  956. base_type(f,a)
  957. {
  958. }
  959. #ifndef BOOST_NO_SFINAE
  960. function(clear_type*) : base_type() {}
  961. #endif
  962. function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
  963. function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
  964. self_type& operator=(const self_type& f)
  965. {
  966. self_type(f).swap(*this);
  967. return *this;
  968. }
  969. template<typename Functor>
  970. #ifndef BOOST_NO_SFINAE
  971. typename enable_if_c<
  972. (boost::type_traits::ice_not<
  973. (is_integral<Functor>::value)>::value),
  974. self_type&>::type
  975. #else
  976. self_type&
  977. #endif
  978. operator=(Functor f)
  979. {
  980. self_type(f).swap(*this);
  981. return *this;
  982. }
  983. #ifndef BOOST_NO_SFINAE
  984. self_type& operator=(clear_type*)
  985. {
  986. this->clear();
  987. return *this;
  988. }
  989. #endif
  990. self_type& operator=(const base_type& f)
  991. {
  992. self_type(f).swap(*this);
  993. return *this;
  994. }
  995. };
  996. #undef BOOST_FUNCTION_PARTIAL_SPEC
  997. #endif // have partial specialization
  998. } // end namespace boost
  999. // Cleanup after ourselves...
  1000. #undef BOOST_FUNCTION_VTABLE
  1001. #undef BOOST_FUNCTION_COMMA
  1002. #undef BOOST_FUNCTION_FUNCTION
  1003. #undef BOOST_FUNCTION_FUNCTION_INVOKER
  1004. #undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
  1005. #undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
  1006. #undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
  1007. #undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
  1008. #undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
  1009. #undef BOOST_FUNCTION_MEMBER_INVOKER
  1010. #undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
  1011. #undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
  1012. #undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
  1013. #undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
  1014. #undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
  1015. #undef BOOST_FUNCTION_GET_INVOKER
  1016. #undef BOOST_FUNCTION_TEMPLATE_PARMS
  1017. #undef BOOST_FUNCTION_TEMPLATE_ARGS
  1018. #undef BOOST_FUNCTION_PARMS
  1019. #undef BOOST_FUNCTION_PARM
  1020. #undef BOOST_FUNCTION_ARGS
  1021. #undef BOOST_FUNCTION_ARG_TYPE
  1022. #undef BOOST_FUNCTION_ARG_TYPES
  1023. #undef BOOST_FUNCTION_VOID_RETURN_TYPE
  1024. #undef BOOST_FUNCTION_RETURN
  1025. #if defined(BOOST_MSVC)
  1026. # pragma warning( pop )
  1027. #endif