Skip to content

Commit 184c036

Browse files
Daniel Wallinpdimov
authored andcommitted
more editing
[SVN r33964]
1 parent 63bede6 commit 184c036

1 file changed

Lines changed: 126 additions & 71 deletions

File tree

doc/python.rst

Lines changed: 126 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -52,41 +52,38 @@ must be specified. Additionally, because Boost.Parameter enabled
5252
functions are templates, the desired function signature must be
5353
specified.
5454

55-
.. Always diff my edited version with the original to see what I
56-
.. changed, and think about why I changed it. Ask if you don't
57-
.. understand. "Boost.Parameter-enabled" needs that hyphen
58-
.. everywhere. I'm leaving that change to you.
59-
60-
.. Why must keyword tags be specified again? Ah, because we didn't
61-
.. record their association with the wrapped function in the first
62-
.. place. I think that should be possible, no?
63-
6455
The keyword tags are specified as an `MPL Sequence`_, using the
6556
pointer qualifications described in |KeywordsSpec|_ below. The
6657
signature is also specifid as an `MPL sequence`_ of parameter
67-
types. Additional data may be needed in the signature sequence by
68-
specific binding utilities. For example, ``function`` requires the
69-
return type to be part of the signature sequence.
58+
types. Additionally, ``boost::parameter::python::function`` and
59+
``boost::parameter::python::def`` requires a class with forwarding
60+
overloads. We will take a closer look at how this is done in the
61+
tutorial section below.
7062

7163
.. The last two sentences are terribly vague. Which namespace is
7264
.. ``function`` in? Isn't the return type always needed? What
7365
.. else are we going to do other than pass these sequences to
7466
.. function?
7567
7668
.. _`MPL Sequence`: ../../../mpl/doc/refmanual/sequences.html
69+
.. _keywordsspec: `concept KeywordsSpec`_
7770

7871
Tutorial
7972
--------
8073

8174
In this section we will outline the steps needed to bind a simple
82-
Boost.Parameter enabled member function to Python. Knowledge of the
83-
Boost.Parameter macros are required to understand this section.
75+
Boost.Parameter-enabled member function to Python. Knowledge of the
76+
Boost.Parameter macros_ are required to understand this section.
8477

85-
.. Link to the docs for Boost.Parameter macros
78+
.. _macros: index.html
8679

8780
The class and member function we are interested in binding looks
8881
like this::
8982

83+
#include <boost/parameter/keyword.hpp>
84+
#include <boost/parameter/preprocessor.hpp>
85+
#include <boost/parameter/python.hpp>
86+
9087
// First the keywords
9188
BOOST_PARAMETER_KEYWORD(tag, title)
9289
BOOST_PARAMETER_KEYWORD(tag, width)
@@ -100,16 +97,51 @@ like this::
10097
(required (title, (std::string)))
10198
(optional (width, (unsigned), 400)
10299
(height, (unsigned), 400))
103-
);
100+
)
101+
{
102+
103+
}
104+
};
105+
106+
It defines a set of overloaded member functions called ``open`` with one
107+
required parameter and two optional ones. To bind this member function to
108+
Python we use the binding utility ``boost::parameter::python::function``.
109+
``boost::parameter::python::function`` is a def_visitor_ that we'll instantiate
110+
and pass to ``boost::python::class_::def()``.
111+
112+
To use ``boost::parameter::python::function`` we first need to define
113+
a class with forwarding overloads.
114+
115+
::
116+
117+
struct open_fwd
118+
{
119+
template <class A0, class A1, class A2>
120+
void operator()(
121+
boost::type<void>, window& self, A0 const& a0, A1 const& a1, A2 const& a2
122+
)
123+
{
124+
self.open(a0, a1, a2);
125+
}
104126
};
105127

106-
.. Don't use endline layout.
128+
The first parameter, ``boost::type<void>``, tells the forwarding overload
129+
what the return type should be. In this case we know that it's always void
130+
but in some cases, when we are exporting several specializations of a
131+
Boost.Parameter-enabled template, we need to use that parameter to
132+
deduce the return type.
133+
134+
``window::open()`` takes a total of 3 parameters, so the forwarding function
135+
needs to take three parameters as well.
107136

108-
It defines a set of overloaded member functions called ``open``
109-
with one required parameter and two optional ones. To bind this
110-
member function to Python we use the binding utility
111-
``function``. ``function`` is a def_visitor_ that we'll
112-
instantiate and pass to ``boost::python::class_::def()``.
137+
.. Note::
138+
139+
We only need one overload in the forwarding class, despite the
140+
fact that there are two optional parameters. There are special
141+
circumstances when several overload are needed; see
142+
`special keywords`_.
143+
144+
Next we'll define the module and export the class:
113145

114146
::
115147

@@ -121,21 +153,51 @@ instantiate and pass to ``boost::python::class_::def()``.
121153
class_<window>("window")
122154
.def(
123155
"open", py::function<
124-
mpl::vector<tag::title, tag::width*, tag::height*>,
125-
mpl::vector<void, std::string, unsigned, unsigned>
156+
open_fwd
157+
, mpl::vector<tag::title, tag::width*, tag::height*>
158+
, mpl::vector<void, std::string, unsigned, unsigned>
126159
>()
127160
);
128161
}
129162

