+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 The Boost Parameter Library Python Binding Documentation 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

:Authors:       David Abrahams, Daniel Wallin
:Contact:       dave@boost-consulting.com, daniel@boostpro.com
:organization:  `BoostPro Computing`_
:date:          $Date: 2010-05-27 13:58:58 -0400 (Thu, 27 May 2010) $

:copyright:     Copyright David Abrahams, Daniel Wallin
                2005-2009. Distributed under the Boost Software License,
                Version 1.0. (See accompanying file LICENSE_1_0.txt
                or copy at http://www.boost.org/LICENSE_1_0.txt)

:abstract:      Makes it possible to bind Boost.Parameter-enabled
                functions, operators and constructors to Python.

|(logo)|__

.. |(logo)| image:: ../../../../boost.png
   :alt: Boost

__ ../../../../index.htm

.. _`BoostPro Computing`: http://www.boostpro.com


.. role:: class
    :class: class

.. role:: concept
    :class: concept

.. role:: function
    :class: function

.. |ParameterSpec| replace:: :concept:`ParameterSpec`

.. contents::
    :depth: 1

Introduction
------------

``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.

.. |def_visitor| replace:: ``def_visitor``
.. |def_visitors| replace:: ``def_visitors``

.. _def_visitor: def_visitors_
.. _def_visitors: ../../../python/doc/v2/def_visitor.html

When binding 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 as an `MPL Sequence`_, using the
    pointer qualifications described in |ParameterSpec|_ below.  The
    signature is also specifid as an `MPL sequence`_ of parameter
    types. Additionally, ``boost::parameter::python::function`` and
    ``boost::parameter::python::def`` requires a class with forwarding
    overloads. We will take a closer look at how this is done in the
    tutorial section below.

The keyword tags and associated argument types are specified as an `MPL
Sequence`_, using the function type syntax described in |ParameterSpec|_
below. Additionally, ``boost::parameter::python::function`` and
``boost::parameter::python::def`` requires a class with forwarding overloads.
We will take a closer look at how this is done in the tutorial section below.

.. The last two sentences are terribly vague.  Which namespace is
.. ``function`` in?  Isn't the return type always needed?  What
.. else are we going to do other than pass these sequences to
.. function?

.. _`MPL Sequence`: ../../../mpl/doc/refmanual/sequences.html
.. _parameterspec: `concept ParameterSpec`_

Tutorial
--------

In this section we will outline the steps needed to bind a simple
Boost.Parameter-enabled member function to Python. Knowledge of the
Boost.Parameter macros_ are required to understand this section.

.. _macros: index.html

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

.. parsed-literal::

  #include <boost/parameter/keyword.hpp>
  #include <boost/parameter/preprocessor.hpp>
  #include <boost/parameter/python.hpp>
  #include <boost/python.hpp>

  // First the keywords
  BOOST_PARAMETER_KEYWORD(tag, title)
  BOOST_PARAMETER_KEYWORD(tag, width)
  BOOST_PARAMETER_KEYWORD(tag, height)

  class window
  {
  public:
      BOOST_PARAMETER_MEMBER_FUNCTION(
        (void), open, tag,
        (required (title, (std::string)))
        (optional (width, (unsigned), 400)
                  (height, (unsigned), 400))
      )
      {
          *… function implementation …*
      }
  };

.. @example.prepend('#include <cassert>')
.. @example.replace_emphasis('''
   assert(title == "foo");
   assert(height == 20);
   assert(width == 400);
   ''')

It defines a set of overloaded member functions called ``open`` with one
required parameter and two optional ones. To bind this member function to
Python we use the binding utility ``boost::parameter::python::function``.
``boost::parameter::python::function`` is a |def_visitor|_ that we'll instantiate
and pass to ``boost::python::class_::def()``.

To use ``boost::parameter::python::function`` we first need to define
a class with forwarding overloads. This is needed because ``window::open()``
is a function template, so we can't refer to it in any other way. 

::

  struct open_fwd
  {
      template <class A0, class A1, class A2>
      void operator()(
          boost::type<void>, window& self
        , A0 const& a0, A1 const& a1, A2 const& a2
      )
      {
          self.open(a0, a1, a2);
      }
  };

The first parameter, ``boost::type<void>``, tells the forwarding overload
what the return type should be. In this case we know that it's always void
but in some cases, when we are exporting several specializations of a
Boost.Parameter-enabled template, we need to use that parameter to
deduce the return type.

``window::open()`` takes a total of 3 parameters, so the forwarding function
needs to take three parameters as well.

.. Note::

    We only need one overload in the forwarding class, despite the
    fact that there are two optional parameters. There are special
    circumstances when several overload are needed; see 
    `special keywords`_.

Next we'll define the module and export the class:

::

  BOOST_PYTHON_MODULE(my_module)
  {
      using namespace boost::python;
      namespace py = boost::parameter::python;
      namespace mpl = boost::mpl;

      class_<window>("window")
          .def(
              "open", py::function<
                  open_fwd
                , mpl::vector<
                      void
                    , tag::title(std::string)
                    , tag::width*(unsigned)
                    , tag::height*(unsigned)
                  >
              >()
          );
  }

.. @jam_prefix.append('import python ;')
.. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
.. @my_module = build(
        output = 'my_module'
      , target_rule = 'python-extension'
      , input = '/boost/python//boost_python'
      , howmany = 'all'
    )

.. @del jam_prefix[:]

``py::function`` is passed two parameters. The first one is the class with
forwarding overloads that we defined earlier. The second one is an `MPL
Sequence`_ with the keyword tag types and argument types for the function
specified as function types. The pointer syntax used in ``tag::width*`` and
``tag::height*`` means that the parameter is optional. The first element of
the `MPL Sequence`_ is the return type of the function, in this case ``void``,
which is passed as the first argument to ``operator()`` in the forwarding
class.

..  The
    pointer syntax means that the parameter is optional, so in this case
    ``width`` and ``height`` are optional parameters. The third parameter
    is an `MPL Sequence`_ with the desired function signature. The return type comes first, and
    then the parameter types:

    .. parsed-literal::

        mpl::vector<void,        std::string, unsigned, unsigned>
                    *return type*  *title*        *width*     *height*

    .. @ignore()

That's it! This class can now be used in Python with the expected syntax::

    >>> w = my_module.window()
    >>> w.open(title = "foo", height = 20)

.. @example.prepend('import my_module')
.. @run_python(module_path = my_module)

.. Sorry to say this at such a late date, but this syntax really
.. strikes me as cumbersome.  Couldn't we do something like:

    class_<window>("window")
          .def(
              "open", 
              (void (*)( 
                  tag::title(std::string), 
                  tag::width*(unsigned), 
                  tag::height*(unsigned)) 
              )0
          );

   or at least:

      class_<window>("window")
          .def(
              "open", 
              mpl::vector<
                  void, 
                  tag::title(std::string), 
                  tag::width*(unsigned), 
                  tag::height*(unsigned)
              >()
          );

   assuming, that is, that we will have to repeat the tags (yes,
   users of broken compilers will have to give us function pointer
   types instead).

------------------------------------------------------------------------------

concept |ParameterSpec|
-----------------------

A |ParameterSpec| is a function type ``K(T)`` that describes both the keyword tag,
``K``, and the argument type, ``T``, for a parameter.

``K`` is either:

* A *required* keyword of the form ``Tag``
* **or**, an *optional* keyword of the form ``Tag*``
* **or**, a *special* keyword of the form ``Tag**``

where ``Tag`` is a keyword tag type, as used in a specialization
of |keyword|__.

.. |keyword| replace:: ``boost::parameter::keyword``
__ ../../../parameter/doc/html/reference.html#keyword

The **arity range** for an `MPL Sequence`_ of |ParameterSpec|'s is
defined as the closed range:

.. parsed-literal::

  [ mpl::size<S> - number of *special* keyword tags in ``S``, mpl::size<S> ]

For example, the **arity range** of ``mpl::vector2<x(int),y(int)>`` is ``[2,2]``,
the **arity range** of ``mpl::vector2<x(int),y*(int)>`` is ``[2,2]`` and the
**arity range** of ``mpl::vector2<x(int),y**(int)>`` is ``[1,2]``.



*special* keywords
---------------------------------

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. For example:

.. 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::

  namespace core
  {
    template <class ArgumentPack>
    void dfs_dispatch(ArgumentPack const& args, mpl::false\_)
    {
        *…compute and use default color map…*
    }

    template <class ArgumentPack, class ColorMap>
    void dfs_dispatch(ArgumentPack const& args, ColorMap colormap)
    {
        *…use colormap…*
    }
  }

  template <class ArgumentPack>
  void depth_first_search(ArgumentPack const& args)
  {
      core::dfs_dispatch(args, args[color | mpl::false_()]);
  }

.. @example.prepend('''
   #include <boost/parameter/keyword.hpp>
   #include <boost/parameter/parameters.hpp>
   #include <boost/mpl/bool.hpp>
   #include <cassert>

   BOOST_PARAMETER_KEYWORD(tag, color);

   typedef boost::parameter::parameters<tag::color> params;

   namespace mpl = boost::mpl;
   ''')

.. @example.replace_emphasis('''
   assert(args[color | 1] == 1);
   ''')

.. @example.replace_emphasis('''
   assert(args[color | 1] == 0);
   ''')

.. @example.append('''
   int main()
   {
       depth_first_search(params()());
       depth_first_search(params()(color = 0));
   }''')

.. @build()

.. .. _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. This is done by specifying the tag as
``tag::color**`` when binding the function (see `concept ParameterSpec`_ for
more details on the tagging). By doing this we tell the binding functions that
it needs to generate two overloads, one with the ``color`` parameter present
and one without. Had there been two *special* keywords, four overloads would
need to be generated. The number of generated overloads is equal to 2\
:sup:`N`, where ``N`` is the number of *special* keywords.

------------------------------------------------------------------------------

class template ``init``
-----------------------

Defines a named parameter enabled constructor.

.. parsed-literal::

    template <class ParameterSpecs>
    struct init : python::def_visitor<init<ParameterSpecs> >
    {
        template <class Class> 
        void def(Class& class\_);

        template <class CallPolicies>
        *def\_visitor* operator[](CallPolicies const& policies) const;
    };

.. @ignore()

``init`` requirements 
~~~~~~~~~~~~~~~~~~~~~

* ``ParameterSpecs`` is an `MPL sequence`_ where each element is a
  model of |ParameterSpec|. 
* For every ``N`` in ``[U,V]``, where ``[U,V]`` is the **arity
  range** of ``ParameterSpecs``, ``Class`` must support these
  expressions: 

  ======================= ============= =========================================
  Expression              Return type   Requirements
  ======================= ============= =========================================
  ``Class(a0, …, aN)``    \-            ``a0``\ …\ ``aN`` are tagged arguments.
  ======================= ============= =========================================



``template <class CallPolicies> operator[](CallPolicies const&)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Returns a ``def_visitor`` equivalent to ``*this``, except that it
uses CallPolicies when creating the binding.


Example
~~~~~~~

.. parsed-literal::

    #include <boost/parameter/keyword.hpp>
    #include <boost/parameter/preprocessor.hpp>
    #include <boost/parameter/python.hpp>
    #include <boost/python.hpp>
    #include <boost/mpl/vector.hpp>

    BOOST_PARAMETER_KEYWORD(tag, x)
    BOOST_PARAMETER_KEYWORD(tag, y)

    struct base 
    { 
        template <class ArgumentPack>
        base(ArgumentPack const& args)
        {
            *… use args …*
        }
    };

    class X : base
    {
    public:
        BOOST_PARAMETER_CONSTRUCTOR(X, (base), tag,
            (required (x, \*))
            (optional (y, \*))
        )
    };

    BOOST_PYTHON_MODULE(*module name*)
    {
        using namespace boost::python;
        namespace py = boost::parameter::python;
        namespace mpl = boost::mpl;

        class_<X>("X", no_init)
            .def(
                py::init<
                    mpl::vector<tag::x(int), tag::y\*(int)>
                >()
            );
    }

.. @example.replace_emphasis('''
   assert(args[x] == 0);
   assert(args[y | 1] == 1);
   ''')

.. @example.replace_emphasis('my_module')

.. @jam_prefix.append('import python ;')
.. @jam_prefix.append('stage . : my_module /boost/python//boost_python ;')
.. @my_module = build(
        output = 'my_module'
      , target_rule = 'python-extension'
      , input = '/boost/python//boost_python'
    )

------------------------------------------------------------------------------

class template ``call``
-----------------------

Defines a ``__call__`` operator, mapped to ``operator()`` in C++.

.. parsed-literal::

    template <class ParameterSpecs>
    struct call : python::def_visitor<call<ParameterSpecs> >
    {
        template <class Class> 
        void def(Class& class\_);

        template <class CallPolicies>
        *def\_visitor* operator[](CallPolicies const& policies) const;
    };

.. @ignore()

``call`` requirements 
~~~~~~~~~~~~~~~~~~~~~

* ``ParameterSpecs`` is an `MPL sequence`_ where each element
  except the first models |ParameterSpec|. The first element
  is the result type of ``c(…)``.
* ``Class`` must support these expressions, where ``c`` is an 
  instance of ``Class``:

  =================== ==================== =======================================
  Expression          Return type          Requirements
  =================== ==================== =======================================
  ``c(a0, …, aN)``    Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
  =================== ==================== =======================================

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


``template <class CallPolicies> operator[](CallPolicies const&)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Returns a ``def_visitor`` equivalent to ``*this``, except that it
uses CallPolicies when creating the binding.


Example
~~~~~~~

.. parsed-literal::

    #include <boost/parameter/keyword.hpp>
    #include <boost/parameter/preprocessor.hpp>
    #include <boost/parameter/python.hpp>
    #include <boost/python.hpp>
    #include <boost/mpl/vector.hpp>

    BOOST_PARAMETER_KEYWORD(tag, x)
    BOOST_PARAMETER_KEYWORD(tag, y)

    namespace parameter = boost::parameter;

    typedef parameter::parameters<
        parameter::required<tag::x>
      , parameter::optional<tag::y>
    > call_parameters;

    class X
    {
    public:
        template <class ArgumentPack>
        int call_impl(ArgumentPack const& args)
        {
            *… use args …*
        }

        template <class A0>
        int operator()(A0 const& a0)
        {
            return call_impl(call_parameters()(a0));
        }

        template <class A0, class A1>
        int operator()(A0 const& a0, A1 const& a1)
        {
            return call_impl(call_parameters()(a0,a1));
        }
    };

    BOOST_PYTHON_MODULE(*module name*)
    {
        using namespace boost::python;
        namespace py = parameter::python;
        namespace mpl = boost::mpl;

        class_<X>("X")
            .def(
                py::call<
                    mpl::vector<int, tag::x(int), tag::y\*(int)>
                >()
            );
    }    

.. @example.replace_emphasis('''
   assert(args[x] == 0);
   assert(args[y | 1] == 1);
   return 0;
   ''')

.. @example.replace_emphasis('my_module')

.. @my_module = build(
        output = 'my_module'
      , target_rule = 'python-extension'
      , input = '/boost/python//boost_python'
    )

------------------------------------------------------------------------------

class template ``function``
---------------------------

Defines a named parameter enabled member function.

.. parsed-literal::

    template <class Fwd, class ParameterSpecs>
    struct function : python::def_visitor<function<Fwd, ParameterSpecs> >
    {
        template <class Class, class Options> 
        void def(Class& class\_, char const* name, Options const& options);
    };

.. @ignore()

``function`` requirements 
~~~~~~~~~~~~~~~~~~~~~~~~~

* ``ParameterSpecs`` is an `MPL sequence`_ where each element
  except the first models |ParameterSpec|. The first element
  is the result type of ``c.f(…)``, where ``f`` is the member
  function.
* An instance of ``Fwd`` must support this expression:

  ============================================ ==================== =================================================
  Expression                                   Return type          Requirements
  ============================================ ==================== =================================================
  ``fwd(boost::type<R>(), self, a0, …, aN)``   Convertible to ``R`` ``self`` is a reference to the object on which
                                                                    the function should be invoked. ``a0``\ …\ ``aN``
                                                                    are tagged arguments.
  ============================================ ==================== =================================================

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


Example
~~~~~~~

This example exports a member function ``f(int x, int y = …)`` to Python. The
sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
an **arity range** of [2,2], so we only need one forwarding overload.

.. parsed-literal::

    #include <boost/parameter/keyword.hpp>
    #include <boost/parameter/preprocessor.hpp>
    #include <boost/parameter/python.hpp>
    #include <boost/python.hpp>
    #include <boost/mpl/vector.hpp>

    BOOST_PARAMETER_KEYWORD(tag, x)
    BOOST_PARAMETER_KEYWORD(tag, y)

    class X
    {
    public:
        BOOST_PARAMETER_MEMBER_FUNCTION((void), f, tag,
            (required (x, \*))
            (optional (y, \*, 1))
        )
        {
            *…*
        }
    };

    struct f_fwd
    {
        template <class A0, class A1>
        void operator()(boost::type<void>, X& self, A0 const& a0, A1 const& a1)
        {
            self.f(a0, a1);
        }
    };

    BOOST_PYTHON_MODULE(*module name*)
    {
        using namespace boost::python;
        namespace py = boost::parameter::python;
        namespace mpl = boost::mpl;

        class_<X>("X")
            .def("f",
                py::function<
                    f_fwd
                  , mpl::vector<void, tag::x(int), tag::y\*(int)>
                >()
            );
    }

.. @example.replace_emphasis('''
   assert(x == 0);
   assert(y == 1);
   ''')

.. @example.replace_emphasis('my_module')

.. @my_module = build(
        output = 'my_module'
      , target_rule = 'python-extension'
      , input = '/boost/python//boost_python'
    )

------------------------------------------------------------------------------

function template ``def``
-------------------------

Defines a named parameter enabled free function in the current Python scope.

.. parsed-literal::

    template <class Fwd, class ParameterSpecs>
    void def(char const* name);

.. @ignore()

``def`` requirements 
~~~~~~~~~~~~~~~~~~~~

* ``ParameterSpecs`` is an `MPL sequence`_ where each element
  except the first models |ParameterSpec|. The first element
  is the result type of ``f(…)``, where ``f`` is the function.
* An instance of ``Fwd`` must support this expression:

  ====================================== ==================== =======================================
  Expression                             Return type          Requirements
  ====================================== ==================== =======================================
  ``fwd(boost::type<R>(), a0, …, aN)``   Convertible to ``R`` ``a0``\ …\ ``aN`` are tagged arguments.
  ====================================== ==================== =======================================

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


Example
~~~~~~~

This example exports a function ``f(int x, int y = …)`` to Python. The
sequence of |ParameterSpec|'s ``mpl::vector2<tag::x(int), tag::y*(int)>`` has
an **arity range** of [2,2], so we only need one forwarding overload.

.. parsed-literal::

    BOOST_PARAMETER_FUNCTION((void), f, tag,
        (required (x, \*))
        (optional (y, \*, 1))
    )
    {
        *…*
    }

    struct f_fwd
    {
        template <class A0, class A1>
        void operator()(boost::type<void>, A0 const& a0, A1 const& a1)
        {
            f(a0, a1);
        }
    };

    BOOST_PYTHON_MODULE(…)
    {
        def<
            f_fwd
          , mpl::vector<
                void, tag::\ x(int), tag::\ y\*(int)
            >
        >("f");
    }

.. @ignore()

.. again, the undefined ``fwd`` identifier.

Portability
-----------

The Boost.Parameter Python binding library requires *partial template
specialization*.

