@@ -52,41 +52,38 @@ must be specified. Additionally, because Boost.Parameter enabled
5252functions are templates, the desired function signature must be
5353specified.
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-
6455The keyword tags are specified as an `MPL Sequence `_, using the
6556pointer qualifications described in |KeywordsSpec |_ below. The
6657signature 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
7871Tutorial
7972--------
8073
8174In 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
8780The class and member function we are interested in binding looks
8881like 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+
165229concept |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
179243The **arity range ** of a |KeywordsSpec | is defined as the closed
180244range:
@@ -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
195259Sometimes 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-
227286In the above example the type of the default for ``color `` is ``mpl::false_ ``, a
228287type 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
235294overloads would need to be generated. The number of generated overloads is
236295equal 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
418473Example
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.
422477The |KeywordsSpec | ``mpl::vector2<tag::x, tag::y*> `` has an **arity range **
423478of [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
493548Example
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.
497552The |KeywordsSpec | ``mpl::vector2<tag::x, tag::y*> `` has an **arity range **
498553of [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
533588The 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