index.rst 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. The Boost Parameter Library Python Binding Documentation
  3. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4. :Authors: David Abrahams, Daniel Wallin
  5. :Contact: dave@boost-consulting.com, daniel@boostpro.com
  6. :organization: `BoostPro Computing`_
  7. :date: $Date$
  8. :copyright: Copyright David Abrahams, Daniel Wallin
  9. 2005-2009. Distributed under the Boost Software License,
  10. Version 1.0. (See accompanying file LICENSE_1_0.txt
  11. or copy at http://www.boost.org/LICENSE_1_0.txt)
  12. :abstract: Makes it possible to bind Boost.Parameter-enabled
  13. functions, operators and constructors to Python.
  14. |(logo)|__
  15. .. |(logo)| image:: ../../../../boost.png
  16. :alt: Boost
  17. __ ../../../../index.htm
  18. .. _`BoostPro Computing`: http://www.boostpro.com
  19. .. role:: class
  20. :class: class
  21. .. role:: concept
  22. :class: concept
  23. .. role:: function
  24. :class: function
  25. .. |ParameterSpec| replace:: :concept:`ParameterSpec`
  26. .. contents::
  27. :depth: 1
  28. Introduction
  29. ------------
  30. ``boost/parameter/python.hpp`` introduces a group of |def_visitors|_ that can
  31. be used to easily expose Boost.Parameter-enabled member functions to Python with
  32. Boost.Python. It also provides a function template ``def()`` that can be used
  33. to expose Boost.Parameter-enabled free functions.
  34. .. |def_visitor| replace:: ``def_visitor``
  35. .. |def_visitors| replace:: ``def_visitors``
  36. .. _def_visitor: def_visitors_
  37. .. _def_visitors: ../../../python/doc/v2/def_visitor.html
  38. When binding a Boost.Parameter enabled function, the keyword tags
  39. must be specified. Additionally, because Boost.Parameter enabled
  40. functions are templates, the desired function signature must be
  41. specified.
  42. .. The keyword tags are specified as an `MPL Sequence`_, using the
  43. pointer qualifications described in |ParameterSpec|_ below. The
  44. signature is also specifid as an `MPL sequence`_ of parameter
  45. types. Additionally, ``boost::parameter::python::function`` and
  46. ``boost::parameter::python::def`` requires a class with forwarding
  47. overloads. We will take a closer look at how this is done in the
  48. tutorial section below.
  49. The keyword tags and associated argument types are specified as an `MPL
  50. Sequence`_, using the function type syntax described in |ParameterSpec|_
  51. below. Additionally, ``boost::parameter::python::function`` and
  52. ``boost::parameter::python::def`` requires a class with forwarding overloads.
  53. We will take a closer look at how this is done in the tutorial section below.
  54. .. The last two sentences are terribly vague. Which namespace is
  55. .. ``function`` in? Isn't the return type always needed? What
  56. .. else are we going to do other than pass these sequences to
  57. .. function?
  58. .. _`MPL Sequence`: ../../../mpl/doc/refmanual/sequences.html
  59. .. _parameterspec: `concept ParameterSpec`_
  60. Tutorial
  61. --------
  62. In this section we will outline the steps needed to bind a simple
  63. Boost.Parameter-enabled member function to Python. Knowledge of the
  64. Boost.Parameter macros_ are required to understand this section.
  65. .. _macros: index.html
  66. The class and member function we are interested in binding looks
  67. like this:
  68. .. parsed-literal::
  69. #include <boost/parameter/keyword.hpp>
  70. #include <boost/parameter/preprocessor.hpp>
  71. #include <boost/parameter/python.hpp>
  72. #include <boost/python.hpp>
  73. // First the keywords
  74. BOOST_PARAMETER_KEYWORD(tag, title)
  75. BOOST_PARAMETER_KEYWORD(tag, width)
  76. BOOST_PARAMETER_KEYWORD(tag, height)
  77. class window
  78. {
  79. public:
  80. BOOST_PARAMETER_MEMBER_FUNCTION(
  81. (void), open, tag,
  82. (required (title, (std::string)))
  83. (optional (width, (unsigned), 400)
  84. (height, (unsigned), 400))
  85. )
  86. {
  87. *… function implementation …*
  88. }
  89. };
  90. .. @example.prepend('#include <cassert>')
  91. .. @example.replace_emphasis('''
  92. assert(title == "foo");
  93. assert(height == 20);
  94. assert(width == 400);
  95. ''')
  96. It defines a set of overloaded member functions called ``open`` with one
  97. required parameter and two optional ones. To bind this member function to
  98. Python we use the binding utility ``boost::parameter::python::function``.
  99. ``boost::parameter::python::function`` is a |def_visitor|_ that we'll instantiate
  100. and pass to ``boost::python::class_::def()``.
  101. To use ``boost::parameter::python::function`` we first need to define
  102. a class with forwarding overloads. This is needed because ``window::open()``
  103. is a function template, so we can't refer to it in any other way.
  104. ::
  105. struct open_fwd
  106. {
  107. template <class A0, class A1, class A2>
  108. void operator()(
  109. boost::type<void>, window& self
  110. , A0 const& a0, A1 const& a1, A2 const& a2
  111. )
  112. {
  113. self.open(a0, a1, a2);
  114. }
  115. };
  116. The first parameter, ``boost::type<void>``, tells the forwarding overload
  117. what the return type should be. In this case we know that it's always void
  118. but in some cases, when we are exporting several specializations of a
  119. Boost.Parameter-enabled template, we need to use that parameter to
  120. deduce the return type.
  121. ``window::open()`` takes a total of 3 parameters, so the forwarding function
  122. needs to take three parameters as well.
  123. .. Note::
  124. We only need one overload in the forwarding class, despite the
  125. fact that there are two optional parameters. There are special
  126. circumstances when several overload are needed; see
  127. `special keywords`_.
  128. Next we'll define the module and export the class:
  129. ::
  130. BOOST_PYTHON_MODULE(my_module)
  131. {
  132. using namespace boost::python;
  133. namespace py = boost::parameter::python;
  134. namespace mpl = boost::mpl;
  135. class_<window>("window")
  136. .def(
  137. "open", py::function<
  138. open_fwd
  139. , mpl::vector<
  140. void
  141. , tag::title(std::string)
  142. , tag::width*(unsigned)
  143. , tag::height*(unsigned)
  144. >
  145. >()
  146. );
  147. }
  148. .. @jam_prefix.append('import python ;')
  149. .. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
  150. .. @my_module = build(
  151. output = 'my_module'
  152. , target_rule = 'python-extension'
  153. , input = '/boost/python//boost_python'
  154. , howmany = 'all'
  155. )
  156. .. @del jam_prefix[:]
  157. ``py::function`` is passed two parameters. The first one is the class with
  158. forwarding overloads that we defined earlier. The second one is an `MPL
  159. Sequence`_ with the keyword tag types and argument types for the function
  160. specified as function types. The pointer syntax used in ``tag::width*`` and
  161. ``tag::height*`` means that the parameter is optional. The first element of
  162. the `MPL Sequence`_ is the return type of the function, in this case ``void``,
  163. which is passed as the first argument to ``operator()`` in the forwarding
  164. class.
  165. .. The
  166. pointer syntax means that the parameter is optional, so in this case
  167. ``width`` and ``height`` are optional parameters. The third parameter
  168. is an `MPL Sequence`_ with the desired function signature. The return type comes first, and
  169. then the parameter types:
  170. .. parsed-literal::
  171. mpl::vector<void, std::string, unsigned, unsigned>
  172. *return type* *title* *width* *height*
  173. .. @ignore()
  174. That's it! This class can now be used in Python with the expected syntax::
  175. >>> w = my_module.window()
  176. >>> w.open(title = "foo", height = 20)
  177. .. @example.prepend('import my_module')
  178. .. @run_python(module_path = my_module)
  179. .. Sorry to say this at such a late date, but this syntax really
  180. .. strikes me as cumbersome. Couldn't we do something like:
  181. class_<window>("window")
  182. .def(
  183. "open",
  184. (void (*)(
  185. tag::title(std::string),
  186. tag::width*(unsigned),
  187. tag::height*(unsigned))
  188. )0
  189. );
  190. or at least:
  191. class_<window>("window")
  192. .def(
  193. "open",
  194. mpl::vector<
  195. void,
  196. tag::title(std::string),
  197. tag::width*(unsigned),
  198. tag::height*(unsigned)
  199. >()
  200. );
  201. assuming, that is, that we will have to repeat the tags (yes,
  202. users of broken compilers will have to give us function pointer
  203. types instead).
  204. ------------------------------------------------------------------------------
  205. concept |ParameterSpec|
  206. -----------------------
  207. A |ParameterSpec| is a function type ``K(T)`` that describes both the keyword tag,
  208. ``K``, and the argument type, ``T``, for a parameter.
  209. ``K`` is either:
  210. * A *required* keyword of the form ``Tag``
  211. * **or**, an *optional* keyword of the form ``Tag*``
  212. * **or**, a *special* keyword of the form ``Tag**``
  213. where ``Tag`` is a keyword tag type, as used in a specialization
  214. of |keyword|__.
  215. .. |keyword| replace:: ``boost::parameter::keyword``
  216. __ ../../../parameter/doc/html/reference.html#keyword
  217. The **arity range** for an `MPL Sequence`_ of |ParameterSpec|'s is
  218. defined as the closed range:
  219. .. parsed-literal::
  220. [ mpl::size<S> - number of *special* keyword tags in ``S``, mpl::size<S> ]
  221. For example, the **arity range** of ``mpl::vector2<x(int),y(int)>`` is ``[2,2]``,
  222. the **arity range** of ``mpl::vector2<x(int),y*(int)>`` is ``[2,2]`` and the
  223. **arity range** of ``mpl::vector2<x(int),y**(int)>`` is ``[1,2]``.
  224. *special* keywords
  225. ---------------------------------
  226. Sometimes it is desirable to have a default value for a parameter that differ
  227. in type from the parameter. This technique is useful for doing simple tag-dispatching
  228. based on the presence of a parameter. For example:
  229. .. An example_ of this is given in the Boost.Parameter
  230. docs. The example uses a different technique, but could also have been written like this:
  231. .. parsed-literal::
  232. namespace core
  233. {
  234. template <class ArgumentPack>
  235. void dfs_dispatch(ArgumentPack const& args, mpl::false\_)
  236. {
  237. *…compute and use default color map…*
  238. }
  239. template <class ArgumentPack, class ColorMap>
  240. void dfs_dispatch(ArgumentPack const& args, ColorMap colormap)
  241. {
  242. *…use colormap…*
  243. }
  244. }
  245. template <class ArgumentPack>
  246. void depth_first_search(ArgumentPack const& args)
  247. {
  248. core::dfs_dispatch(args, args[color | mpl::false_()]);
  249. }
  250. .. @example.prepend('''
  251. #include <boost/parameter/keyword.hpp>
  252. #include <boost/parameter/parameters.hpp>
  253. #include <boost/mpl/bool.hpp>
  254. #include <cassert>
  255. BOOST_PARAMETER_KEYWORD(tag, color);
  256. typedef boost::parameter::parameters<tag::color> params;
  257. namespace mpl = boost::mpl;
  258. ''')
  259. .. @example.replace_emphasis('''
  260. assert(args[color | 1] == 1);
  261. ''')
  262. .. @example.replace_emphasis('''
  263. assert(args[color | 1] == 0);
  264. ''')
  265. .. @example.append('''
  266. int main()
  267. {
  268. depth_first_search(params()());
  269. depth_first_search(params()(color = 0));
  270. }''')
  271. .. @build()
  272. .. .. _example: index.html#dispatching-based-on-the-presence-of-a-default
  273. In the above example the type of the default for ``color`` is ``mpl::false_``, a
  274. type that is distinct from any color map that the user might supply.
  275. When binding the case outlined above, the default type for ``color`` will not
  276. be convertible to the parameter type. Therefore we need to tag the ``color``
  277. keyword as a *special* keyword. This is done by specifying the tag as
  278. ``tag::color**`` when binding the function (see `concept ParameterSpec`_ for
  279. more details on the tagging). By doing this we tell the binding functions that
  280. it needs to generate two overloads, one with the ``color`` parameter present
  281. and one without. Had there been two *special* keywords, four overloads would
  282. need to be generated. The number of generated overloads is equal to 2\
  283. :sup:`N`, where ``N`` is the number of *special* keywords.
  284. ------------------------------------------------------------------------------
  285. class template ``init``
  286. -----------------------
  287. Defines a named parameter enabled constructor.
  288. .. parsed-literal::
  289. template <class ParameterSpecs>
  290. struct init : python::def_visitor<init<ParameterSpecs> >
  291. {
  292. template <class Class>
  293. void def(Class& class\_);
  294. template <class CallPolicies>
  295. *def\_visitor* operator[](CallPolicies const& policies) const;
  296. };
  297. .. @ignore()
  298. ``init`` requirements
  299. ~~~~~~~~~~~~~~~~~~~~~
  300. * ``ParameterSpecs`` is an `MPL sequence`_ where each element is a
  301. model of |ParameterSpec|.
  302. * For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity
  303. range** of ``ParameterSpecs``, ``Class`` must support these
  304. expressions:
  305. ======================= ============= =========================================
  306. Expression Return type Requirements
  307. ======================= ============= =========================================
  308. ``Class(a0, …, aN)`` \- ``a0``\ …\ ``aN`` are tagged arguments.
  309. ======================= ============= =========================================
  310. ``template <class CallPolicies> operator[](CallPolicies const&)``
  311. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  312. Returns a ``def_visitor`` equivalent to ``*this``, except that it
  313. uses CallPolicies when creating the binding.
  314. Example
  315. ~~~~~~~
  316. .. parsed-literal::
  317. #include <boost/parameter/keyword.hpp>
  318. #include <boost/parameter/preprocessor.hpp>
  319. #include <boost/parameter/python.hpp>
  320. #include <boost/python.hpp>
  321. #include <boost/mpl/vector.hpp>
  322. BOOST_PARAMETER_KEYWORD(tag, x)
  323. BOOST_PARAMETER_KEYWORD(tag, y)
  324. struct base
  325. {
  326. template <class ArgumentPack>
  327. base(ArgumentPack const& args)
  328. {
  329. *… use args …*
  330. }
  331. };
  332. class X : base
  333. {
  334. public:
  335. BOOST_PARAMETER_CONSTRUCTOR(X, (base), tag,
  336. (required (x, \*))
  337. (optional (y, \*))
  338. )
  339. };
  340. BOOST_PYTHON_MODULE(*module name*)
  341. {
  342. using namespace boost::python;
  343. namespace py = boost::parameter::python;
  344. namespace mpl = boost::mpl;
  345. class_<X>("X", no_init)
  346. .def(
  347. py::init<
  348. mpl::vector<tag::x(int), tag::y\*(int)>
  349. >()
  350. );
  351. }
  352. .. @example.replace_emphasis('''
  353. assert(args[x] == 0);
  354. assert(args[y | 1] == 1);
  355. ''')
  356. .. @example.replace_emphasis('my_module')
  357. .. @jam_prefix.append('import python ;')
  358. .. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
  359. .. @my_module = build(
  360. output = 'my_module'
  361. , target_rule = 'python-extension'
  362. , input = '/boost/python//boost_python'
  363. )
  364. ------------------------------------------------------------------------------
  365. class template ``call``
  366. -----------------------
  367. Defines a ``__call__`` operator, mapped to ``operator()`` in C++.
  368. .. parsed-literal::
  369. template <class ParameterSpecs>
  370. struct call : python::def_visitor<call<ParameterSpecs> >
  371. {
  372. template <class Class>
  373. void def(Class& class\_);
  374. template <class CallPolicies>
  375. *def\_visitor* operator[](CallPolicies const& policies) const;
  376. };
  377. .. @ignore()
  378. ``call`` requirements
  379. ~~~~~~~~~~~~~~~~~~~~~
  380. * ``ParameterSpecs`` is an `MPL sequence`_ where each element
  381. except the first models |ParameterSpec|. The first element
  382. is the result type of ``c(…)``.
  383. * ``Class`` must support these expressions, where ``c`` is an
  384. instance of ``Class``:
  385. =================== ==================== =======================================
  386. Expression Return type Requirements
  387. =================== ==================== =======================================
  388. ``c(a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
  389. =================== ==================== =======================================
  390. For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
  391. ``template <class CallPolicies> operator[](CallPolicies const&)``
  392. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  393. Returns a ``def_visitor`` equivalent to ``*this``, except that it
  394. uses CallPolicies when creating the binding.
  395. Example
  396. ~~~~~~~
  397. .. parsed-literal::
  398. #include <boost/parameter/keyword.hpp>
  399. #include <boost/parameter/preprocessor.hpp>
  400. #include <boost/parameter/python.hpp>
  401. #include <boost/python.hpp>
  402. #include <boost/mpl/vector.hpp>
  403. BOOST_PARAMETER_KEYWORD(tag, x)
  404. BOOST_PARAMETER_KEYWORD(tag, y)
  405. namespace parameter = boost::parameter;
  406. typedef parameter::parameters<
  407. parameter::required<tag::x>
  408. , parameter::optional<tag::y>
  409. > call_parameters;
  410. class X
  411. {
  412. public:
  413. template <class ArgumentPack>
  414. int call_impl(ArgumentPack const& args)
  415. {
  416. *… use args …*
  417. }
  418. template <class A0>
  419. int operator()(A0 const& a0)
  420. {
  421. return call_impl(call_parameters()(a0));
  422. }
  423. template <class A0, class A1>
  424. int operator()(A0 const& a0, A1 const& a1)
  425. {
  426. return call_impl(call_parameters()(a0,a1));
  427. }
  428. };
  429. BOOST_PYTHON_MODULE(*module name*)
  430. {
  431. using namespace boost::python;
  432. namespace py = parameter::python;
  433. namespace mpl = boost::mpl;
  434. class_<X>("X")
  435. .def(
  436. py::call<
  437. mpl::vector<int, tag::x(int), tag::y\*(int)>
  438. >()
  439. );
  440. }
  441. .. @example.replace_emphasis('''
  442. assert(args[x] == 0);
  443. assert(args[y | 1] == 1);
  444. return 0;
  445. ''')
  446. .. @example.replace_emphasis('my_module')
  447. .. @my_module = build(
  448. output = 'my_module'
  449. , target_rule = 'python-extension'
  450. , input = '/boost/python//boost_python'
  451. )
  452. ------------------------------------------------------------------------------
  453. class template ``function``
  454. ---------------------------
  455. Defines a named parameter enabled member function.
  456. .. parsed-literal::
  457. template <class Fwd, class ParameterSpecs>
  458. struct function : python::def_visitor<function<Fwd, ParameterSpecs> >
  459. {
  460. template <class Class, class Options>
  461. void def(Class& class\_, char const* name, Options const& options);
  462. };
  463. .. @ignore()
  464. ``function`` requirements
  465. ~~~~~~~~~~~~~~~~~~~~~~~~~
  466. * ``ParameterSpecs`` is an `MPL sequence`_ where each element
  467. except the first models |ParameterSpec|. The first element
  468. is the result type of ``c.f(…)``, where ``f`` is the member
  469. function.
  470. * An instance of ``Fwd`` must support this expression:
  471. ============================================ ==================== =================================================
  472. Expression Return type Requirements
  473. ============================================ ==================== =================================================
  474. ``fwd(boost::type<R>(), self, a0, …, aN)`` Convertible to ``R`` ``self`` is a reference to the object on which
  475. the function should be invoked. ``a0``\ …\ ``aN``
  476. are tagged arguments.
  477. ============================================ ==================== =================================================
  478. For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
  479. Example
  480. ~~~~~~~
  481. This example exports a member function ``f(int x, int y = …)`` to Python. The
  482. sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
  483. an **arity range** of [2,2], so we only need one forwarding overload.
  484. .. parsed-literal::
  485. #include <boost/parameter/keyword.hpp>
  486. #include <boost/parameter/preprocessor.hpp>
  487. #include <boost/parameter/python.hpp>
  488. #include <boost/python.hpp>
  489. #include <boost/mpl/vector.hpp>
  490. BOOST_PARAMETER_KEYWORD(tag, x)
  491. BOOST_PARAMETER_KEYWORD(tag, y)
  492. class X
  493. {
  494. public:
  495. BOOST_PARAMETER_MEMBER_FUNCTION((void), f, tag,
  496. (required (x, \*))
  497. (optional (y, \*, 1))
  498. )
  499. {
  500. *…*
  501. }
  502. };
  503. struct f_fwd
  504. {
  505. template <class A0, class A1>
  506. void operator()(boost::type<void>, X& self, A0 const& a0, A1 const& a1)
  507. {
  508. self.f(a0, a1);
  509. }
  510. };
  511. BOOST_PYTHON_MODULE(*module name*)
  512. {
  513. using namespace boost::python;
  514. namespace py = boost::parameter::python;
  515. namespace mpl = boost::mpl;
  516. class_<X>("X")
  517. .def("f",
  518. py::function<
  519. f_fwd
  520. , mpl::vector<void, tag::x(int), tag::y\*(int)>
  521. >()
  522. );
  523. }
  524. .. @example.replace_emphasis('''
  525. assert(x == 0);
  526. assert(y == 1);
  527. ''')
  528. .. @example.replace_emphasis('my_module')
  529. .. @my_module = build(
  530. output = 'my_module'
  531. , target_rule = 'python-extension'
  532. , input = '/boost/python//boost_python'
  533. )
  534. ------------------------------------------------------------------------------
  535. function template ``def``
  536. -------------------------
  537. Defines a named parameter enabled free function in the current Python scope.
  538. .. parsed-literal::
  539. template <class Fwd, class ParameterSpecs>
  540. void def(char const* name);
  541. .. @ignore()
  542. ``def`` requirements
  543. ~~~~~~~~~~~~~~~~~~~~
  544. * ``ParameterSpecs`` is an `MPL sequence`_ where each element
  545. except the first models |ParameterSpec|. The first element
  546. is the result type of ``f(…)``, where ``f`` is the function.
  547. * An instance of ``Fwd`` must support this expression:
  548. ====================================== ==================== =======================================
  549. Expression Return type Requirements
  550. ====================================== ==================== =======================================
  551. ``fwd(boost::type<R>(), a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
  552. ====================================== ==================== =======================================
  553. For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
  554. Example
  555. ~~~~~~~
  556. This example exports a function ``f(int x, int y = …)`` to Python. The
  557. sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
  558. an **arity range** of [2,2], so we only need one forwarding overload.
  559. .. parsed-literal::
  560. BOOST_PARAMETER_FUNCTION((void), f, tag,
  561. (required (x, \*))
  562. (optional (y, \*, 1))
  563. )
  564. {
  565. *…*
  566. }
  567. struct f_fwd
  568. {
  569. template <class A0, class A1>
  570. void operator()(boost::type<void>, A0 const& a0, A1 const& a1)
  571. {
  572. f(a0, a1);
  573. }
  574. };
  575. BOOST_PYTHON_MODULE(…)
  576. {
  577. def<
  578. f_fwd
  579. , mpl::vector<
  580. void, tag::\ x(int), tag::\ y\*(int)
  581. >
  582. >("f");
  583. }
  584. .. @ignore()
  585. .. again, the undefined ``fwd`` identifier.
  586. Portability
  587. -----------
  588. The Boost.Parameter Python binding library requires *partial template
  589. specialization*.