130-
.. you missed passing the first argument, open_fwd, I think?
163+
.. @jam_prefix.append('import python ;')
164+
.. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
165+
.. @my_module = build(
166+
output = 'my_module'
167+
, target_rule = 'python-extension'
168+
, input = '/boost/python//boost_python'
169+
, howmany = 'all'
170+
)
171+
172+
.. @del jam_prefix[-1:]
173+
174+
``py::function`` is passed three parameters. The first one is the class
175+
with forwarding overloads that we defined earlier. The second one is
176+
an `MPL Sequence`_ with the keyword tag types for the function. The
177+
pointer syntax means that the parameter is optional, so in this case
178+
``width`` and ``height`` are optional parameters. The third parameter
179+
is an `MPL Sequence`_ with the desired function signature. The return type comes first, and
180+
then the parameter types:
181+
182+
.. parsed-literal::
183+
184+
mpl::vector<void, std::string, unsigned, unsigned>
185+
*return type* *title* *width* *height*
186+
187+
.. @ignore()
188+
189+
That's it! This class can now be used in Python with the expected syntax::
131190

132-
.. be consistent in indentation and comma placement. Pick either
133-
.. leading or trailing commas.
191+
>>> w = my_module.window()
192+
>>> w.open(title = "foo", height = 20)
193+
194+
.. @example.prepend('import my_module')
195+
.. @run_python(module_path = my_module)
134196
135197
.. Sorry to say this at such a late date, but this syntax really
136198
.. strikes me as cumbersome. Couldn't we do something like:
137199
138-
class_<window>("window")
200+
class_<window>("window")
139201
.def(
140202
"open",
141203
(void (*)(
@@ -162,6 +224,8 @@ instantiate and pass to ``boost::python::class_::def()``.
162224
users of broken compilers will have to give us function pointer
163225
types instead).
164226
227+
------------------------------------------------------------------------------
228+
165229
concept |KeywordsSpec|
166230
----------------------
167231

@@ -171,10 +235,10 @@ A |KeywordsSpec| is an `MPL sequence`_ where each element is either:
171235
* **or**, an *optional* keyword of the form ``K*``
172236
* **or**, a *special* keyword of the form ``K**``
173237

174-
where ``K`` is a specialization of ``boost::parameter::keyword``__.
175-
238+
where ``K`` is a keyword tag type, as used in a specialization
239+
of boost::parameter::keyword__.
176240

177-
.. __ ../../../parameter/doc/html/reference.html#keyword
241+
__ ../../../parameter/doc/html/reference.html#keyword
178242

179243
The **arity range** of a |KeywordsSpec| is defined as the closed
180244
range:
@@ -189,7 +253,7 @@ For example, the **arity range** of ``mpl::vector2<x,y>`` is [2,2], the **arity
189253
.. Don't optional keywords affect the arity range?
190254
191255
192-
*special* keyword tags
256+
*special* keywords
193257
---------------------------------
194258

195259
Sometimes it is desirable to have a default value for a parameter that differ
@@ -219,11 +283,6 @@ docs. The example uses a different technique, but could also have been written l
219283
220284
.. _example: index.html#dispatching-based-on-the-presence-of-a-default
221285

222-
.. there have been several mistakes in these code examples. I
223-
.. built a literate programming system for ReST, which we used for
224-
.. the MPL book. If you'd like I'll check it in and you can use it
225-
.. to check these.
226-
227286
In the above example the type of the default for ``color`` is ``mpl::false_``, a
228287
type that is distinct from any color map that the user might supply.
229288

@@ -235,10 +294,6 @@ present and one without. Had there been two *special* keywords, four
235294
overloads would need to be generated. The number of generated overloads is
236295
equal to ``2^N``, where ``N`` is the number of *special* keywords.
237296

238-
.. The entire section below was rewritten.
239-
240-
.. No need to leave commented out detritus in the document. That's
241-
.. what source control is for.
242297

243298
------------------------------------------------------------------------------
244299

@@ -266,11 +321,11 @@ Defines a named parameter enabled constructor.
266321
range** of ``Keywords``, ``Class`` must support these
267322
expressions:
268323

269-
======================================================= ==================== ==============================================
270-
Expression Return type Requirements
271-
======================================================= ==================== ==============================================
272-
``Class(a0, ..., aN)`` \- ``a0``..\ ``aN`` are tagged arguments.
273-
======================================================= ==================== ==============================================
324+
======================= ============= =========================================
325+
Expression Return type Requirements
326+
======================= ============= =========================================
327+
``Class(a0, ..., aN)`` \- ``a0``..\ ``aN`` are tagged arguments.
328+
======================= ============= =========================================
274329

275330
.. Limit the width of these table cells. Some rst backend
276331
.. processors actually produce different results depending on the
@@ -329,11 +384,11 @@ Defines a ``__call__`` operator, mapped to ``operator()`` in C++.
329384
in the order dictated by ``Keywords``, and the return type prepended.
330385
* ``Class`` must support these expressions, where ``c`` is an instance of ``Class``:
331386

332-
======================================================= ==================== ==============================================
333-
Expression Return type Requirements
334-
======================================================= ==================== ==============================================
335-
``c(a0, ..., aN)`` Convertible to ``R`` ``a0``..\ ``aN`` are tagged arguments.
336-
======================================================= ==================== ==============================================
387+
=================== ==================== =======================================
388+
Expression Return type Requirements
389+
=================== ==================== =======================================
390+
``c(a0, ..., aN)`` Convertible to ``R`` ``a0``..\ ``aN`` are tagged arguments.
391+
=================== ==================== =======================================
337392

338393
For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``Keywords``.
339394

@@ -404,21 +459,21 @@ Defines a named parameter enabled member function.
404459
in the order dictated by ``Keywords``, and the return type prepended.
405460
* An instance of ``Fwd`` must support this expression:
406461

407-
======================================================= ==================== ==============================================
408-
Expression Return type Requirements
409-
======================================================= ==================== ==============================================
410-
``fwd(boost::type<R>(), self, a0, ..., aN)`` Convertible to ``R`` ``self`` is a reference to the object on which
411-
the function should be invoked. ``a0``..\ ``aN``
412-
are tagged arguments.
413-
======================================================= ==================== ==============================================
462+
============================================ ==================== ==============================================
463+
Expression Return type Requirements
464+
============================================ ==================== ==============================================
465+
``fwd(boost::type<R>(), self, a0, , aN)`` Convertible to ``R`` ``self`` is a reference to the object on which
466+
the function should be invoked. ``a0````aN``
467+
are tagged arguments.
468+
============================================ ==================== ==============================================
414469

415470
For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``Keywords``.
416471

417472

418473
Example
419474
~~~~~~~
420475

421-
This example exports a member function ``f(int x, int y = ..)`` to Python.
476+
This example exports a member function ``f(int x, int y = )`` to Python.
422477
The |KeywordsSpec| ``mpl::vector2<tag::x, tag::y*>`` has an **arity range**
423478
of [2,2], so we only need one forwarding overload.
424479

@@ -432,7 +487,7 @@ of [2,2], so we only need one forwarding overload.
432487
(optional (y, \*))
433488
)
434489
{
435-
/\* .. \*/
490+
/\* \*/
436491
}
437492
};
438493
@@ -450,7 +505,7 @@ of [2,2], so we only need one forwarding overload.
450505
class_<X>("X")
451506
.def("f",
452507
function<
453-
fwd
508+
f_fwd
454509
, mpl::vector2<tag::x, tag::y\*>
455510
, mpl::vector3<void, int, int>
456511
>()
@@ -481,19 +536,19 @@ Defines a named parameter enabled free function in the current Python scope.
481536
prepended.
482537
* An instance of ``Fwd`` must support this expression:
483538

484-
======================================================= ==================== ==============================================
485-
Expression Return type Requirements
486-
======================================================= ==================== ==============================================
487-
``fwd(boost::type<R>(), a0, ..., aN)`` Convertible to ``R`` ``a0``..\ ``aN`` are tagged arguments.
488-
======================================================= ==================== ==============================================
539+
====================================== ==================== ======================================
540+
Expression Return type Requirements
541+
====================================== ==================== ======================================
542+
``fwd(boost::type<R>(), a0, , aN)`` Convertible to ``R`` ``a0````aN`` are tagged arguments.
543+
====================================== ==================== ======================================
489544

490545
For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``Keywords``.
491546

492547

493548
Example
494549
~~~~~~~
495550

496-
This example exports a function ``f(int x, int y = ...)`` to Python.
551+
This example exports a function ``f(int x, int y = )`` to Python.
497552
The |KeywordsSpec| ``mpl::vector2<tag::x, tag::y*>`` has an **arity range**
498553
of [2,2], so we only need one forwarding overload.
499554

@@ -504,7 +559,7 @@ of [2,2], so we only need one forwarding overload.
504559
(optional (y, \*))
505560
)
506561
{
507-
/\* .. \*/
562+
/\* \*/
508563
}
509564
510565
struct f_fwd
@@ -516,10 +571,10 @@ of [2,2], so we only need one forwarding overload.
516571
}
517572
};
518573
519-
BOOST_PYTHON_MODULE(..)
574+
BOOST_PYTHON_MODULE()
520575
{
521576
def<
522-
fwd
577+
f_fwd
523578
, mpl::vector2<tag::x, tag::y\*>
524579
, mpl::vector3<void, int, int>
525580
>("f");
@@ -533,4 +588,4 @@ Portability
533588
The Boost.Parameter Python binding library requires *partial template specialization*.
534589

535590
.. Oh. In that case, we don't have to worry so much about
536-
.. compilers that can't parse function types.
591+
.. compilers that can't parse function types.

0 commit comments

Comments
 (0)