[29] | 1 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
---|
| 2 | The Boost Parameter Library Python Binding Documentation |
---|
| 3 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
---|
| 4 | |
---|
| 5 | :Authors: Daniel Wallin |
---|
| 6 | :Contact: dalwan01@student.umu.se |
---|
| 7 | :organization: `Boost Consulting`_ |
---|
| 8 | :date: $Date: 2006/09/21 17:33:28 $ |
---|
| 9 | |
---|
| 10 | :copyright: Copyright David Abrahams, Daniel Wallin |
---|
| 11 | 2005. 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) |
---|
| 14 | |
---|
| 15 | :abstract: Makes it possible to bind Boost.Parameter-enabled |
---|
| 16 | functions, operators and constructors to Python. |
---|
| 17 | |
---|
| 18 | |(logo)|__ |
---|
| 19 | |
---|
| 20 | .. |(logo)| image:: ../../../../boost.png |
---|
| 21 | :alt: Boost |
---|
| 22 | |
---|
| 23 | __ ../../../../index.htm |
---|
| 24 | |
---|
| 25 | .. _`Boost Consulting`: http://www.boost-consulting.com |
---|
| 26 | |
---|
| 27 | |
---|
| 28 | .. role:: class |
---|
| 29 | :class: class |
---|
| 30 | |
---|
| 31 | .. role:: concept |
---|
| 32 | :class: concept |
---|
| 33 | |
---|
| 34 | .. role:: function |
---|
| 35 | :class: function |
---|
| 36 | |
---|
| 37 | .. |ParameterSpec| replace:: :concept:`ParameterSpec` |
---|
| 38 | |
---|
| 39 | .. contents:: |
---|
| 40 | :depth: 1 |
---|
| 41 | |
---|
| 42 | Introduction |
---|
| 43 | ------------ |
---|
| 44 | |
---|
| 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. |
---|
| 49 | |
---|
| 50 | .. |def_visitor| replace:: ``def_visitor`` |
---|
| 51 | .. |def_visitors| replace:: ``def_visitors`` |
---|
| 52 | |
---|
| 53 | .. _def_visitor: def_visitors_ |
---|
| 54 | .. _def_visitors: ../../../python/doc/v2/def_visitor.html |
---|
| 55 | |
---|
| 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 |
---|
| 59 | specified. |
---|
| 60 | |
---|
| 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. |
---|
| 68 | |
---|
| 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. |
---|
| 74 | |
---|
| 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 |
---|
| 78 | .. function? |
---|
| 79 | |
---|
| 80 | .. _`MPL Sequence`: ../../../mpl/doc/refmanual/sequences.html |
---|
| 81 | .. _parameterspec: `concept ParameterSpec`_ |
---|
| 82 | |
---|
| 83 | Tutorial |
---|
| 84 | -------- |
---|
| 85 | |
---|
| 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. |
---|
| 89 | |
---|
| 90 | .. _macros: index.html |
---|
| 91 | |
---|
| 92 | The class and member function we are interested in binding looks |
---|
| 93 | like this: |
---|
| 94 | |
---|
| 95 | .. parsed-literal:: |
---|
| 96 | |
---|
| 97 | #include <boost/parameter/keyword.hpp> |
---|
| 98 | #include <boost/parameter/preprocessor.hpp> |
---|
| 99 | #include <boost/parameter/python.hpp> |
---|
| 100 | #include <boost/python.hpp> |
---|
| 101 | |
---|
| 102 | // First the keywords |
---|
| 103 | BOOST_PARAMETER_KEYWORD(tag, title) |
---|
| 104 | BOOST_PARAMETER_KEYWORD(tag, width) |
---|
| 105 | BOOST_PARAMETER_KEYWORD(tag, height) |
---|
| 106 | |
---|
| 107 | class window |
---|
| 108 | { |
---|
| 109 | public: |
---|
| 110 | BOOST_PARAMETER_MEMBER_FUNCTION( |
---|
| 111 | (void), open, tag, |
---|
| 112 | (required (title, (std::string))) |
---|
| 113 | (optional (width, (unsigned), 400) |
---|
| 114 | (height, (unsigned), 400)) |
---|
| 115 | ) |
---|
| 116 | { |
---|
| 117 | *… function implementation …* |
---|
| 118 | } |
---|
| 119 | }; |
---|
| 120 | |
---|
| 121 | .. @example.prepend('#include <cassert>') |
---|
| 122 | .. @example.replace_emphasis(''' |
---|
| 123 | assert(title == "foo"); |
---|
| 124 | assert(height == 20); |
---|
| 125 | assert(width == 400); |
---|
| 126 | ''') |
---|
| 127 | |
---|
| 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()``. |
---|
| 133 | |
---|
| 134 | To use ``boost::parameter::python::function`` we first need to define |
---|
| 135 | a class with forwarding overloads. |
---|
| 136 | |
---|
| 137 | :: |
---|
| 138 | |
---|
| 139 | struct open_fwd |
---|
| 140 | { |
---|
| 141 | template <class A0, class A1, class A2> |
---|
| 142 | void operator()( |
---|
| 143 | boost::type<void>, window& self |
---|
| 144 | , A0 const& a0, A1 const& a1, A2 const& a2 |
---|
| 145 | ) |
---|
| 146 | { |
---|
| 147 | self.open(a0, a1, a2); |
---|
| 148 | } |
---|
| 149 | }; |
---|
| 150 | |
---|
| 151 | The first parameter, ``boost::type<void>``, tells the forwarding overload |
---|
| 152 | what the return type should be. In this case we know that it's always void |
---|
| 153 | but in some cases, when we are exporting several specializations of a |
---|
| 154 | Boost.Parameter-enabled template, we need to use that parameter to |
---|
| 155 | deduce the return type. |
---|
| 156 | |
---|
| 157 | ``window::open()`` takes a total of 3 parameters, so the forwarding function |
---|
| 158 | needs to take three parameters as well. |
---|
| 159 | |
---|
| 160 | .. Note:: |
---|
| 161 | |
---|
| 162 | We only need one overload in the forwarding class, despite the |
---|
| 163 | fact that there are two optional parameters. There are special |
---|
| 164 | circumstances when several overload are needed; see |
---|
| 165 | `special keywords`_. |
---|
| 166 | |
---|
| 167 | Next we'll define the module and export the class: |
---|
| 168 | |
---|
| 169 | :: |
---|
| 170 | |
---|
| 171 | BOOST_PYTHON_MODULE(my_module) |
---|
| 172 | { |
---|
| 173 | using namespace boost::python; |
---|
| 174 | namespace py = boost::parameter::python; |
---|
| 175 | namespace mpl = boost::mpl; |
---|
| 176 | |
---|
| 177 | class_<window>("window") |
---|
| 178 | .def( |
---|
| 179 | "open", py::function< |
---|
| 180 | open_fwd |
---|
| 181 | , mpl::vector< |
---|
| 182 | void |
---|
| 183 | , tag::title(std::string) |
---|
| 184 | , tag::width*(unsigned) |
---|
| 185 | , tag::height*(unsigned) |
---|
| 186 | > |
---|
| 187 | >() |
---|
| 188 | ); |
---|
| 189 | } |
---|
| 190 | |
---|
| 191 | .. @jam_prefix.append('import python ;') |
---|
| 192 | .. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;') |
---|
| 193 | .. @my_module = build( |
---|
| 194 | output = 'my_module' |
---|
| 195 | , target_rule = 'python-extension' |
---|
| 196 | , input = '/boost/python//boost_python' |
---|
| 197 | , howmany = 'all' |
---|
| 198 | ) |
---|
| 199 | |
---|
| 200 | .. @del jam_prefix[:] |
---|
| 201 | |
---|
| 202 | ``py::function`` is passed two parameters. The first one is the class with |
---|
| 203 | forwarding overloads that we defined earlier. The second one is an `MPL |
---|
| 204 | Sequence`_ with the keyword tag types and argument types for the function |
---|
| 205 | specified as function types. The pointer syntax used in ``tag::width*`` and |
---|
| 206 | ``tag::height*`` means that the parameter is optional. The first element of |
---|
| 207 | the `MPL Sequence`_ is the return type of the function, in this case ``void``. |
---|
| 208 | |
---|
| 209 | .. The |
---|
| 210 | pointer syntax means that the parameter is optional, so in this case |
---|
| 211 | ``width`` and ``height`` are optional parameters. The third parameter |
---|
| 212 | is an `MPL Sequence`_ with the desired function signature. The return type comes first, and |
---|
| 213 | then the parameter types: |
---|
| 214 | |
---|
| 215 | .. parsed-literal:: |
---|
| 216 | |
---|
| 217 | mpl::vector<void, std::string, unsigned, unsigned> |
---|
| 218 | *return type* *title* *width* *height* |
---|
| 219 | |
---|
| 220 | .. @ignore() |
---|
| 221 | |
---|
| 222 | That's it! This class can now be used in Python with the expected syntax:: |
---|
| 223 | |
---|
| 224 | >>> w = my_module.window() |
---|
| 225 | >>> w.open(title = "foo", height = 20) |
---|
| 226 | |
---|
| 227 | .. @example.prepend('import my_module') |
---|
| 228 | .. @run_python(module_path = my_module) |
---|
| 229 | |
---|
| 230 | .. Sorry to say this at such a late date, but this syntax really |
---|
| 231 | .. strikes me as cumbersome. Couldn't we do something like: |
---|
| 232 | |
---|
| 233 | class_<window>("window") |
---|
| 234 | .def( |
---|
| 235 | "open", |
---|
| 236 | (void (*)( |
---|
| 237 | tag::title(std::string), |
---|
| 238 | tag::width*(unsigned), |
---|
| 239 | tag::height*(unsigned)) |
---|
| 240 | )0 |
---|
| 241 | ); |
---|
| 242 | |
---|
| 243 | or at least: |
---|
| 244 | |
---|
| 245 | class_<window>("window") |
---|
| 246 | .def( |
---|
| 247 | "open", |
---|
| 248 | mpl::vector< |
---|
| 249 | void, |
---|
| 250 | tag::title(std::string), |
---|
| 251 | tag::width*(unsigned), |
---|
| 252 | tag::height*(unsigned) |
---|
| 253 | >() |
---|
| 254 | ); |
---|
| 255 | |
---|
| 256 | assuming, that is, that we will have to repeat the tags (yes, |
---|
| 257 | users of broken compilers will have to give us function pointer |
---|
| 258 | types instead). |
---|
| 259 | |
---|
| 260 | ------------------------------------------------------------------------------ |
---|
| 261 | |
---|
| 262 | concept |ParameterSpec| |
---|
| 263 | ----------------------- |
---|
| 264 | |
---|
| 265 | A |ParameterSpec| is a function type ``K(T)`` that describes both the keyword tag, |
---|
| 266 | ``K``, and the argument type, ``T``, for a parameter. |
---|
| 267 | |
---|
| 268 | ``K`` is either: |
---|
| 269 | |
---|
| 270 | * A *required* keyword of the form ``Tag`` |
---|
| 271 | * **or**, an *optional* keyword of the form ``Tag*`` |
---|
| 272 | * **or**, a *special* keyword of the form ``Tag**`` |
---|
| 273 | |
---|
| 274 | where ``Tag`` is a keyword tag type, as used in a specialization |
---|
| 275 | of |keyword|__. |
---|
| 276 | |
---|
| 277 | .. |keyword| replace:: ``boost::parameter::keyword`` |
---|
| 278 | __ ../../../parameter/doc/html/reference.html#keyword |
---|
| 279 | |
---|
| 280 | The **arity range** for an `MPL Sequence`_ of |ParameterSpec|'s is |
---|
| 281 | defined as the closed range: |
---|
| 282 | |
---|
| 283 | .. parsed-literal:: |
---|
| 284 | |
---|
| 285 | [ mpl::size<S> - number of *special* keyword tags in ``S``, mpl::size<S> ] |
---|
| 286 | |
---|
| 287 | For example, the **arity range** of ``mpl::vector2<x(int),y(int)>`` is ``[2,2]``, |
---|
| 288 | the **arity range** of ``mpl::vector2<x(int),y*(int)>`` is ``[2,2]`` and the |
---|
| 289 | **arity range** of ``mpl::vector2<x(int),y**(int)>`` is ``[1,2]``. |
---|
| 290 | |
---|
| 291 | |
---|
| 292 | |
---|
| 293 | *special* keywords |
---|
| 294 | --------------------------------- |
---|
| 295 | |
---|
| 296 | Sometimes it is desirable to have a default value for a parameter that differ |
---|
| 297 | in type from the parameter. This technique is useful for doing simple tag-dispatching |
---|
| 298 | based on the presence of a parameter. An example_ of this is given in the Boost.Parameter |
---|
| 299 | docs. The example uses a different technique, but could also have been written like this: |
---|
| 300 | |
---|
| 301 | .. parsed-literal:: |
---|
| 302 | |
---|
| 303 | namespace core |
---|
| 304 | { |
---|
| 305 | template <class ArgumentPack> |
---|
| 306 | void dfs_dispatch(ArgumentPack const& args, mpl::false\_) |
---|
| 307 | { |
---|
| 308 | *…compute and use default color map…* |
---|
| 309 | } |
---|
| 310 | |
---|
| 311 | template <class ArgumentPack, class ColorMap> |
---|
| 312 | void dfs_dispatch(ArgumentPack const& args, ColorMap colormap) |
---|
| 313 | { |
---|
| 314 | *…use colormap…* |
---|
| 315 | } |
---|
| 316 | } |
---|
| 317 | |
---|
| 318 | template <class ArgumentPack> |
---|
| 319 | void depth_first_search(ArgumentPack const& args) |
---|
| 320 | { |
---|
| 321 | core::dfs_dispatch(args, args[color | mpl::false_()]); |
---|
| 322 | } |
---|
| 323 | |
---|
| 324 | .. @example.prepend(''' |
---|
| 325 | #include <boost/parameter/keyword.hpp> |
---|
| 326 | #include <boost/parameter/parameters.hpp> |
---|
| 327 | #include <boost/mpl/bool.hpp> |
---|
| 328 | #include <cassert> |
---|
| 329 | |
---|
| 330 | BOOST_PARAMETER_KEYWORD(tag, color); |
---|
| 331 | |
---|
| 332 | typedef boost::parameter::parameters<tag::color> params; |
---|
| 333 | |
---|
| 334 | namespace mpl = boost::mpl; |
---|
| 335 | ''') |
---|
| 336 | |
---|
| 337 | .. @example.replace_emphasis(''' |
---|
| 338 | assert(args[color | 1] == 1); |
---|
| 339 | ''') |
---|
| 340 | |
---|
| 341 | .. @example.replace_emphasis(''' |
---|
| 342 | assert(args[color | 1] == 0); |
---|
| 343 | ''') |
---|
| 344 | |
---|
| 345 | .. @example.append(''' |
---|
| 346 | int main() |
---|
| 347 | { |
---|
| 348 | depth_first_search(params()()); |
---|
| 349 | depth_first_search(params()(color = 0)); |
---|
| 350 | }''') |
---|
| 351 | |
---|
| 352 | .. @build() |
---|
| 353 | |
---|
| 354 | .. _example: index.html#dispatching-based-on-the-presence-of-a-default |
---|
| 355 | |
---|
| 356 | In the above example the type of the default for ``color`` is ``mpl::false_``, a |
---|
| 357 | type that is distinct from any color map that the user might supply. |
---|
| 358 | |
---|
| 359 | When binding the case outlined above, the default type for ``color`` will not |
---|
| 360 | be convertible to the parameter type. Therefore we need to tag the ``color`` |
---|
| 361 | keyword as a *special* keyword. By doing this we tell the binding functions |
---|
| 362 | that it needs to generate two overloads, one with the ``color`` parameter |
---|
| 363 | present and one without. Had there been two *special* keywords, four |
---|
| 364 | overloads would need to be generated. The number of generated overloads is |
---|
| 365 | equal to 2\ :sup:`N`, where ``N`` is the number of *special* keywords. |
---|
| 366 | |
---|
| 367 | ------------------------------------------------------------------------------ |
---|
| 368 | |
---|
| 369 | class template ``init`` |
---|
| 370 | ----------------------- |
---|
| 371 | |
---|
| 372 | Defines a named parameter enabled constructor. |
---|
| 373 | |
---|
| 374 | .. parsed-literal:: |
---|
| 375 | |
---|
| 376 | template <class ParameterSpecs> |
---|
| 377 | struct init : python::def_visitor<init<ParameterSpecs> > |
---|
| 378 | { |
---|
| 379 | template <class Class> |
---|
| 380 | void def(Class& class\_); |
---|
| 381 | |
---|
| 382 | template <class CallPolicies> |
---|
| 383 | *def\_visitor* operator[](CallPolicies const& policies) const; |
---|
| 384 | }; |
---|
| 385 | |
---|
| 386 | .. @ignore() |
---|
| 387 | |
---|
| 388 | ``init`` requirements |
---|
| 389 | ~~~~~~~~~~~~~~~~~~~~~ |
---|
| 390 | |
---|
| 391 | * ``ParameterSpecs`` is an `MPL sequence`_ where each element is a |
---|
| 392 | model of |ParameterSpec|. |
---|
| 393 | * For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity |
---|
| 394 | range** of ``ParameterSpecs``, ``Class`` must support these |
---|
| 395 | expressions: |
---|
| 396 | |
---|
| 397 | ======================= ============= ========================================= |
---|
| 398 | Expression Return type Requirements |
---|
| 399 | ======================= ============= ========================================= |
---|
| 400 | ``Class(a0, …, aN)`` \- ``a0``\ …\ ``aN`` are tagged arguments. |
---|
| 401 | ======================= ============= ========================================= |
---|
| 402 | |
---|
| 403 | |
---|
| 404 | |
---|
| 405 | ``template <class CallPolicies> operator[](CallPolicies const&)`` |
---|
| 406 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 407 | |
---|
| 408 | Returns a ``def_visitor`` equivalent to ``*this``, except that it |
---|
| 409 | uses CallPolicies when creating the binding. |
---|
| 410 | |
---|
| 411 | |
---|
| 412 | Example |
---|
| 413 | ~~~~~~~ |
---|
| 414 | |
---|
| 415 | .. parsed-literal:: |
---|
| 416 | |
---|
| 417 | #include <boost/parameter/keyword.hpp> |
---|
| 418 | #include <boost/parameter/preprocessor.hpp> |
---|
| 419 | #include <boost/parameter/python.hpp> |
---|
| 420 | #include <boost/python.hpp> |
---|
| 421 | #include <boost/mpl/vector.hpp> |
---|
| 422 | |
---|
| 423 | BOOST_PARAMETER_KEYWORD(tag, x) |
---|
| 424 | BOOST_PARAMETER_KEYWORD(tag, y) |
---|
| 425 | |
---|
| 426 | struct base |
---|
| 427 | { |
---|
| 428 | template <class ArgumentPack> |
---|
| 429 | base(ArgumentPack const& args) |
---|
| 430 | { |
---|
| 431 | *… use args …* |
---|
| 432 | } |
---|
| 433 | }; |
---|
| 434 | |
---|
| 435 | class X : base |
---|
| 436 | { |
---|
| 437 | public: |
---|
| 438 | BOOST_PARAMETER_CONSTRUCTOR(X, (base), tag, |
---|
| 439 | (required (x, \*)) |
---|
| 440 | (optional (y, \*)) |
---|
| 441 | ) |
---|
| 442 | }; |
---|
| 443 | |
---|
| 444 | BOOST_PYTHON_MODULE(*module name*) |
---|
| 445 | { |
---|
| 446 | using namespace boost::python; |
---|
| 447 | namespace py = boost::parameter::python; |
---|
| 448 | namespace mpl = boost::mpl; |
---|
| 449 | |
---|
| 450 | class_<X>("X", no_init) |
---|
| 451 | .def( |
---|
| 452 | py::init< |
---|
| 453 | mpl::vector<tag::x(int), tag::y\*(int)> |
---|
| 454 | >() |
---|
| 455 | ); |
---|
| 456 | } |
---|
| 457 | |
---|
| 458 | .. @example.replace_emphasis(''' |
---|
| 459 | assert(args[x] == 0); |
---|
| 460 | assert(args[y | 1] == 1); |
---|
| 461 | ''') |
---|
| 462 | |
---|
| 463 | .. @example.replace_emphasis('my_module') |
---|
| 464 | |
---|
| 465 | .. @jam_prefix.append('import python ;') |
---|
| 466 | .. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;') |
---|
| 467 | .. @my_module = build( |
---|
| 468 | output = 'my_module' |
---|
| 469 | , target_rule = 'python-extension' |
---|
| 470 | , input = '/boost/python//boost_python' |
---|
| 471 | ) |
---|
| 472 | |
---|
| 473 | ------------------------------------------------------------------------------ |
---|
| 474 | |
---|
| 475 | class template ``call`` |
---|
| 476 | ----------------------- |
---|
| 477 | |
---|
| 478 | Defines a ``__call__`` operator, mapped to ``operator()`` in C++. |
---|
| 479 | |
---|
| 480 | .. parsed-literal:: |
---|
| 481 | |
---|
| 482 | template <class ParameterSpecs> |
---|
| 483 | struct call : python::def_visitor<call<ParameterSpecs> > |
---|
| 484 | { |
---|
| 485 | template <class Class> |
---|
| 486 | void def(Class& class\_); |
---|
| 487 | |
---|
| 488 | template <class CallPolicies> |
---|
| 489 | *def\_visitor* operator[](CallPolicies const& policies) const; |
---|
| 490 | }; |
---|
| 491 | |
---|
| 492 | .. @ignore() |
---|
| 493 | |
---|
| 494 | ``call`` requirements |
---|
| 495 | ~~~~~~~~~~~~~~~~~~~~~ |
---|
| 496 | |
---|
| 497 | * ``ParameterSpecs`` is an `MPL sequence`_ where each element |
---|
| 498 | except the first models |ParameterSpec|. The first element |
---|
| 499 | is the result type of ``c(…)``. |
---|
| 500 | * ``Class`` must support these expressions, where ``c`` is an |
---|
| 501 | instance of ``Class``: |
---|
| 502 | |
---|
| 503 | =================== ==================== ======================================= |
---|
| 504 | Expression Return type Requirements |
---|
| 505 | =================== ==================== ======================================= |
---|
| 506 | ``c(a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments. |
---|
| 507 | =================== ==================== ======================================= |
---|
| 508 | |
---|
| 509 | For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``. |
---|
| 510 | |
---|
| 511 | |
---|
| 512 | ``template <class CallPolicies> operator[](CallPolicies const&)`` |
---|
| 513 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 514 | |
---|
| 515 | Returns a ``def_visitor`` equivalent to ``*this``, except that it |
---|
| 516 | uses CallPolicies when creating the binding. |
---|
| 517 | |
---|
| 518 | |
---|
| 519 | Example |
---|
| 520 | ~~~~~~~ |
---|
| 521 | |
---|
| 522 | .. parsed-literal:: |
---|
| 523 | |
---|
| 524 | #include <boost/parameter/keyword.hpp> |
---|
| 525 | #include <boost/parameter/preprocessor.hpp> |
---|
| 526 | #include <boost/parameter/python.hpp> |
---|
| 527 | #include <boost/python.hpp> |
---|
| 528 | #include <boost/mpl/vector.hpp> |
---|
| 529 | |
---|
| 530 | BOOST_PARAMETER_KEYWORD(tag, x) |
---|
| 531 | BOOST_PARAMETER_KEYWORD(tag, y) |
---|
| 532 | |
---|
| 533 | namespace parameter = boost::parameter; |
---|
| 534 | |
---|
| 535 | typedef parameter::parameters< |
---|
| 536 | parameter::required<tag::x> |
---|
| 537 | , parameter::optional<tag::y> |
---|
| 538 | > call_parameters; |
---|
| 539 | |
---|
| 540 | class X |
---|
| 541 | { |
---|
| 542 | public: |
---|
| 543 | template <class ArgumentPack> |
---|
| 544 | int call_impl(ArgumentPack const& args) |
---|
| 545 | { |
---|
| 546 | *… use args …* |
---|
| 547 | } |
---|
| 548 | |
---|
| 549 | template <class A0> |
---|
| 550 | int operator()(A0 const& a0) |
---|
| 551 | { |
---|
| 552 | return call_impl(call_parameters()(a0)); |
---|
| 553 | } |
---|
| 554 | |
---|
| 555 | template <class A0, class A1> |
---|
| 556 | int operator()(A0 const& a0, A1 const& a1) |
---|
| 557 | { |
---|
| 558 | return call_impl(call_parameters()(a0,a1)); |
---|
| 559 | } |
---|
| 560 | }; |
---|
| 561 | |
---|
| 562 | BOOST_PYTHON_MODULE(*module name*) |
---|
| 563 | { |
---|
| 564 | using namespace boost::python; |
---|
| 565 | namespace py = parameter::python; |
---|
| 566 | namespace mpl = boost::mpl; |
---|
| 567 | |
---|
| 568 | class_<X>("X") |
---|
| 569 | .def( |
---|
| 570 | py::call< |
---|
| 571 | mpl::vector<int, tag::x(int), tag::y\*(int)> |
---|
| 572 | >() |
---|
| 573 | ); |
---|
| 574 | } |
---|
| 575 | |
---|
| 576 | .. @example.replace_emphasis(''' |
---|
| 577 | assert(args[x] == 0); |
---|
| 578 | assert(args[y | 1] == 1); |
---|
| 579 | return 0; |
---|
| 580 | ''') |
---|
| 581 | |
---|
| 582 | .. @example.replace_emphasis('my_module') |
---|
| 583 | |
---|
| 584 | .. @my_module = build( |
---|
| 585 | output = 'my_module' |
---|
| 586 | , target_rule = 'python-extension' |
---|
| 587 | , input = '/boost/python//boost_python' |
---|
| 588 | ) |
---|
| 589 | |
---|
| 590 | ------------------------------------------------------------------------------ |
---|
| 591 | |
---|
| 592 | class template ``function`` |
---|
| 593 | --------------------------- |
---|
| 594 | |
---|
| 595 | Defines a named parameter enabled member function. |
---|
| 596 | |
---|
| 597 | .. parsed-literal:: |
---|
| 598 | |
---|
| 599 | template <class Fwd, class ParameterSpecs> |
---|
| 600 | struct function : python::def_visitor<function<Fwd, ParameterSpecs> > |
---|
| 601 | { |
---|
| 602 | template <class Class, class Options> |
---|
| 603 | void def(Class& class\_, char const* name, Options const& options); |
---|
| 604 | }; |
---|
| 605 | |
---|
| 606 | .. @ignore() |
---|
| 607 | |
---|
| 608 | ``function`` requirements |
---|
| 609 | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 610 | |
---|
| 611 | * ``ParameterSpecs`` is an `MPL sequence`_ where each element |
---|
| 612 | except the first models |ParameterSpec|. The first element |
---|
| 613 | is the result type of ``c.f(…)``, where ``f`` is the member |
---|
| 614 | function. |
---|
| 615 | * An instance of ``Fwd`` must support this expression: |
---|
| 616 | |
---|
| 617 | ============================================ ==================== ================================================= |
---|
| 618 | Expression Return type Requirements |
---|
| 619 | ============================================ ==================== ================================================= |
---|
| 620 | ``fwd(boost::type<R>(), self, a0, …, aN)`` Convertible to ``R`` ``self`` is a reference to the object on which |
---|
| 621 | the function should be invoked. ``a0``\ …\ ``aN`` |
---|
| 622 | are tagged arguments. |
---|
| 623 | ============================================ ==================== ================================================= |
---|
| 624 | |
---|
| 625 | For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``. |
---|
| 626 | |
---|
| 627 | |
---|
| 628 | Example |
---|
| 629 | ~~~~~~~ |
---|
| 630 | |
---|
| 631 | This example exports a member function ``f(int x, int y = …)`` to Python. The |
---|
| 632 | sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has |
---|
| 633 | an **arity range** of [2,2], so we only need one forwarding overload. |
---|
| 634 | |
---|
| 635 | .. parsed-literal:: |
---|
| 636 | |
---|
| 637 | #include <boost/parameter/keyword.hpp> |
---|
| 638 | #include <boost/parameter/preprocessor.hpp> |
---|
| 639 | #include <boost/parameter/python.hpp> |
---|
| 640 | #include <boost/python.hpp> |
---|
| 641 | #include <boost/mpl/vector.hpp> |
---|
| 642 | |
---|
| 643 | BOOST_PARAMETER_KEYWORD(tag, x) |
---|
| 644 | BOOST_PARAMETER_KEYWORD(tag, y) |
---|
| 645 | |
---|
| 646 | class X |
---|
| 647 | { |
---|
| 648 | public: |
---|
| 649 | BOOST_PARAMETER_MEMBER_FUNCTION((void), f, tag, |
---|
| 650 | (required (x, \*)) |
---|
| 651 | (optional (y, \*, 1)) |
---|
| 652 | ) |
---|
| 653 | { |
---|
| 654 | *…* |
---|
| 655 | } |
---|
| 656 | }; |
---|
| 657 | |
---|
| 658 | struct f_fwd |
---|
| 659 | { |
---|
| 660 | template <class A0, class A1> |
---|
| 661 | void operator()(boost::type<void>, X& self, A0 const& a0, A1 const& a1) |
---|
| 662 | { |
---|
| 663 | self.f(a0, a1); |
---|
| 664 | } |
---|
| 665 | }; |
---|
| 666 | |
---|
| 667 | BOOST_PYTHON_MODULE(*module name*) |
---|
| 668 | { |
---|
| 669 | using namespace boost::python; |
---|
| 670 | namespace py = boost::parameter::python; |
---|
| 671 | namespace mpl = boost::mpl; |
---|
| 672 | |
---|
| 673 | class_<X>("X") |
---|
| 674 | .def("f", |
---|
| 675 | py::function< |
---|
| 676 | f_fwd |
---|
| 677 | , mpl::vector<void, tag::x(int), tag::y\*(int)> |
---|
| 678 | >() |
---|
| 679 | ); |
---|
| 680 | } |
---|
| 681 | |
---|
| 682 | .. @example.replace_emphasis(''' |
---|
| 683 | assert(x == 0); |
---|
| 684 | assert(y == 1); |
---|
| 685 | ''') |
---|
| 686 | |
---|
| 687 | .. @example.replace_emphasis('my_module') |
---|
| 688 | |
---|
| 689 | .. @my_module = build( |
---|
| 690 | output = 'my_module' |
---|
| 691 | , target_rule = 'python-extension' |
---|
| 692 | , input = '/boost/python//boost_python' |
---|
| 693 | ) |
---|
| 694 | |
---|
| 695 | ------------------------------------------------------------------------------ |
---|
| 696 | |
---|
| 697 | function template ``def`` |
---|
| 698 | ------------------------- |
---|
| 699 | |
---|
| 700 | Defines a named parameter enabled free function in the current Python scope. |
---|
| 701 | |
---|
| 702 | .. parsed-literal:: |
---|
| 703 | |
---|
| 704 | template <class Fwd, class ParameterSpecs> |
---|
| 705 | void def(char const* name); |
---|
| 706 | |
---|
| 707 | .. @ignore() |
---|
| 708 | |
---|
| 709 | ``def`` requirements |
---|
| 710 | ~~~~~~~~~~~~~~~~~~~~ |
---|
| 711 | |
---|
| 712 | * ``ParameterSpecs`` is an `MPL sequence`_ where each element |
---|
| 713 | except the first models |ParameterSpec|. The first element |
---|
| 714 | is the result type of ``f(…)``, where ``f`` is the function. |
---|
| 715 | * An instance of ``Fwd`` must support this expression: |
---|
| 716 | |
---|
| 717 | ====================================== ==================== ======================================= |
---|
| 718 | Expression Return type Requirements |
---|
| 719 | ====================================== ==================== ======================================= |
---|
| 720 | ``fwd(boost::type<R>(), a0, …, aN)`` Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments. |
---|
| 721 | ====================================== ==================== ======================================= |
---|
| 722 | |
---|
| 723 | For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity range** of ``ParameterSpecs``. |
---|
| 724 | |
---|
| 725 | |
---|
| 726 | Example |
---|
| 727 | ~~~~~~~ |
---|
| 728 | |
---|
| 729 | This example exports a function ``f(int x, int y = …)`` to Python. The |
---|
| 730 | sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has |
---|
| 731 | an **arity range** of [2,2], so we only need one forwarding overload. |
---|
| 732 | |
---|
| 733 | .. parsed-literal:: |
---|
| 734 | |
---|
| 735 | BOOST_PARAMETER_FUNCTION((void), f, tag, |
---|
| 736 | (required (x, \*)) |
---|
| 737 | (optional (y, \*, 1)) |
---|
| 738 | ) |
---|
| 739 | { |
---|
| 740 | *…* |
---|
| 741 | } |
---|
| 742 | |
---|
| 743 | struct f_fwd |
---|
| 744 | { |
---|
| 745 | template <class A0, class A1> |
---|
| 746 | void operator()(boost::type<void>, A0 const& a0, A1 const& a1) |
---|
| 747 | { |
---|
| 748 | f(a0, a1); |
---|
| 749 | } |
---|
| 750 | }; |
---|
| 751 | |
---|
| 752 | BOOST_PYTHON_MODULE(…) |
---|
| 753 | { |
---|
| 754 | def< |
---|
| 755 | f_fwd |
---|
| 756 | , mpl::vector< |
---|
| 757 | void, tag::\ x(int), tag::\ y\*(int) |
---|
| 758 | > |
---|
| 759 | >("f"); |
---|
| 760 | } |
---|
| 761 | |
---|
| 762 | .. @ignore() |
---|
| 763 | |
---|
| 764 | .. again, the undefined ``fwd`` identifier. |
---|
| 765 | |
---|
| 766 | Portability |
---|
| 767 | ----------- |
---|
| 768 | |
---|
| 769 | The Boost.Parameter Python binding library requires *partial template |
---|
| 770 | specialization*. |
---|
| 771 | |
---|