diff --git a/doc/python.rst b/doc/python.rst index 8ae3d52..3b4b7a8 100755 --- a/doc/python.rst +++ b/doc/python.rst @@ -39,7 +39,7 @@ __ ../../../../index.htm Introduction ------------ -``boost/parameter/python.hpp`` introduces a group of **def_visitors** that can +``boost/parameter/python.hpp`` introduces a group of def_visitors_ that can be used to easily expose Boost.Parameter-enabled member functions to Python with Boost.Python. It also provides a function template ``def()`` that can be used to expose Boost.Parameter-enabled free functions. @@ -47,25 +47,42 @@ to expose Boost.Parameter-enabled free functions. .. Need a link from "def_visitors" to the place in Python docs .. where that's defined. +.. _def_visitors: ../../../python/doc/v2/def_visitor.html + +To bind a Boost.Parameter enabled function the keyword tags must be specified. +Additionally, because Boost.Parameter enabled functions are templates, the +desired function signature must be specified. + +The keyword tags are specified using the syntax described in |KeywordsSpec| below, +and the signature as an MPL sequence of parameter types. Additional data may be +needed in the signature sequence by specific binding utilities. For example, +``function`` requires the return type to be part of the signature sequence. + + concept |KeywordsSpec| ---------------------- A |KeywordsSpec| is an MPL sequence where each element is either: -* A *required* keyword tag of the form ``K`` -* **or**, an *optional* keyword tag of the form ``K*`` -* **or**, a *special* keyword tag of the formn ``K**`` +* A *required* keyword of the form ``K`` +* **or**, an *optional* keyword of the form ``K*`` +* **or**, a *special* keyword of the form ``K**`` + +where ``K`` is a `keyword tag type`_. + +.. _keyword tag type: reference.html#terminology .. here you have to say, "where K is..." +.. # -The **arity range** of a |KeywordsSpec| is determined by: +The **arity range** of a |KeywordsSpec| is defined as: .. parsed-literal:: [ mpl::size - number of *special* keyword tags in ``S`` , mpl::size ] -For example, the **arity range** of ``mpl::vector2`` is 2, the **arity range** of -``mpl::vector2`` is 2 and the **arity range** of ``mpl::vector2`` is 1. +For example, the **arity range** of ``mpl::vector2`` is [2,2], the **arity range** of +``mpl::vector2`` is [2,2] and the **arity range** of ``mpl::vector2`` is [1,2]. .. It makes no sense to say that the "range" of something is x, .. where x is just a number. A range goes from x to y. I don't @@ -74,82 +91,123 @@ For example, the **arity range** of ``mpl::vector2`` is 2, the **arity rang .. results above. I'd have guessed that the arity range of .. vector2 was [1,2] ... which makes some sense. +.. # + + *special* keyword tags --------------------------------- -If the default type for an argument is not convertible to the argument type, as -specified to the binding functions below, that argument must be specified as a -*special* argument. - -.. This whole thing comes out of order. You need to explain that -.. to bind pararameter-endabled functions to python you need to -.. specify an parameter type (not an argument type), and that an -.. optional argument has to have a default value _and_ type. -.. I think. If that's not the right explanation, you need to say -.. something that sets up similar context. - -In the example below the default type for argument ``y`` is ``char const[5]``, but -the argument type is ``int``. Therefore ``y`` must be specified as a *special* -argument in the |KeywordsSpec|. - -.. The example below doesn't make any sense to me. Where does char -.. const[5] come from? Why would I choose a different argument -.. type from a default type. What is the effect on the resulting -.. Python interface? - -Doing this will generate N^2 overloads, where N is the number of *special* arguments. -In this case two overloads will be generated, one with ``y`` included and one without. -Having many *special* keywords will result in lots of overloads, and stress the -compiler. - -.. using "this" without an antecedent above. What are we "doing?" -.. Don't you mean 2^N? - -Note that this makes the *arity range* ``[1,2]``, so we'll need two forwarding overloads. +Sometimes it is desirable to have a default value for a parameter that differ +in type from the parameter. This technique is useful for doing simple tag-dispatching +based on the presence of a parameter. An example_ of this is given in the Boost.Parameter +docs. The example uses a different technique, but could also have been written like this: .. parsed-literal:: - BOOST_PARAMETER_FUNCTION((void), f, tag, - (required (x, \*)) - (optional (y, \*)) - ) - { - std::cout << args[x] << args[y | "none"] << "\n"; - } + template + void dfs_dispatch(ArgumentPack& args, mpl::false\_) + { + *…compute and use default color map…* + } + + template + void dfs_dispatch(ArgumentPack& args, ColorMap colormap) + { + *…use colormap…* + } + + template + void depth_first_search(ArgumentPack& args) + { + core::dfs_dispatch(args, args[color | mpl::false_()); + } - struct f_fwd - { - template - void operator()(boost::type, A0 const& a0) +.. _example: index.html#dispatching-based-on-the-presence-of-a-default + +In the above example the type of the default for ``color`` is ``mpl::false_``, a +type that is distinct from any color map that the user might supply. + +When binding the case outlined above, the default type for ``color`` will not +be convertible to the parameter type. Therefore we need to tag the ``color`` +keyword as a *special* keyword. By doing this we tell the binding functions +that it needs to generate two overloads, one with the ``color`` parameter +present and one without. If we would have had two *special* keywords, four +overloads would need to be generated. The number of generated overloads is +equal to ``2^N``, where ``N`` is the number of *special* keywords. + +.. If the default type for an argument is not convertible to the argument type, as + specified to the binding functions below, that argument must be specified as a + *special* argument. + + .. This whole thing comes out of order. You need to explain that + .. to bind pararameter-endabled functions to python you need to + .. specify an parameter type (not an argument type), and that an + .. optional argument has to have a default value _and_ type. + .. I think. If that's not the right explanation, you need to say + .. something that sets up similar context. + + In the example below the default type for argument ``y`` is ``char const[5]``, but + the argument type is ``int``. Therefore ``y`` must be specified as a *special* + argument in the |KeywordsSpec|. + + .. The example below doesn't make any sense to me. Where does char + .. const[5] come from? Why would I choose a different argument + .. type from a default type. What is the effect on the resulting + .. Python interface? + + Doing this will generate ``2^N`` overloads, where ``N`` is the number of *special* parameters. + In this case two overloads will be generated, one with ``y`` included and one without. + Having many *special* keywords will result in lots of overloads, and stress the + compiler. + + .. using "this" without an antecedent above. What are we "doing?" + .. Don't you mean 2^N? + + Note that this makes the *arity range* ``[1,2]``, so we'll need two forwarding overloads. + + .. parsed-literal:: + + BOOST_PARAMETER_FUNCTION((void), f, tag, + (required (x, \*)) + (optional (y, \*)) + ) { - f(a0); + std::cout << args[x] << args[y | "none"] << "\n"; } - template - void operator()(boost::type, A0 const& a0, A1 const& a1) + struct f_fwd { - f(a0, a1); + template + void operator()(boost::type, A0 const& a0) + { + f(a0); + } + + template + void operator()(boost::type, A0 const& a0, A1 const& a1) + { + f(a0, a1); + } + }; + + BOOST_PYTHON_MODULE(..) + { + class_("X") + .def("f", + function< + fwd + , mpl::vector2 + , mpl::vector3 + >() + ); } - }; + - BOOST_PYTHON_MODULE(..) - { - class_("X") - .def("f", - function< - fwd - , mpl::vector2 - , mpl::vector3 - >() - ); - } - - -.. You don't explain what those boost::type things are all -.. about. -.. Weren't we going to generate the f_fwd struct ourselves? -.. I don't think this code has been tested. I see the identifier -.. "fwd" above, which surely must be wrong. + .. You don't explain what those boost::type things are all + .. about. + .. Weren't we going to generate the f_fwd struct ourselves? + .. I don't think this code has been tested. I see the identifier + .. "fwd" above, which surely must be wrong. ------------------------------------------------------------------------------ @@ -171,7 +229,7 @@ Defines a named parameter enabled constructor. ~~~~~~~~~~~~~~~~~~~~~ * ``Keywords`` is a model of |KeywordsSpec|. -* ``Signature`` is an MPL sequence with the types of the keyword arguments, +* ``Signature`` is an MPL sequence with the types of the keyword , in the order dictated by ``Keywords``. * ``Class`` must support these expressions: @@ -230,7 +288,7 @@ Defines a ``__call__`` operator, mapped to ``operator()`` in C++. ~~~~~~~~~~~~~~~~~~~~~ * ``Keywords`` is a model of |KeywordsSpec|. -* ``Signature`` is an MPL sequence with the types of the keyword arguments, +* ``Signature`` is an MPL sequence with the types of the keyword parameters, in the order dictated by ``Keywords``, and the return type prepended. * ``Class`` must support these expressions, where ``c`` is an instance of ``Class``: @@ -305,7 +363,7 @@ Defines a named parameter enabled member function. ~~~~~~~~~~~~~~~~~~~~~~~~~ * ``Keywords`` is a model of |KeywordsSpec|. -* ``Signature`` is an MPL sequence with the types of the keyword arguments, +* ``Signature`` is an MPL sequence with the types of the keyword parameters, in the order dictated by ``Keywords``, and the return type prepended. * An instance of ``Fwd`` must support this expression: @@ -378,7 +436,7 @@ Defines a named parameter enabled free function in the current Python scope. ~~~~~~~~~~~~~~~~~~~~ * ``Keywords`` is a model of |KeywordsSpec|. -* ``Signature`` is an MPL sequence with the types of the keyword arguments, +* ``Signature`` is an MPL sequence with the types of the keyword parameters, in the order dictated by ``Keywords``, and the return type prepended. * An instance of ``Fwd`` must support this expression: