1 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 The Boost Parameter Library Python Binding Documentation
3 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 :Authors: David Abrahams, Daniel Wallin
6 :Contact: dave@boost-consulting.com, daniel@boostpro.com
7 :organization: `BoostPro Computing`_
10 :copyright: Copyright David Abrahams, Daniel Wallin
11 2005-2009. Distributed under the Boost Software License,
12 Version 1.0. (See accompanying file LICENSE_1_0.txt
13 or copy at http://www.boost.org/LICENSE_1_0.txt)
15 :abstract: Makes it possible to bind Boost.Parameter-enabled
16 functions, operators and constructors to Python.
20 .. |(logo)| image:: ../../../../boost.png
23 __ ../../../../index.htm
25 .. _`BoostPro Computing`: http://www.boostpro.com
37 .. |ParameterSpec| replace:: :concept:`ParameterSpec`
45 ``boost/parameter/python.hpp`` introduces a group of |def_visitors|_ that can
46 be used to easily expose Boost.Parameter-enabled member functions to Python with
47 Boost.Python. It also provides a function template ``def()`` that can be used
48 to expose Boost.Parameter-enabled free functions.
50 .. |def_visitor| replace:: ``def_visitor``
51 .. |def_visitors| replace:: ``def_visitors``
53 .. _def_visitor: def_visitors_
54 .. _def_visitors: ../../../python/doc/v2/def_visitor.html
56 When binding a Boost.Parameter enabled function, the keyword tags
57 must be specified. Additionally, because Boost.Parameter enabled
58 functions are templates, the desired function signature must be
61 .. The keyword tags are specified as an `MPL Sequence`_, using the
62 pointer qualifications described in |ParameterSpec|_ below. The
63 signature is also specifid as an `MPL sequence`_ of parameter
64 types. Additionally, ``boost::parameter::python::function`` and
65 ``boost::parameter::python::def`` requires a class with forwarding
66 overloads. We will take a closer look at how this is done in the
67 tutorial section below.
69 The keyword tags and associated argument types are specified as an `MPL
70 Sequence`_, using the function type syntax described in |ParameterSpec|_
71 below. Additionally, ``boost::parameter::python::function`` and
72 ``boost::parameter::python::def`` requires a class with forwarding overloads.
73 We will take a closer look at how this is done in the tutorial section below.
75 .. The last two sentences are terribly vague. Which namespace is
76 .. ``function`` in? Isn't the return type always needed? What
77 .. else are we going to do other than pass these sequences to
80 .. _`MPL Sequence`: ../../../mpl/doc/refmanual/sequences.html
81 .. _parameterspec: `concept ParameterSpec`_
86 In this section we will outline the steps needed to bind a simple
87 Boost.Parameter-enabled member function to Python. Knowledge of the
88 Boost.Parameter macros_ are required to understand this section.
90 .. _macros: index.html
92 The class and member function we are interested in binding looks
97 #include <boost/parameter/keyword.hpp>
98 #include <boost/parameter/preprocessor.hpp>
99 #include <boost/parameter/python.hpp>
100 #include <boost/python.hpp>
102 // First the keywords
103 BOOST_PARAMETER_KEYWORD(tag, title)
104 BOOST_PARAMETER_KEYWORD(tag, width)
105 BOOST_PARAMETER_KEYWORD(tag, height)
110 BOOST_PARAMETER_MEMBER_FUNCTION(
112 (required (title, (std::string)))
113 (optional (width, (unsigned), 400)
114 (height, (unsigned), 400))
117 *… function implementation …*
121 .. @example.prepend('#include <cassert>')
122 .. @example.replace_emphasis('''
123 assert(title == "foo");
124 assert(height == 20);
125 assert(width == 400);
128 It defines a set of overloaded member functions called ``open`` with one
129 required parameter and two optional ones. To bind this member function to
130 Python we use the binding utility ``boost::parameter::python::function``.
131 ``boost::parameter::python::function`` is a |def_visitor|_ that we'll instantiate
132 and pass to ``boost::python::class_::def()``.
134 To use ``boost::parameter::python::function`` we first need to define
135 a class with forwarding overloads. This is needed because ``window::open()``
136 is a function template, so we can't refer to it in any other way.
142 template <class A0, class A1, class A2>
144 boost::type<void>, window& self
145 , A0 const& a0, A1 const& a1, A2 const& a2
148 self.open(a0, a1, a2);
152 The first parameter, ``boost::type<void>``, tells the forwarding overload
153 what the return type should be. In this case we know that it's always void
154 but in some cases, when we are exporting several specializations of a
155 Boost.Parameter-enabled template, we need to use that parameter to
156 deduce the return type.
158 ``window::open()`` takes a total of 3 parameters, so the forwarding function
159 needs to take three parameters as well.
163 We only need one overload in the forwarding class, despite the
164 fact that there are two optional parameters. There are special
165 circumstances when several overload are needed; see
168 Next we'll define the module and export the class:
172 BOOST_PYTHON_MODULE(my_module)
174 using namespace boost::python;
175 namespace py = boost::parameter::python;
176 namespace mpl = boost::mpl;
178 class_<window>("window")
180 "open", py::function<
184 , tag::title(std::string)
185 , tag::width*(unsigned)
186 , tag::height*(unsigned)
192 .. @jam_prefix.append('import python ;')
193 .. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
194 .. @my_module = build(
196 , target_rule = 'python-extension'
197 , input = '/boost/python//boost_python'
201 .. @del jam_prefix[:]
203 ``py::function`` is passed two parameters. The first one is the class with
204 forwarding overloads that we defined earlier. The second one is an `MPL
205 Sequence`_ with the keyword tag types and argument types for the function
206 specified as function types. The pointer syntax used in ``tag::width*`` and
207 ``tag::height*`` means that the parameter is optional. The first element of
208 the `MPL Sequence`_ is the return type of the function, in this case ``void``,
209 which is passed as the first argument to ``operator()`` in the forwarding
213 pointer syntax means that the parameter is optional, so in this case
214 ``width`` and ``height`` are optional parameters. The third parameter
215 is an `MPL Sequence`_ with the desired function signature. The return type comes first, and
216 then the parameter types:
220 mpl::vector<void, std::string, unsigned, unsigned>
221 *return type* *title* *width* *height*
225 That's it! This class can now be used in Python with the expected syntax::
227 >>> w = my_module.window()
228 >>> w.open(title = "foo", height = 20)
230 .. @example.prepend('import my_module')
231 .. @run_python(module_path = my_module)
233 .. Sorry to say this at such a late date, but this syntax really
234 .. strikes me as cumbersome. Couldn't we do something like:
236 class_<window>("window")
240 tag::title(std::string),
241 tag::width*(unsigned),
242 tag::height*(unsigned))
248 class_<window>("window")
253 tag::title(std::string),
254 tag::width*(unsigned),
255 tag::height*(unsigned)
259 assuming, that is, that we will have to repeat the tags (yes,
260 users of broken compilers will have to give us function pointer
263 ------------------------------------------------------------------------------
265 concept |ParameterSpec|
266 -----------------------
268 A |ParameterSpec| is a function type ``K(T)`` that describes both the keyword tag,
269 ``K``, and the argument type, ``T``, for a parameter.
273 * A *required* keyword of the form ``Tag``
274 * **or**, an *optional* keyword of the form ``Tag*``
275 * **or**, a *special* keyword of the form ``Tag**``
277 where ``Tag`` is a keyword tag type, as used in a specialization
280 .. |keyword| replace:: ``boost::parameter::keyword``
281 __ ../../../parameter/doc/html/reference.html#keyword
283 The **arity range** for an `MPL Sequence`_ of |ParameterSpec|'s is
284 defined as the closed range:
288 [ mpl::size<S> - number of *special* keyword tags in ``S``, mpl::size<S> ]
290 For example, the **arity range** of ``mpl::vector2<x(int),y(int)>`` is ``[2,2]``,
291 the **arity range** of ``mpl::vector2<x(int),y*(int)>`` is ``[2,2]`` and the
292 **arity range** of ``mpl::vector2<x(int),y**(int)>`` is ``[1,2]``.
297 ---------------------------------
299 Sometimes it is desirable to have a default value for a parameter that differ
300 in type from the parameter. This technique is useful for doing simple tag-dispatching
301 based on the presence of a parameter. For example:
303 .. An example_ of this is given in the Boost.Parameter
304 docs. The example uses a different technique, but could also have been written like this:
310 template <class ArgumentPack>
311 void dfs_dispatch(ArgumentPack const& args, mpl::false\_)
313 *…compute and use default color map…*
316 template <class ArgumentPack, class ColorMap>
317 void dfs_dispatch(ArgumentPack const& args, ColorMap colormap)
323 template <class ArgumentPack>
324 void depth_first_search(ArgumentPack const& args)
326 core::dfs_dispatch(args, args[color | mpl::false_()]);
329 .. @example.prepend('''
330 #include <boost/parameter/keyword.hpp>
331 #include <boost/parameter/parameters.hpp>
332 #include <boost/mpl/bool.hpp>
335 BOOST_PARAMETER_KEYWORD(tag, color);
337 typedef boost::parameter::parameters<tag::color> params;
339 namespace mpl = boost::mpl;
342 .. @example.replace_emphasis('''
343 assert(args[color | 1] == 1);
346 .. @example.replace_emphasis('''
347 assert(args[color | 1] == 0);
350 .. @example.append('''
353 depth_first_search(params()());
354 depth_first_search(params()(color = 0));
359 .. .. _example: index.html#dispatching-based-on-the-presence-of-a-default
361 In the above example the type of the default for ``color`` is ``mpl::false_``, a
362 type that is distinct from any color map that the user might supply.
364 When binding the case outlined above, the default type for ``color`` will not
365 be convertible to the parameter type. Therefore we need to tag the ``color``
366 keyword as a *special* keyword. This is done by specifying the tag as
367 ``tag::color**`` when binding the function (see `concept ParameterSpec`_ for
368 more details on the tagging). By doing this we tell the binding functions that
369 it needs to generate two overloads, one with the ``color`` parameter present
370 and one without. Had there been two *special* keywords, four overloads would
371 need to be generated. The number of generated overloads is equal to 2\
372 :sup:`N`, where ``N`` is the number of *special* keywords.
374 ------------------------------------------------------------------------------
376 class template ``init``
377 -----------------------
379 Defines a named parameter enabled constructor.
383 template <class ParameterSpecs>
384 struct init : python::def_visitor<init<ParameterSpecs> >
386 template <class Class>
387 void def(Class& class\_);
389 template <class CallPolicies>
390 *def\_visitor* operator[](CallPolicies const& policies) const;
395 ``init`` requirements
396 ~~~~~~~~~~~~~~~~~~~~~
398 * ``ParameterSpecs`` is an `MPL sequence`_ where each element is a
399 model of |ParameterSpec|.
400 * For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity
401 range** of ``ParameterSpecs``, ``Class`` must support these
404 ======================= ============= =========================================
405 Expression Return type Requirements
406 ======================= ============= =========================================
407 ``Class(a0, …, aN)`` \- ``a0``\ …\ ``aN`` are tagged arguments.
408 ======================= ============= =========================================
412 ``template <class CallPolicies> operator[](CallPolicies const&)``
413 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
415 Returns a ``def_visitor`` equivalent to ``*this``, except that it
416 uses CallPolicies when creating the binding.
424 #include <boost/parameter/keyword.hpp>
425 #include <boost/parameter/preprocessor.hpp>
426 #include <boost/parameter/python.hpp>
427 #include <boost/python.hpp>
428 #include <boost/mpl/vector.hpp>
430 BOOST_PARAMETER_KEYWORD(tag, x)
431 BOOST_PARAMETER_KEYWORD(tag, y)
435 template <class ArgumentPack>
436 base(ArgumentPack const& args)
445 BOOST_PARAMETER_CONSTRUCTOR(X, (base), tag,
451 BOOST_PYTHON_MODULE(*module name*)
453 using namespace boost::python;
454 namespace py = boost::parameter::python;
455 namespace mpl = boost::mpl;
457 class_<X>("X", no_init)
460 mpl::vector<tag::x(int), tag::y\*(int)>
465 .. @example.replace_emphasis('''
466 assert(args[x] == 0);
467 assert(args[y | 1] == 1);
470 .. @example.replace_emphasis('my_module')
472 .. @jam_prefix.append('import python ;')
473 .. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
474 .. @my_module = build(
476 , target_rule = 'python-extension'
477 , input = '/boost/python//boost_python'
480 ------------------------------------------------------------------------------
482 class template ``call``
483 -----------------------
485 Defines a ``__call__`` operator, mapped to ``operator()`` in C++.
489 template <class ParameterSpecs>
490 struct call : python::def_visitor<call<ParameterSpecs> >
492 template <class Class>
493 void def(Class& class\_);
495 template <class CallPolicies>
496 *def\_visitor* operator[](CallPolicies const& policies) const;
501 ``call`` requirements
502 ~~~~~~~~~~~~~~~~~~~~~
504 * ``ParameterSpecs`` is an `MPL sequence`_ where each element
505 except the first models |ParameterSpec|. The first element
506 is the result type of ``c(…)``.
507 * ``Class`` must support these expressions, where ``c`` is an
508 instance of ``Class``:
510 =================== ==================== =======================================
511 Expression Return type Requirements
512 =================== ==================== =======================================
513 ``c(a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
514 =================== ==================== =======================================
516 For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
519 ``template <class CallPolicies> operator[](CallPolicies const&)``
520 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
522 Returns a ``def_visitor`` equivalent to ``*this``, except that it
523 uses CallPolicies when creating the binding.
531 #include <boost/parameter/keyword.hpp>
532 #include <boost/parameter/preprocessor.hpp>
533 #include <boost/parameter/python.hpp>
534 #include <boost/python.hpp>
535 #include <boost/mpl/vector.hpp>
537 BOOST_PARAMETER_KEYWORD(tag, x)
538 BOOST_PARAMETER_KEYWORD(tag, y)
540 namespace parameter = boost::parameter;
542 typedef parameter::parameters<
543 parameter::required<tag::x>
544 , parameter::optional<tag::y>
550 template <class ArgumentPack>
551 int call_impl(ArgumentPack const& args)
557 int operator()(A0 const& a0)
559 return call_impl(call_parameters()(a0));
562 template <class A0, class A1>
563 int operator()(A0 const& a0, A1 const& a1)
565 return call_impl(call_parameters()(a0,a1));
569 BOOST_PYTHON_MODULE(*module name*)
571 using namespace boost::python;
572 namespace py = parameter::python;
573 namespace mpl = boost::mpl;
578 mpl::vector<int, tag::x(int), tag::y\*(int)>
583 .. @example.replace_emphasis('''
584 assert(args[x] == 0);
585 assert(args[y | 1] == 1);
589 .. @example.replace_emphasis('my_module')
591 .. @my_module = build(
593 , target_rule = 'python-extension'
594 , input = '/boost/python//boost_python'
597 ------------------------------------------------------------------------------
599 class template ``function``
600 ---------------------------
602 Defines a named parameter enabled member function.
606 template <class Fwd, class ParameterSpecs>
607 struct function : python::def_visitor<function<Fwd, ParameterSpecs> >
609 template <class Class, class Options>
610 void def(Class& class\_, char const* name, Options const& options);
615 ``function`` requirements
616 ~~~~~~~~~~~~~~~~~~~~~~~~~
618 * ``ParameterSpecs`` is an `MPL sequence`_ where each element
619 except the first models |ParameterSpec|. The first element
620 is the result type of ``c.f(…)``, where ``f`` is the member
622 * An instance of ``Fwd`` must support this expression:
624 ============================================ ==================== =================================================
625 Expression Return type Requirements
626 ============================================ ==================== =================================================
627 ``fwd(boost::type<R>(), self, a0, …, aN)`` Convertible to ``R`` ``self`` is a reference to the object on which
628 the function should be invoked. ``a0``\ …\ ``aN``
629 are tagged arguments.
630 ============================================ ==================== =================================================
632 For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
638 This example exports a member function ``f(int x, int y = …)`` to Python. The
639 sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
640 an **arity range** of [2,2], so we only need one forwarding overload.
644 #include <boost/parameter/keyword.hpp>
645 #include <boost/parameter/preprocessor.hpp>
646 #include <boost/parameter/python.hpp>
647 #include <boost/python.hpp>
648 #include <boost/mpl/vector.hpp>
650 BOOST_PARAMETER_KEYWORD(tag, x)
651 BOOST_PARAMETER_KEYWORD(tag, y)
656 BOOST_PARAMETER_MEMBER_FUNCTION((void), f, tag,
658 (optional (y, \*, 1))
667 template <class A0, class A1>
668 void operator()(boost::type<void>, X& self, A0 const& a0, A1 const& a1)
674 BOOST_PYTHON_MODULE(*module name*)
676 using namespace boost::python;
677 namespace py = boost::parameter::python;
678 namespace mpl = boost::mpl;
684 , mpl::vector<void, tag::x(int), tag::y\*(int)>
689 .. @example.replace_emphasis('''
694 .. @example.replace_emphasis('my_module')
696 .. @my_module = build(
698 , target_rule = 'python-extension'
699 , input = '/boost/python//boost_python'
702 ------------------------------------------------------------------------------
704 function template ``def``
705 -------------------------
707 Defines a named parameter enabled free function in the current Python scope.
711 template <class Fwd, class ParameterSpecs>
712 void def(char const* name);
719 * ``ParameterSpecs`` is an `MPL sequence`_ where each element
720 except the first models |ParameterSpec|. The first element
721 is the result type of ``f(…)``, where ``f`` is the function.
722 * An instance of ``Fwd`` must support this expression:
724 ====================================== ==================== =======================================
725 Expression Return type Requirements
726 ====================================== ==================== =======================================
727 ``fwd(boost::type<R>(), a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
728 ====================================== ==================== =======================================
730 For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``.
736 This example exports a function ``f(int x, int y = …)`` to Python. The
737 sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
738 an **arity range** of [2,2], so we only need one forwarding overload.
742 BOOST_PARAMETER_FUNCTION((void), f, tag,
744 (optional (y, \*, 1))
752 template <class A0, class A1>
753 void operator()(boost::type<void>, A0 const& a0, A1 const& a1)
759 BOOST_PYTHON_MODULE(…)
764 void, tag::\ x(int), tag::\ y\*(int)
771 .. again, the undefined ``fwd`` identifier.
776 The Boost.Parameter Python binding library requires *partial template